diff --git a/.gitignore b/.gitignore index eff6268c1973c..1c8d4b15925de 100644 --- a/.gitignore +++ b/.gitignore @@ -53,5 +53,11 @@ autoconf/autom4te.cache # VS2017 and VSCode config files. .vscode .vs -# clangd index -.clangd +# clangd index. (".clangd" is a config file now, thus trailing slash) +.clangd/ +.cache +# static analyzer regression testing project files +/clang/utils/analyzer/projects/*/CachedSource +/clang/utils/analyzer/projects/*/PatchedSource +/clang/utils/analyzer/projects/*/ScanBuildResults +/clang/utils/analyzer/projects/*/RefScanBuildResults diff --git a/clang-tools-extra/clang-change-namespace/CMakeLists.txt b/clang-tools-extra/clang-change-namespace/CMakeLists.txt index bfce9869dde84..4cd9e7520b97b 100644 --- a/clang-tools-extra/clang-change-namespace/CMakeLists.txt +++ b/clang-tools-extra/clang-change-namespace/CMakeLists.txt @@ -5,6 +5,9 @@ set(LLVM_LINK_COMPONENTS add_clang_library(clangChangeNamespace ChangeNamespace.cpp + + DEPENDS + omp_gen ) clang_target_link_libraries(clangChangeNamespace diff --git a/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp b/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp index e2a70db4102b2..61ae7c4cc7036 100644 --- a/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp +++ b/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp @@ -19,14 +19,8 @@ namespace change_namespace { namespace { -inline std::string -joinNamespaces(const llvm::SmallVectorImpl &Namespaces) { - if (Namespaces.empty()) - return ""; - std::string Result(Namespaces.front()); - for (auto I = Namespaces.begin() + 1, E = Namespaces.end(); I != E; ++I) - Result += ("::" + *I).str(); - return Result; +inline std::string joinNamespaces(ArrayRef Namespaces) { + return llvm::join(Namespaces, "::"); } // Given "a::b::c", returns {"a", "b", "c"}. diff --git a/clang-tools-extra/clang-doc/CMakeLists.txt b/clang-tools-extra/clang-doc/CMakeLists.txt index 56ec9eb6e94e2..a43660c488495 100644 --- a/clang-tools-extra/clang-doc/CMakeLists.txt +++ b/clang-tools-extra/clang-doc/CMakeLists.txt @@ -15,6 +15,9 @@ add_clang_library(clangDoc Representation.cpp Serialize.cpp YAMLGenerator.cpp + + DEPENDS + omp_gen ) clang_target_link_libraries(clangDoc diff --git a/clang-tools-extra/clang-include-fixer/CMakeLists.txt b/clang-tools-extra/clang-include-fixer/CMakeLists.txt index d8685cb20758c..5581d436f2fe4 100644 --- a/clang-tools-extra/clang-include-fixer/CMakeLists.txt +++ b/clang-tools-extra/clang-include-fixer/CMakeLists.txt @@ -12,6 +12,9 @@ add_clang_library(clangIncludeFixer LINK_LIBS findAllSymbols + + DEPENDS + omp_gen ) clang_target_link_libraries(clangIncludeFixer diff --git a/clang-tools-extra/clang-include-fixer/find-all-symbols/CMakeLists.txt b/clang-tools-extra/clang-include-fixer/find-all-symbols/CMakeLists.txt index c0760e8b69c6c..0d9f686dfe80a 100644 --- a/clang-tools-extra/clang-include-fixer/find-all-symbols/CMakeLists.txt +++ b/clang-tools-extra/clang-include-fixer/find-all-symbols/CMakeLists.txt @@ -12,6 +12,9 @@ add_clang_library(findAllSymbols PragmaCommentHandler.cpp STLPostfixHeaderMap.cpp SymbolInfo.cpp + + DEPENDS + omp_gen ) clang_target_link_libraries(findAllSymbols diff --git a/clang-tools-extra/clang-include-fixer/plugin/CMakeLists.txt b/clang-tools-extra/clang-include-fixer/plugin/CMakeLists.txt index df792ea1bbe43..6d0328ed83124 100644 --- a/clang-tools-extra/clang-include-fixer/plugin/CMakeLists.txt +++ b/clang-tools-extra/clang-include-fixer/plugin/CMakeLists.txt @@ -10,4 +10,7 @@ add_clang_library(clangIncludeFixerPlugin clangSema clangTooling ${LLVM_PTHREAD_LIB} + + DEPENDS + omp_gen ) diff --git a/clang-tools-extra/clang-move/CMakeLists.txt b/clang-tools-extra/clang-move/CMakeLists.txt index e3bef84baa003..0b748ce6cd99a 100644 --- a/clang-tools-extra/clang-move/CMakeLists.txt +++ b/clang-tools-extra/clang-move/CMakeLists.txt @@ -6,6 +6,9 @@ set(LLVM_LINK_COMPONENTS add_clang_library(clangMove Move.cpp HelperDeclRefGraph.cpp + + DEPENDS + omp_gen ) clang_target_link_libraries(clangMove diff --git a/clang-tools-extra/clang-move/Move.cpp b/clang-tools-extra/clang-move/Move.cpp index 28184a0dce0c6..3f09f68a8046f 100644 --- a/clang-tools-extra/clang-move/Move.cpp +++ b/clang-tools-extra/clang-move/Move.cpp @@ -552,20 +552,22 @@ void ClangMoveTool::registerMatchers(ast_matchers::MatchFinder *Finder) { // Match static functions/variable definitions which are defined in named // namespaces. - Optional> HasAnySymbolNames; + SmallVector QualNames; + QualNames.reserve(Context->Spec.Names.size()); for (StringRef SymbolName : Context->Spec.Names) { - llvm::StringRef GlobalSymbolName = SymbolName.trim().ltrim(':'); - const auto HasName = hasName(("::" + GlobalSymbolName).str()); - HasAnySymbolNames = - HasAnySymbolNames ? anyOf(*HasAnySymbolNames, HasName) : HasName; + QualNames.push_back(("::" + SymbolName.trim().ltrim(':')).str()); } - if (!HasAnySymbolNames) { + if (QualNames.empty()) { llvm::errs() << "No symbols being moved.\n"; return; } + + ast_matchers::internal::Matcher HasAnySymbolNames = + hasAnyName(SmallVector(QualNames.begin(), QualNames.end())); + auto InMovedClass = - hasOutermostEnclosingClass(cxxRecordDecl(*HasAnySymbolNames)); + hasOutermostEnclosingClass(cxxRecordDecl(HasAnySymbolNames)); // Matchers for helper declarations in old.cc. auto InAnonymousNS = hasParent(namespaceDecl(isAnonymous())); @@ -612,17 +614,17 @@ void ClangMoveTool::registerMatchers(ast_matchers::MatchFinder *Finder) { // Create a MatchCallback for class declarations. MatchCallbacks.push_back(std::make_unique(this)); // Match moved class declarations. - auto MovedClass = cxxRecordDecl(InOldFiles, *HasAnySymbolNames, - isDefinition(), TopLevelDecl) - .bind("moved_class"); + auto MovedClass = + cxxRecordDecl(InOldFiles, HasAnySymbolNames, isDefinition(), TopLevelDecl) + .bind("moved_class"); Finder->addMatcher(MovedClass, MatchCallbacks.back().get()); // Match moved class methods (static methods included) which are defined // outside moved class declaration. - Finder->addMatcher( - cxxMethodDecl(InOldFiles, ofOutermostEnclosingClass(*HasAnySymbolNames), - isDefinition()) - .bind("class_method"), - MatchCallbacks.back().get()); + Finder->addMatcher(cxxMethodDecl(InOldFiles, + ofOutermostEnclosingClass(HasAnySymbolNames), + isDefinition()) + .bind("class_method"), + MatchCallbacks.back().get()); // Match static member variable definition of the moved class. Finder->addMatcher( varDecl(InMovedClass, InOldFiles, isDefinition(), isStaticDataMember()) @@ -630,20 +632,20 @@ void ClangMoveTool::registerMatchers(ast_matchers::MatchFinder *Finder) { MatchCallbacks.back().get()); MatchCallbacks.push_back(std::make_unique(this)); - Finder->addMatcher(functionDecl(InOldFiles, *HasAnySymbolNames, TopLevelDecl) + Finder->addMatcher(functionDecl(InOldFiles, HasAnySymbolNames, TopLevelDecl) .bind("function"), MatchCallbacks.back().get()); MatchCallbacks.push_back(std::make_unique(this)); Finder->addMatcher( - varDecl(InOldFiles, *HasAnySymbolNames, TopLevelDecl).bind("var"), + varDecl(InOldFiles, HasAnySymbolNames, TopLevelDecl).bind("var"), MatchCallbacks.back().get()); // Match enum definition in old.h. Enum helpers (which are defined in old.cc) // will not be moved for now no matter whether they are used or not. MatchCallbacks.push_back(std::make_unique(this)); Finder->addMatcher( - enumDecl(InOldHeader, *HasAnySymbolNames, isDefinition(), TopLevelDecl) + enumDecl(InOldHeader, HasAnySymbolNames, isDefinition(), TopLevelDecl) .bind("enum"), MatchCallbacks.back().get()); @@ -653,7 +655,7 @@ void ClangMoveTool::registerMatchers(ast_matchers::MatchFinder *Finder) { MatchCallbacks.push_back(std::make_unique(this)); Finder->addMatcher(namedDecl(anyOf(typedefDecl().bind("typedef"), typeAliasDecl().bind("type_alias")), - InOldHeader, *HasAnySymbolNames, TopLevelDecl), + InOldHeader, HasAnySymbolNames, TopLevelDecl), MatchCallbacks.back().get()); } diff --git a/clang-tools-extra/clang-query/CMakeLists.txt b/clang-tools-extra/clang-query/CMakeLists.txt index 8192ec4770ebc..043d26147a7f1 100644 --- a/clang-tools-extra/clang-query/CMakeLists.txt +++ b/clang-tools-extra/clang-query/CMakeLists.txt @@ -7,6 +7,9 @@ set(LLVM_LINK_COMPONENTS add_clang_library(clangQuery Query.cpp QueryParser.cpp + + DEPENDS + omp_gen ) clang_target_link_libraries(clangQuery diff --git a/clang-tools-extra/clang-query/Query.cpp b/clang-tools-extra/clang-query/Query.cpp index 2fc7af6a56e14..ca2a285e9eb7a 100644 --- a/clang-tools-extra/clang-query/Query.cpp +++ b/clang-tools-extra/clang-query/Query.cpp @@ -46,12 +46,12 @@ bool HelpQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const { " set traversal " "Set traversal kind of clang-query session. Available kinds are:\n" " AsIs " - "Print and match the AST as clang sees it.\n" + "Print and match the AST as clang sees it. This mode is the " + "default.\n" " IgnoreImplicitCastsAndParentheses " "Omit implicit casts and parens in matching and dumping.\n" " IgnoreUnlessSpelledInSource " - "Omit AST nodes unless spelled in the source. This mode is the " - "default.\n" + "Omit AST nodes unless spelled in the source.\n" " set output " "Set whether to output only content.\n" " enable output " @@ -157,8 +157,7 @@ bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const { OS << "Binding for \"" << BI->first << "\":\n"; const ASTContext &Ctx = AST->getASTContext(); const SourceManager &SM = Ctx.getSourceManager(); - ASTDumper Dumper(OS, &Ctx.getCommentCommandTraits(), &SM, - SM.getDiagnostics().getShowColors(), Ctx.getPrintingPolicy()); + ASTDumper Dumper(OS, Ctx, SM.getDiagnostics().getShowColors()); Dumper.SetTraversalKind(QS.TK); Dumper.Visit(BI->second); OS << "\n"; diff --git a/clang-tools-extra/clang-query/QuerySession.h b/clang-tools-extra/clang-query/QuerySession.h index 1660e4039f613..20c788b206a0a 100644 --- a/clang-tools-extra/clang-query/QuerySession.h +++ b/clang-tools-extra/clang-query/QuerySession.h @@ -26,7 +26,7 @@ class QuerySession { QuerySession(llvm::ArrayRef> ASTs) : ASTs(ASTs), PrintOutput(false), DiagOutput(true), DetailedASTOutput(false), BindRoot(true), PrintMatcher(false), - Terminate(false), TK(ast_type_traits::TK_IgnoreUnlessSpelledInSource) {} + Terminate(false), TK(ast_type_traits::TK_AsIs) {} llvm::ArrayRef> ASTs; diff --git a/clang-tools-extra/clang-reorder-fields/CMakeLists.txt b/clang-tools-extra/clang-reorder-fields/CMakeLists.txt index 995efbb2f83a3..4013c46433e65 100644 --- a/clang-tools-extra/clang-reorder-fields/CMakeLists.txt +++ b/clang-tools-extra/clang-reorder-fields/CMakeLists.txt @@ -5,6 +5,9 @@ set(LLVM_LINK_COMPONENTS add_clang_library(clangReorderFields ReorderFieldsAction.cpp + + DEPENDS + omp_gen ) clang_target_link_libraries(clangReorderFields diff --git a/clang-tools-extra/clang-tidy/CMakeLists.txt b/clang-tools-extra/clang-tidy/CMakeLists.txt index f552cb3ad835a..02573534ccaef 100644 --- a/clang-tools-extra/clang-tidy/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/CMakeLists.txt @@ -15,6 +15,7 @@ add_clang_library(clangTidy DEPENDS ClangSACheckers + omp_gen ) clang_target_link_libraries(clangTidy diff --git a/clang-tools-extra/clang-tidy/ClangTidy.cpp b/clang-tools-extra/clang-tidy/ClangTidy.cpp index 163aad2ec3782..d6913dfd3c078 100644 --- a/clang-tools-extra/clang-tidy/ClangTidy.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidy.cpp @@ -15,6 +15,7 @@ //===----------------------------------------------------------------------===// #include "ClangTidy.h" +#include "ClangTidyCheck.h" #include "ClangTidyDiagnosticConsumer.h" #include "ClangTidyModuleRegistry.h" #include "ClangTidyProfiling.h" diff --git a/clang-tools-extra/clang-tidy/ClangTidy.h b/clang-tools-extra/clang-tidy/ClangTidy.h index 0f3c3ac8ab96c..99dcbb6a269a8 100644 --- a/clang-tools-extra/clang-tidy/ClangTidy.h +++ b/clang-tools-extra/clang-tidy/ClangTidy.h @@ -9,19 +9,22 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDY_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDY_H -#include "ClangTidyCheck.h" #include "ClangTidyDiagnosticConsumer.h" #include "ClangTidyOptions.h" -#include "llvm/Support/raw_ostream.h" #include #include +namespace llvm { +class raw_ostream; +} // namespace llvm + namespace clang { +class ASTConsumer; class CompilerInstance; namespace tooling { class CompilationDatabase; -} +} // namespace tooling namespace tidy { diff --git a/clang-tools-extra/clang-tidy/ClangTidyCheck.cpp b/clang-tools-extra/clang-tidy/ClangTidyCheck.cpp index 7ddf054a21a94..e149978bcdeaf 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyCheck.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidyCheck.cpp @@ -76,16 +76,25 @@ ClangTidyCheck::OptionsView::get(StringRef LocalName) const { return llvm::make_error((NamePrefix + LocalName).str()); } +static ClangTidyOptions::OptionMap::const_iterator +findPriorityOption(const ClangTidyOptions::OptionMap &Options, StringRef NamePrefix, + StringRef LocalName) { + auto IterLocal = Options.find((NamePrefix + LocalName).str()); + auto IterGlobal = Options.find(LocalName.str()); + if (IterLocal == Options.end()) + return IterGlobal; + if (IterGlobal == Options.end()) + return IterLocal; + if (IterLocal->second.Priority >= IterGlobal->second.Priority) + return IterLocal; + return IterGlobal; +} + llvm::Expected ClangTidyCheck::OptionsView::getLocalOrGlobal(StringRef LocalName) const { - auto IterLocal = CheckOptions.find(NamePrefix + LocalName.str()); - auto IterGlobal = CheckOptions.find(LocalName.str()); - if (IterLocal != CheckOptions.end() && - (IterGlobal == CheckOptions.end() || - IterLocal->second.Priority >= IterGlobal->second.Priority)) - return IterLocal->second.Value; - if (IterGlobal != CheckOptions.end()) - return IterGlobal->second.Value; + auto Iter = findPriorityOption(CheckOptions, NamePrefix, LocalName); + if (Iter != CheckOptions.end()) + return Iter->second.Value; return llvm::make_error((NamePrefix + LocalName).str()); } @@ -124,14 +133,9 @@ bool ClangTidyCheck::OptionsView::get(StringRef LocalName, template <> llvm::Expected ClangTidyCheck::OptionsView::getLocalOrGlobal(StringRef LocalName) const { - auto IterLocal = CheckOptions.find(NamePrefix + LocalName.str()); - auto IterGlobal = CheckOptions.find(LocalName.str()); - if (IterLocal != CheckOptions.end() && - (IterGlobal == CheckOptions.end() || - IterLocal->second.Priority >= IterGlobal->second.Priority)) - return getAsBool(IterLocal->second.Value, NamePrefix + LocalName); - if (IterGlobal != CheckOptions.end()) - return getAsBool(IterGlobal->second.Value, llvm::Twine(LocalName)); + auto Iter = findPriorityOption(CheckOptions, NamePrefix, LocalName); + if (Iter != CheckOptions.end()) + return getAsBool(Iter->second.Value, Iter->first); return llvm::make_error((NamePrefix + LocalName).str()); } @@ -157,12 +161,13 @@ void ClangTidyCheck::OptionsView::store(ClangTidyOptions::OptionMap &Options, store(Options, LocalName, llvm::itostr(Value)); } -llvm::Expected ClangTidyCheck::OptionsView::getEnumInt( - StringRef LocalName, ArrayRef> Mapping, - bool CheckGlobal, bool IgnoreCase) { - auto Iter = CheckOptions.find((NamePrefix + LocalName).str()); - if (CheckGlobal && Iter == CheckOptions.end()) - Iter = CheckOptions.find(LocalName.str()); +llvm::Expected +ClangTidyCheck::OptionsView::getEnumInt(StringRef LocalName, + ArrayRef Mapping, + bool CheckGlobal, bool IgnoreCase) { + auto Iter = CheckGlobal + ? findPriorityOption(CheckOptions, NamePrefix, LocalName) + : CheckOptions.find((NamePrefix + LocalName).str()); if (Iter == CheckOptions.end()) return llvm::make_error((NamePrefix + LocalName).str()); @@ -171,19 +176,19 @@ llvm::Expected ClangTidyCheck::OptionsView::getEnumInt( unsigned EditDistance = -1; for (const auto &NameAndEnum : Mapping) { if (IgnoreCase) { - if (Value.equals_lower(NameAndEnum.first)) - return NameAndEnum.second; - } else if (Value.equals(NameAndEnum.first)) { - return NameAndEnum.second; - } else if (Value.equals_lower(NameAndEnum.first)) { - Closest = NameAndEnum.first; + if (Value.equals_lower(NameAndEnum.second)) + return NameAndEnum.first; + } else if (Value.equals(NameAndEnum.second)) { + return NameAndEnum.first; + } else if (Value.equals_lower(NameAndEnum.second)) { + Closest = NameAndEnum.second; EditDistance = 0; continue; } - unsigned Distance = Value.edit_distance(NameAndEnum.first); + unsigned Distance = Value.edit_distance(NameAndEnum.second); if (Distance < EditDistance) { EditDistance = Distance; - Closest = NameAndEnum.first; + Closest = NameAndEnum.second; } } if (EditDistance < 3) diff --git a/clang-tools-extra/clang-tidy/ClangTidyCheck.h b/clang-tools-extra/clang-tidy/ClangTidyCheck.h index 84438c21a30b8..3c625ee0cb796 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyCheck.h +++ b/clang-tools-extra/clang-tidy/ClangTidyCheck.h @@ -13,20 +13,26 @@ #include "ClangTidyOptions.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Basic/Diagnostic.h" -#include "clang/Basic/SourceManager.h" #include "llvm/ADT/Optional.h" -#include "llvm/ADT/StringExtras.h" #include "llvm/Support/Error.h" -#include #include +#include #include namespace clang { class CompilerInstance; +class SourceManager; namespace tidy { +/// This class should be specialized by any enum type that needs to be converted +/// to and from an \ref llvm::StringRef. +template struct OptionEnumMapping { + // Specializations of this struct must implement this function. + static ArrayRef> getEnumMapping() = delete; +}; + template class OptionError : public llvm::ErrorInfo { std::error_code convertToErrorCode() const override { return llvm::inconvertibleErrorCode(); @@ -313,36 +319,38 @@ class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback { } /// Read a named option from the ``Context`` and parse it as an - /// enum type ``T`` using the \p Mapping provided. If \p IgnoreCase is set, - /// it will search the mapping ignoring the case. + /// enum type ``T``. /// /// Reads the option with the check-local name \p LocalName from the /// ``CheckOptions``. If the corresponding key is not present, returns a /// ``MissingOptionError``. If the key can't be parsed as a ``T`` returns a /// ``UnparseableEnumOptionError``. + /// + /// \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to + /// supply the mapping required to convert between ``T`` and a string. template std::enable_if_t::value, llvm::Expected> - get(StringRef LocalName, ArrayRef> Mapping, - bool IgnoreCase = false) { - if (llvm::Expected ValueOr = getEnumInt( - LocalName, typeEraseMapping(Mapping), false, IgnoreCase)) + get(StringRef LocalName, bool IgnoreCase = false) { + if (llvm::Expected ValueOr = + getEnumInt(LocalName, typeEraseMapping(), false, IgnoreCase)) return static_cast(*ValueOr); else return std::move(ValueOr.takeError()); } /// Read a named option from the ``Context`` and parse it as an - /// enum type ``T`` using the \p Mapping provided. If \p IgnoreCase is set, - /// it will search the mapping ignoring the case. + /// enum type ``T``. /// /// Reads the option with the check-local name \p LocalName from the /// ``CheckOptions``. If the corresponding key is not present or it can't be /// parsed as a ``T``, returns \p Default. + /// + /// \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to + /// supply the mapping required to convert between ``T`` and a string. template std::enable_if_t::value, T> - get(StringRef LocalName, ArrayRef> Mapping, - T Default, bool IgnoreCase = false) { - if (auto ValueOr = get(LocalName, Mapping, IgnoreCase)) + get(StringRef LocalName, T Default, bool IgnoreCase = false) { + if (auto ValueOr = get(LocalName, IgnoreCase)) return *ValueOr; else logErrToStdErr(ValueOr.takeError()); @@ -350,40 +358,41 @@ class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback { } /// Read a named option from the ``Context`` and parse it as an - /// enum type ``T`` using the \p Mapping provided. If \p IgnoreCase is set, - /// it will search the mapping ignoring the case. + /// enum type ``T``. /// /// Reads the option with the check-local name \p LocalName from local or /// global ``CheckOptions``. Gets local option first. If local is not /// present, falls back to get global option. If global option is not /// present either, returns a ``MissingOptionError``. If the key can't be /// parsed as a ``T`` returns a ``UnparseableEnumOptionError``. + /// + /// \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to + /// supply the mapping required to convert between ``T`` and a string. template std::enable_if_t::value, llvm::Expected> getLocalOrGlobal(StringRef LocalName, - ArrayRef> Mapping, bool IgnoreCase = false) { - if (llvm::Expected ValueOr = getEnumInt( - LocalName, typeEraseMapping(Mapping), true, IgnoreCase)) + if (llvm::Expected ValueOr = + getEnumInt(LocalName, typeEraseMapping(), true, IgnoreCase)) return static_cast(*ValueOr); else return std::move(ValueOr.takeError()); } /// Read a named option from the ``Context`` and parse it as an - /// enum type ``T`` using the \p Mapping provided. If \p IgnoreCase is set, - /// it will search the mapping ignoring the case. + /// enum type ``T``. /// /// Reads the option with the check-local name \p LocalName from local or /// global ``CheckOptions``. Gets local option first. If local is not /// present, falls back to get global option. If global option is not /// present either or it can't be parsed as a ``T``, returns \p Default. + /// + /// \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to + /// supply the mapping required to convert between ``T`` and a string. template std::enable_if_t::value, T> - getLocalOrGlobal(StringRef LocalName, - ArrayRef> Mapping, T Default, - bool IgnoreCase = false) { - if (auto ValueOr = getLocalOrGlobal(LocalName, Mapping, IgnoreCase)) + getLocalOrGlobal(StringRef LocalName, T Default, bool IgnoreCase = false) { + if (auto ValueOr = getLocalOrGlobal(LocalName, IgnoreCase)) return *ValueOr; else logErrToStdErr(ValueOr.takeError()); @@ -401,21 +410,25 @@ class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback { int64_t Value) const; /// Stores an option with the check-local name \p LocalName as the string - /// representation of the Enum \p Value using the \p Mapping to \p Options. + /// representation of the Enum \p Value to \p Options. + /// + /// \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to + /// supply the mapping required to convert between ``T`` and a string. template std::enable_if_t::value> - store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, T Value, - ArrayRef> Mapping) { + store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, T Value) { + ArrayRef> Mapping = + OptionEnumMapping::getEnumMapping(); auto Iter = llvm::find_if( - Mapping, [&](const std::pair &NameAndEnum) { - return NameAndEnum.second == Value; + Mapping, [&](const std::pair &NameAndEnum) { + return NameAndEnum.first == Value; }); assert(Iter != Mapping.end() && "Unknown Case Value"); - store(Options, LocalName, Iter->first); + store(Options, LocalName, Iter->second); } private: - using NameAndValue = std::pair; + using NameAndValue = std::pair; llvm::Expected getEnumInt(StringRef LocalName, ArrayRef Mapping, @@ -423,12 +436,14 @@ class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback { template std::enable_if_t::value, std::vector> - typeEraseMapping(ArrayRef> Mapping) { + typeEraseMapping() { + ArrayRef> Mapping = + OptionEnumMapping::getEnumMapping(); std::vector Result; Result.reserve(Mapping.size()); for (auto &MappedItem : Mapping) { - Result.emplace_back(MappedItem.first, - static_cast(MappedItem.second)); + Result.emplace_back(static_cast(MappedItem.first), + MappedItem.second); } return Result; } diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp index 5c23323b03f0d..521e6ef549b96 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp @@ -18,16 +18,21 @@ #include "ClangTidyDiagnosticConsumer.h" #include "ClangTidyOptions.h" #include "GlobList.h" +#include "clang/AST/ASTContext.h" #include "clang/AST/ASTDiagnostic.h" #include "clang/AST/Attr.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticOptions.h" +#include "clang/Basic/FileManager.h" +#include "clang/Basic/SourceManager.h" #include "clang/Frontend/DiagnosticRenderer.h" #include "clang/Tooling/Core/Diagnostic.h" +#include "clang/Tooling/Core/Replacement.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" -#include "llvm/Support/Regex.h" +#include "llvm/ADT/StringMap.h" #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/Regex.h" #include #include using namespace clang; diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h index 90cc4da3021f1..eaa7f1851ce32 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h +++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h @@ -12,21 +12,15 @@ #include "ClangTidyOptions.h" #include "ClangTidyProfiling.h" #include "clang/Basic/Diagnostic.h" -#include "clang/Basic/SourceManager.h" #include "clang/Tooling/Core/Diagnostic.h" -#include "clang/Tooling/Refactoring.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/Support/Timer.h" - -namespace llvm { -class Regex; -} +#include "llvm/Support/Regex.h" namespace clang { class ASTContext; class CompilerInstance; +class SourceManager; namespace ast_matchers { class MatchFinder; } diff --git a/clang-tools-extra/clang-tidy/ClangTidyModule.cpp b/clang-tools-extra/clang-tidy/ClangTidyModule.cpp index 6e44f72079877..e9031d498eeff 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidyModule.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "ClangTidyModule.h" +#include "ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/ClangTidyModule.h b/clang-tools-extra/clang-tidy/ClangTidyModule.h index 5c484f1a68ddb..31cf4774a885a 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyModule.h +++ b/clang-tools-extra/clang-tidy/ClangTidyModule.h @@ -9,17 +9,20 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYMODULE_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYMODULE_H -#include "ClangTidy.h" +#include "ClangTidyOptions.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include #include #include #include -#include namespace clang { namespace tidy { +class ClangTidyCheck; +class ClangTidyContext; + /// A collection of \c ClangTidyCheckFactory instances. /// /// All clang-tidy modules register their check factories with an instance of @@ -27,12 +30,12 @@ namespace tidy { class ClangTidyCheckFactories { public: using CheckFactory = std::function( - StringRef Name, ClangTidyContext *Context)>; + llvm::StringRef Name, ClangTidyContext *Context)>; /// Registers check \p Factory with name \p Name. /// /// For all checks that have default constructors, use \c registerCheck. - void registerCheckFactory(StringRef Name, CheckFactory Factory); + void registerCheckFactory(llvm::StringRef Name, CheckFactory Factory); /// Registers the \c CheckType with the name \p Name. /// @@ -55,9 +58,9 @@ class ClangTidyCheckFactories { /// } /// }; /// \endcode - template void registerCheck(StringRef CheckName) { + template void registerCheck(llvm::StringRef CheckName) { registerCheckFactory(CheckName, - [](StringRef Name, ClangTidyContext *Context) { + [](llvm::StringRef Name, ClangTidyContext *Context) { return std::make_unique(Name, Context); }); } diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp index 4fa78e2803f13..4c1f286737817 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp @@ -287,7 +287,7 @@ FileOptionsProvider::FileOptionsProvider( const ClangTidyOptions &OverrideOptions, llvm::IntrusiveRefCntPtr VFS) : FileOptionsBaseProvider(GlobalOptions, DefaultOptions, OverrideOptions, - VFS){}; + VFS){} FileOptionsProvider::FileOptionsProvider( const ClangTidyGlobalOptions &GlobalOptions, diff --git a/clang-tools-extra/clang-tidy/ClangTidyProfiling.h b/clang-tools-extra/clang-tidy/ClangTidyProfiling.h index a266e388bbe3a..9487a34620e0a 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyProfiling.h +++ b/clang-tools-extra/clang-tidy/ClangTidyProfiling.h @@ -13,10 +13,11 @@ #include "llvm/ADT/StringMap.h" #include "llvm/Support/Chrono.h" #include "llvm/Support/Timer.h" -#include "llvm/Support/raw_ostream.h" #include -#include -#include + +namespace llvm { +class raw_ostream; +} // namespace llvm namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/abseil/CMakeLists.txt b/clang-tools-extra/clang-tidy/abseil/CMakeLists.txt index 7d8601ad60e45..b6ea21879dafa 100644 --- a/clang-tools-extra/clang-tidy/abseil/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/abseil/CMakeLists.txt @@ -28,6 +28,9 @@ add_clang_library(clangTidyAbseilModule LINK_LIBS clangTidy clangTidyUtils + + DEPENDS + omp_gen ) clang_target_link_libraries(clangTidyAbseilModule diff --git a/clang-tools-extra/clang-tidy/abseil/DurationAdditionCheck.h b/clang-tools-extra/clang-tidy/abseil/DurationAdditionCheck.h index 64b4d89e834f6..4f93be6abaa10 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationAdditionCheck.h +++ b/clang-tools-extra/clang-tidy/abseil/DurationAdditionCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMEADDITIONCHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMEADDITIONCHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/abseil/DurationComparisonCheck.h b/clang-tools-extra/clang-tidy/abseil/DurationComparisonCheck.h index 4c7085fce7731..b3d6add1dd5bf 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationComparisonCheck.h +++ b/clang-tools-extra/clang-tidy/abseil/DurationComparisonCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_DURATIONCOMPARISONCHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_DURATIONCOMPARISONCHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/abseil/DurationConversionCastCheck.h b/clang-tools-extra/clang-tidy/abseil/DurationConversionCastCheck.h index bc1d6203c1c62..0aa95fffa3bbf 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationConversionCastCheck.h +++ b/clang-tools-extra/clang-tidy/abseil/DurationConversionCastCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_DURATIONCONVERSIONCASTCHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_DURATIONCONVERSIONCASTCHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.cpp b/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.cpp index 01e01469acee8..ab55dd7f9019e 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.cpp @@ -9,6 +9,7 @@ #include "DurationDivisionCheck.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.h b/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.h index 42f6cd3701ba0..a4e4dd57a4d80 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.h +++ b/clang-tools-extra/clang-tidy/abseil/DurationDivisionCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_DURATIONDIVISIONCHECK_H_ #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_DURATIONDIVISIONCHECK_H_ -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.cpp b/clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.cpp index d46265d18ae80..ed7e9fd0dfade 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.cpp @@ -10,6 +10,7 @@ #include "DurationRewriter.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" #include "clang/Tooling/FixIt.h" using namespace clang::ast_matchers; diff --git a/clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.h b/clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.h index cc773153d5118..f804ca296f6bd 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.h +++ b/clang-tools-extra/clang-tidy/abseil/DurationFactoryFloatCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_DURATIONFACTORYFLOATCHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_DURATIONFACTORYFLOATCHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/abseil/DurationFactoryScaleCheck.h b/clang-tools-extra/clang-tidy/abseil/DurationFactoryScaleCheck.h index 3b79b91d0eeaa..15a9f3fca3c43 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationFactoryScaleCheck.h +++ b/clang-tools-extra/clang-tidy/abseil/DurationFactoryScaleCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_DURATIONFACTORYSCALECHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_DURATIONFACTORYSCALECHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/abseil/DurationSubtractionCheck.h b/clang-tools-extra/clang-tidy/abseil/DurationSubtractionCheck.h index 89deb375785f1..19a684a995cde 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationSubtractionCheck.h +++ b/clang-tools-extra/clang-tidy/abseil/DurationSubtractionCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_DURATIONSUBTRACTIONCHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_DURATIONSUBTRACTIONCHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/abseil/DurationUnnecessaryConversionCheck.h b/clang-tools-extra/clang-tidy/abseil/DurationUnnecessaryConversionCheck.h index 180613388918e..b3eb5677f4f7b 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationUnnecessaryConversionCheck.h +++ b/clang-tools-extra/clang-tidy/abseil/DurationUnnecessaryConversionCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMEDOUBLECONVERSIONCHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMEDOUBLECONVERSIONCHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.h b/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.h index 4b7e18bc43987..439e7db9982e5 100644 --- a/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.h +++ b/clang-tools-extra/clang-tidy/abseil/FasterStrsplitDelimiterCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_FASTERSTRSPLITDELIMITERCHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_FASTERSTRSPLITDELIMITERCHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/abseil/NoInternalDependenciesCheck.h b/clang-tools-extra/clang-tidy/abseil/NoInternalDependenciesCheck.h index c71a81fe29361..9b0f2323e6b74 100644 --- a/clang-tools-extra/clang-tidy/abseil/NoInternalDependenciesCheck.h +++ b/clang-tools-extra/clang-tidy/abseil/NoInternalDependenciesCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_NOINTERNALDEPSCHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_NOINTERNALDEPSCHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/abseil/NoNamespaceCheck.h b/clang-tools-extra/clang-tidy/abseil/NoNamespaceCheck.h index e19f53b972bcf..9460a39f274cc 100644 --- a/clang-tools-extra/clang-tidy/abseil/NoNamespaceCheck.h +++ b/clang-tools-extra/clang-tidy/abseil/NoNamespaceCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_NONAMESPACECHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_NONAMESPACECHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/abseil/RedundantStrcatCallsCheck.h b/clang-tools-extra/clang-tidy/abseil/RedundantStrcatCallsCheck.h index 850e354ef8672..7146497733091 100644 --- a/clang-tools-extra/clang-tidy/abseil/RedundantStrcatCallsCheck.h +++ b/clang-tools-extra/clang-tidy/abseil/RedundantStrcatCallsCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_REDUNDANTSTRCATCALLSCHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_REDUNDANTSTRCATCALLSCHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/abseil/StrCatAppendCheck.h b/clang-tools-extra/clang-tidy/abseil/StrCatAppendCheck.h index b5b36813d5f2d..3b41b2be13108 100644 --- a/clang-tools-extra/clang-tidy/abseil/StrCatAppendCheck.h +++ b/clang-tools-extra/clang-tidy/abseil/StrCatAppendCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_STRCATAPPENDCHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_STRCATAPPENDCHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp index 9539e28cd7909..11bbcbcb527f5 100644 --- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp @@ -12,8 +12,8 @@ #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchers.h" #include "clang/Frontend/CompilerInstance.h" - -#include +#include "clang/Lex/Lexer.h" +#include "clang/Lex/Preprocessor.h" using namespace clang::ast_matchers; @@ -27,7 +27,6 @@ StringFindStartswithCheck::StringFindStartswithCheck(StringRef Name, StringLikeClasses(utils::options::parseStringList( Options.get("StringLikeClasses", "::std::basic_string"))), IncludeStyle(Options.getLocalOrGlobal("IncludeStyle", - utils::IncludeSorter::getMapping(), utils::IncludeSorter::IS_LLVM)), AbseilStringsMatchHeader( Options.get("AbseilStringsMatchHeader", "absl/strings/match.h")) {} @@ -122,8 +121,7 @@ void StringFindStartswithCheck::storeOptions( ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "StringLikeClasses", utils::options::serializeStringList(StringLikeClasses)); - Options.store(Opts, "IncludeStyle", IncludeStyle, - utils::IncludeSorter::getMapping()); + Options.store(Opts, "IncludeStyle", IncludeStyle); Options.store(Opts, "AbseilStringsMatchHeader", AbseilStringsMatchHeader); } diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h index 8a702f73cdad7..d232d3b3efb61 100644 --- a/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h +++ b/clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_STRINGFINDSTARTSWITHCHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_STRINGFINDSTARTSWITHCHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" #include "../utils/IncludeInserter.h" #include "clang/ASTMatchers/ASTMatchFinder.h" diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp b/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp index f60ce20007661..87af9ea6cd5ac 100644 --- a/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp @@ -15,6 +15,9 @@ #include "clang/Tooling/Transformer/RewriteRule.h" #include "clang/Tooling/Transformer/Stencil.h" +// FixItHint - Hint to check documentation script to mark this check as +// providing a FixIt. + using namespace clang::ast_matchers; namespace clang { diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.h b/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.h index 351cc3784a96e..a021dcdb74a92 100644 --- a/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.h +++ b/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_STRINGFINDSTRCONTAINSCHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_STRINGFINDSTRCONTAINSCHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" #include "../utils/TransformerClangTidyCheck.h" namespace clang { diff --git a/clang-tools-extra/clang-tidy/abseil/TimeComparisonCheck.h b/clang-tools-extra/clang-tidy/abseil/TimeComparisonCheck.h index 55984338544b2..f855c31d52825 100644 --- a/clang-tools-extra/clang-tidy/abseil/TimeComparisonCheck.h +++ b/clang-tools-extra/clang-tidy/abseil/TimeComparisonCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMECOMPARECHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMECOMPARECHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp b/clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp index 368aa576c5f43..92319715fbc56 100644 --- a/clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp @@ -10,6 +10,7 @@ #include "DurationRewriter.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" #include "clang/Tooling/FixIt.h" using namespace clang::ast_matchers; diff --git a/clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.h b/clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.h index 4e3cd3b5bee5c..9fe58b7d9303d 100644 --- a/clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.h +++ b/clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMESUBTRACTIONCHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMESUBTRACTIONCHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp b/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp index a660cbdebda5a..4d28d1242f25c 100644 --- a/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp @@ -10,6 +10,7 @@ #include "DurationRewriter.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" using namespace clang::ast_matchers; diff --git a/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.h b/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.h index 55978615faf91..7a450a8e92496 100644 --- a/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.h +++ b/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_UPGRADEDURATIONCONVERSIONSCHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_UPGRADEDURATIONCONVERSIONSCHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" #include diff --git a/clang-tools-extra/clang-tidy/add_new_check.py b/clang-tools-extra/clang-tidy/add_new_check.py index 454d128a5dcb3..231f43c0b8f3d 100755 --- a/clang-tools-extra/clang-tidy/add_new_check.py +++ b/clang-tools-extra/clang-tidy/add_new_check.py @@ -289,6 +289,19 @@ def write_test(module_path, module, check_name, test_extension): """ % {'check_name_dashes': check_name_dashes}) +def get_actual_filename(dirname, filename): + if not os.path.isdir(dirname): + return "" + name = os.path.join(dirname, filename) + if (os.path.isfile(name)): + return name + caselessname = filename.lower() + for file in os.listdir(dirname): + if (file.lower() == caselessname): + return os.path.join(dirname, file) + return "" + + # Recreates the list of checks in the docs/clang-tidy/checks directory. def update_checks_list(clang_tidy_path): docs_dir = os.path.join(clang_tidy_path, '../docs/clang-tidy/checks') @@ -304,7 +317,8 @@ def update_checks_list(clang_tidy_path): def has_auto_fix(check_name): dirname, _, check_name = check_name.partition("-") - checkerCode = os.path.join(dirname, get_camel_name(check_name)) + ".cpp" + checkerCode = get_actual_filename(dirname, + get_camel_name(check_name) + '.cpp') if not os.path.isfile(checkerCode): return "" diff --git a/clang-tools-extra/clang-tidy/android/CMakeLists.txt b/clang-tools-extra/clang-tidy/android/CMakeLists.txt index 72ed16061f6c0..d00e1a7fa1dbf 100644 --- a/clang-tools-extra/clang-tidy/android/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/android/CMakeLists.txt @@ -25,6 +25,9 @@ add_clang_library(clangTidyAndroidModule LINK_LIBS clangTidy clangTidyUtils + + DEPENDS + omp_gen ) clang_target_link_libraries(clangTidyAndroidModule diff --git a/clang-tools-extra/clang-tidy/boost/CMakeLists.txt b/clang-tools-extra/clang-tidy/boost/CMakeLists.txt index 2bddb707dd0e1..8bf959d632749 100644 --- a/clang-tools-extra/clang-tidy/boost/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/boost/CMakeLists.txt @@ -10,6 +10,9 @@ add_clang_library(clangTidyBoostModule LINK_LIBS clangTidy clangTidyUtils + + DEPENDS + omp_gen ) clang_target_link_libraries(clangTidyBoostModule diff --git a/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp index 1f3dec497c076..3591a7da8eb77 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp @@ -9,6 +9,7 @@ #include "BadSignalToKillThreadCheck.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Preprocessor.h" using namespace clang::ast_matchers; diff --git a/clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp index e5f9ebd486265..8c89350c6d07c 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp @@ -11,6 +11,7 @@ #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Analysis/CloneDetection.h" +#include "clang/Lex/Lexer.h" #include "llvm/Support/Casting.h" using namespace clang; diff --git a/clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.h b/clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.h index 4a3eadf68f348..1f8ebbe2d3a5e 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.h @@ -10,7 +10,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_BRANCHCLONECHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_BRANCHCLONECHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index d010c3ce7e522..3f735a8484d84 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -34,6 +34,7 @@ #include "MisplacedWideningCastCheck.h" #include "MoveForwardingReferenceCheck.h" #include "MultipleStatementMacroCheck.h" +#include "NoEscapeCheck.h" #include "NotNullTerminatedResultCheck.h" #include "ParentVirtualCallCheck.h" #include "PosixReturnCheck.h" @@ -120,6 +121,7 @@ class BugproneModule : public ClangTidyModule { "bugprone-multiple-statement-macro"); CheckFactories.registerCheck( "bugprone-narrowing-conversions"); + CheckFactories.registerCheck("bugprone-no-escape"); CheckFactories.registerCheck( "bugprone-not-null-terminated-result"); CheckFactories.registerCheck( diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index e220fd0e67fbb..6e7a94928a5af 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -29,6 +29,7 @@ add_clang_library(clangTidyBugproneModule MisplacedWideningCastCheck.cpp MoveForwardingReferenceCheck.cpp MultipleStatementMacroCheck.cpp + NoEscapeCheck.cpp NotNullTerminatedResultCheck.cpp ParentVirtualCallCheck.cpp PosixReturnCheck.cpp @@ -62,6 +63,9 @@ add_clang_library(clangTidyBugproneModule clangTidy clangTidyCppCoreGuidelinesModule clangTidyUtils + + DEPENDS + omp_gen ) clang_target_link_libraries(clangTidyBugproneModule diff --git a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp index c9dd47ef0cf92..310fbec72a500 100644 --- a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp @@ -10,8 +10,10 @@ #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Analysis/Analyses/ExprMutationAnalyzer.h" +#include "../utils/Aliasing.h" using namespace clang::ast_matchers; +using clang::tidy::utils::hasPtrOrReferenceInFunc; namespace clang { namespace tidy { @@ -24,54 +26,6 @@ loopEndingStmt(internal::Matcher Internal) { callExpr(Internal, callee(functionDecl(isNoReturn()))))); } -/// Return whether `S` is a reference to the declaration of `Var`. -static bool isAccessForVar(const Stmt *S, const VarDecl *Var) { - if (const auto *DRE = dyn_cast(S)) - return DRE->getDecl() == Var; - - return false; -} - -/// Return whether `Var` has a pointer or reference in `S`. -static bool isPtrOrReferenceForVar(const Stmt *S, const VarDecl *Var) { - if (const auto *DS = dyn_cast(S)) { - for (const Decl *D : DS->getDeclGroup()) { - if (const auto *LeftVar = dyn_cast(D)) { - if (LeftVar->hasInit() && LeftVar->getType()->isReferenceType()) { - return isAccessForVar(LeftVar->getInit(), Var); - } - } - } - } else if (const auto *UnOp = dyn_cast(S)) { - if (UnOp->getOpcode() == UO_AddrOf) - return isAccessForVar(UnOp->getSubExpr(), Var); - } - - return false; -} - -/// Return whether `Var` has a pointer or reference in `S`. -static bool hasPtrOrReferenceInStmt(const Stmt *S, const VarDecl *Var) { - if (isPtrOrReferenceForVar(S, Var)) - return true; - - for (const Stmt *Child : S->children()) { - if (!Child) - continue; - - if (hasPtrOrReferenceInStmt(Child, Var)) - return true; - } - - return false; -} - -/// Return whether `Var` has a pointer or reference in `Func`. -static bool hasPtrOrReferenceInFunc(const FunctionDecl *Func, - const VarDecl *Var) { - return hasPtrOrReferenceInStmt(Func->getBody(), Var); -} - /// Return whether `Var` was changed in `LoopStmt`. static bool isChanged(const Stmt *LoopStmt, const VarDecl *Var, ASTContext *Context) { diff --git a/clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp index ed2c17607169d..7c8c26370118f 100644 --- a/clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp @@ -9,6 +9,7 @@ #include "MisplacedOperatorInStrlenInAllocCheck.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" using namespace clang::ast_matchers; @@ -18,12 +19,10 @@ namespace bugprone { void MisplacedOperatorInStrlenInAllocCheck::registerMatchers( MatchFinder *Finder) { - const auto StrLenFunc = functionDecl(anyOf( - hasName("::strlen"), hasName("::std::strlen"), hasName("::strnlen"), - hasName("::std::strnlen"), hasName("::strnlen_s"), - hasName("::std::strnlen_s"), hasName("::wcslen"), - hasName("::std::wcslen"), hasName("::wcsnlen"), hasName("::std::wcsnlen"), - hasName("::wcsnlen_s"), hasName("std::wcsnlen_s"))); + const auto StrLenFunc = functionDecl(hasAnyName( + "::strlen", "::std::strlen", "::strnlen", "::std::strnlen", "::strnlen_s", + "::std::strnlen_s", "::wcslen", "::std::wcslen", "::wcsnlen", + "::std::wcsnlen", "::wcsnlen_s", "std::wcsnlen_s")); const auto BadUse = callExpr(callee(StrLenFunc), @@ -41,12 +40,10 @@ void MisplacedOperatorInStrlenInAllocCheck::registerMatchers( hasDescendant(BadUse)), BadUse); - const auto Alloc0Func = - functionDecl(anyOf(hasName("::malloc"), hasName("std::malloc"), - hasName("::alloca"), hasName("std::alloca"))); - const auto Alloc1Func = - functionDecl(anyOf(hasName("::calloc"), hasName("std::calloc"), - hasName("::realloc"), hasName("std::realloc"))); + const auto Alloc0Func = functionDecl( + hasAnyName("::malloc", "std::malloc", "::alloca", "std::alloca")); + const auto Alloc1Func = functionDecl( + hasAnyName("::calloc", "std::calloc", "::realloc", "std::realloc")); const auto Alloc0FuncPtr = varDecl(hasType(isConstQualified()), diff --git a/clang-tools-extra/clang-tidy/bugprone/MisplacedPointerArithmeticInAllocCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/MisplacedPointerArithmeticInAllocCheck.cpp index ca5209448b00c..2a6a0ae53a4f3 100644 --- a/clang-tools-extra/clang-tidy/bugprone/MisplacedPointerArithmeticInAllocCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/MisplacedPointerArithmeticInAllocCheck.cpp @@ -9,6 +9,7 @@ #include "MisplacedPointerArithmeticInAllocCheck.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" using namespace clang::ast_matchers; @@ -18,10 +19,9 @@ namespace bugprone { void MisplacedPointerArithmeticInAllocCheck::registerMatchers( MatchFinder *Finder) { - const auto AllocFunc = functionDecl( - anyOf(hasName("::malloc"), hasName("std::malloc"), hasName("::alloca"), - hasName("::calloc"), hasName("std::calloc"), hasName("::realloc"), - hasName("std::realloc"))); + const auto AllocFunc = + functionDecl(hasAnyName("::malloc", "std::malloc", "::alloca", "::calloc", + "std::calloc", "::realloc", "std::realloc")); const auto AllocFuncPtr = varDecl(hasType(isConstQualified()), diff --git a/clang-tools-extra/clang-tidy/bugprone/NoEscapeCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/NoEscapeCheck.cpp new file mode 100644 index 0000000000000..654e80d9a9c6c --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/NoEscapeCheck.cpp @@ -0,0 +1,51 @@ +//===--- NoEscapeCheck.cpp - clang-tidy -----------------------------------===// +// +// 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 "NoEscapeCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace bugprone { + +void NoEscapeCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(callExpr(callee(functionDecl(hasName("::dispatch_async"))), + argumentCountIs(2), + hasArgument(1, blockExpr().bind("arg-block"))), + this); + Finder->addMatcher(callExpr(callee(functionDecl(hasName("::dispatch_after"))), + argumentCountIs(3), + hasArgument(2, blockExpr().bind("arg-block"))), + this); +} + +void NoEscapeCheck::check(const MatchFinder::MatchResult &Result) { + const auto *MatchedEscapingBlock = + Result.Nodes.getNodeAs("arg-block"); + const BlockDecl *EscapingBlockDecl = MatchedEscapingBlock->getBlockDecl(); + for (const BlockDecl::Capture &CapturedVar : EscapingBlockDecl->captures()) { + const VarDecl *Var = CapturedVar.getVariable(); + if (Var && Var->hasAttr()) { + // FIXME: Add a method to get the location of the use of a CapturedVar so + // that we can diagnose the use of the pointer instead of the block. + diag(MatchedEscapingBlock->getBeginLoc(), + "pointer %0 with attribute 'noescape' is captured by an " + "asynchronously-executed block") + << Var; + diag(Var->getBeginLoc(), "the 'noescape' attribute is declared here.", + DiagnosticIDs::Note); + } + } +} + +} // namespace bugprone +} // namespace tidy +} // namespace clang diff --git a/clang-tools-extra/clang-tidy/bugprone/NoEscapeCheck.h b/clang-tools-extra/clang-tidy/bugprone/NoEscapeCheck.h new file mode 100644 index 0000000000000..126c37c9df0a1 --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/NoEscapeCheck.h @@ -0,0 +1,39 @@ +//===--- NoEscapeCheck.h - clang-tidy ---------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_NOESCAPECHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_NOESCAPECHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang { +namespace tidy { +namespace bugprone { + +/// Block arguments in `dispatch_async()` and `dispatch_after()` are guaranteed +/// to escape. If those blocks capture any pointers with the `noescape` +/// attribute, then we warn the user of their error. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone-no-escape.html +class NoEscapeCheck : public ClangTidyCheck { +public: + NoEscapeCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.Blocks; + } + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace bugprone +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_NOESCAPECHECK_H diff --git a/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp index 87c1c85e70976..269d69c1c124e 100644 --- a/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp @@ -12,6 +12,7 @@ #include "clang/Frontend/CompilerInstance.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/PPCallbacks.h" +#include "clang/Lex/Preprocessor.h" using namespace clang::ast_matchers; diff --git a/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.h b/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.h index f2a7cd3998f74..18bd2335adfe3 100644 --- a/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_NOT_NULL_TERMINATED_RESULT_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_NOT_NULL_TERMINATED_RESULT_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/bugprone/PosixReturnCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/PosixReturnCheck.cpp index 076e239826cb6..586940ffd795a 100644 --- a/clang-tools-extra/clang-tidy/bugprone/PosixReturnCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/PosixReturnCheck.cpp @@ -10,6 +10,7 @@ #include "../utils/Matchers.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" using namespace clang::ast_matchers; diff --git a/clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp index 9619524a0c038..47a84c225711e 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp @@ -11,6 +11,7 @@ #include "../utils/OptionsUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Token.h" #include #include diff --git a/clang-tools-extra/clang-tidy/bugprone/SpuriouslyWakeUpFunctionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SpuriouslyWakeUpFunctionsCheck.cpp index 844d672f121fb..ee46818839644 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SpuriouslyWakeUpFunctionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SpuriouslyWakeUpFunctionsCheck.cpp @@ -54,8 +54,7 @@ void SpuriouslyWakeUpFunctionsCheck::registerMatchers(MatchFinder *Finder) { .bind("wait")); auto hasWaitDescendantC = hasDescendant( - callExpr(callee(functionDecl( - anyOf(hasName("cnd_wait"), hasName("cnd_timedwait"))))) + callExpr(callee(functionDecl(hasAnyName("cnd_wait", "cnd_timedwait")))) .bind("wait")); if (getLangOpts().CPlusPlus) { // Check for `CON54-CPP` diff --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.cpp index 87ff284408dca..80004f91c0692 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.cpp @@ -8,6 +8,7 @@ #include "SuspiciousIncludeCheck.h" #include "clang/AST/ASTContext.h" +#include "clang/Lex/Preprocessor.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.cpp index 9f98316984ed8..37748d9fa8ccf 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.cpp @@ -20,11 +20,19 @@ namespace tidy { namespace bugprone { void SuspiciousMemsetUsageCheck::registerMatchers(MatchFinder *Finder) { - // Note: void *memset(void *buffer, int fill_char, size_t byte_count); + // Match the standard memset: + // void *memset(void *buffer, int fill_char, size_t byte_count); + auto MemsetDecl = + functionDecl(hasName("::memset"), + parameterCountIs(3), + hasParameter(0, hasType(pointerType(pointee(voidType())))), + hasParameter(1, hasType(isInteger())), + hasParameter(2, hasType(isInteger()))); + // Look for memset(x, '0', z). Probably memset(x, 0, z) was intended. Finder->addMatcher( callExpr( - callee(functionDecl(hasName("::memset"))), + callee(MemsetDecl), hasArgument(1, characterLiteral(equals(static_cast('0'))) .bind("char-zero-fill")), unless( @@ -36,14 +44,14 @@ void SuspiciousMemsetUsageCheck::registerMatchers(MatchFinder *Finder) { // Look for memset with an integer literal in its fill_char argument. // Will check if it gets truncated. - Finder->addMatcher(callExpr(callee(functionDecl(hasName("::memset"))), + Finder->addMatcher(callExpr(callee(MemsetDecl), hasArgument(1, integerLiteral().bind("num-fill")), unless(isInTemplateInstantiation())), this); // Look for memset(x, y, 0) as that is most likely an argument swap. Finder->addMatcher( - callExpr(callee(functionDecl(hasName("::memset"))), + callExpr(callee(MemsetDecl), unless(hasArgument(1, anyOf(characterLiteral(equals( static_cast('0'))), integerLiteral()))), diff --git a/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp index 34a489e324e4b..70ce413d20ff1 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp @@ -27,9 +27,10 @@ void UnusedRaiiCheck::registerMatchers(MatchFinder *Finder) { // Look for temporaries that are constructed in-place and immediately // destroyed. Look for temporaries created by a functional cast but not for // those returned from a call. - auto BindTemp = - cxxBindTemporaryExpr(unless(has(ignoringParenImpCasts(callExpr())))) - .bind("temp"); + auto BindTemp = cxxBindTemporaryExpr( + unless(has(ignoringParenImpCasts(callExpr()))), + unless(has(ignoringParenImpCasts(objcMessageExpr())))) + .bind("temp"); Finder->addMatcher( traverse(ast_type_traits::TK_AsIs, exprWithCleanups( @@ -79,6 +80,7 @@ void UnusedRaiiCheck::check(const MatchFinder::MatchResult &Result) { auto Matches = match(expr(hasDescendant(typeLoc().bind("t"))), *E, *Result.Context); const auto *TL = selectFirst("t", Matches); + assert(TL); D << FixItHint::CreateInsertion( Lexer::getLocForEndOfToken(TL->getEndLoc(), 0, *Result.SourceManager, getLangOpts()), diff --git a/clang-tools-extra/clang-tidy/cert/CMakeLists.txt b/clang-tools-extra/clang-tidy/cert/CMakeLists.txt index 2aa172718a383..e56de01b4780c 100644 --- a/clang-tools-extra/clang-tidy/cert/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/cert/CMakeLists.txt @@ -28,6 +28,9 @@ add_clang_library(clangTidyCERTModule clangTidyPerformanceModule clangTidyReadabilityModule clangTidyUtils + + DEPENDS + omp_gen ) clang_target_link_libraries(clangTidyCERTModule diff --git a/clang-tools-extra/clang-tidy/cert/CommandProcessorCheck.cpp b/clang-tools-extra/clang-tidy/cert/CommandProcessorCheck.cpp index 72b39d18f9f18..131ae9b3ed55f 100644 --- a/clang-tools-extra/clang-tidy/cert/CommandProcessorCheck.cpp +++ b/clang-tools-extra/clang-tidy/cert/CommandProcessorCheck.cpp @@ -19,8 +19,7 @@ namespace cert { void CommandProcessorCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( callExpr( - callee(functionDecl(anyOf(hasName("::system"), hasName("::popen"), - hasName("::_popen"))) + callee(functionDecl(hasAnyName("::system", "::popen", "::_popen")) .bind("func")), // Do not diagnose when the call expression passes a null pointer // constant to system(); that only checks for the presence of a diff --git a/clang-tools-extra/clang-tidy/cert/DontModifyStdNamespaceCheck.cpp b/clang-tools-extra/clang-tidy/cert/DontModifyStdNamespaceCheck.cpp index 2b30933385644..f4051c34aad9c 100644 --- a/clang-tools-extra/clang-tidy/cert/DontModifyStdNamespaceCheck.cpp +++ b/clang-tools-extra/clang-tidy/cert/DontModifyStdNamespaceCheck.cpp @@ -19,7 +19,7 @@ namespace cert { void DontModifyStdNamespaceCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( namespaceDecl(unless(isExpansionInSystemHeader()), - anyOf(hasName("std"), hasName("posix")), + hasAnyName("std", "posix"), has(decl(unless(anyOf( functionDecl(isExplicitTemplateSpecialization()), cxxRecordDecl(isExplicitTemplateSpecialization())))))) diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.h index a00fe9cb4887a..9913d9caf6b28 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_AVOIDGOTOCHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_AVOIDGOTOCHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt b/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt index 797799da8b087..39c2c552eb73e 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt @@ -32,6 +32,9 @@ add_clang_library(clangTidyCppCoreGuidelinesModule clangTidyModernizeModule clangTidyReadabilityModule clangTidyUtils + + DEPENDS + omp_gen ) clang_target_link_libraries(clangTidyCppCoreGuidelinesModule diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/InitVariablesCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/InitVariablesCheck.cpp index 608df8a0ab441..f1755d3f9b855 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/InitVariablesCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/InitVariablesCheck.cpp @@ -10,6 +10,8 @@ #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/PPCallbacks.h" +#include "clang/Lex/Preprocessor.h" using namespace clang::ast_matchers; @@ -25,13 +27,11 @@ InitVariablesCheck::InitVariablesCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), IncludeStyle(Options.getLocalOrGlobal("IncludeStyle", - utils::IncludeSorter::getMapping(), utils::IncludeSorter::IS_LLVM)), MathHeader(Options.get("MathHeader", "math.h")) {} void InitVariablesCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { - Options.store(Opts, "IncludeStyle", IncludeStyle, - utils::IncludeSorter::getMapping()); + Options.store(Opts, "IncludeStyle", IncludeStyle); Options.store(Opts, "MathHeader", MathHeader); } @@ -40,6 +40,7 @@ void InitVariablesCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( varDecl(unless(hasInitializer(anything())), unless(isInstantiated()), isLocalVarDecl(), unless(isStaticLocal()), isDefinition(), + unless(hasParent(cxxCatchStmt())), optionally(hasParent(declStmt(hasParent( cxxForRangeStmt(hasLoopVariable(varDecl().bind(BadDecl))))))), unless(equalsBoundNode(BadDecl))) diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.h index ecaaaa3360946..ddca98d062a11 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_INTERFACES_GLOBAL_INIT_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_INTERFACES_GLOBAL_INIT_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp index 9c8652770963d..febc295d78e6a 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp @@ -9,6 +9,7 @@ #include "MacroUsageCheck.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Lex/PPCallbacks.h" +#include "clang/Lex/Preprocessor.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Regex.h" #include diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/MacroUsageCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/MacroUsageCheck.h index 1938eb6727181..81450802c86d6 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/MacroUsageCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/MacroUsageCheck.h @@ -9,11 +9,12 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_MACROUSAGECHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_MACROUSAGECHECK_H -#include "../ClangTidy.h" -#include "clang/Lex/Preprocessor.h" +#include "../ClangTidyCheck.h" +#include "clang/Lex/MacroInfo.h" #include namespace clang { +class MacroDirective; namespace tidy { namespace cppcoreguidelines { diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h index 6a9f38bb5d509..177cdabaa2527 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_NARROWING_CONVERSIONS_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_NARROWING_CONVERSIONS_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/NoMallocCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/NoMallocCheck.h index cf676421bc53e..6be01923ce851 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/NoMallocCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/NoMallocCheck.h @@ -9,9 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_NO_MALLOC_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_NO_MALLOC_H -#include "../ClangTidy.h" -#include "clang/AST/ASTContext.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.h index aaa3511d2f2e8..bac16bb6e1b09 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_OWNING_MEMORY_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_OWNING_MEMORY_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h index a219d03b1c12d..b81a46f0d02a1 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_BOUNDS_ARRAY_TO_POINTER_DECAY_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_BOUNDS_ARRAY_TO_POINTER_DECAY_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp index b48511287f883..dd0bedd742a40 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp @@ -22,7 +22,6 @@ ProBoundsConstantArrayIndexCheck::ProBoundsConstantArrayIndexCheck( StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), GslHeader(Options.get("GslHeader", "")), IncludeStyle(Options.getLocalOrGlobal("IncludeStyle", - utils::IncludeSorter::getMapping(), utils::IncludeSorter::IS_LLVM)) {} void ProBoundsConstantArrayIndexCheck::storeOptions( diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h index 1b5d7f1428db2..ac7475b4372db 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_BOUNDS_CONSTANT_ARRAY_INDEX_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_BOUNDS_CONSTANT_ARRAY_INDEX_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" #include "../utils/IncludeInserter.h" namespace clang { diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h index ab43c789e0d32..a3aef8e6899fe 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_BOUNDS_POINTER_ARITHMETIC_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_BOUNDS_POINTER_ARITHMETIC_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h index 969e8092e2138..3689e2e963b09 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_CONST_CAST_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_CONST_CAST_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.h index 144b4c7b6da96..76d2b67107fe5 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_CSTYLE_CAST_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_CSTYLE_CAST_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h index 338fc14023883..5b4144396eab4 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_MEMBER_INIT_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_MEMBER_INIT_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h index c33bbd66fae12..8be18003d2310 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_REINTERPRETCAST_CHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_REINTERPRETCAST_CHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h index 5eacb42a613da..e3d7685319a35 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_STATIC_CAST_DOWNCAST_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_STATIC_CAST_DOWNCAST_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.h index 5d36e05225d1c..de4f8bb3fcafa 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_UNION_ACCESS_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_UNION_ACCESS_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.h index 11348d768e871..06de06e3e8361 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_VARARG_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_VARARG_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.h index a2322a9f0031c..002c724f86b8c 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_SLICING_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_SLICING_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h index 78468cc5c31ef..83fca3d5799b0 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_SPECIAL_MEMBER_FUNCTIONS_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_SPECIAL_MEMBER_FUNCTIONS_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" #include "llvm/ADT/DenseMapInfo.h" diff --git a/clang-tools-extra/clang-tidy/darwin/CMakeLists.txt b/clang-tools-extra/clang-tidy/darwin/CMakeLists.txt index 28245b7bce91f..aeb9ac7071426 100644 --- a/clang-tools-extra/clang-tidy/darwin/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/darwin/CMakeLists.txt @@ -11,6 +11,9 @@ add_clang_library(clangTidyDarwinModule LINK_LIBS clangTidy clangTidyUtils + + DEPENDS + omp_gen ) clang_target_link_libraries(clangTidyDarwinModule diff --git a/clang-tools-extra/clang-tidy/fuchsia/CMakeLists.txt b/clang-tools-extra/clang-tidy/fuchsia/CMakeLists.txt index daf092eb49230..dd07813cded09 100644 --- a/clang-tools-extra/clang-tidy/fuchsia/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/fuchsia/CMakeLists.txt @@ -17,6 +17,9 @@ add_clang_library(clangTidyFuchsiaModule clangTidy clangTidyGoogleModule clangTidyUtils + + DEPENDS + omp_gen ) clang_target_link_libraries(clangTidyFuchsiaModule diff --git a/clang-tools-extra/clang-tidy/fuchsia/DefaultArgumentsDeclarationsCheck.cpp b/clang-tools-extra/clang-tidy/fuchsia/DefaultArgumentsDeclarationsCheck.cpp index 926c8b426dfe5..273c322edb8b4 100644 --- a/clang-tools-extra/clang-tidy/fuchsia/DefaultArgumentsDeclarationsCheck.cpp +++ b/clang-tools-extra/clang-tidy/fuchsia/DefaultArgumentsDeclarationsCheck.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "DefaultArgumentsDeclarationsCheck.h" +#include "clang/Lex/Lexer.h" using namespace clang::ast_matchers; diff --git a/clang-tools-extra/clang-tidy/google/AvoidNSObjectNewCheck.cpp b/clang-tools-extra/clang-tidy/google/AvoidNSObjectNewCheck.cpp index b7388fd31bfc2..aab07bad81220 100644 --- a/clang-tools-extra/clang-tidy/google/AvoidNSObjectNewCheck.cpp +++ b/clang-tools-extra/clang-tidy/google/AvoidNSObjectNewCheck.cpp @@ -12,6 +12,7 @@ #include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" +#include "clang/Lex/Lexer.h" #include "llvm/Support/FormatVariadic.h" #include #include diff --git a/clang-tools-extra/clang-tidy/google/AvoidUnderscoreInGoogletestNameCheck.cpp b/clang-tools-extra/clang-tidy/google/AvoidUnderscoreInGoogletestNameCheck.cpp index a811d37af77f1..3a5aaa1e18328 100644 --- a/clang-tools-extra/clang-tidy/google/AvoidUnderscoreInGoogletestNameCheck.cpp +++ b/clang-tools-extra/clang-tidy/google/AvoidUnderscoreInGoogletestNameCheck.cpp @@ -13,6 +13,8 @@ #include "clang/ASTMatchers/ASTMatchers.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Lex/MacroArgs.h" +#include "clang/Lex/PPCallbacks.h" +#include "clang/Lex/Preprocessor.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/google/CMakeLists.txt b/clang-tools-extra/clang-tidy/google/CMakeLists.txt index 68076c1d3bef0..e38ba8abb78d3 100644 --- a/clang-tools-extra/clang-tidy/google/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/google/CMakeLists.txt @@ -27,6 +27,9 @@ add_clang_library(clangTidyGoogleModule clangTidy clangTidyReadabilityModule clangTidyUtils + + DEPENDS + omp_gen ) clang_target_link_libraries(clangTidyGoogleModule diff --git a/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp b/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp index 16fed8156e81a..b2261ca7f5075 100644 --- a/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp +++ b/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp @@ -9,6 +9,8 @@ #include "UpgradeGoogletestCaseCheck.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/PPCallbacks.h" +#include "clang/Lex/Preprocessor.h" using namespace clang::ast_matchers; diff --git a/clang-tools-extra/clang-tidy/hicpp/CMakeLists.txt b/clang-tools-extra/clang-tidy/hicpp/CMakeLists.txt index 53edd21fa61bc..a25c21db4425a 100644 --- a/clang-tools-extra/clang-tidy/hicpp/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/hicpp/CMakeLists.txt @@ -20,6 +20,9 @@ add_clang_library(clangTidyHICPPModule clangTidyPerformanceModule clangTidyReadabilityModule clangTidyUtils + + DEPENDS + omp_gen ) clang_target_link_libraries(clangTidyHICPPModule diff --git a/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.h b/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.h index ed9fcb6f7eadf..ab5e95506ab09 100644 --- a/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.h +++ b/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_HICPP_EXCEPTION_BASECLASS_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_HICPP_EXCEPTION_BASECLASS_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/hicpp/HICPPTidyModule.cpp b/clang-tools-extra/clang-tidy/hicpp/HICPPTidyModule.cpp index ad367dcfed388..253c3893f0d42 100644 --- a/clang-tools-extra/clang-tidy/hicpp/HICPPTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/hicpp/HICPPTidyModule.cpp @@ -9,6 +9,7 @@ #include "../ClangTidy.h" #include "../ClangTidyModule.h" #include "../ClangTidyModuleRegistry.h" +#include "../bugprone/UndelegatedConstructorCheck.h" #include "../bugprone/UseAfterMoveCheck.h" #include "../cppcoreguidelines/AvoidGotoCheck.h" #include "../cppcoreguidelines/NoMallocCheck.h" @@ -20,7 +21,6 @@ #include "../google/ExplicitConstructorCheck.h" #include "../misc/NewDeleteOverloadsCheck.h" #include "../misc/StaticAssertCheck.h" -#include "../bugprone/UndelegatedConstructorCheck.h" #include "../modernize/AvoidCArraysCheck.h" #include "../modernize/DeprecatedHeadersCheck.h" #include "../modernize/UseAutoCheck.h" @@ -34,7 +34,7 @@ #include "../performance/NoexceptMoveConstructorCheck.h" #include "../readability/BracesAroundStatementsCheck.h" #include "../readability/FunctionSizeCheck.h" -#include "../readability/IdentifierNamingCheck.h" +#include "../readability/NamedParameterCheck.h" #include "../readability/UppercaseLiteralSuffixCheck.h" #include "ExceptionBaseclassCheck.h" #include "MultiwayPathsCoveredCheck.h" @@ -65,7 +65,7 @@ class HICPPModule : public ClangTidyModule { "hicpp-explicit-conversions"); CheckFactories.registerCheck( "hicpp-function-size"); - CheckFactories.registerCheck( + CheckFactories.registerCheck( "hicpp-named-parameter"); CheckFactories.registerCheck( "hicpp-invalid-access-moved"); diff --git a/clang-tools-extra/clang-tidy/hicpp/MultiwayPathsCoveredCheck.h b/clang-tools-extra/clang-tidy/hicpp/MultiwayPathsCoveredCheck.h index 6c2a45f716341..c9f9b9f1110f1 100644 --- a/clang-tools-extra/clang-tidy/hicpp/MultiwayPathsCoveredCheck.h +++ b/clang-tools-extra/clang-tidy/hicpp/MultiwayPathsCoveredCheck.h @@ -9,9 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_HICPP_MULTIWAY_PATHS_COVERED_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_HICPP_MULTIWAY_PATHS_COVERED_H -#include "../ClangTidy.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" -#include +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/hicpp/NoAssemblerCheck.h b/clang-tools-extra/clang-tidy/hicpp/NoAssemblerCheck.h index d91c5de2fba0d..a613bc45a4dc9 100644 --- a/clang-tools-extra/clang-tidy/hicpp/NoAssemblerCheck.h +++ b/clang-tools-extra/clang-tidy/hicpp/NoAssemblerCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_HICPP_NO_ASSEMBLER_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_HICPP_NO_ASSEMBLER_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/hicpp/SignedBitwiseCheck.h b/clang-tools-extra/clang-tidy/hicpp/SignedBitwiseCheck.h index 74b3f0eb235de..3510fbdc09adc 100644 --- a/clang-tools-extra/clang-tidy/hicpp/SignedBitwiseCheck.h +++ b/clang-tools-extra/clang-tidy/hicpp/SignedBitwiseCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_HICPP_SIGNED_BITWISE_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_HICPP_SIGNED_BITWISE_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/linuxkernel/CMakeLists.txt b/clang-tools-extra/clang-tidy/linuxkernel/CMakeLists.txt index 5edb652182bec..7a86cfb32cb84 100644 --- a/clang-tools-extra/clang-tidy/linuxkernel/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/linuxkernel/CMakeLists.txt @@ -10,6 +10,9 @@ add_clang_library(clangTidyLinuxKernelModule LINK_LIBS clangTidy clangTidyUtils + + DEPENDS + omp_gen ) clang_target_link_libraries(clangTidyLinuxKernelModule diff --git a/clang-tools-extra/clang-tidy/llvm/CMakeLists.txt b/clang-tools-extra/clang-tidy/llvm/CMakeLists.txt index 74c92eeaa3a9e..5b5cbaffcc9e7 100644 --- a/clang-tools-extra/clang-tidy/llvm/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/llvm/CMakeLists.txt @@ -15,6 +15,9 @@ add_clang_library(clangTidyLLVMModule clangTidy clangTidyReadabilityModule clangTidyUtils + + DEPENDS + omp_gen ) clang_target_link_libraries(clangTidyLLVMModule diff --git a/clang-tools-extra/clang-tidy/llvm/HeaderGuardCheck.cpp b/clang-tools-extra/clang-tidy/llvm/HeaderGuardCheck.cpp index 27e29de54f076..3e4c39d941938 100644 --- a/clang-tools-extra/clang-tidy/llvm/HeaderGuardCheck.cpp +++ b/clang-tools-extra/clang-tidy/llvm/HeaderGuardCheck.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "HeaderGuardCheck.h" +#include "clang/Tooling/Tooling.h" namespace clang { namespace tidy { @@ -53,6 +54,10 @@ std::string LLVMHeaderGuardCheck::getHeaderGuard(StringRef Filename, if (StringRef(Guard).startswith("clang")) Guard = "LLVM_" + Guard; + // The prevalent style in flang is FORTRAN_FOO_BAR_H + if (StringRef(Guard).startswith("flang")) + Guard = "FORTRAN" + Guard.substr(sizeof("flang") - 1); + return StringRef(Guard).upper(); } diff --git a/clang-tools-extra/clang-tidy/llvm/LLVMTidyModule.cpp b/clang-tools-extra/clang-tidy/llvm/LLVMTidyModule.cpp index 2aaf07639267d..bf871e21f501f 100644 --- a/clang-tools-extra/clang-tidy/llvm/LLVMTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/llvm/LLVMTidyModule.cpp @@ -9,6 +9,7 @@ #include "../ClangTidy.h" #include "../ClangTidyModule.h" #include "../ClangTidyModuleRegistry.h" +#include "../readability/ElseAfterReturnCheck.h" #include "../readability/NamespaceCommentCheck.h" #include "../readability/QualifiedAutoCheck.h" #include "HeaderGuardCheck.h" @@ -24,6 +25,8 @@ namespace llvm_check { class LLVMModule : public ClangTidyModule { public: void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { + CheckFactories.registerCheck( + "llvm-else-after-return"); CheckFactories.registerCheck("llvm-header-guard"); CheckFactories.registerCheck("llvm-include-order"); CheckFactories.registerCheck( @@ -40,6 +43,9 @@ class LLVMModule : public ClangTidyModule { ClangTidyOptions getModuleOptions() override { ClangTidyOptions Options; Options.CheckOptions["llvm-qualified-auto.AddConstToQualified"] = "0"; + Options.CheckOptions["llvm-else-after-return.WarnOnUnfixable"] = "0"; + Options.CheckOptions["llvm-else-after-return.WarnOnConditionVariables"] = + "0"; return Options; } }; diff --git a/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp b/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp index 2ca976fd4bc95..13646ccbafa6d 100644 --- a/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp +++ b/clang-tools-extra/clang-tidy/llvm/PreferIsaOrDynCastInConditionalsCheck.cpp @@ -10,6 +10,7 @@ #include "PreferIsaOrDynCastInConditionalsCheck.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" using namespace clang::ast_matchers; @@ -41,14 +42,13 @@ void PreferIsaOrDynCastInConditionalsCheck::registerMatchers( auto CallExpression = callExpr( - allOf(unless(isMacroID()), unless(cxxMemberCallExpr()), - allOf(callee(namedDecl(anyOf(hasName("isa"), hasName("cast"), - hasName("cast_or_null"), - hasName("dyn_cast"), - hasName("dyn_cast_or_null"))) - .bind("func")), - hasArgument(0, anyOf(declRefExpr().bind("arg"), - cxxMemberCallExpr().bind("arg")))))) + allOf( + unless(isMacroID()), unless(cxxMemberCallExpr()), + allOf(callee(namedDecl(hasAnyName("isa", "cast", "cast_or_null", + "dyn_cast", "dyn_cast_or_null")) + .bind("func")), + hasArgument(0, anyOf(declRefExpr().bind("arg"), + cxxMemberCallExpr().bind("arg")))))) .bind("rhs"); Finder->addMatcher( diff --git a/clang-tools-extra/clang-tidy/llvm/TwineLocalCheck.cpp b/clang-tools-extra/clang-tidy/llvm/TwineLocalCheck.cpp index 63a9314a49e5e..907bdcb264bf3 100644 --- a/clang-tools-extra/clang-tidy/llvm/TwineLocalCheck.cpp +++ b/clang-tools-extra/clang-tidy/llvm/TwineLocalCheck.cpp @@ -19,8 +19,10 @@ namespace llvm_check { void TwineLocalCheck::registerMatchers(MatchFinder *Finder) { auto TwineType = - qualType(hasDeclaration(recordDecl(hasName("::llvm::Twine")))); - Finder->addMatcher(varDecl(hasType(TwineType)).bind("variable"), this); + qualType(hasDeclaration(cxxRecordDecl(hasName("::llvm::Twine")))); + Finder->addMatcher( + varDecl(unless(parmVarDecl()), hasType(TwineType)).bind("variable"), + this); } void TwineLocalCheck::check(const MatchFinder::MatchResult &Result) { diff --git a/clang-tools-extra/clang-tidy/llvmlibc/CMakeLists.txt b/clang-tools-extra/clang-tidy/llvmlibc/CMakeLists.txt index 4a4e654f72c61..85b22d157a0ec 100644 --- a/clang-tools-extra/clang-tidy/llvmlibc/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/llvmlibc/CMakeLists.txt @@ -13,6 +13,9 @@ add_clang_library(clangTidyLLVMLibcModule clangTidy clangTidyPortabilityModule clangTidyUtils + + DEPENDS + omp_gen ) clang_target_link_libraries(clangTidyLLVMLibcModule diff --git a/clang-tools-extra/clang-tidy/llvmlibc/RestrictSystemLibcHeadersCheck.cpp b/clang-tools-extra/clang-tidy/llvmlibc/RestrictSystemLibcHeadersCheck.cpp index 4a19b5359d4f9..e64338756a25b 100644 --- a/clang-tools-extra/clang-tidy/llvmlibc/RestrictSystemLibcHeadersCheck.cpp +++ b/clang-tools-extra/clang-tidy/llvmlibc/RestrictSystemLibcHeadersCheck.cpp @@ -11,6 +11,10 @@ #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/HeaderSearchOptions.h" +#include "clang/Lex/Preprocessor.h" + +// FixItHint - Hint to check documentation script to mark this check as +// providing a FixIt. namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt index 236a3a8875bdb..880b7aacdc65a 100644 --- a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt @@ -23,6 +23,9 @@ add_clang_library(clangTidyMiscModule LINK_LIBS clangTidy clangTidyUtils + + DEPENDS + omp_gen ) clang_target_link_libraries(clangTidyMiscModule diff --git a/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp b/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp index 91d88747527e3..535ac78b3f78a 100644 --- a/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp @@ -13,6 +13,7 @@ #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Lex/Lexer.h" #include "llvm/ADT/STLExtras.h" +#include #include using namespace clang::ast_matchers; diff --git a/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp b/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp index 37f9eb6955d3b..63f9f066f1943 100644 --- a/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp @@ -18,6 +18,7 @@ #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSet.h" #include "llvm/Support/Casting.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Regex.h" @@ -35,7 +36,8 @@ namespace modernize { namespace { enum BindArgumentKind { BK_Temporary, BK_Placeholder, BK_CallExpr, BK_Other }; -enum CaptureMode { CM_None, CM_ByRef, CM_ByValue, CM_InitExpression }; +enum CaptureMode { CM_None, CM_ByRef, CM_ByValue }; +enum CaptureExpr { CE_None, CE_Var, CE_InitExpression }; enum CallableType { CT_Other, // unknown @@ -60,6 +62,10 @@ struct BindArgument { // captured. CaptureMode CM = CM_None; + // Whether the argument is a simple variable (we can capture it directly), + // or an expression (we must introduce a capture variable). + CaptureExpr CE = CE_None; + // The exact spelling of this argument in the source code. StringRef SourceTokens; @@ -86,6 +92,7 @@ struct CallableInfo { CallableType Type = CT_Other; CallableMaterializationKind Materialization = CMK_Other; CaptureMode CM = CM_None; + CaptureExpr CE = CE_None; StringRef SourceTokens; std::string CaptureIdentifier; std::string UsageIdentifier; @@ -102,6 +109,12 @@ struct LambdaProperties { } // end namespace +static bool tryCaptureAsLocalVariable(const MatchFinder::MatchResult &Result, + BindArgument &B, const Expr *E); + +static bool tryCaptureAsMemberVariable(const MatchFinder::MatchResult &Result, + BindArgument &B, const Expr *E); + static const Expr *ignoreTemporariesAndPointers(const Expr *E) { if (const auto *T = dyn_cast(E)) return ignoreTemporariesAndPointers(T->getSubExpr()); @@ -148,12 +161,22 @@ initializeBindArgumentForCallExpr(const MatchFinder::MatchResult &Result, // std::ref(x) means to capture x by reference. if (isCallExprNamed(CE, "boost::ref") || isCallExprNamed(CE, "std::ref")) { B.Kind = BK_Other; + if (tryCaptureAsLocalVariable(Result, B, CE->getArg(0)) || + tryCaptureAsMemberVariable(Result, B, CE->getArg(0))) { + B.CE = CE_Var; + } else { + // The argument to std::ref is an expression that produces a reference. + // Create a capture reference to hold it. + B.CE = CE_InitExpression; + B.UsageIdentifier = "capture" + llvm::utostr(CaptureIndex++); + } + // Strip off the reference wrapper. + B.SourceTokens = getSourceTextForExpr(Result, CE->getArg(0)); B.CM = CM_ByRef; - B.UsageIdentifier = - std::string(getSourceTextForExpr(Result, CE->getArg(0))); } else { B.Kind = BK_CallExpr; - B.CM = CM_InitExpression; + B.CM = CM_ByValue; + B.CE = CE_InitExpression; B.UsageIdentifier = "capture" + llvm::utostr(CaptureIndex++); } B.CaptureIdentifier = B.UsageIdentifier; @@ -204,6 +227,7 @@ static bool tryCaptureAsMemberVariable(const MatchFinder::MatchResult &Result, E = E->IgnoreImplicit(); if (isa(E)) { + // E is a direct use of "this". B.CM = CM_ByValue; B.UsageIdentifier = std::string(getSourceTextForExpr(Result, E)); B.CaptureIdentifier = "this"; @@ -217,17 +241,22 @@ static bool tryCaptureAsMemberVariable(const MatchFinder::MatchResult &Result, if (!ME->isLValue() || !isa(ME->getMemberDecl())) return false; - B.CM = CM_ByValue; - B.UsageIdentifier = std::string(getSourceTextForExpr(Result, E)); - B.CaptureIdentifier = "this"; - return true; + if (isa(ME->getBase())) { + // E refers to a data member without an explicit "this". + B.CM = CM_ByValue; + B.UsageIdentifier = std::string(getSourceTextForExpr(Result, E)); + B.CaptureIdentifier = "this"; + return true; + } + + return false; } static SmallVector buildBindArguments(const MatchFinder::MatchResult &Result, const CallableInfo &Callable) { SmallVector BindArguments; - llvm::Regex MatchPlaceholder("^_([0-9]+)$"); + static llvm::Regex MatchPlaceholder("^_([0-9]+)$"); const auto *BindCall = Result.Nodes.getNodeAs("bind"); @@ -251,7 +280,10 @@ buildBindArguments(const MatchFinder::MatchResult &Result, B.IsUsed = true; SmallVector Matches; - if (MatchPlaceholder.match(B.SourceTokens, &Matches)) { + const auto *DRE = dyn_cast(E); + if (MatchPlaceholder.match(B.SourceTokens, &Matches) || + // Check for match with qualifiers removed. + (DRE && MatchPlaceholder.match(DRE->getDecl()->getName(), &Matches))) { B.Kind = BK_Placeholder; B.PlaceHolderIndex = std::stoi(std::string(Matches[1])); B.UsageIdentifier = "PH" + llvm::utostr(B.PlaceHolderIndex); @@ -273,11 +305,13 @@ buildBindArguments(const MatchFinder::MatchResult &Result, // safe. B.Kind = BK_Other; if (IsObjectPtr) { - B.CM = CM_InitExpression; + B.CE = CE_InitExpression; + B.CM = CM_ByValue; B.UsageIdentifier = "ObjectPtr"; B.CaptureIdentifier = B.UsageIdentifier; } else if (anyDescendantIsLocal(B.E)) { - B.CM = CM_InitExpression; + B.CE = CE_InitExpression; + B.CM = CM_ByValue; B.CaptureIdentifier = "capture" + llvm::utostr(CaptureIndex++); B.UsageIdentifier = B.CaptureIdentifier; } @@ -337,9 +371,12 @@ static void addFunctionCallArgs(ArrayRef Args, Stream << Delimiter; - if (B.Kind == BK_Placeholder || B.CM != CM_None) + if (B.Kind == BK_Placeholder) { + Stream << "std::forward"; + Stream << "(" << B.UsageIdentifier << ")"; + } else if (B.CM != CM_None) Stream << B.UsageIdentifier; - else if (B.CM == CM_None) + else Stream << B.SourceTokens; Delimiter = ", "; @@ -357,9 +394,9 @@ static bool isPlaceHolderIndexRepeated(const ArrayRef Args) { return false; } -static std::vector +static std::vector findCandidateCallOperators(const CXXRecordDecl *RecordDecl, size_t NumArgs) { - std::vector Candidates; + std::vector Candidates; for (const clang::CXXMethodDecl *Method : RecordDecl->methods()) { OverloadedOperatorKind OOK = Method->getOverloadedOperator(); @@ -373,6 +410,23 @@ findCandidateCallOperators(const CXXRecordDecl *RecordDecl, size_t NumArgs) { Candidates.push_back(Method); } + // Find templated operator(), if any. + for (const clang::Decl *D : RecordDecl->decls()) { + const auto *FTD = dyn_cast(D); + if (!FTD) + continue; + const FunctionDecl *FD = FTD->getTemplatedDecl(); + + OverloadedOperatorKind OOK = FD->getOverloadedOperator(); + if (OOK != OverloadedOperatorKind::OO_Call) + continue; + + if (FD->getNumParams() > NumArgs) + continue; + + Candidates.push_back(FD); + } + return Candidates; } @@ -407,7 +461,7 @@ static bool isFixitSupported(const CallableInfo &Callee, const FunctionDecl *getCallOperator(const CXXRecordDecl *Callable, size_t NumArgs) { - std::vector Candidates = + std::vector Candidates = findCandidateCallOperators(Callable, NumArgs); if (Candidates.size() != 1) return nullptr; @@ -466,11 +520,15 @@ getCallableMaterialization(const MatchFinder::MatchResult &Result) { const auto *NoTemporaries = ignoreTemporariesAndPointers(CallableExpr); - if (isa(NoTemporaries)) + const auto *CE = dyn_cast(NoTemporaries); + const auto *FC = dyn_cast(NoTemporaries); + if ((isa(NoTemporaries)) || (CE && (CE->getNumArgs() > 0)) || + (FC && (FC->getCastKind() == CK_ConstructorConversion))) + // CE is something that looks like a call, with arguments - either + // a function call or a constructor invocation. return CMK_CallExpression; - if (isa(NoTemporaries) || - isa(NoTemporaries)) + if (isa(NoTemporaries) || CE) return CMK_Function; if (const auto *DRE = dyn_cast(NoTemporaries)) { @@ -503,13 +561,15 @@ getLambdaProperties(const MatchFinder::MatchResult &Result) { getCallMethodDecl(Result, LP.Callable.Type, LP.Callable.Materialization); LP.Callable.SourceTokens = getSourceTextForExpr(Result, CalleeExpr); if (LP.Callable.Materialization == CMK_VariableRef) { + LP.Callable.CE = CE_Var; LP.Callable.CM = CM_ByValue; LP.Callable.UsageIdentifier = std::string(getSourceTextForExpr(Result, CalleeExpr)); LP.Callable.CaptureIdentifier = std::string( getSourceTextForExpr(Result, ignoreTemporariesAndPointers(CalleeExpr))); } else if (LP.Callable.Materialization == CMK_CallExpression) { - LP.Callable.CM = CM_InitExpression; + LP.Callable.CE = CE_InitExpression; + LP.Callable.CM = CM_ByValue; LP.Callable.UsageIdentifier = "Func"; LP.Callable.CaptureIdentifier = "Func"; LP.Callable.CaptureInitializer = getSourceTextForExpr(Result, CalleeExpr); @@ -523,7 +583,7 @@ getLambdaProperties(const MatchFinder::MatchResult &Result) { } static bool emitCapture(llvm::StringSet<> &CaptureSet, StringRef Delimiter, - CaptureMode CM, StringRef Identifier, + CaptureMode CM, CaptureExpr CE, StringRef Identifier, StringRef InitExpression, raw_ostream &Stream) { if (CM == CM_None) return false; @@ -537,7 +597,7 @@ static bool emitCapture(llvm::StringSet<> &CaptureSet, StringRef Delimiter, if (CM == CM_ByRef) Stream << "&"; Stream << Identifier; - if (CM == CM_InitExpression) + if (CE == CE_InitExpression) Stream << " = " << InitExpression; CaptureSet.insert(Identifier); @@ -550,9 +610,9 @@ static void emitCaptureList(const LambdaProperties &LP, llvm::StringSet<> CaptureSet; bool AnyCapturesEmitted = false; - AnyCapturesEmitted = emitCapture(CaptureSet, "", LP.Callable.CM, - LP.Callable.CaptureIdentifier, - LP.Callable.CaptureInitializer, Stream); + AnyCapturesEmitted = emitCapture( + CaptureSet, "", LP.Callable.CM, LP.Callable.CE, + LP.Callable.CaptureIdentifier, LP.Callable.CaptureInitializer, Stream); for (const BindArgument &B : LP.BindArguments) { if (B.CM == CM_None || !B.IsUsed) @@ -560,7 +620,7 @@ static void emitCaptureList(const LambdaProperties &LP, StringRef Delimiter = AnyCapturesEmitted ? ", " : ""; - if (emitCapture(CaptureSet, Delimiter, B.CM, B.CaptureIdentifier, + if (emitCapture(CaptureSet, Delimiter, B.CM, B.CE, B.CaptureIdentifier, B.SourceTokens, Stream)) AnyCapturesEmitted = true; } @@ -585,8 +645,7 @@ void AvoidBindCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { void AvoidBindCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( callExpr( - callee(namedDecl( - anyOf(hasName("::boost::bind"), hasName("::std::bind")))), + callee(namedDecl(hasAnyName("::boost::bind", "::std::bind"))), hasArgument( 0, anyOf(expr(hasType(memberPointerType())).bind("ref"), expr(hasParent(materializeTemporaryExpr().bind("ref"))), @@ -635,19 +694,18 @@ void AvoidBindCheck::check(const MatchFinder::MatchResult &Result) { Stream << MethodDecl->getName(); } else { Stream << " { return "; - switch (LP.Callable.CM) { - case CM_ByValue: - case CM_ByRef: + switch (LP.Callable.CE) { + case CE_Var: if (LP.Callable.UsageIdentifier != LP.Callable.CaptureIdentifier) { Stream << "(" << LP.Callable.UsageIdentifier << ")"; break; } LLVM_FALLTHROUGH; - case CM_InitExpression: + case CE_InitExpression: Stream << LP.Callable.UsageIdentifier; break; default: - Ref->printPretty(Stream, nullptr, Result.Context->getPrintingPolicy()); + Stream << getSourceTextForExpr(Result, Ref); } } diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index ee170279c8347..147c2741d59e4 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -43,6 +43,9 @@ add_clang_library(clangTidyModernizeModule clangTidy clangTidyReadabilityModule clangTidyUtils + + DEPENDS + omp_gen ) clang_target_link_libraries(clangTidyModernizeModule diff --git a/clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp index 48afcdc5c14be..83c3fac949baa 100644 --- a/clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp @@ -9,8 +9,8 @@ #include "ConcatNestedNamespacesCheck.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" #include -#include namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp index dd18d866e5084..b90af1521baf5 100644 --- a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp @@ -28,6 +28,31 @@ using namespace llvm; namespace clang { namespace tidy { + +template <> struct OptionEnumMapping { + static llvm::ArrayRef> + getEnumMapping() { + static constexpr std::pair + Mapping[] = {{modernize::Confidence::CL_Reasonable, "reasonable"}, + {modernize::Confidence::CL_Safe, "safe"}, + {modernize::Confidence::CL_Risky, "risky"}}; + return makeArrayRef(Mapping); + } +}; + +template <> struct OptionEnumMapping { + static llvm::ArrayRef< + std::pair> + getEnumMapping() { + static constexpr std::pair + Mapping[] = {{modernize::VariableNamer::NS_CamelCase, "CamelCase"}, + {modernize::VariableNamer::NS_CamelBack, "camelBack"}, + {modernize::VariableNamer::NS_LowerCase, "lower_case"}, + {modernize::VariableNamer::NS_UpperCase, "UPPER_CASE"}}; + return makeArrayRef(Mapping); + } +}; + namespace modernize { static const char LoopNameArray[] = "forLoopArray"; @@ -44,25 +69,6 @@ static const char EndVarName[] = "endVar"; static const char DerefByValueResultName[] = "derefByValueResult"; static const char DerefByRefResultName[] = "derefByRefResult"; -static ArrayRef> -getConfidenceMapping() { - static constexpr std::pair Mapping[] = { - {"reasonable", Confidence::CL_Reasonable}, - {"safe", Confidence::CL_Safe}, - {"risky", Confidence::CL_Risky}}; - return makeArrayRef(Mapping); -} - -static ArrayRef> -getStyleMapping() { - static constexpr std::pair Mapping[] = - {{"CamelCase", VariableNamer::NS_CamelCase}, - {"camelBack", VariableNamer::NS_CamelBack}, - {"lower_case", VariableNamer::NS_LowerCase}, - {"UPPER_CASE", VariableNamer::NS_UpperCase}}; - return makeArrayRef(Mapping); -} - // shared matchers static const TypeMatcher AnyType() { return anything(); } @@ -146,9 +152,8 @@ StatementMatcher makeArrayLoopMatcher() { /// - If the end iterator variable 'g' is defined, it is the same as 'f'. StatementMatcher makeIteratorLoopMatcher() { StatementMatcher BeginCallMatcher = - cxxMemberCallExpr( - argumentCountIs(0), - callee(cxxMethodDecl(anyOf(hasName("begin"), hasName("cbegin"))))) + cxxMemberCallExpr(argumentCountIs(0), + callee(cxxMethodDecl(hasAnyName("begin", "cbegin")))) .bind(BeginCallName); DeclarationMatcher InitDeclMatcher = @@ -162,8 +167,7 @@ StatementMatcher makeIteratorLoopMatcher() { varDecl(hasInitializer(anything())).bind(EndVarName); StatementMatcher EndCallMatcher = cxxMemberCallExpr( - argumentCountIs(0), - callee(cxxMethodDecl(anyOf(hasName("end"), hasName("cend"))))); + argumentCountIs(0), callee(cxxMethodDecl(hasAnyName("end", "cend")))); StatementMatcher IteratorBoundMatcher = expr(anyOf(ignoringParenImpCasts( @@ -280,8 +284,7 @@ StatementMatcher makePseudoArrayLoopMatcher() { )); StatementMatcher SizeCallMatcher = cxxMemberCallExpr( - argumentCountIs(0), - callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))), + argumentCountIs(0), callee(cxxMethodDecl(hasAnyName("size", "length"))), on(anyOf(hasType(pointsTo(RecordWithBeginEnd)), hasType(RecordWithBeginEnd)))); @@ -477,15 +480,13 @@ LoopConvertCheck::RangeDescriptor::RangeDescriptor() LoopConvertCheck::LoopConvertCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), TUInfo(new TUTrackingInfo), MaxCopySize(Options.get("MaxCopySize", 16ULL)), - MinConfidence(Options.get("MinConfidence", getConfidenceMapping(), - Confidence::CL_Reasonable)), - NamingStyle(Options.get("NamingStyle", getStyleMapping(), - VariableNamer::NS_CamelCase)) {} + MinConfidence(Options.get("MinConfidence", Confidence::CL_Reasonable)), + NamingStyle(Options.get("NamingStyle", VariableNamer::NS_CamelCase)) {} void LoopConvertCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "MaxCopySize", std::to_string(MaxCopySize)); - Options.store(Opts, "MinConfidence", MinConfidence, getConfidenceMapping()); - Options.store(Opts, "NamingStyle", NamingStyle, getStyleMapping()); + Options.store(Opts, "MinConfidence", MinConfidence); + Options.store(Opts, "NamingStyle", NamingStyle); } void LoopConvertCheck::registerMatchers(MatchFinder *Finder) { diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp b/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp index 67f281b3ed1f7..56d4cceb6002a 100644 --- a/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp +++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp @@ -500,7 +500,7 @@ void ForLoopIndexUseVisitor::addUsage(const Usage &U) { /// int k = *i + 2; /// } /// \endcode -bool ForLoopIndexUseVisitor::TraverseUnaryDeref(UnaryOperator *Uop) { +bool ForLoopIndexUseVisitor::TraverseUnaryOperator(UnaryOperator *Uop) { // If we dereference an iterator that's actually a pointer, count the // occurrence. if (isDereferenceOfUop(Uop, IndexVar)) { diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.h b/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.h index b2cba8c0172ae..4f75c9c7522f4 100644 --- a/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.h +++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.h @@ -346,7 +346,7 @@ class ForLoopIndexUseVisitor bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C, Expr *Init); bool TraverseMemberExpr(MemberExpr *Member); - bool TraverseUnaryDeref(UnaryOperator *Uop); + bool TraverseUnaryOperator(UnaryOperator *Uop); bool VisitDeclRefExpr(DeclRefExpr *E); bool VisitDeclStmt(DeclStmt *S); bool TraverseStmt(Stmt *S); diff --git a/clang-tools-extra/clang-tidy/modernize/MakeSharedCheck.cpp b/clang-tools-extra/clang-tidy/modernize/MakeSharedCheck.cpp index 11d24432edafc..5ab3f3e26be2c 100644 --- a/clang-tools-extra/clang-tidy/modernize/MakeSharedCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/MakeSharedCheck.cpp @@ -8,6 +8,9 @@ #include "MakeSharedCheck.h" +// FixItHint - Hint to check documentation script to mark this check as +// providing a FixIt. + using namespace clang::ast_matchers; namespace clang { diff --git a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp index e34fd7038bb86..c677043946f7f 100644 --- a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp @@ -45,7 +45,6 @@ MakeSmartPtrCheck::MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context, StringRef MakeSmartPtrFunctionName) : ClangTidyCheck(Name, Context), IncludeStyle(Options.getLocalOrGlobal("IncludeStyle", - utils::IncludeSorter::getMapping(), utils::IncludeSorter::IS_LLVM)), MakeSmartPtrFunctionHeader( Options.get("MakeSmartPtrFunctionHeader", StdMemoryHeader)), @@ -54,8 +53,7 @@ MakeSmartPtrCheck::MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context, IgnoreMacros(Options.getLocalOrGlobal("IgnoreMacros", true)) {} void MakeSmartPtrCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { - Options.store(Opts, "IncludeStyle", IncludeStyle, - utils::IncludeSorter::getMapping()); + Options.store(Opts, "IncludeStyle", IncludeStyle); Options.store(Opts, "MakeSmartPtrFunctionHeader", MakeSmartPtrFunctionHeader); Options.store(Opts, "MakeSmartPtrFunction", MakeSmartPtrFunctionName); Options.store(Opts, "IgnoreMacros", IgnoreMacros); diff --git a/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp b/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp index ed1a1a26bb62b..b6dedfbc2b6eb 100644 --- a/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp @@ -121,13 +121,11 @@ collectParamDecls(const CXXConstructorDecl *Ctor, PassByValueCheck::PassByValueCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), IncludeStyle(Options.getLocalOrGlobal("IncludeStyle", - utils::IncludeSorter::getMapping(), utils::IncludeSorter::IS_LLVM)), ValuesOnly(Options.get("ValuesOnly", false)) {} void PassByValueCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { - Options.store(Opts, "IncludeStyle", IncludeStyle, - utils::IncludeSorter::getMapping()); + Options.store(Opts, "IncludeStyle", IncludeStyle); Options.store(Opts, "ValuesOnly", ValuesOnly); } diff --git a/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp index 295be200bca6f..f98254dbf7c83 100644 --- a/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp @@ -75,12 +75,10 @@ ReplaceAutoPtrCheck::ReplaceAutoPtrCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), IncludeStyle(Options.getLocalOrGlobal("IncludeStyle", - utils::IncludeSorter::getMapping(), utils::IncludeSorter::IS_LLVM)) {} void ReplaceAutoPtrCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { - Options.store(Opts, "IncludeStyle", IncludeStyle, - utils::IncludeSorter::getMapping()); + Options.store(Opts, "IncludeStyle", IncludeStyle); } void ReplaceAutoPtrCheck::registerMatchers(MatchFinder *Finder) { diff --git a/clang-tools-extra/clang-tidy/modernize/ReplaceDisallowCopyAndAssignMacroCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ReplaceDisallowCopyAndAssignMacroCheck.cpp index 2219a3c477b36..9752fd0a9e955 100644 --- a/clang-tools-extra/clang-tidy/modernize/ReplaceDisallowCopyAndAssignMacroCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ReplaceDisallowCopyAndAssignMacroCheck.cpp @@ -9,6 +9,8 @@ #include "ReplaceDisallowCopyAndAssignMacroCheck.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Lex/MacroArgs.h" +#include "clang/Lex/PPCallbacks.h" +#include "clang/Lex/Preprocessor.h" #include "llvm/Support/FormatVariadic.h" namespace clang { diff --git a/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp index 9cfbd87239dce..66917df3e91d2 100644 --- a/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp @@ -24,7 +24,6 @@ ReplaceRandomShuffleCheck::ReplaceRandomShuffleCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), IncludeStyle(Options.getLocalOrGlobal("IncludeStyle", - utils::IncludeSorter::getMapping(), utils::IncludeSorter::IS_LLVM)) {} void ReplaceRandomShuffleCheck::registerMatchers(MatchFinder *Finder) { @@ -52,8 +51,7 @@ void ReplaceRandomShuffleCheck::registerPPCallbacks( void ReplaceRandomShuffleCheck::storeOptions( ClangTidyOptions::OptionMap &Opts) { - Options.store(Opts, "IncludeStyle", IncludeStyle, - utils::IncludeSorter::getMapping()); + Options.store(Opts, "IncludeStyle", IncludeStyle); } void ReplaceRandomShuffleCheck::check(const MatchFinder::MatchResult &Result) { diff --git a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp index e3953c5d84041..8e31b4b5f75fc 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp @@ -11,6 +11,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Preprocessor.h" #include "clang/Tooling/FixIt.h" #include "llvm/ADT/StringExtras.h" diff --git a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.h b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.h index 4da9b7a9aa92f..0cd4e7741c3e5 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.h @@ -10,7 +10,8 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USETRAILINGRETURNTYPECHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USETRAILINGRETURNTYPECHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" +#include "clang/Lex/Token.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/modernize/UseUncaughtExceptionsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseUncaughtExceptionsCheck.cpp index 82308f75c1330..b9d68cea8ced0 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseUncaughtExceptionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseUncaughtExceptionsCheck.cpp @@ -9,6 +9,7 @@ #include "UseUncaughtExceptionsCheck.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" using namespace clang::ast_matchers; diff --git a/clang-tools-extra/clang-tidy/mpi/CMakeLists.txt b/clang-tools-extra/clang-tidy/mpi/CMakeLists.txt index 1ac973648eff4..113740cc56b12 100644 --- a/clang-tools-extra/clang-tidy/mpi/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/mpi/CMakeLists.txt @@ -11,6 +11,9 @@ add_clang_library(clangTidyMPIModule LINK_LIBS clangTidy clangTidyUtils + + DEPENDS + omp_gen ) clang_target_link_libraries(clangTidyMPIModule diff --git a/clang-tools-extra/clang-tidy/objc/CMakeLists.txt b/clang-tools-extra/clang-tidy/objc/CMakeLists.txt index 297471b54ea11..9a553f5a785b3 100644 --- a/clang-tools-extra/clang-tidy/objc/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/objc/CMakeLists.txt @@ -16,6 +16,9 @@ add_clang_library(clangTidyObjCModule LINK_LIBS clangTidy clangTidyUtils + + DEPENDS + omp_gen ) clang_target_link_libraries(clangTidyObjCModule diff --git a/clang-tools-extra/clang-tidy/objc/NSInvocationArgumentLifetimeCheck.cpp b/clang-tools-extra/clang-tidy/objc/NSInvocationArgumentLifetimeCheck.cpp index ecbf0953ec6d5..2b9eee2f0f33b 100644 --- a/clang-tools-extra/clang-tidy/objc/NSInvocationArgumentLifetimeCheck.cpp +++ b/clang-tools-extra/clang-tidy/objc/NSInvocationArgumentLifetimeCheck.cpp @@ -8,7 +8,6 @@ #include "NSInvocationArgumentLifetimeCheck.h" #include "clang/AST/ASTContext.h" -#include "clang/AST/Attrs.inc" #include "clang/AST/ComputeDependence.h" #include "clang/AST/Decl.h" #include "clang/AST/Expr.h" @@ -23,10 +22,10 @@ #include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" +#include "clang/Lex/Lexer.h" #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" -#include "llvm/Support/raw_ostream.h" using namespace clang::ast_matchers; diff --git a/clang-tools-extra/clang-tidy/objc/SuperSelfCheck.h b/clang-tools-extra/clang-tidy/objc/SuperSelfCheck.h index 03f0fc1bb1f9b..4dcc0c1d7064e 100644 --- a/clang-tools-extra/clang-tidy/objc/SuperSelfCheck.h +++ b/clang-tools-extra/clang-tidy/objc/SuperSelfCheck.h @@ -10,7 +10,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_SUPERSELFCHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_SUPERSELFCHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/openmp/CMakeLists.txt b/clang-tools-extra/clang-tidy/openmp/CMakeLists.txt index a23c719456aac..4ef61f88c0509 100644 --- a/clang-tools-extra/clang-tidy/openmp/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/openmp/CMakeLists.txt @@ -11,6 +11,9 @@ add_clang_library(clangTidyOpenMPModule LINK_LIBS clangTidy clangTidyUtils + + DEPENDS + omp_gen ) clang_target_link_libraries(clangTidyOpenMPModule diff --git a/clang-tools-extra/clang-tidy/openmp/ExceptionEscapeCheck.h b/clang-tools-extra/clang-tidy/openmp/ExceptionEscapeCheck.h index d7a80feaec099..1fb78a95c77f5 100644 --- a/clang-tools-extra/clang-tidy/openmp/ExceptionEscapeCheck.h +++ b/clang-tools-extra/clang-tidy/openmp/ExceptionEscapeCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OPENMP_EXCEPTIONESCAPECHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OPENMP_EXCEPTIONESCAPECHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" #include "../utils/ExceptionAnalyzer.h" namespace clang { diff --git a/clang-tools-extra/clang-tidy/openmp/UseDefaultNoneCheck.h b/clang-tools-extra/clang-tidy/openmp/UseDefaultNoneCheck.h index 09744c01a7cc4..8901fa7c4a78b 100644 --- a/clang-tools-extra/clang-tidy/openmp/UseDefaultNoneCheck.h +++ b/clang-tools-extra/clang-tidy/openmp/UseDefaultNoneCheck.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OPENMP_USEDEFAULTNONECHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OPENMP_USEDEFAULTNONECHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt index 5aa8c24c21cad..0e38e9fc5c0c9 100644 --- a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt @@ -23,6 +23,9 @@ add_clang_library(clangTidyPerformanceModule LINK_LIBS clangTidy clangTidyUtils + + DEPENDS + omp_gen ) clang_target_link_libraries(clangTidyPerformanceModule diff --git a/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp b/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp index bb0a02f06fc63..0d2efb31b7744 100644 --- a/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp @@ -51,7 +51,8 @@ FasterStringFindCheck::FasterStringFindCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), StringLikeClasses(utils::options::parseStringList( - Options.get("StringLikeClasses", "std::basic_string"))) {} + Options.get("StringLikeClasses", + "::std::basic_string;::std::basic_string_view"))) {} void FasterStringFindCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "StringLikeClasses", @@ -59,9 +60,6 @@ void FasterStringFindCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void FasterStringFindCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - const auto SingleChar = expr(ignoringParenCasts(stringLiteral(hasSize(1)).bind("literal"))); const auto StringFindFunctions = diff --git a/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.h b/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.h index 7d46d06c375cd..71a45705f1e81 100644 --- a/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.h +++ b/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.h @@ -27,6 +27,9 @@ namespace performance { class FasterStringFindCheck : public ClangTidyCheck { public: FasterStringFindCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override{ + return LangOpts.CPlusPlus; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; void storeOptions(ClangTidyOptions::OptionMap &Opts) override; diff --git a/clang-tools-extra/clang-tidy/performance/ForRangeCopyCheck.h b/clang-tools-extra/clang-tidy/performance/ForRangeCopyCheck.h index 3745c7bb46811..71f662ba55445 100644 --- a/clang-tools-extra/clang-tidy/performance/ForRangeCopyCheck.h +++ b/clang-tools-extra/clang-tidy/performance/ForRangeCopyCheck.h @@ -22,6 +22,9 @@ namespace performance { class ForRangeCopyCheck : public ClangTidyCheck { public: ForRangeCopyCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override{ + return LangOpts.CPlusPlus11; + } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/performance/ImplicitConversionInLoopCheck.h b/clang-tools-extra/clang-tidy/performance/ImplicitConversionInLoopCheck.h index b372003a80024..4b271366f0f66 100644 --- a/clang-tools-extra/clang-tidy/performance/ImplicitConversionInLoopCheck.h +++ b/clang-tools-extra/clang-tidy/performance/ImplicitConversionInLoopCheck.h @@ -22,6 +22,9 @@ class ImplicitConversionInLoopCheck : public ClangTidyCheck { public: ImplicitConversionInLoopCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override{ + return LangOpts.CPlusPlus11; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; diff --git a/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.h b/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.h index e224dcc90685f..533b30dc32b0e 100644 --- a/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.h +++ b/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.h @@ -26,6 +26,9 @@ namespace performance { class InefficientVectorOperationCheck : public ClangTidyCheck { public: InefficientVectorOperationCheck(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override{ + return LangOpts.CPlusPlus; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; void storeOptions(ClangTidyOptions::OptionMap &Opts) override; diff --git a/clang-tools-extra/clang-tidy/performance/MoveConstructorInitCheck.cpp b/clang-tools-extra/clang-tidy/performance/MoveConstructorInitCheck.cpp index d09673fa7f23f..4cbb014867c4d 100644 --- a/clang-tools-extra/clang-tidy/performance/MoveConstructorInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/MoveConstructorInitCheck.cpp @@ -24,7 +24,6 @@ MoveConstructorInitCheck::MoveConstructorInitCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), IncludeStyle(Options.getLocalOrGlobal("IncludeStyle", - utils::IncludeSorter::getMapping(), utils::IncludeSorter::IS_LLVM)) {} void MoveConstructorInitCheck::registerMatchers(MatchFinder *Finder) { @@ -97,8 +96,7 @@ void MoveConstructorInitCheck::registerPPCallbacks( } void MoveConstructorInitCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { - Options.store(Opts, "IncludeStyle", IncludeStyle, - utils::IncludeSorter::getMapping()); + Options.store(Opts, "IncludeStyle", IncludeStyle); } } // namespace performance diff --git a/clang-tools-extra/clang-tidy/performance/NoexceptMoveConstructorCheck.cpp b/clang-tools-extra/clang-tidy/performance/NoexceptMoveConstructorCheck.cpp index a54b295b2e0c7..d23f0ab0cf44d 100644 --- a/clang-tools-extra/clang-tidy/performance/NoexceptMoveConstructorCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/NoexceptMoveConstructorCheck.cpp @@ -9,6 +9,7 @@ #include "NoexceptMoveConstructorCheck.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" #include "clang/Tooling/FixIt.h" using namespace clang::ast_matchers; diff --git a/clang-tools-extra/clang-tidy/performance/TypePromotionInMathFnCheck.cpp b/clang-tools-extra/clang-tidy/performance/TypePromotionInMathFnCheck.cpp index d08cec1a2c3ca..597445d0fc266 100644 --- a/clang-tools-extra/clang-tidy/performance/TypePromotionInMathFnCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/TypePromotionInMathFnCheck.cpp @@ -32,7 +32,6 @@ TypePromotionInMathFnCheck::TypePromotionInMathFnCheck( StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), IncludeStyle(Options.getLocalOrGlobal("IncludeStyle", - utils::IncludeSorter::getMapping(), utils::IncludeSorter::IS_LLVM)) {} void TypePromotionInMathFnCheck::registerPPCallbacks( @@ -44,8 +43,7 @@ void TypePromotionInMathFnCheck::registerPPCallbacks( void TypePromotionInMathFnCheck::storeOptions( ClangTidyOptions::OptionMap &Opts) { - Options.store(Opts, "IncludeStyle", IncludeStyle, - utils::IncludeSorter::getMapping()); + Options.store(Opts, "IncludeStyle", IncludeStyle); } void TypePromotionInMathFnCheck::registerMatchers(MatchFinder *Finder) { diff --git a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.h b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.h index 0a530e3732962..eeb9138d8532d 100644 --- a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.h +++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.h @@ -26,6 +26,9 @@ namespace performance { class UnnecessaryCopyInitialization : public ClangTidyCheck { public: UnnecessaryCopyInitialization(StringRef Name, ClangTidyContext *Context); + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override{ + return LangOpts.CPlusPlus; + } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; void storeOptions(ClangTidyOptions::OptionMap &Opts) override; diff --git a/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp b/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp index 5b5f2ff994783..5de53b1840f12 100644 --- a/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp @@ -69,7 +69,6 @@ UnnecessaryValueParamCheck::UnnecessaryValueParamCheck( StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), IncludeStyle(Options.getLocalOrGlobal("IncludeStyle", - utils::IncludeSorter::getMapping(), utils::IncludeSorter::IS_LLVM)), AllowedTypes( utils::options::parseStringList(Options.get("AllowedTypes", ""))) {} @@ -181,8 +180,7 @@ void UnnecessaryValueParamCheck::registerPPCallbacks( void UnnecessaryValueParamCheck::storeOptions( ClangTidyOptions::OptionMap &Opts) { - Options.store(Opts, "IncludeStyle", IncludeStyle, - utils::IncludeSorter::getMapping()); + Options.store(Opts, "IncludeStyle", IncludeStyle); Options.store(Opts, "AllowedTypes", utils::options::serializeStringList(AllowedTypes)); } diff --git a/clang-tools-extra/clang-tidy/plugin/CMakeLists.txt b/clang-tools-extra/clang-tidy/plugin/CMakeLists.txt index 0bfe122314eb4..0b281e0799cf3 100644 --- a/clang-tools-extra/clang-tidy/plugin/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/plugin/CMakeLists.txt @@ -4,6 +4,9 @@ add_clang_library(clangTidyPlugin LINK_LIBS clangTidy ${ALL_CLANG_TIDY_CHECKS} + + DEPENDS + omp_gen ) clang_target_link_libraries(clangTidyPlugin diff --git a/clang-tools-extra/clang-tidy/portability/CMakeLists.txt b/clang-tools-extra/clang-tidy/portability/CMakeLists.txt index b4fcf28a99034..a0de5871e036a 100644 --- a/clang-tools-extra/clang-tidy/portability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/portability/CMakeLists.txt @@ -11,6 +11,9 @@ add_clang_library(clangTidyPortabilityModule LINK_LIBS clangTidy clangTidyUtils + + DEPENDS + omp_gen ) clang_target_link_libraries(clangTidyPortabilityModule diff --git a/clang-tools-extra/clang-tidy/portability/RestrictSystemIncludesCheck.h b/clang-tools-extra/clang-tidy/portability/RestrictSystemIncludesCheck.h index c34f054fba2e0..80eddf7bcee79 100644 --- a/clang-tools-extra/clang-tidy/portability/RestrictSystemIncludesCheck.h +++ b/clang-tools-extra/clang-tidy/portability/RestrictSystemIncludesCheck.h @@ -11,6 +11,7 @@ #include "../ClangTidyCheck.h" #include "../GlobList.h" +#include "clang/Lex/PPCallbacks.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index ca2f69b8deb87..4539ab177ced1 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -47,6 +47,9 @@ add_clang_library(clangTidyReadabilityModule LINK_LIBS clangTidy clangTidyUtils + + DEPENDS + omp_gen ) clang_target_link_libraries(clangTidyReadabilityModule diff --git a/clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStatic.cpp b/clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStatic.cpp index ba054fb3aaf34..b2ad1bcf39463 100644 --- a/clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStatic.cpp +++ b/clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStatic.cpp @@ -13,6 +13,7 @@ #include "clang/AST/RecursiveASTVisitor.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Basic/SourceLocation.h" +#include "clang/Lex/Lexer.h" using namespace clang::ast_matchers; diff --git a/clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStatic.h b/clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStatic.h index d9947650ab539..333fe94479dda 100644 --- a/clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStatic.h +++ b/clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStatic.h @@ -10,7 +10,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_CONVERTMEMFUNCTOSTATIC_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_CONVERTMEMFUNCTOSTATIC_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp index a13c172c7f769..9ad6fb737ec9c 100644 --- a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp @@ -9,6 +9,7 @@ #include "ElseAfterReturnCheck.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" #include "clang/Tooling/FixIt.h" #include "llvm/ADT/SmallVector.h" @@ -18,52 +19,48 @@ namespace clang { namespace tidy { namespace readability { -namespace { static const char ReturnStr[] = "return"; static const char ContinueStr[] = "continue"; static const char BreakStr[] = "break"; static const char ThrowStr[] = "throw"; static const char WarningMessage[] = "do not use 'else' after '%0'"; static const char WarnOnUnfixableStr[] = "WarnOnUnfixable"; +static const char WarnOnConditionVariablesStr[] = "WarnOnConditionVariables"; -const DeclRefExpr *findUsage(const Stmt *Node, int64_t DeclIdentifier) { +static const DeclRefExpr *findUsage(const Stmt *Node, int64_t DeclIdentifier) { if (!Node) return nullptr; if (const auto *DeclRef = dyn_cast(Node)) { - if (DeclRef->getDecl()->getID() == DeclIdentifier) { + if (DeclRef->getDecl()->getID() == DeclIdentifier) return DeclRef; - } } else { for (const Stmt *ChildNode : Node->children()) { - if (const DeclRefExpr *Result = findUsage(ChildNode, DeclIdentifier)) { + if (const DeclRefExpr *Result = findUsage(ChildNode, DeclIdentifier)) return Result; - } } } return nullptr; } -const DeclRefExpr * +static const DeclRefExpr * findUsageRange(const Stmt *Node, - const llvm::iterator_range &DeclIdentifiers) { + const llvm::ArrayRef &DeclIdentifiers) { if (!Node) return nullptr; if (const auto *DeclRef = dyn_cast(Node)) { - if (llvm::is_contained(DeclIdentifiers, DeclRef->getDecl()->getID())) { + if (llvm::is_contained(DeclIdentifiers, DeclRef->getDecl()->getID())) return DeclRef; - } } else { for (const Stmt *ChildNode : Node->children()) { if (const DeclRefExpr *Result = - findUsageRange(ChildNode, DeclIdentifiers)) { + findUsageRange(ChildNode, DeclIdentifiers)) return Result; - } } } return nullptr; } -const DeclRefExpr *checkInitDeclUsageInElse(const IfStmt *If) { +static const DeclRefExpr *checkInitDeclUsageInElse(const IfStmt *If) { const auto *InitDeclStmt = dyn_cast_or_null(If->getInit()); if (!InitDeclStmt) return nullptr; @@ -80,25 +77,23 @@ const DeclRefExpr *checkInitDeclUsageInElse(const IfStmt *If) { return findUsageRange(If->getElse(), DeclIdentifiers); } -const DeclRefExpr *checkConditionVarUsageInElse(const IfStmt *If) { - const VarDecl *CondVar = If->getConditionVariable(); - return CondVar != nullptr ? findUsage(If->getElse(), CondVar->getID()) - : nullptr; +static const DeclRefExpr *checkConditionVarUsageInElse(const IfStmt *If) { + if (const VarDecl *CondVar = If->getConditionVariable()) + return findUsage(If->getElse(), CondVar->getID()); + return nullptr; } -bool containsDeclInScope(const Stmt *Node) { - if (isa(Node)) { +static bool containsDeclInScope(const Stmt *Node) { + if (isa(Node)) return true; - } - if (const auto *Compound = dyn_cast(Node)) { + if (const auto *Compound = dyn_cast(Node)) return llvm::any_of(Compound->body(), [](const Stmt *SubNode) { return isa(SubNode); }); - } return false; } -void removeElseAndBrackets(DiagnosticBuilder &Diag, ASTContext &Context, +static void removeElseAndBrackets(DiagnosticBuilder &Diag, ASTContext &Context, const Stmt *Else, SourceLocation ElseLoc) { auto Remap = [&](SourceLocation Loc) { return Context.getSourceManager().getExpansionLoc(Loc); @@ -132,15 +127,17 @@ void removeElseAndBrackets(DiagnosticBuilder &Diag, ASTContext &Context, SourceRange(ElseExpandedLoc, EndLoc), Repl); } } -} // namespace ElseAfterReturnCheck::ElseAfterReturnCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), - WarnOnUnfixable(Options.get(WarnOnUnfixableStr, true)) {} + WarnOnUnfixable(Options.get(WarnOnUnfixableStr, true)), + WarnOnConditionVariables(Options.get(WarnOnConditionVariablesStr, true)) { +} void ElseAfterReturnCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, WarnOnUnfixableStr, WarnOnUnfixable); + Options.store(Opts, WarnOnConditionVariablesStr, WarnOnConditionVariables); } void ElseAfterReturnCheck::registerMatchers(MatchFinder *Finder) { @@ -185,6 +182,8 @@ void ElseAfterReturnCheck::check(const MatchFinder::MatchResult &Result) { } if (checkConditionVarUsageInElse(If) != nullptr) { + if (!WarnOnConditionVariables) + return; if (IsLastInScope) { // If the if statement is the last statement its enclosing statements // scope, we can pull the decl out of the if statement. @@ -218,6 +217,8 @@ void ElseAfterReturnCheck::check(const MatchFinder::MatchResult &Result) { } if (checkInitDeclUsageInElse(If) != nullptr) { + if (!WarnOnConditionVariables) + return; if (IsLastInScope) { // If the if statement is the last statement its enclosing statements // scope, we can pull the decl out of the if statement. diff --git a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.h b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.h index 990d4b4c3f6b7..07d6314640a8b 100644 --- a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.h +++ b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.h @@ -28,6 +28,7 @@ class ElseAfterReturnCheck : public ClangTidyCheck { private: const bool WarnOnUnfixable; + const bool WarnOnConditionVariables; }; } // namespace readability diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp index 6e7fcaa4345a5..c885aac89072a 100644 --- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp @@ -26,6 +26,26 @@ using namespace clang::ast_matchers; namespace clang { namespace tidy { + +llvm::ArrayRef< + std::pair> +OptionEnumMapping< + readability::IdentifierNamingCheck::CaseType>::getEnumMapping() { + static constexpr std::pair + Mapping[] = { + {readability::IdentifierNamingCheck::CT_AnyCase, "aNy_CasE"}, + {readability::IdentifierNamingCheck::CT_LowerCase, "lower_case"}, + {readability::IdentifierNamingCheck::CT_UpperCase, "UPPER_CASE"}, + {readability::IdentifierNamingCheck::CT_CamelBack, "camelBack"}, + {readability::IdentifierNamingCheck::CT_CamelCase, "CamelCase"}, + {readability::IdentifierNamingCheck::CT_CamelSnakeCase, + "Camel_Snake_Case"}, + {readability::IdentifierNamingCheck::CT_CamelSnakeBack, + "camel_Snake_Back"}}; + return llvm::makeArrayRef(Mapping); +} + namespace readability { // clang-format off @@ -99,16 +119,6 @@ static StringRef const StyleNames[] = { #undef NAMING_KEYS // clang-format on -static constexpr std::pair - Mapping[] = { - {"aNy_CasE", IdentifierNamingCheck::CT_AnyCase}, - {"lower_case", IdentifierNamingCheck::CT_LowerCase}, - {"UPPER_CASE", IdentifierNamingCheck::CT_UpperCase}, - {"camelBack", IdentifierNamingCheck::CT_CamelBack}, - {"CamelCase", IdentifierNamingCheck::CT_CamelCase}, - {"Camel_Snake_Case", IdentifierNamingCheck::CT_CamelSnakeCase}, - {"camel_Snake_Back", IdentifierNamingCheck::CT_CamelSnakeBack}}; - IdentifierNamingCheck::IdentifierNamingCheck(StringRef Name, ClangTidyContext *Context) : RenamerClangTidyCheck(Name, Context), @@ -117,7 +127,7 @@ IdentifierNamingCheck::IdentifierNamingCheck(StringRef Name, for (auto const &Name : StyleNames) { auto CaseOptional = [&]() -> llvm::Optional { - auto ValueOr = Options.get((Name + "Case").str(), makeArrayRef(Mapping)); + auto ValueOr = Options.get((Name + "Case").str()); if (ValueOr) return *ValueOr; llvm::logAllUnhandledErrors( @@ -148,7 +158,7 @@ void IdentifierNamingCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { if (NamingStyles[i]) { if (NamingStyles[i]->Case) { Options.store(Opts, (StyleNames[i] + "Case").str(), - *NamingStyles[i]->Case, llvm::makeArrayRef(Mapping)); + *NamingStyles[i]->Case); } Options.store(Opts, (StyleNames[i] + "Prefix").str(), NamingStyles[i]->Prefix); diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h index 04bf53fe16b56..0f6c77b2c9a86 100644 --- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h +++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h @@ -75,6 +75,12 @@ class IdentifierNamingCheck final : public RenamerClangTidyCheck { }; } // namespace readability +template <> +struct OptionEnumMapping { + static llvm::ArrayRef< + std::pair> + getEnumMapping(); +}; } // namespace tidy } // namespace clang diff --git a/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.h b/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.h index a53fa917066ee..9612fd7ec6aab 100644 --- a/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.h +++ b/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.h @@ -10,9 +10,9 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MAGICNUMBERSCHECK_H #include "../ClangTidyCheck.h" +#include "clang/Lex/Lexer.h" #include #include -#include namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp b/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp index ee087e3b3133c..7a8ad2c3aec62 100644 --- a/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp @@ -11,6 +11,7 @@ #include "clang/AST/ParentMapContext.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" using namespace clang::ast_matchers; diff --git a/clang-tools-extra/clang-tidy/readability/RedundantPreprocessorCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantPreprocessorCheck.cpp index 0870f2db2e6db..822c4cd14ddc1 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantPreprocessorCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantPreprocessorCheck.cpp @@ -8,6 +8,9 @@ #include "RedundantPreprocessorCheck.h" #include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/Lexer.h" +#include "clang/Lex/PPCallbacks.h" +#include "clang/Lex/Preprocessor.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp b/clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp index aab45faa6cb3a..eef6253f6a1ff 100644 --- a/clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp @@ -8,9 +8,9 @@ #include "UppercaseLiteralSuffixCheck.h" #include "../utils/ASTUtils.h" -#include "../utils/OptionsUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallString.h" diff --git a/clang-tools-extra/clang-tidy/readability/UseAnyOfAllOfCheck.h b/clang-tools-extra/clang-tidy/readability/UseAnyOfAllOfCheck.h index c44ef2e70ae98..768fb5254e288 100644 --- a/clang-tools-extra/clang-tidy/readability/UseAnyOfAllOfCheck.h +++ b/clang-tools-extra/clang-tidy/readability/UseAnyOfAllOfCheck.h @@ -10,7 +10,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_USEALGORITHMCHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_USEALGORITHMCHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" #include "../utils/IncludeInserter.h" namespace clang { diff --git a/clang-tools-extra/clang-tidy/tool/CMakeLists.txt b/clang-tools-extra/clang-tidy/tool/CMakeLists.txt index 00554e43ad2fb..f12cff1b1303a 100644 --- a/clang-tools-extra/clang-tidy/tool/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/tool/CMakeLists.txt @@ -15,6 +15,9 @@ add_clang_library(clangTidyMain LINK_LIBS clangTidy ${ALL_CLANG_TIDY_CHECKS} + + DEPENDS + omp_gen ) clang_target_link_libraries(clangTidyMain diff --git a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp index 82939faf1ea88..e248c04ea5709 100644 --- a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp +++ b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp @@ -25,8 +25,6 @@ #include "llvm/Support/TargetSelect.h" #include "llvm/Support/WithColor.h" -using namespace clang::ast_matchers; -using namespace clang::driver; using namespace clang::tooling; using namespace llvm; diff --git a/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py b/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py index 2b5e78b38f016..4272ae0957fe2 100755 --- a/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py +++ b/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py @@ -277,7 +277,6 @@ def main(): tmpdir = tempfile.mkdtemp() # Build up a big regexy filter from all command line arguments. - args.files = [re.escape(f) for f in args.files] file_name_re = re.compile('|'.join(args.files)) return_code = 0 diff --git a/clang-tools-extra/clang-tidy/utils/Aliasing.cpp b/clang-tools-extra/clang-tidy/utils/Aliasing.cpp new file mode 100644 index 0000000000000..3a88126a9ee6a --- /dev/null +++ b/clang-tools-extra/clang-tidy/utils/Aliasing.cpp @@ -0,0 +1,65 @@ +//===------------- Aliasing.cpp - clang-tidy ------------------------------===// +// +// 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 "Aliasing.h" + +#include "clang/AST/Expr.h" + +namespace clang { +namespace tidy { +namespace utils { + +/// Return whether \p S is a reference to the declaration of \p Var. +static bool isAccessForVar(const Stmt *S, const VarDecl *Var) { + if (const auto *DRE = dyn_cast(S)) + return DRE->getDecl() == Var; + + return false; +} + +/// Return whether \p Var has a pointer or reference in \p S. +static bool isPtrOrReferenceForVar(const Stmt *S, const VarDecl *Var) { + if (const auto *DS = dyn_cast(S)) { + for (const Decl *D : DS->getDeclGroup()) { + if (const auto *LeftVar = dyn_cast(D)) { + if (LeftVar->hasInit() && LeftVar->getType()->isReferenceType()) { + return isAccessForVar(LeftVar->getInit(), Var); + } + } + } + } else if (const auto *UnOp = dyn_cast(S)) { + if (UnOp->getOpcode() == UO_AddrOf) + return isAccessForVar(UnOp->getSubExpr(), Var); + } + + return false; +} + +/// Return whether \p Var has a pointer or reference in \p S. +static bool hasPtrOrReferenceInStmt(const Stmt *S, const VarDecl *Var) { + if (isPtrOrReferenceForVar(S, Var)) + return true; + + for (const Stmt *Child : S->children()) { + if (!Child) + continue; + + if (hasPtrOrReferenceInStmt(Child, Var)) + return true; + } + + return false; +} + +bool hasPtrOrReferenceInFunc(const FunctionDecl *Func, const VarDecl *Var) { + return hasPtrOrReferenceInStmt(Func->getBody(), Var); +} + +} // namespace utils +} // namespace tidy +} // namespace clang diff --git a/clang-tools-extra/clang-tidy/utils/Aliasing.h b/clang-tools-extra/clang-tidy/utils/Aliasing.h new file mode 100644 index 0000000000000..e43995a6714ad --- /dev/null +++ b/clang-tools-extra/clang-tidy/utils/Aliasing.h @@ -0,0 +1,36 @@ +//===------------- Aliasing.h - clang-tidy --------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_ALIASING_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_ALIASING_H + +#include "clang/AST/Decl.h" + +namespace clang { +namespace tidy { +namespace utils { + +/// Returns whether \p Var has a pointer or reference in \p Func. +/// +/// Example: +/// void f() { +/// int n; +/// ... +/// int *p = &n; +/// } +/// +/// For `f()` and `n` the function returns ``true`` because `p` is a +/// pointer to `n` created in `f()`. + +bool hasPtrOrReferenceInFunc(const FunctionDecl *Func, const VarDecl *Var); + +} // namespace utils +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_ALIASING_H diff --git a/clang-tools-extra/clang-tidy/utils/CMakeLists.txt b/clang-tools-extra/clang-tidy/utils/CMakeLists.txt index 26032f21c7016..70edb9c33d74b 100644 --- a/clang-tools-extra/clang-tidy/utils/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/utils/CMakeLists.txt @@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS ) add_clang_library(clangTidyUtils + Aliasing.cpp ASTUtils.cpp DeclRefExprUtils.cpp ExceptionAnalyzer.cpp @@ -23,6 +24,9 @@ add_clang_library(clangTidyUtils LINK_LIBS clangTidy + + DEPENDS + omp_gen ) clang_target_link_libraries(clangTidyUtils diff --git a/clang-tools-extra/clang-tidy/utils/ExprSequence.cpp b/clang-tools-extra/clang-tidy/utils/ExprSequence.cpp index 8fddf4d4996aa..15c4375a64be7 100644 --- a/clang-tools-extra/clang-tidy/utils/ExprSequence.cpp +++ b/clang-tools-extra/clang-tidy/utils/ExprSequence.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "ExprSequence.h" +#include "clang/AST/ParentMapContext.h" namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/utils/HeaderGuard.h b/clang-tools-extra/clang-tidy/utils/HeaderGuard.h index d3e09a32b6878..86c0f3dc8fda2 100644 --- a/clang-tools-extra/clang-tidy/utils/HeaderGuard.h +++ b/clang-tools-extra/clang-tidy/utils/HeaderGuard.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_HEADERGUARD_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_HEADERGUARD_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" #include "../utils/FileExtensionsUtils.h" namespace clang { diff --git a/clang-tools-extra/clang-tidy/utils/IncludeSorter.cpp b/clang-tools-extra/clang-tidy/utils/IncludeSorter.cpp index 6013412a41385..c9d018f076e76 100644 --- a/clang-tools-extra/clang-tidy/utils/IncludeSorter.cpp +++ b/clang-tools-extra/clang-tidy/utils/IncludeSorter.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "IncludeSorter.h" +#include "clang/Basic/SourceManager.h" #include "clang/Lex/Lexer.h" namespace clang { @@ -174,13 +175,14 @@ Optional IncludeSorter::CreateIncludeInsertion(StringRef FileName, IncludeStmt); } -llvm::ArrayRef> -IncludeSorter::getMapping() { - static constexpr std::pair Mapping[] = - {{"llvm", IS_LLVM}, {"google", IS_Google}}; +} // namespace utils + +llvm::ArrayRef> +OptionEnumMapping::getEnumMapping() { + static constexpr std::pair + Mapping[] = {{utils::IncludeSorter::IS_LLVM, "llvm"}, + {utils::IncludeSorter::IS_Google, "google"}}; return makeArrayRef(Mapping); } - -} // namespace utils } // namespace tidy } // namespace clang diff --git a/clang-tools-extra/clang-tidy/utils/IncludeSorter.h b/clang-tools-extra/clang-tidy/utils/IncludeSorter.h index 7dab2cc536a48..1d8997364e5ce 100644 --- a/clang-tools-extra/clang-tidy/utils/IncludeSorter.h +++ b/clang-tools-extra/clang-tidy/utils/IncludeSorter.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_INCLUDESORTER_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_INCLUDESORTER_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" #include namespace clang { @@ -25,8 +25,6 @@ class IncludeSorter { /// Supported include styles. enum IncludeStyle { IS_LLVM = 0, IS_Google = 1 }; - static ArrayRef> getMapping(); - /// The classifications of inclusions, in the order they should be sorted. enum IncludeKinds { IK_MainTUInclude = 0, ///< e.g. ``#include "foo.h"`` when editing foo.cc @@ -66,6 +64,11 @@ class IncludeSorter { }; } // namespace utils + +template <> struct OptionEnumMapping { + static ArrayRef> + getEnumMapping(); +}; } // namespace tidy } // namespace clang #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_INCLUDESORTER_H diff --git a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp index e90ab1782b4b4..040378d980f1a 100644 --- a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp +++ b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp @@ -156,14 +156,17 @@ void RenamerClangTidyCheck::addUsage( // is already in there RenamerClangTidyCheck::NamingCheckFailure &Failure = NamingCheckFailures[Decl]; - if (!Failure.RawUsageLocs.insert(FixLocation.getRawEncoding()).second) - return; if (!Failure.ShouldFix()) return; + if (SourceMgr && SourceMgr->isWrittenInScratchSpace(FixLocation)) + Failure.FixStatus = RenamerClangTidyCheck::ShouldFixStatus::InsideMacro; + if (!utils::rangeCanBeFixed(Range, SourceMgr)) Failure.FixStatus = RenamerClangTidyCheck::ShouldFixStatus::InsideMacro; + + Failure.RawUsageLocs.insert(FixLocation.getRawEncoding()); } void RenamerClangTidyCheck::addUsage(const NamedDecl *Decl, SourceRange Range, @@ -248,13 +251,15 @@ void RenamerClangTidyCheck::check(const MatchFinder::MatchResult &Result) { if (const auto *Decl = Result.Nodes.getNodeAs("classRef")) { - addUsage(Decl->getParent(), Decl->getNameInfo().getSourceRange()); + addUsage(Decl->getParent(), Decl->getNameInfo().getSourceRange(), + Result.SourceManager); for (const auto *Init : Decl->inits()) { if (!Init->isWritten() || Init->isInClassMemberInitializer()) continue; if (const FieldDecl *FD = Init->getAnyMember()) - addUsage(FD, SourceRange(Init->getMemberLocation())); + addUsage(FD, SourceRange(Init->getMemberLocation()), + Result.SourceManager); // Note: delegating constructors and base class initializers are handled // via the "typeLoc" matcher. } @@ -271,7 +276,7 @@ void RenamerClangTidyCheck::check(const MatchFinder::MatchResult &Result) { // we want instead to replace the next token, that will be the identifier. Range.setBegin(CharSourceRange::getTokenRange(Range).getEnd()); - addUsage(Decl->getParent(), Range); + addUsage(Decl->getParent(), Range, Result.SourceManager); return; } @@ -289,7 +294,7 @@ void RenamerClangTidyCheck::check(const MatchFinder::MatchResult &Result) { // further TypeLocs handled below if (Decl) { - addUsage(Decl, Loc->getSourceRange()); + addUsage(Decl, Loc->getSourceRange(), Result.SourceManager); return; } @@ -300,7 +305,7 @@ void RenamerClangTidyCheck::check(const MatchFinder::MatchResult &Result) { SourceRange Range(Ref.getTemplateNameLoc(), Ref.getTemplateNameLoc()); if (const auto *ClassDecl = dyn_cast(Decl)) { if (const NamedDecl *TemplDecl = ClassDecl->getTemplatedDecl()) - addUsage(TemplDecl, Range); + addUsage(TemplDecl, Range, Result.SourceManager); return; } } @@ -308,7 +313,7 @@ void RenamerClangTidyCheck::check(const MatchFinder::MatchResult &Result) { if (const auto &Ref = Loc->getAs()) { if (const TagDecl *Decl = Ref.getTypePtr()->getAsTagDecl()) - addUsage(Decl, Loc->getSourceRange()); + addUsage(Decl, Loc->getSourceRange(), Result.SourceManager); return; } } @@ -317,7 +322,7 @@ void RenamerClangTidyCheck::check(const MatchFinder::MatchResult &Result) { Result.Nodes.getNodeAs("nestedNameLoc")) { if (const NestedNameSpecifier *Spec = Loc->getNestedNameSpecifier()) { if (const NamespaceDecl *Decl = Spec->getAsNamespace()) { - addUsage(Decl, Loc->getLocalSourceRange()); + addUsage(Decl, Loc->getLocalSourceRange(), Result.SourceManager); return; } } @@ -325,7 +330,8 @@ void RenamerClangTidyCheck::check(const MatchFinder::MatchResult &Result) { if (const auto *Decl = Result.Nodes.getNodeAs("using")) { for (const auto *Shadow : Decl->shadows()) - addUsage(Shadow->getTargetDecl(), Decl->getNameInfo().getSourceRange()); + addUsage(Shadow->getTargetDecl(), Decl->getNameInfo().getSourceRange(), + Result.SourceManager); return; } @@ -371,14 +377,14 @@ void RenamerClangTidyCheck::check(const MatchFinder::MatchResult &Result) { // Fix using namespace declarations. if (const auto *UsingNS = dyn_cast(Decl)) addUsage(UsingNS->getNominatedNamespaceAsWritten(), - UsingNS->getIdentLocation()); + UsingNS->getIdentLocation(), Result.SourceManager); if (!Decl->getIdentifier() || Decl->getName().empty() || Decl->isImplicit()) return; const auto *Canonical = cast(Decl->getCanonicalDecl()); if (Canonical != Decl) { - addUsage(Canonical, Decl->getLocation()); + addUsage(Canonical, Decl->getLocation(), Result.SourceManager); return; } @@ -386,7 +392,8 @@ void RenamerClangTidyCheck::check(const MatchFinder::MatchResult &Result) { if (const auto *Value = Result.Nodes.getNodeAs("decl")) { if (const Type *TypePtr = Value->getType().getTypePtrOrNull()) { if (const auto *Typedef = TypePtr->getAs()) - addUsage(Typedef->getDecl(), Value->getSourceRange()); + addUsage(Typedef->getDecl(), Value->getSourceRange(), + Result.SourceManager); } } @@ -394,11 +401,13 @@ void RenamerClangTidyCheck::check(const MatchFinder::MatchResult &Result) { if (const auto *Value = Result.Nodes.getNodeAs("decl")) { if (const auto *Typedef = Value->getReturnType().getTypePtr()->getAs()) - addUsage(Typedef->getDecl(), Value->getSourceRange()); + addUsage(Typedef->getDecl(), Value->getSourceRange(), + Result.SourceManager); for (const ParmVarDecl *Param : Value->parameters()) { if (const TypedefType *Typedef = Param->getType().getTypePtr()->getAs()) - addUsage(Typedef->getDecl(), Value->getSourceRange()); + addUsage(Typedef->getDecl(), Value->getSourceRange(), + Result.SourceManager); } } diff --git a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h index d20f27ce0466f..a352b6a5584ae 100644 --- a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h +++ b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.h @@ -12,6 +12,7 @@ #include "../ClangTidyCheck.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/FunctionExtras.h" #include "llvm/ADT/Optional.h" #include #include diff --git a/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp b/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp index 0a57856b79722..03af5dd1565f8 100644 --- a/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp +++ b/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "TransformerClangTidyCheck.h" +#include "clang/Lex/Preprocessor.h" #include "llvm/ADT/STLExtras.h" namespace clang { @@ -32,7 +33,6 @@ TransformerClangTidyCheck::TransformerClangTidyCheck( StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), Rule(MakeRule(getLangOpts(), Options)), IncludeStyle(Options.getLocalOrGlobal("IncludeStyle", - IncludeSorter::getMapping(), IncludeSorter::IS_LLVM)) { if (Rule) assert(llvm::all_of(Rule->Cases, hasExplanation) && @@ -45,7 +45,6 @@ TransformerClangTidyCheck::TransformerClangTidyCheck(RewriteRule R, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), Rule(std::move(R)), IncludeStyle(Options.getLocalOrGlobal("IncludeStyle", - IncludeSorter::getMapping(), IncludeSorter::IS_LLVM)) { assert(llvm::all_of(Rule->Cases, hasExplanation) && "clang-tidy checks must have an explanation by default;" @@ -111,8 +110,7 @@ void TransformerClangTidyCheck::check( void TransformerClangTidyCheck::storeOptions( ClangTidyOptions::OptionMap &Opts) { - Options.store(Opts, "IncludeStyle", IncludeStyle, - IncludeSorter::getMapping()); + Options.store(Opts, "IncludeStyle", IncludeStyle); } } // namespace utils diff --git a/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.h b/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.h index d99f927a79732..829a22fe8e2cc 100644 --- a/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.h +++ b/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.h @@ -9,14 +9,11 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_TRANSFORMER_CLANG_TIDY_CHECK_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_TRANSFORMER_CLANG_TIDY_CHECK_H -#include "../ClangTidy.h" +#include "../ClangTidyCheck.h" #include "IncludeInserter.h" #include "IncludeSorter.h" #include "clang/ASTMatchers/ASTMatchFinder.h" -#include "clang/Frontend/CompilerInstance.h" #include "clang/Tooling/Transformer/Transformer.h" -#include -#include namespace clang { namespace tidy { diff --git a/clang-tools-extra/clang-tidy/zircon/CMakeLists.txt b/clang-tools-extra/clang-tidy/zircon/CMakeLists.txt index 29c99e92e0974..89c0d5737cec1 100644 --- a/clang-tools-extra/clang-tidy/zircon/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/zircon/CMakeLists.txt @@ -10,6 +10,9 @@ add_clang_library(clangTidyZirconModule LINK_LIBS clangTidy clangTidyUtils + + DEPENDS + omp_gen ) clang_target_link_libraries(clangTidyZirconModule diff --git a/clang-tools-extra/clangd/CMakeLists.txt b/clang-tools-extra/clangd/CMakeLists.txt index fa4f8b41ff8d4..9eb06941e4dd3 100644 --- a/clang-tools-extra/clangd/CMakeLists.txt +++ b/clang-tools-extra/clangd/CMakeLists.txt @@ -36,6 +36,10 @@ add_clang_library(clangDaemon CollectMacros.cpp CompileCommands.cpp Compiler.cpp + Config.cpp + ConfigCompile.cpp + ConfigProvider.cpp + ConfigYAML.cpp Diagnostics.cpp DraftStore.cpp ExpectedTypes.cpp @@ -100,6 +104,9 @@ add_clang_library(clangDaemon clangTidy ${LLVM_PTHREAD_LIB} ${ALL_CLANG_TIDY_CHECKS} + + DEPENDS + omp_gen ) clang_target_link_libraries(clangDaemon diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp index 93f2746bb6f0c..b0aba886edbe4 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -599,8 +599,8 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params, }}, {"semanticTokensProvider", llvm::json::Object{ - {"documentProvider", llvm::json::Object{{"edits", true}}}, - {"rangeProvider", false}, + {"full", llvm::json::Object{{"delta", true}}}, + {"range", false}, {"legend", llvm::json::Object{{"tokenTypes", semanticTokenTypes()}, {"tokenModifiers", llvm::json::Array()}}}, @@ -879,7 +879,8 @@ void ClangdLSPServer::onDocumentOnTypeFormatting( "onDocumentOnTypeFormatting called for non-added file", ErrorCode::InvalidParams)); - Reply(Server->formatOnType(Code->Contents, File, Params.position, Params.ch)); + Server->formatOnType(File, Code->Contents, Params.position, Params.ch, + std::move(Reply)); } void ClangdLSPServer::onDocumentRangeFormatting( @@ -892,12 +893,15 @@ void ClangdLSPServer::onDocumentRangeFormatting( "onDocumentRangeFormatting called for non-added file", ErrorCode::InvalidParams)); - auto ReplacementsOrError = - Server->formatRange(Code->Contents, File, Params.range); - if (ReplacementsOrError) - Reply(replacementsToEdits(Code->Contents, ReplacementsOrError.get())); - else - Reply(ReplacementsOrError.takeError()); + Server->formatRange( + File, Code->Contents, Params.range, + [Code = Code->Contents, Reply = std::move(Reply)]( + llvm::Expected Result) mutable { + if (Result) + Reply(replacementsToEdits(Code, Result.get())); + else + Reply(Result.takeError()); + }); } void ClangdLSPServer::onDocumentFormatting( @@ -910,11 +914,14 @@ void ClangdLSPServer::onDocumentFormatting( "onDocumentFormatting called for non-added file", ErrorCode::InvalidParams)); - auto ReplacementsOrError = Server->formatFile(Code->Contents, File); - if (ReplacementsOrError) - Reply(replacementsToEdits(Code->Contents, ReplacementsOrError.get())); - else - Reply(ReplacementsOrError.takeError()); + Server->formatFile(File, Code->Contents, + [Code = Code->Contents, Reply = std::move(Reply)]( + llvm::Expected Result) mutable { + if (Result) + Reply(replacementsToEdits(Code, Result.get())); + else + Reply(Result.takeError()); + }); } /// The functions constructs a flattened view of the DocumentSymbol hierarchy. @@ -1304,9 +1311,9 @@ void ClangdLSPServer::onSemanticTokens(const SemanticTokensParams &Params, }); } -void ClangdLSPServer::onSemanticTokensEdits( - const SemanticTokensEditsParams &Params, - Callback CB) { +void ClangdLSPServer::onSemanticTokensDelta( + const SemanticTokensDeltaParams &Params, + Callback CB) { Server->semanticHighlights( Params.textDocument.uri.file(), [this, PrevResultID(Params.previousResultId), @@ -1316,7 +1323,7 @@ void ClangdLSPServer::onSemanticTokensEdits( return CB(HT.takeError()); std::vector Toks = toSemanticTokens(*HT); - SemanticTokensOrEdits Result; + SemanticTokensOrDelta Result; { std::lock_guard Lock(SemanticTokensMutex); auto &Last = LastSemanticTokens[File]; @@ -1324,8 +1331,8 @@ void ClangdLSPServer::onSemanticTokensEdits( if (PrevResultID == Last.resultId) { Result.edits = diffTokens(Last.tokens, Toks); } else { - vlog("semanticTokens/edits: wanted edits vs {0} but last result " - "had ID {1}. Returning full token list.", + vlog("semanticTokens/full/delta: wanted edits vs {0} but last " + "result had ID {1}. Returning full token list.", PrevResultID, Last.resultId); Result.tokens = Toks; } @@ -1386,8 +1393,8 @@ ClangdLSPServer::ClangdLSPServer( MsgHandler->bind("typeHierarchy/resolve", &ClangdLSPServer::onResolveTypeHierarchy); MsgHandler->bind("textDocument/selectionRange", &ClangdLSPServer::onSelectionRange); MsgHandler->bind("textDocument/documentLink", &ClangdLSPServer::onDocumentLink); - MsgHandler->bind("textDocument/semanticTokens", &ClangdLSPServer::onSemanticTokens); - MsgHandler->bind("textDocument/semanticTokens/edits", &ClangdLSPServer::onSemanticTokensEdits); + MsgHandler->bind("textDocument/semanticTokens/full", &ClangdLSPServer::onSemanticTokens); + MsgHandler->bind("textDocument/semanticTokens/full/delta", &ClangdLSPServer::onSemanticTokensDelta); // clang-format on } diff --git a/clang-tools-extra/clangd/ClangdLSPServer.h b/clang-tools-extra/clangd/ClangdLSPServer.h index 6ccef9500679c..a779e9036c4a8 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.h +++ b/clang-tools-extra/clangd/ClangdLSPServer.h @@ -121,8 +121,8 @@ class ClangdLSPServer : private ClangdServer::Callbacks { void onDocumentLink(const DocumentLinkParams &, Callback>); void onSemanticTokens(const SemanticTokensParams &, Callback); - void onSemanticTokensEdits(const SemanticTokensEditsParams &, - Callback); + void onSemanticTokensDelta(const SemanticTokensDeltaParams &, + Callback); std::vector getFixes(StringRef File, const clangd::Diagnostic &D); diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp index 6c7255c96963d..5d99104dadaf6 100644 --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -8,6 +8,7 @@ #include "ClangdServer.h" #include "CodeComplete.h" +#include "Config.h" #include "FindSymbols.h" #include "Format.h" #include "HeaderSourceSwitch.h" @@ -132,7 +133,7 @@ ClangdServer::Options::operator TUScheduler::Options() const { ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB, const ThreadsafeFS &TFS, const Options &Opts, Callbacks *Callbacks) - : TFS(TFS), + : ConfigProvider(Opts.ConfigProvider), TFS(TFS), DynamicIdx(Opts.BuildDynamicSymbolIndex ? new FileIndex(Opts.HeavyweightDynamicSymbolIndex) : nullptr), @@ -147,7 +148,14 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB, // FIXME(ioeric): this can be slow and we may be able to index on less // critical paths. WorkScheduler( - CDB, TUScheduler::Options(Opts), + CDB, + [&, this] { + TUScheduler::Options O(Opts); + O.ContextProvider = [this](PathRef P) { + return createProcessingContext(P); + }; + return O; + }(), std::make_unique( DynamicIdx.get(), Callbacks, Opts.TheiaSemanticHighlighting)) { // Adds an index to the stack, at higher priority than existing indexes. @@ -170,7 +178,8 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB, [Callbacks](BackgroundQueue::Stats S) { if (Callbacks) Callbacks->onBackgroundIndexProgress(S); - }); + }, + [this](PathRef P) { return createProcessingContext(P); }); AddIndex(BackgroundIdx.get()); } if (DynamicIdx) @@ -296,40 +305,46 @@ void ClangdServer::signatureHelp(PathRef File, Position Pos, std::move(Action)); } -llvm::Expected -ClangdServer::formatRange(llvm::StringRef Code, PathRef File, Range Rng) { +void ClangdServer::formatRange(PathRef File, llvm::StringRef Code, Range Rng, + Callback CB) { llvm::Expected Begin = positionToOffset(Code, Rng.start); if (!Begin) - return Begin.takeError(); + return CB(Begin.takeError()); llvm::Expected End = positionToOffset(Code, Rng.end); if (!End) - return End.takeError(); - return formatCode(Code, File, {tooling::Range(*Begin, *End - *Begin)}); + return CB(End.takeError()); + formatCode(File, Code, {tooling::Range(*Begin, *End - *Begin)}, + std::move(CB)); } -llvm::Expected -ClangdServer::formatFile(llvm::StringRef Code, PathRef File) { +void ClangdServer::formatFile(PathRef File, llvm::StringRef Code, + Callback CB) { // Format everything. - return formatCode(Code, File, {tooling::Range(0, Code.size())}); + formatCode(File, Code, {tooling::Range(0, Code.size())}, std::move(CB)); } -llvm::Expected> -ClangdServer::formatOnType(llvm::StringRef Code, PathRef File, Position Pos, - StringRef TriggerText) { +void ClangdServer::formatOnType(PathRef File, llvm::StringRef Code, + Position Pos, StringRef TriggerText, + Callback> CB) { llvm::Expected CursorPos = positionToOffset(Code, Pos); if (!CursorPos) - return CursorPos.takeError(); - auto Style = format::getStyle(format::DefaultFormatStyle, File, - format::DefaultFallbackStyle, Code, - TFS.view(/*CWD=*/llvm::None).get()); - if (!Style) - return Style.takeError(); - - std::vector Result; - for (const tooling::Replacement &R : - formatIncremental(Code, *CursorPos, TriggerText, *Style)) - Result.push_back(replacementToEdit(Code, R)); - return Result; + return CB(CursorPos.takeError()); + auto Action = [File = File.str(), Code = Code.str(), + TriggerText = TriggerText.str(), CursorPos = *CursorPos, + CB = std::move(CB), this]() mutable { + auto Style = format::getStyle(format::DefaultFormatStyle, File, + format::DefaultFallbackStyle, Code, + TFS.view(/*CWD=*/llvm::None).get()); + if (!Style) + return CB(Style.takeError()); + + std::vector Result; + for (const tooling::Replacement &R : + formatIncremental(Code, CursorPos, TriggerText, *Style)) + Result.push_back(replacementToEdit(Code, R)); + return CB(Result); + }; + WorkScheduler.run("FormatOnType", File, std::move(Action)); } void ClangdServer::prepareRename(PathRef File, Position Pos, @@ -561,21 +576,25 @@ void ClangdServer::switchSourceHeader( WorkScheduler.runWithAST("SwitchHeaderSource", Path, std::move(Action)); } -llvm::Expected -ClangdServer::formatCode(llvm::StringRef Code, PathRef File, - llvm::ArrayRef Ranges) { +void ClangdServer::formatCode(PathRef File, llvm::StringRef Code, + llvm::ArrayRef Ranges, + Callback CB) { // Call clang-format. - format::FormatStyle Style = getFormatStyleForFile(File, Code, TFS); - tooling::Replacements IncludeReplaces = - format::sortIncludes(Style, Code, Ranges, File); - auto Changed = tooling::applyAllReplacements(Code, IncludeReplaces); - if (!Changed) - return Changed.takeError(); - - return IncludeReplaces.merge(format::reformat( - Style, *Changed, - tooling::calculateRangesAfterReplacements(IncludeReplaces, Ranges), - File)); + auto Action = [File = File.str(), Code = Code.str(), Ranges = Ranges.vec(), + CB = std::move(CB), this]() mutable { + format::FormatStyle Style = getFormatStyleForFile(File, Code, TFS); + tooling::Replacements IncludeReplaces = + format::sortIncludes(Style, Code, Ranges, File); + auto Changed = tooling::applyAllReplacements(Code, IncludeReplaces); + if (!Changed) + return CB(Changed.takeError()); + + CB(IncludeReplaces.merge(format::reformat( + Style, *Changed, + tooling::calculateRangesAfterReplacements(IncludeReplaces, Ranges), + File))); + }; + WorkScheduler.run("Format", File, std::move(Action)); } void ClangdServer::findDocumentHighlights( @@ -636,7 +655,7 @@ void ClangdServer::workspaceSymbols( llvm::StringRef Query, int Limit, Callback> CB) { WorkScheduler.run( - "getWorkspaceSymbols", + "getWorkspaceSymbols", /*Path=*/"", [Query = Query.str(), Limit, CB = std::move(CB), this]() mutable { CB(clangd::getWorkspaceSymbols(Query, Limit, Index, WorkspaceRoot.getValueOr(""))); @@ -726,6 +745,31 @@ llvm::StringMap ClangdServer::fileStats() const { return WorkScheduler.fileStats(); } +Context ClangdServer::createProcessingContext(PathRef File) const { + if (!ConfigProvider) + return Context::current().clone(); + + config::Params Params; + llvm::SmallString<256> PosixPath; + if (!File.empty()) { + assert(llvm::sys::path::is_absolute(File)); + llvm::sys::path::native(File, PosixPath, llvm::sys::path::Style::posix); + Params.Path = PosixPath.str(); + } + + auto DiagnosticHandler = [](const llvm::SMDiagnostic &Diag) { + if (Diag.getKind() == llvm::SourceMgr::DK_Error) { + elog("config error at {0}:{1}:{2}: {3}", Diag.getFilename(), + Diag.getLineNo(), Diag.getColumnNo(), Diag.getMessage()); + } else { + log("config warning at {0}:{1}:{2}: {3}", Diag.getFilename(), + Diag.getLineNo(), Diag.getColumnNo(), Diag.getMessage()); + } + }; + Config C = ConfigProvider->getConfig(Params, DiagnosticHandler); + return Context::current().derive(Config::Key, std::move(C)); +} + LLVM_NODISCARD bool ClangdServer::blockUntilIdleForTest(llvm::Optional TimeoutSeconds) { return WorkScheduler.blockUntilIdle(timeoutSeconds(TimeoutSeconds)) && diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h index 021540df66f36..ea82081f24405 100644 --- a/clang-tools-extra/clangd/ClangdServer.h +++ b/clang-tools-extra/clangd/ClangdServer.h @@ -11,6 +11,7 @@ #include "../clang-tidy/ClangTidyOptions.h" #include "CodeComplete.h" +#include "ConfigProvider.h" #include "GlobalCompilationDatabase.h" #include "Hover.h" #include "Protocol.h" @@ -99,7 +100,7 @@ class ClangdServer { bool StorePreamblesInMemory = true; /// Reuse even stale preambles, and rebuild them in the background. /// This improves latency at the cost of accuracy. - bool AsyncPreambleBuilds = false; + bool AsyncPreambleBuilds = true; /// If true, ClangdServer builds a dynamic in-memory index for symbols in /// opened files and uses the index to augment code completion results. @@ -113,6 +114,9 @@ class ClangdServer { /// If set, use this index to augment code completion results. SymbolIndex *StaticIndex = nullptr; + /// If set, queried to obtain the configuration to handle each request. + config::Provider *ConfigProvider = nullptr; + /// If set, enable clang-tidy in clangd and use to it get clang-tidy /// configurations for a particular file. /// Clangd supports only a small subset of ClangTidyOptions, these options @@ -247,18 +251,17 @@ class ClangdServer { Callback CB); /// Run formatting for \p Rng inside \p File with content \p Code. - llvm::Expected formatRange(StringRef Code, - PathRef File, Range Rng); + void formatRange(PathRef File, StringRef Code, Range Rng, + Callback CB); /// Run formatting for the whole \p File with content \p Code. - llvm::Expected formatFile(StringRef Code, - PathRef File); + void formatFile(PathRef File, StringRef Code, + Callback CB); /// Run formatting after \p TriggerText was typed at \p Pos in \p File with /// content \p Code. - llvm::Expected> formatOnType(StringRef Code, - PathRef File, Position Pos, - StringRef TriggerText); + void formatOnType(PathRef File, StringRef Code, Position Pos, + StringRef TriggerText, Callback> CB); /// Test the validity of a rename operation. void prepareRename(PathRef File, Position Pos, @@ -323,11 +326,18 @@ class ClangdServer { blockUntilIdleForTest(llvm::Optional TimeoutSeconds = 10); private: - /// FIXME: This stats several files to find a .clang-format file. I/O can be - /// slow. Think of a way to cache this. - llvm::Expected - formatCode(llvm::StringRef Code, PathRef File, - ArrayRef Ranges); + void formatCode(PathRef File, llvm::StringRef Code, + ArrayRef Ranges, + Callback CB); + + /// Derives a context for a task processing the specified source file. + /// This includes the current configuration (see Options::ConfigProvider). + /// The empty string means no particular file is the target. + /// Rather than called by each feature, this is exposed to the components + /// that control worker threads, like TUScheduler and BackgroundIndex. + /// This means it's OK to do some IO here, and it cuts across all features. + Context createProcessingContext(PathRef) const; + config::Provider *ConfigProvider = nullptr; const ThreadsafeFS &TFS; diff --git a/clang-tools-extra/clangd/CompileCommands.cpp b/clang-tools-extra/clangd/CompileCommands.cpp index a2d704f57bda6..0b27e0e3e8284 100644 --- a/clang-tools-extra/clangd/CompileCommands.cpp +++ b/clang-tools-extra/clangd/CompileCommands.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "CompileCommands.h" +#include "Config.h" #include "support/Logger.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Tooling/ArgumentsAdjusters.h" @@ -182,6 +183,10 @@ CommandMangler CommandMangler::forTests() { } void CommandMangler::adjust(std::vector &Cmd) const { + // FIXME: remove const_cast once unique_function is const-compatible. + for (auto &Edit : const_cast(Config::current()).CompileFlags.Edits) + Edit(Cmd); + // Check whether the flag exists, either as -flag or -flag=* auto Has = [&](llvm::StringRef Flag) { for (llvm::StringRef Arg : Cmd) { diff --git a/clang-tools-extra/clangd/Config.cpp b/clang-tools-extra/clangd/Config.cpp new file mode 100644 index 0000000000000..3b9b9bf71e24d --- /dev/null +++ b/clang-tools-extra/clangd/Config.cpp @@ -0,0 +1,25 @@ +//===--- Config.cpp - User configuration of clangd behavior ---------------===// +// +// 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 "Config.h" +#include "support/Context.h" + +namespace clang { +namespace clangd { + +Key Config::Key; + +const Config &Config::current() { + if (const Config *C = Context::current().get(Key)) + return *C; + static Config Default; + return Default; +} + +} // namespace clangd +} // namespace clang diff --git a/clang-tools-extra/clangd/Config.h b/clang-tools-extra/clangd/Config.h new file mode 100644 index 0000000000000..878c9e8549b52 --- /dev/null +++ b/clang-tools-extra/clangd/Config.h @@ -0,0 +1,63 @@ +//===--- Config.h - User configuration of clangd behavior --------*- C++-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Various clangd features have configurable behaviour (or can be disabled). +// This file defines "resolved" configuration seen by features within clangd. +// For example, settings may vary per-file, the resolved Config only contains +// settings that apply to the current file. +// +// This is distinct from how the config is specified by the user (Fragment) +// interpreted (CompiledFragment), and combined (Provider). +// ConfigFragment.h describes the steps to add a new configuration option. +// +// Because this structure is shared throughout clangd, it's a potential source +// of layering problems. Config should be expressed in terms of simple +// vocubulary types where possible. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONFIG_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONFIG_H + +#include "support/Context.h" +#include "llvm/ADT/FunctionExtras.h" +#include +#include + +namespace clang { +namespace clangd { + +/// Settings that express user/project preferences and control clangd behavior. +/// +/// Generally, features should consume Config::current() and the caller is +/// responsible for setting it appropriately. In practice these callers are +/// ClangdServer, TUScheduler, and BackgroundQueue. +struct Config { + /// Returns the Config of the current Context, or an empty configuration. + static const Config ¤t(); + /// Context key which can be used to set the current Config. + static clangd::Key Key; + + Config() = default; + Config(const Config &) = delete; + Config &operator=(const Config &) = delete; + Config(Config &&) = default; + Config &operator=(Config &&) = default; + + /// Controls how the compile command for the current file is determined. + struct { + // Edits to apply to the compile command, in sequence. + // FIXME: these functions need to be const-callable. For now, const_cast. + std::vector &)>> Edits; + } CompileFlags; +}; + +} // namespace clangd +} // namespace clang + +#endif diff --git a/clang-tools-extra/clangd/ConfigCompile.cpp b/clang-tools-extra/clangd/ConfigCompile.cpp new file mode 100644 index 0000000000000..04c0df88bbf76 --- /dev/null +++ b/clang-tools-extra/clangd/ConfigCompile.cpp @@ -0,0 +1,172 @@ +//===--- ConfigCompile.cpp - Translating Fragments into Config ------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// Fragments are applied to Configs in two steps: +// +// 1. (When the fragment is first loaded) +// FragmentCompiler::compile() traverses the Fragment and creates +// function objects that know how to apply the configuration. +// 2. (Every time a config is required) +// CompiledFragment() executes these functions to populate the Config. +// +// Work could be split between these steps in different ways. We try to +// do as much work as possible in the first step. For example, regexes are +// compiled in stage 1 and captured by the apply function. This is because: +// +// - it's more efficient, as the work done in stage 1 must only be done once +// - problems can be reported in stage 1, in stage 2 we must silently recover +// +//===----------------------------------------------------------------------===// + +#include "Config.h" +#include "ConfigFragment.h" +#include "support/Logger.h" +#include "support/Trace.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Regex.h" +#include "llvm/Support/SMLoc.h" +#include "llvm/Support/SourceMgr.h" + +namespace clang { +namespace clangd { +namespace config { +namespace { + +struct CompiledFragmentImpl { + // The independent conditions to check before using settings from this config. + // The following fragment has *two* conditions: + // If: { Platform: [mac, linux], PathMatch: foo/.* } + // All of them must be satisfied: the platform and path conditions are ANDed. + // The OR logic for the platform condition is implemented inside the function. + std::vector> Conditions; + // Mutations that this fragment will apply to the configuration. + // These are invoked only if the conditions are satisfied. + std::vector> Apply; + + bool operator()(const Params &P, Config &C) const { + for (const auto &C : Conditions) { + if (!C(P)) { + dlog("Config fragment {0}: condition not met", this); + return false; + } + } + dlog("Config fragment {0}: applying {1} rules", this, Apply.size()); + for (const auto &A : Apply) + A(C); + return true; + } +}; + +// Wrapper around condition compile() functions to reduce arg-passing. +struct FragmentCompiler { + CompiledFragmentImpl &Out; + DiagnosticCallback Diagnostic; + llvm::SourceMgr *SourceMgr; + + llvm::Optional compileRegex(const Located &Text) { + std::string Anchored = "^(" + *Text + ")$"; + llvm::Regex Result(Anchored); + std::string RegexError; + if (!Result.isValid(RegexError)) { + diag(Error, "Invalid regex " + Anchored + ": " + RegexError, Text.Range); + return llvm::None; + } + return Result; + } + + void compile(Fragment &&F) { + compile(std::move(F.If)); + compile(std::move(F.CompileFlags)); + } + + void compile(Fragment::IfBlock &&F) { + if (F.HasUnrecognizedCondition) + Out.Conditions.push_back([&](const Params &) { return false; }); + + auto PathMatch = std::make_unique>(); + for (auto &Entry : F.PathMatch) { + if (auto RE = compileRegex(Entry)) + PathMatch->push_back(std::move(*RE)); + } + if (!PathMatch->empty()) { + Out.Conditions.push_back( + [PathMatch(std::move(PathMatch))](const Params &P) { + if (P.Path.empty()) + return false; + return llvm::any_of(*PathMatch, [&](const llvm::Regex &RE) { + return RE.match(P.Path); + }); + }); + } + + auto PathExclude = std::make_unique>(); + for (auto &Entry : F.PathExclude) { + if (auto RE = compileRegex(Entry)) + PathExclude->push_back(std::move(*RE)); + } + if (!PathExclude->empty()) { + Out.Conditions.push_back( + [PathExclude(std::move(PathExclude))](const Params &P) { + if (P.Path.empty()) + return false; + return llvm::none_of(*PathExclude, [&](const llvm::Regex &RE) { + return RE.match(P.Path); + }); + }); + } + } + + void compile(Fragment::CompileFlagsBlock &&F) { + if (!F.Add.empty()) { + std::vector Add; + for (auto &A : F.Add) + Add.push_back(std::move(*A)); + Out.Apply.push_back([Add(std::move(Add))](Config &C) { + C.CompileFlags.Edits.push_back([Add](std::vector &Args) { + Args.insert(Args.end(), Add.begin(), Add.end()); + }); + }); + } + } + + constexpr static llvm::SourceMgr::DiagKind Error = llvm::SourceMgr::DK_Error; + void diag(llvm::SourceMgr::DiagKind Kind, llvm::StringRef Message, + llvm::SMRange Range) { + if (Range.isValid() && SourceMgr != nullptr) + Diagnostic(SourceMgr->GetMessage(Range.Start, Kind, Message, Range)); + else + Diagnostic(llvm::SMDiagnostic("", Kind, Message)); + } +}; + +} // namespace + +CompiledFragment Fragment::compile(DiagnosticCallback D) && { + llvm::StringRef ConfigFile = ""; + std::pair LineCol = {0, 0}; + if (auto *SM = Source.Manager.get()) { + unsigned BufID = SM->getMainFileID(); + LineCol = SM->getLineAndColumn(Source.Location, BufID); + ConfigFile = SM->getBufferInfo(BufID).Buffer->getBufferIdentifier(); + } + trace::Span Tracer("ConfigCompile"); + SPAN_ATTACH(Tracer, "ConfigFile", ConfigFile); + auto Result = std::make_shared(); + vlog("Config fragment: compiling {0}:{1} -> {2}", ConfigFile, LineCol.first, + Result.get()); + + FragmentCompiler{*Result, D, Source.Manager.get()}.compile(std::move(*this)); + // Return as cheaply-copyable wrapper. + return [Result(std::move(Result))](const Params &P, Config &C) { + return (*Result)(P, C); + }; +} + +} // namespace config +} // namespace clangd +} // namespace clang diff --git a/clang-tools-extra/clangd/ConfigFragment.h b/clang-tools-extra/clangd/ConfigFragment.h new file mode 100644 index 0000000000000..42f9ec2edc724 --- /dev/null +++ b/clang-tools-extra/clangd/ConfigFragment.h @@ -0,0 +1,129 @@ +//===--- ConfigFragment.h - Unit of user-specified configuration -*- C++-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Various clangd features have configurable behaviour (or can be disabled). +// The configuration system allows users to control this: +// - in a user config file, a project config file, via LSP, or via flags +// - specifying different settings for different files +// +// This file defines the config::Fragment structure which models one piece of +// configuration as obtained from a source like a file. +// +// This is distinct from how the config is interpreted (CompiledFragment), +// combined (Provider) and exposed to the rest of clangd (Config). +// +//===----------------------------------------------------------------------===// +// +// To add a new configuration option, you must: +// - add its syntactic form to Fragment +// - update ConfigYAML.cpp to parse it +// - add its semantic form to Config (in Config.h) +// - update ConfigCompile.cpp to map Fragment -> Config +// - make use of the option inside clangd +// - document the new option (config.md in the llvm/clangd-www repository) +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONFIGFRAGMENT_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONFIGFRAGMENT_H + +#include "ConfigProvider.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/SMLoc.h" +#include "llvm/Support/SourceMgr.h" +#include +#include + +namespace clang { +namespace clangd { +namespace config { + +/// An entity written in config along, with its optional location in the file. +template struct Located { + Located(T Value, llvm::SMRange Range = {}) + : Range(Range), Value(std::move(Value)) {} + + llvm::SMRange Range; + T &operator->() { return Value; } + const T &operator->() const { return Value; } + T &operator*() { return Value; } + const T &operator*() const { return Value; } + +private: + T Value; +}; + +/// A chunk of configuration obtained from a config file, LSP, or elsewhere. +struct Fragment { + /// Parses fragments from a YAML file (one from each --- delimited document). + /// Documents that contained fatal errors are omitted from the results. + /// BufferName is used for the SourceMgr and diagnostics. + static std::vector parseYAML(llvm::StringRef YAML, + llvm::StringRef BufferName, + DiagnosticCallback); + + /// Analyzes and consumes this fragment, possibly yielding more diagnostics. + /// This always produces a usable result (errors are recovered). + /// + /// Typically, providers will compile a Fragment once when it's first loaded, + /// caching the result for reuse. + /// Like a compiled program, this is good for performance and also encourages + /// errors to be reported early and only once. + /// + /// The returned function is a cheap-copyable wrapper of refcounted internals. + CompiledFragment compile(DiagnosticCallback) &&; + + /// These fields are not part of the user-specified configuration, but + /// instead are populated by the parser to describe the configuration source. + struct SourceInfo { + /// Retains a buffer of the original source this fragment was parsed from. + /// Locations within Located objects point into this SourceMgr. + /// Shared because multiple fragments are often parsed from one (YAML) file. + /// May be null, then all locations should be ignored. + std::shared_ptr Manager; + /// The start of the original source for this fragment. + /// Only valid if SourceManager is set. + llvm::SMLoc Location; + }; + SourceInfo Source; + + /// Conditions in the If block restrict when a Fragment applies. + /// + /// Each separate condition must match (combined with AND). + /// When one condition has multiple values, any may match (combined with OR). + /// e.g. `PathMatch: [foo/.*, bar/.*]` matches files in either directory. + /// + /// Conditions based on a file's path use the following form: + /// - if the fragment came from a project directory, the path is relative + /// - if the fragment is global (e.g. user config), the path is absolute + /// - paths always use forward-slashes (UNIX-style) + /// If no file is being processed, these conditions will not match. + struct IfBlock { + /// The file being processed must fully match a regular expression. + std::vector> PathMatch; + /// The file being processed must *not* fully match a regular expression. + std::vector> PathExclude; + + /// An unrecognized key was found while parsing the condition. + /// The condition will evaluate to false. + bool HasUnrecognizedCondition = false; + }; + IfBlock If; + + struct CompileFlagsBlock { + std::vector> Add; + } CompileFlags; +}; + +} // namespace config +} // namespace clangd +} // namespace clang + +#endif diff --git a/clang-tools-extra/clangd/ConfigProvider.cpp b/clang-tools-extra/clangd/ConfigProvider.cpp new file mode 100644 index 0000000000000..4b466d53e2930 --- /dev/null +++ b/clang-tools-extra/clangd/ConfigProvider.cpp @@ -0,0 +1,207 @@ +//===--- ConfigProvider.cpp - Loading of user configuration ---------------===// +// +// 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 "ConfigProvider.h" +#include "Config.h" +#include "ConfigFragment.h" +#include "support/ThreadsafeFS.h" +#include "support/Trace.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/Support/Path.h" +#include + +namespace clang { +namespace clangd { +namespace config { + +// Threadsafe cache around reading a YAML config file from disk. +class FileConfigCache { + std::mutex Mu; + llvm::SmallVector CachedValue; + llvm::sys::TimePoint<> MTime = {}; + unsigned Size = -1; + + void updateCacheLocked(const llvm::vfs::Status &Stat, + llvm::vfs::FileSystem &FS, DiagnosticCallback DC) { + if (Size == Stat.getSize() && MTime == Stat.getLastModificationTime()) + return; // Already valid. + + Size = Stat.getSize(); + MTime = Stat.getLastModificationTime(); + CachedValue.clear(); + + auto Buf = FS.getBufferForFile(Path); + // If stat() succeeds but we failed to read, don't cache failure. + if (!Buf) { + Size = -1; + MTime = {}; + return; + } + + // If file changed between stat and open, we don't know its mtime. + // For simplicity, don't cache the value in this case (use a bad key). + if (Buf->get()->getBufferSize() != Size) { + Size = -1; + MTime = {}; + } + + // Finally parse and compile the actual fragments. + for (auto &Fragment : + Fragment::parseYAML(Buf->get()->getBuffer(), Path, DC)) + CachedValue.push_back(std::move(Fragment).compile(DC)); + } + +public: + // Must be set before the cache is used. Not a constructor param to allow + // computing ancestor-relative paths to be deferred. + std::string Path; + + // Retrieves up-to-date config fragments from disk. + // A cached result may be reused if the mtime and size are unchanged. + // (But several concurrent read()s can miss the cache after a single change). + // Future performance ideas: + // - allow caches to be reused based on short elapsed walltime + // - allow latency-sensitive operations to skip revalidating the cache + void read(const ThreadsafeFS &TFS, DiagnosticCallback DC, + std::vector &Out) { + assert(llvm::sys::path::is_absolute(Path)); + auto FS = TFS.view(/*CWD=*/llvm::None); + auto Stat = FS->status(Path); + if (!Stat || !Stat->isRegularFile()) { + // No point taking the lock to clear the cache. We know what to return. + // If the file comes back we'll invalidate the cache at that point. + return; + } + + std::lock_guard Lock(Mu); + updateCacheLocked(*Stat, *FS, DC); + llvm::copy(CachedValue, std::back_inserter(Out)); + } +}; + +std::unique_ptr Provider::fromYAMLFile(llvm::StringRef AbsPath, + const ThreadsafeFS &FS) { + class AbsFileProvider : public Provider { + mutable FileConfigCache Cache; // threadsafe + const ThreadsafeFS &FS; + + std::vector + getFragments(const Params &P, DiagnosticCallback DC) const override { + std::vector Result; + Cache.read(FS, DC, Result); + return Result; + }; + + public: + AbsFileProvider(llvm::StringRef Path, const ThreadsafeFS &FS) : FS(FS) { + assert(llvm::sys::path::is_absolute(Path)); + Cache.Path = Path.str(); + } + }; + + return std::make_unique(AbsPath, FS); +} + +std::unique_ptr +Provider::fromAncestorRelativeYAMLFiles(llvm::StringRef RelPath, + const ThreadsafeFS &FS) { + class RelFileProvider : public Provider { + std::string RelPath; + const ThreadsafeFS &FS; + + mutable std::mutex Mu; + // Keys are the ancestor directory, not the actual config path within it. + // We only insert into this map, so pointers to values are stable forever. + // Mutex guards the map itself, not the values (which are threadsafe). + mutable llvm::StringMap Cache; + + std::vector + getFragments(const Params &P, DiagnosticCallback DC) const override { + namespace path = llvm::sys::path; + + if (P.Path.empty()) + return {}; + + // Compute absolute paths to all ancestors (substrings of P.Path). + llvm::StringRef Parent = path::parent_path(P.Path); + llvm::SmallVector Ancestors; + for (auto I = path::begin(Parent, path::Style::posix), + E = path::end(Parent); + I != E; ++I) { + // Avoid weird non-substring cases like phantom "." components. + // In practice, Component is a substring for all "normal" ancestors. + if (I->end() < Parent.begin() && I->end() > Parent.end()) + continue; + Ancestors.emplace_back(Parent.begin(), I->end() - Parent.begin()); + } + // Ensure corresponding cache entries exist in the map. + llvm::SmallVector Caches; + { + std::lock_guard Lock(Mu); + for (llvm::StringRef Ancestor : Ancestors) { + auto R = Cache.try_emplace(Ancestor); + // Assemble the actual config file path only once. + if (R.second) { + llvm::SmallString<256> ConfigPath = Ancestor; + path::append(ConfigPath, RelPath); + R.first->second.Path = ConfigPath.str().str(); + } + Caches.push_back(&R.first->second); + } + } + // Finally query each individual file. + // This will take a (per-file) lock for each file that actually exists. + std::vector Result; + for (FileConfigCache *Cache : Caches) + Cache->read(FS, DC, Result); + return Result; + }; + + public: + RelFileProvider(llvm::StringRef RelPath, const ThreadsafeFS &FS) + : RelPath(RelPath), FS(FS) { + assert(llvm::sys::path::is_relative(RelPath)); + } + }; + + return std::make_unique(RelPath, FS); +} + +std::unique_ptr +Provider::combine(std::vector> Providers) { + struct CombinedProvider : Provider { + std::vector> Providers; + + std::vector + getFragments(const Params &P, DiagnosticCallback DC) const override { + std::vector Result; + for (const auto &Provider : Providers) { + for (auto &Fragment : Provider->getFragments(P, DC)) + Result.push_back(std::move(Fragment)); + } + return Result; + } + }; + auto Result = std::make_unique(); + Result->Providers = std::move(Providers); + return Result; +} + +Config Provider::getConfig(const Params &P, DiagnosticCallback DC) const { + trace::Span Tracer("getConfig"); + if (!P.Path.empty()) + SPAN_ATTACH(Tracer, "path", P.Path); + Config C; + for (const auto &Fragment : getFragments(P, DC)) + Fragment(P, C); + return C; +} + +} // namespace config +} // namespace clangd +} // namespace clang diff --git a/clang-tools-extra/clangd/ConfigProvider.h b/clang-tools-extra/clangd/ConfigProvider.h new file mode 100644 index 0000000000000..a773e56b3bd72 --- /dev/null +++ b/clang-tools-extra/clangd/ConfigProvider.h @@ -0,0 +1,97 @@ +//===--- ConfigProvider.h - Loading of user configuration --------*- C++-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Various clangd features have configurable behaviour (or can be disabled). +// The configuration system allows users to control this: +// - in a user config file, a project config file, via LSP, or via flags +// - specifying different settings for different files +// This file defines the structures used for this, that produce a Config. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONFIGPROVIDER_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONFIGPROVIDER_H + +#include "llvm/ADT/FunctionExtras.h" +#include "llvm/Support/SMLoc.h" +#include "llvm/Support/SourceMgr.h" +#include +#include + +namespace clang { +namespace clangd { +struct Config; +class ThreadsafeFS; +namespace config { + +/// Describes the context used to evaluate configuration fragments. +struct Params { + /// Absolute path to a source file we're applying the config to. Unix slashes. + /// Empty if not configuring a particular file. + llvm::StringRef Path; +}; + +/// Used to report problems in parsing or interpreting a config. +/// Errors reflect structurally invalid config that should be user-visible. +/// Warnings reflect e.g. unknown properties that are recoverable. +using DiagnosticCallback = llvm::function_ref; + +/// A chunk of configuration that has been fully analyzed and is ready to apply. +/// Typically this is obtained from a Fragment by calling Fragment::compile(). +/// +/// Calling it updates the configuration to reflect settings from the fragment. +/// Returns true if the condition was met and the settings were used. +using CompiledFragment = std::function; + +/// A source of configuration fragments. +/// Generally these providers reflect a fixed policy for obtaining config, +/// but return different concrete configuration over time. +/// e.g. a provider that reads config from files is responsive to file changes. +class Provider { +public: + virtual ~Provider() = default; + + // Reads fragments from a single YAML file with a fixed path. + static std::unique_ptr fromYAMLFile(llvm::StringRef AbsPathPath, + const ThreadsafeFS &); + // Reads fragments from YAML files found relative to ancestors of Params.Path. + // + // All fragments that exist are returned, starting from distant ancestors. + // For instance, given RelPath of ".clangd", then for source file /foo/bar.cc, + // the searched fragments are [/.clangd, /foo/.clangd]. + // + // If Params does not specify a path, no fragments are returned. + static std::unique_ptr + fromAncestorRelativeYAMLFiles(llvm::StringRef RelPath, const ThreadsafeFS &); + + /// A provider that includes fragments from all the supplied providers. + /// Order is preserved; later providers take precedence over earlier ones. + static std::unique_ptr + combine(std::vector>); + + /// Build a config based on this provider. + Config getConfig(const Params &, DiagnosticCallback) const; + +private: + /// Provide fragments that may be relevant to the file. + /// The configuration provider is not responsible for testing conditions. + /// + /// Providers are expected to cache compiled fragments, and only + /// reparse/recompile when the source data has changed. + /// Despite the need for caching, this function must be threadsafe. + /// + /// When parsing/compiling, the DiagnosticCallback is used to report errors. + virtual std::vector + getFragments(const Params &, DiagnosticCallback) const = 0; +}; + +} // namespace config +} // namespace clangd +} // namespace clang + +#endif diff --git a/clang-tools-extra/clangd/ConfigYAML.cpp b/clang-tools-extra/clangd/ConfigYAML.cpp new file mode 100644 index 0000000000000..ef6003b024392 --- /dev/null +++ b/clang-tools-extra/clangd/ConfigYAML.cpp @@ -0,0 +1,218 @@ +//===--- ConfigYAML.cpp - Loading configuration fragments from YAML files -===// +// +// 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 "ConfigFragment.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/YAMLParser.h" +#include + +namespace clang { +namespace clangd { +namespace config { +namespace { +using llvm::yaml::BlockScalarNode; +using llvm::yaml::MappingNode; +using llvm::yaml::Node; +using llvm::yaml::ScalarNode; +using llvm::yaml::SequenceNode; + +class Parser { + llvm::SourceMgr &SM; + bool HadError = false; + +public: + Parser(llvm::SourceMgr &SM) : SM(SM) {} + + // Tries to parse N into F, returning false if it failed and we couldn't + // meaningfully recover (YAML syntax error, or hard semantic error). + bool parse(Fragment &F, Node &N) { + DictParser Dict("Config", this); + Dict.handle("If", [&](Node &N) { parse(F.If, N); }); + Dict.handle("CompileFlags", [&](Node &N) { parse(F.CompileFlags, N); }); + Dict.parse(N); + return !(N.failed() || HadError); + } + +private: + void parse(Fragment::IfBlock &F, Node &N) { + DictParser Dict("If", this); + Dict.unrecognized( + [&](llvm::StringRef) { F.HasUnrecognizedCondition = true; }); + Dict.handle("PathMatch", [&](Node &N) { + if (auto Values = scalarValues(N)) + F.PathMatch = std::move(*Values); + }); + Dict.handle("PathExclude", [&](Node &N) { + if (auto Values = scalarValues(N)) + F.PathExclude = std::move(*Values); + }); + Dict.parse(N); + } + + void parse(Fragment::CompileFlagsBlock &F, Node &N) { + DictParser Dict("CompileFlags", this); + Dict.handle("Add", [&](Node &N) { + if (auto Values = scalarValues(N)) + F.Add = std::move(*Values); + }); + Dict.parse(N); + } + + // Helper for parsing mapping nodes (dictionaries). + // We don't use YamlIO as we want to control over unknown keys. + class DictParser { + llvm::StringRef Description; + std::vector>> Keys; + std::function Unknown; + Parser *Outer; + + public: + DictParser(llvm::StringRef Description, Parser *Outer) + : Description(Description), Outer(Outer) {} + + // Parse is called when Key is encountered, and passed the associated value. + // It should emit diagnostics if the value is invalid (e.g. wrong type). + // If Key is seen twice, Parse runs only once and an error is reported. + void handle(llvm::StringLiteral Key, std::function Parse) { + for (const auto &Entry : Keys) { + (void) Entry; + assert(Entry.first != Key && "duplicate key handler"); + } + Keys.emplace_back(Key, std::move(Parse)); + } + + // Fallback is called when a Key is not matched by any handle(). + // A warning is also automatically emitted. + void unrecognized(std::function Fallback) { + Unknown = std::move(Fallback); + } + + // Process a mapping node and call handlers for each key/value pair. + void parse(Node &N) const { + if (N.getType() != Node::NK_Mapping) { + Outer->error(Description + " should be a dictionary", N); + return; + } + llvm::SmallSet Seen; + // We *must* consume all items, even on error, or the parser will assert. + for (auto &KV : llvm::cast(N)) { + auto *K = KV.getKey(); + if (!K) // YAMLParser emitted an error. + continue; + auto Key = Outer->scalarValue(*K, "Dictionary key"); + if (!Key) + continue; + if (!Seen.insert(**Key).second) { + Outer->warning("Duplicate key " + **Key + " is ignored", *K); + continue; + } + auto *Value = KV.getValue(); + if (!Value) // YAMLParser emitted an error. + continue; + bool Matched = false; + for (const auto &Handler : Keys) { + if (Handler.first == **Key) { + Matched = true; + Handler.second(*Value); + break; + } + } + if (!Matched) { + Outer->warning("Unknown " + Description + " key " + **Key, *K); + if (Unknown) + Unknown(**Key); + } + } + } + }; + + // Try to parse a single scalar value from the node, warn on failure. + llvm::Optional> scalarValue(Node &N, + llvm::StringRef Desc) { + llvm::SmallString<256> Buf; + if (auto *S = llvm::dyn_cast(&N)) + return Located(S->getValue(Buf).str(), N.getSourceRange()); + if (auto *BS = llvm::dyn_cast(&N)) + return Located(BS->getValue().str(), N.getSourceRange()); + warning(Desc + " should be scalar", N); + return llvm::None; + } + + // Try to parse a list of single scalar values, or just a single value. + llvm::Optional>> scalarValues(Node &N) { + std::vector> Result; + if (auto *S = llvm::dyn_cast(&N)) { + llvm::SmallString<256> Buf; + Result.emplace_back(S->getValue(Buf).str(), N.getSourceRange()); + } else if (auto *S = llvm::dyn_cast(&N)) { + Result.emplace_back(S->getValue().str(), N.getSourceRange()); + } else if (auto *S = llvm::dyn_cast(&N)) { + // We *must* consume all items, even on error, or the parser will assert. + for (auto &Child : *S) { + if (auto Value = scalarValue(Child, "List item")) + Result.push_back(std::move(*Value)); + } + } else { + warning("Expected scalar or list of scalars", N); + return llvm::None; + } + return Result; + } + + // Report a "hard" error, reflecting a config file that can never be valid. + void error(const llvm::Twine &Msg, const Node &N) { + HadError = true; + SM.PrintMessage(N.getSourceRange().Start, llvm::SourceMgr::DK_Error, Msg, + N.getSourceRange()); + } + + // Report a "soft" error that could be caused by e.g. version skew. + void warning(const llvm::Twine &Msg, const Node &N) { + SM.PrintMessage(N.getSourceRange().Start, llvm::SourceMgr::DK_Warning, Msg, + N.getSourceRange()); + } +}; + +} // namespace + +std::vector Fragment::parseYAML(llvm::StringRef YAML, + llvm::StringRef BufferName, + DiagnosticCallback Diags) { + // The YAML document may contain multiple conditional fragments. + // The SourceManager is shared for all of them. + auto SM = std::make_shared(); + auto Buf = llvm::MemoryBuffer::getMemBufferCopy(YAML, BufferName); + // Adapt DiagnosticCallback to function-pointer interface. + // Callback receives both errors we emit and those from the YAML parser. + SM->setDiagHandler( + [](const llvm::SMDiagnostic &Diag, void *Ctx) { + (*reinterpret_cast(Ctx))(Diag); + }, + &Diags); + std::vector Result; + for (auto &Doc : llvm::yaml::Stream(*Buf, *SM)) { + if (Node *N = Doc.getRoot()) { + Fragment Fragment; + Fragment.Source.Manager = SM; + Fragment.Source.Location = N->getSourceRange().Start; + if (Parser(*SM).parse(Fragment, *N)) + Result.push_back(std::move(Fragment)); + } + } + // Hack: stash the buffer in the SourceMgr to keep it alive. + // SM has two entries: "main" non-owning buffer, and ignored owning buffer. + SM->AddNewSourceBuffer(std::move(Buf), llvm::SMLoc()); + return Result; +} + +} // namespace config +} // namespace clangd +} // namespace clang diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp index 1d09e8408c837..627f40c854368 100644 --- a/clang-tools-extra/clangd/FindTarget.cpp +++ b/clang-tools-extra/clangd/FindTarget.cpp @@ -58,6 +58,24 @@ nodeToString(const ast_type_traits::DynTypedNode &N) { return S; } +// Helper function for getMembersReferencedViaDependentName() +// which takes a dependent type `T` and heuristically +// resolves it to a CXXRecordDecl in which we can try name lookup. +CXXRecordDecl *resolveTypeToRecordDecl(const Type *T) { + assert(T); + if (const auto *ICNT = T->getAs()) { + T = ICNT->getInjectedSpecializationType().getTypePtrOrNull(); + } + const auto *TST = T->getAs(); + if (!TST) + return nullptr; + const ClassTemplateDecl *TD = dyn_cast_or_null( + TST->getTemplateName().getAsTemplateDecl()); + if (!TD) + return nullptr; + return TD->getTemplatedDecl(); +} + // Given a dependent type and a member name, heuristically resolve the // name to one or more declarations. // The current heuristic is simply to look up the name in the primary @@ -82,25 +100,17 @@ std::vector getMembersReferencedViaDependentName( ET->getDecl()->lookup(NameFactory(ET->getDecl()->getASTContext())); return {Result.begin(), Result.end()}; } - if (auto *ICNT = T->getAs()) { - T = ICNT->getInjectedSpecializationType().getTypePtrOrNull(); + if (auto *RD = resolveTypeToRecordDecl(T)) { + if (!RD->hasDefinition()) + return {}; + RD = RD->getDefinition(); + DeclarationName Name = NameFactory(RD->getASTContext()); + return RD->lookupDependentName(Name, [=](const NamedDecl *D) { + return IsNonstaticMember ? D->isCXXInstanceMember() + : !D->isCXXInstanceMember(); + }); } - auto *TST = T->getAs(); - if (!TST) - return {}; - const ClassTemplateDecl *TD = dyn_cast_or_null( - TST->getTemplateName().getAsTemplateDecl()); - if (!TD) - return {}; - CXXRecordDecl *RD = TD->getTemplatedDecl(); - if (!RD->hasDefinition()) - return {}; - RD = RD->getDefinition(); - DeclarationName Name = NameFactory(RD->getASTContext()); - return RD->lookupDependentName(Name, [=](const NamedDecl *D) { - return IsNonstaticMember ? D->isCXXInstanceMember() - : !D->isCXXInstanceMember(); - }); + return {}; } // Given the type T of a dependent expression that appears of the LHS of a "->", @@ -144,6 +154,28 @@ const Type *getPointeeType(const Type *T) { return FirstArg.getAsType().getTypePtrOrNull(); } +// Try to heuristically resolve a dependent expression `E` to one +// or more declarations that it likely references. +std::vector resolveDependentExprToDecls(const Expr *E) { + assert(E->isTypeDependent()); + if (const auto *ME = dyn_cast(E)) { + const Type *BaseType = ME->getBaseType().getTypePtrOrNull(); + if (ME->isArrow()) { + BaseType = getPointeeType(BaseType); + } + return getMembersReferencedViaDependentName( + BaseType, [ME](ASTContext &) { return ME->getMember(); }, + /*IsNonstaticMember=*/true); + } + if (const auto *RE = dyn_cast(E)) { + return getMembersReferencedViaDependentName( + RE->getQualifier()->getAsType(), + [RE](ASTContext &) { return RE->getDeclName(); }, + /*IsNonstaticMember=*/false); + } + return {}; +} + const NamedDecl *getTemplatePattern(const NamedDecl *D) { if (const CXXRecordDecl *CRD = dyn_cast(D)) { if (const auto *Result = CRD->getTemplateInstantiationPattern()) @@ -341,21 +373,12 @@ struct TargetFinder { } void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) { - const Type *BaseType = E->getBaseType().getTypePtrOrNull(); - if (E->isArrow()) { - BaseType = getPointeeType(BaseType); - } - for (const NamedDecl *D : getMembersReferencedViaDependentName( - BaseType, [E](ASTContext &) { return E->getMember(); }, - /*IsNonstaticMember=*/true)) { + for (const NamedDecl *D : resolveDependentExprToDecls(E)) { Outer.add(D, Flags); } } void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E) { - for (const NamedDecl *D : getMembersReferencedViaDependentName( - E->getQualifier()->getAsType(), - [E](ASTContext &) { return E->getDeclName(); }, - /*IsNonstaticMember=*/false)) { + for (const NamedDecl *D : resolveDependentExprToDecls(E)) { Outer.add(D, Flags); } } diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp index 2861d63d4d008..8305a47240356 100644 --- a/clang-tools-extra/clangd/Hover.cpp +++ b/clang-tools-extra/clangd/Hover.cpp @@ -124,8 +124,8 @@ std::string printType(QualType QT, const PrintingPolicy &Policy) { // TypePrinter doesn't resolve decltypes, so resolve them here. // FIXME: This doesn't handle composite types that contain a decltype in them. // We should rather have a printing policy for that. - while (const auto *DT = QT->getAs()) - QT = DT->getUnderlyingType(); + while (!QT.isNull() && QT->isDecltypeType()) + QT = QT->getAs()->getUnderlyingType(); return QT.getAsString(Policy); } @@ -289,31 +289,27 @@ const Expr *getDefaultArg(const ParmVarDecl *PVD) { : PVD->getDefaultArg(); } +HoverInfo::Param toHoverInfoParam(const ParmVarDecl *PVD, + const PrintingPolicy &Policy) { + HoverInfo::Param Out; + Out.Type = printType(PVD->getType(), Policy); + if (!PVD->getName().empty()) + Out.Name = PVD->getNameAsString(); + if (const Expr *DefArg = getDefaultArg(PVD)) { + Out.Default.emplace(); + llvm::raw_string_ostream OS(*Out.Default); + DefArg->printPretty(OS, nullptr, Policy); + } + return Out; +} + // Populates Type, ReturnType, and Parameters for function-like decls. void fillFunctionTypeAndParams(HoverInfo &HI, const Decl *D, const FunctionDecl *FD, const PrintingPolicy &Policy) { HI.Parameters.emplace(); - for (const ParmVarDecl *PVD : FD->parameters()) { - HI.Parameters->emplace_back(); - auto &P = HI.Parameters->back(); - if (!PVD->getType().isNull()) { - P.Type = printType(PVD->getType(), Policy); - } else { - std::string Param; - llvm::raw_string_ostream OS(Param); - PVD->dump(OS); - OS.flush(); - elog("Got param with null type: {0}", Param); - } - if (!PVD->getName().empty()) - P.Name = PVD->getNameAsString(); - if (const Expr *DefArg = getDefaultArg(PVD)) { - P.Default.emplace(); - llvm::raw_string_ostream Out(*P.Default); - DefArg->printPretty(Out, nullptr, Policy); - } - } + for (const ParmVarDecl *PVD : FD->parameters()) + HI.Parameters->emplace_back(toHoverInfoParam(PVD, Policy)); // We don't want any type info, if name already contains it. This is true for // constructors/destructors and conversion operators. @@ -333,15 +329,28 @@ void fillFunctionTypeAndParams(HoverInfo &HI, const Decl *D, llvm::Optional printExprValue(const Expr *E, const ASTContext &Ctx) { - Expr::EvalResult Constant; + // InitListExpr has two forms, syntactic and semantic. They are the same thing + // (refer to a same AST node) in most cases. + // When they are different, RAV returns the syntactic form, and we should feed + // the semantic form to EvaluateAsRValue. + if (const auto *ILE = llvm::dyn_cast(E)) { + if (!ILE->isSemanticForm()) + E = ILE->getSemanticForm(); + } + // Evaluating [[foo]]() as "&foo" isn't useful, and prevents us walking up // to the enclosing call. QualType T = E->getType(); if (T.isNull() || T->isFunctionType() || T->isFunctionPointerType() || T->isFunctionReferenceType()) return llvm::None; + + Expr::EvalResult Constant; // Attempt to evaluate. If expr is dependent, evaluation crashes! - if (E->isValueDependent() || !E->EvaluateAsRValue(Constant, Ctx)) + if (E->isValueDependent() || !E->EvaluateAsRValue(Constant, Ctx) || + // Disable printing for record-types, as they are usually confusing and + // might make clang crash while printing the expressions. + Constant.Val.isStruct() || Constant.Val.isUnion()) return llvm::None; // Show enums symbolically, not numerically like APValue::printPretty(). @@ -353,7 +362,7 @@ llvm::Optional printExprValue(const Expr *E, if (ECD->getInitVal() == Val) return llvm::formatv("{0} ({1})", ECD->getNameAsString(), Val).str(); } - return Constant.Val.getAsString(Ctx, E->getType()); + return Constant.Val.getAsString(Ctx, T); } llvm::Optional printExprValue(const SelectionTree::Node *N, @@ -660,8 +669,10 @@ bool isHardLineBreakAfter(llvm::StringRef Line, llvm::StringRef Rest) { } void addLayoutInfo(const NamedDecl &ND, HoverInfo &HI) { - const auto &Ctx = ND.getASTContext(); + if (ND.isInvalidDecl()) + return; + const auto &Ctx = ND.getASTContext(); if (auto *RD = llvm::dyn_cast(&ND)) { if (auto Size = Ctx.getTypeSizeInCharsIfKnown(RD->getTypeForDecl())) HI.Size = Size->getQuantity(); @@ -672,17 +683,101 @@ void addLayoutInfo(const NamedDecl &ND, HoverInfo &HI) { const auto *Record = FD->getParent(); if (Record) Record = Record->getDefinition(); - if (Record && !Record->isDependentType()) { - uint64_t OffsetBits = Ctx.getFieldOffset(FD); - if (auto Size = Ctx.getTypeSizeInCharsIfKnown(FD->getType())) { + if (Record && !Record->isInvalidDecl() && !Record->isDependentType()) { + HI.Offset = Ctx.getFieldOffset(FD) / 8; + if (auto Size = Ctx.getTypeSizeInCharsIfKnown(FD->getType())) HI.Size = Size->getQuantity(); - HI.Offset = OffsetBits / 8; - } } return; } } +// If N is passed as argument to a function, fill HI.CalleeArgInfo with +// information about that argument. +void maybeAddCalleeArgInfo(const SelectionTree::Node *N, HoverInfo &HI, + const PrintingPolicy &Policy) { + const auto &OuterNode = N->outerImplicit(); + if (!OuterNode.Parent) + return; + const auto *CE = OuterNode.Parent->ASTNode.get(); + if (!CE) + return; + const FunctionDecl *FD = CE->getDirectCallee(); + // For non-function-call-like operatators (e.g. operator+, operator<<) it's + // not immediattely obvious what the "passed as" would refer to and, given + // fixed function signature, the value would be very low anyway, so we choose + // to not support that. + // Both variadic functions and operator() (especially relevant for lambdas) + // should be supported in the future. + if (!FD || FD->isOverloadedOperator() || FD->isVariadic()) + return; + + // Find argument index for N. + for (unsigned I = 0; I < CE->getNumArgs() && I < FD->getNumParams(); ++I) { + if (CE->getArg(I) != OuterNode.ASTNode.get()) + continue; + + // Extract matching argument from function declaration. + if (const ParmVarDecl *PVD = FD->getParamDecl(I)) + HI.CalleeArgInfo.emplace(toHoverInfoParam(PVD, Policy)); + break; + } + if (!HI.CalleeArgInfo) + return; + + // If we found a matching argument, also figure out if it's a + // [const-]reference. For this we need to walk up the AST from the arg itself + // to CallExpr and check all implicit casts, constructor calls, etc. + HoverInfo::PassType PassType; + if (const auto *E = N->ASTNode.get()) { + if (E->getType().isConstQualified()) + PassType.PassBy = HoverInfo::PassType::ConstRef; + } + + for (auto *CastNode = N->Parent; + CastNode != OuterNode.Parent && !PassType.Converted; + CastNode = CastNode->Parent) { + if (const auto *ImplicitCast = CastNode->ASTNode.get()) { + switch (ImplicitCast->getCastKind()) { + case CK_NoOp: + case CK_DerivedToBase: + case CK_UncheckedDerivedToBase: + // If it was a reference before, it's still a reference. + if (PassType.PassBy != HoverInfo::PassType::Value) + PassType.PassBy = ImplicitCast->getType().isConstQualified() + ? HoverInfo::PassType::ConstRef + : HoverInfo::PassType::Ref; + break; + case CK_LValueToRValue: + case CK_ArrayToPointerDecay: + case CK_FunctionToPointerDecay: + case CK_NullToPointer: + case CK_NullToMemberPointer: + // No longer a reference, but we do not show this as type conversion. + PassType.PassBy = HoverInfo::PassType::Value; + break; + default: + PassType.PassBy = HoverInfo::PassType::Value; + PassType.Converted = true; + break; + } + } else if (const auto *CtorCall = + CastNode->ASTNode.get()) { + // We want to be smart about copy constructors. They should not show up as + // type conversion, but instead as passing by value. + if (CtorCall->getConstructor()->isCopyConstructor()) + PassType.PassBy = HoverInfo::PassType::Value; + else + PassType.Converted = true; + } else { // Unknown implicit node, assume type conversion. + PassType.PassBy = HoverInfo::PassType::Value; + PassType.Converted = true; + } + } + + HI.CallPassType.emplace(PassType); +} + } // namespace llvm::Optional getHover(ParsedAST &AST, Position Pos, @@ -745,6 +840,7 @@ llvm::Optional getHover(ParsedAST &AST, Position Pos, // Look for a close enclosing expression to show the value of. if (!HI->Value) HI->Value = printExprValue(N, AST.getASTContext()); + maybeAddCalleeArgInfo(N, *HI, AST.getASTContext().getPrintingPolicy()); } else if (const Expr *E = N->ASTNode.get()) { HI = getHoverContents(E, AST); } @@ -825,6 +921,24 @@ markup::Document HoverInfo::present() const { Output.addParagraph().appendText( llvm::formatv("Size: {0} byte{1}", *Size, *Size == 1 ? "" : "s").str()); + if (CalleeArgInfo) { + assert(CallPassType); + std::string Buffer; + llvm::raw_string_ostream OS(Buffer); + OS << "Passed "; + if (CallPassType->PassBy != HoverInfo::PassType::Value) { + OS << "by "; + if (CallPassType->PassBy == HoverInfo::PassType::ConstRef) + OS << "const "; + OS << "reference "; + } + if (CalleeArgInfo->Name) + OS << "as " << CalleeArgInfo->Name; + if (CallPassType->Converted && CalleeArgInfo->Type) + OS << " (converted to " << CalleeArgInfo->Type << ")"; + Output.addParagraph().appendText(OS.str()); + } + if (!Documentation.empty()) parseDocumentation(Documentation, Output); @@ -849,6 +963,7 @@ markup::Document HoverInfo::present() const { // non-c++ projects or projects that are not making use of namespaces. Output.addCodeBlock(ScopeComment + DefinitionWithAccess); } + return Output; } diff --git a/clang-tools-extra/clangd/Hover.h b/clang-tools-extra/clangd/Hover.h index b712d844e33d0..2f2afbf6723bf 100644 --- a/clang-tools-extra/clangd/Hover.h +++ b/clang-tools-extra/clangd/Hover.h @@ -77,11 +77,31 @@ struct HoverInfo { llvm::Optional Size; /// Contains the offset of fields within the enclosing class. llvm::Optional Offset; + // Set when symbol is inside function call. Contains information extracted + // from the callee definition about the argument this is passed as. + llvm::Optional CalleeArgInfo; + struct PassType { + // How the variable is passed to callee. + enum PassMode { Ref, ConstRef, Value }; + PassMode PassBy = Ref; + // True if type conversion happened. This includes calls to implicit + // constructor, as well as built-in type conversions. Casting to base class + // is not considered conversion. + bool Converted = false; + }; + // Set only if CalleeArgInfo is set. + llvm::Optional CallPassType; /// Produce a user-readable information. markup::Document present() const; }; +inline bool operator==(const HoverInfo::PassType &LHS, + const HoverInfo::PassType &RHS) { + return std::tie(LHS.PassBy, LHS.Converted) == + std::tie(RHS.PassBy, RHS.Converted); +} + // Try to infer structure of a documentation comment (e.g. line breaks). // FIXME: move to another file so CodeComplete doesn't depend on Hover. void parseDocumentation(llvm::StringRef Input, markup::Document &Output); diff --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp index 048d076a977c4..7a7853a6245c8 100644 --- a/clang-tools-extra/clangd/ParsedAST.cpp +++ b/clang-tools-extra/clangd/ParsedAST.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "ParsedAST.h" +#include "../clang-tidy/ClangTidyCheck.h" #include "../clang-tidy/ClangTidyDiagnosticConsumer.h" #include "../clang-tidy/ClangTidyModuleRegistry.h" #include "AST.h" diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp index ca0a76db78f4b..b71afa0b16191 100644 --- a/clang-tools-extra/clangd/Preamble.cpp +++ b/clang-tools-extra/clangd/Preamble.cpp @@ -229,9 +229,8 @@ struct ScannedPreamble { llvm::Expected scanPreamble(llvm::StringRef Contents, const tooling::CompileCommand &Cmd) { class EmptyFS : public ThreadsafeFS { - public: - llvm::IntrusiveRefCntPtr - view(llvm::NoneType) const override { + private: + llvm::IntrusiveRefCntPtr viewImpl() const override { return new llvm::vfs::InMemoryFileSystem; } }; diff --git a/clang-tools-extra/clangd/Protocol.cpp b/clang-tools-extra/clangd/Protocol.cpp index ecae65336e5b1..2396037157853 100644 --- a/clang-tools-extra/clangd/Protocol.cpp +++ b/clang-tools-extra/clangd/Protocol.cpp @@ -1029,7 +1029,7 @@ llvm::json::Value toJSON(const SemanticTokensEdit &Edit) { {"data", encodeTokens(Edit.tokens)}}; } -llvm::json::Value toJSON(const SemanticTokensOrEdits &TE) { +llvm::json::Value toJSON(const SemanticTokensOrDelta &TE) { llvm::json::Object Result{{"resultId", TE.resultId}}; if (TE.edits) Result["edits"] = *TE.edits; @@ -1043,7 +1043,7 @@ bool fromJSON(const llvm::json::Value &Params, SemanticTokensParams &R) { return O && O.map("textDocument", R.textDocument); } -bool fromJSON(const llvm::json::Value &Params, SemanticTokensEditsParams &R) { +bool fromJSON(const llvm::json::Value &Params, SemanticTokensDeltaParams &R) { llvm::json::ObjectMapper O(Params); return O && O.map("textDocument", R.textDocument) && O.map("previousResultId", R.previousResultId); diff --git a/clang-tools-extra/clangd/Protocol.h b/clang-tools-extra/clangd/Protocol.h index 0177ee262ae34..77d402a6a9ba1 100644 --- a/clang-tools-extra/clangd/Protocol.h +++ b/clang-tools-extra/clangd/Protocol.h @@ -1384,27 +1384,27 @@ struct SemanticTokens { // send a delta. std::string resultId; - /// The actual tokens. For a detailed description about how the data is - /// structured pls see - /// https://github.com/microsoft/vscode-extension-samples/blob/5ae1f7787122812dcc84e37427ca90af5ee09f14/semantic-tokens-sample/vscode.proposed.d.ts#L71 - std::vector tokens; + /// The actual tokens. + std::vector tokens; // encoded as a flat integer array. }; llvm::json::Value toJSON(const SemanticTokens &); +/// Body of textDocument/semanticTokens/full request. struct SemanticTokensParams { /// The text document. TextDocumentIdentifier textDocument; }; bool fromJSON(const llvm::json::Value &, SemanticTokensParams &); +/// Body of textDocument/semanticTokens/full/delta request. /// Requests the changes in semantic tokens since a previous response. -struct SemanticTokensEditsParams { +struct SemanticTokensDeltaParams { /// The text document. TextDocumentIdentifier textDocument; /// The previous result id. std::string previousResultId; }; -bool fromJSON(const llvm::json::Value &Params, SemanticTokensEditsParams &R); +bool fromJSON(const llvm::json::Value &Params, SemanticTokensDeltaParams &R); /// Describes a a replacement of a contiguous range of semanticTokens. struct SemanticTokensEdit { @@ -1413,20 +1413,20 @@ struct SemanticTokensEdit { // We use token counts instead, and translate when serializing this struct. unsigned startToken = 0; unsigned deleteTokens = 0; - std::vector tokens; + std::vector tokens; // encoded as a flat integer array }; llvm::json::Value toJSON(const SemanticTokensEdit &); -/// This models LSP SemanticTokensEdits | SemanticTokens, which is the result of -/// textDocument/semanticTokens/edits. -struct SemanticTokensOrEdits { +/// This models LSP SemanticTokensDelta | SemanticTokens, which is the result of +/// textDocument/semanticTokens/full/delta. +struct SemanticTokensOrDelta { std::string resultId; /// Set if we computed edits relative to a previous set of tokens. llvm::Optional> edits; /// Set if we computed a fresh set of tokens. - llvm::Optional> tokens; + llvm::Optional> tokens; // encoded as integer array }; -llvm::json::Value toJSON(const SemanticTokensOrEdits &); +llvm::json::Value toJSON(const SemanticTokensOrDelta &); /// Represents a semantic highlighting information that has to be applied on a /// specific line of the text document. diff --git a/clang-tools-extra/clangd/RIFF.cpp b/clang-tools-extra/clangd/RIFF.cpp index cdbae4f727394..b87c2d56af0c5 100644 --- a/clang-tools-extra/clangd/RIFF.cpp +++ b/clang-tools-extra/clangd/RIFF.cpp @@ -8,25 +8,29 @@ #include "RIFF.h" #include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" namespace clang { namespace clangd { namespace riff { -static llvm::Error makeError(const char *Msg) { - return llvm::createStringError(llvm::inconvertibleErrorCode(), Msg); +static llvm::Error makeError(const llvm::Twine &Msg) { + return llvm::make_error(Msg, + llvm::inconvertibleErrorCode()); } llvm::Expected readChunk(llvm::StringRef &Stream) { if (Stream.size() < 8) - return makeError("incomplete chunk header"); + return makeError("incomplete chunk header: " + llvm::Twine(Stream.size()) + + " bytes available"); Chunk C; std::copy(Stream.begin(), Stream.begin() + 4, C.ID.begin()); Stream = Stream.drop_front(4); uint32_t Len = llvm::support::endian::read32le(Stream.take_front(4).begin()); Stream = Stream.drop_front(4); if (Stream.size() < Len) - return makeError("truncated chunk"); + return makeError("truncated chunk: want " + llvm::Twine(Len) + ", got " + + llvm::Twine(Stream.size())); C.Data = Stream.take_front(Len); Stream = Stream.drop_front(Len); if (Len % 2 & !Stream.empty()) { // Skip padding byte. @@ -53,7 +57,7 @@ llvm::Expected readFile(llvm::StringRef Stream) { if (!RIFF) return RIFF.takeError(); if (RIFF->ID != fourCC("RIFF")) - return makeError("not a RIFF container"); + return makeError("not a RIFF container: root is " + fourCCStr(RIFF->ID)); if (RIFF->Data.size() < 4) return makeError("RIFF chunk too short"); File F; diff --git a/clang-tools-extra/clangd/RIFF.h b/clang-tools-extra/clangd/RIFF.h index d827a90f2bd7c..96d8ab5463d36 100644 --- a/clang-tools-extra/clangd/RIFF.h +++ b/clang-tools-extra/clangd/RIFF.h @@ -44,6 +44,9 @@ using FourCC = std::array; inline constexpr FourCC fourCC(const char (&Literal)[5]) { return FourCC{{Literal[0], Literal[1], Literal[2], Literal[3]}}; } +inline constexpr llvm::StringRef fourCCStr(const FourCC &Data) { + return llvm::StringRef(&Data[0], Data.size()); +} // A chunk is a section in a RIFF container. struct Chunk { FourCC ID; diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp index d2470da601408..ed75ce80999cd 100644 --- a/clang-tools-extra/clangd/SemanticHighlighting.cpp +++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp @@ -224,7 +224,7 @@ class HighlightingsBuilder { // Create one token for each line in the skipped range, so it works // with line-based diffing. assert(R.start.line <= R.end.line); - for (int Line = R.start.line; Line < R.end.line; ++Line) { + for (int Line = R.start.line; Line <= R.end.line; ++Line) { // Don't bother computing the offset for the end of the line, just use // zero. The client will treat this highlighting kind specially, and // highlight the entire line visually (i.e. not just to where the text diff --git a/clang-tools-extra/clangd/TUScheduler.cpp b/clang-tools-extra/clangd/TUScheduler.cpp index 7f15d44134a05..5454b1c92c8a8 100644 --- a/clang-tools-extra/clangd/TUScheduler.cpp +++ b/clang-tools-extra/clangd/TUScheduler.cpp @@ -270,6 +270,10 @@ class PreambleThread { { WithContext Guard(std::move(CurrentReq->Ctx)); + // Note that we don't make use of the ContextProvider here. + // Preamble tasks are always scheduled by ASTWorker tasks, and we + // reuse the context/config that was created at that level. + // Build the preamble and let the waiters know about it. build(std::move(*CurrentReq)); } @@ -456,6 +460,8 @@ class ASTWorker { const DebouncePolicy UpdateDebounce; /// File that ASTWorker is responsible for. const Path FileName; + /// Callback to create processing contexts for tasks. + const std::function ContextProvider; const GlobalCompilationDatabase &CDB; /// Callback invoked when preamble or main file AST is built. ParsingCallbacks &Callbacks; @@ -569,8 +575,9 @@ ASTWorker::ASTWorker(PathRef FileName, const GlobalCompilationDatabase &CDB, bool RunSync, const TUScheduler::Options &Opts, ParsingCallbacks &Callbacks) : IdleASTs(LRUCache), RunSync(RunSync), UpdateDebounce(Opts.UpdateDebounce), - FileName(FileName), CDB(CDB), Callbacks(Callbacks), Barrier(Barrier), - Done(false), Status(FileName, Callbacks), + FileName(FileName), ContextProvider(Opts.ContextProvider), CDB(CDB), + Callbacks(Callbacks), Barrier(Barrier), Done(false), + Status(FileName, Callbacks), PreamblePeer(FileName, Callbacks, Opts.StorePreamblesInMemory, RunSync || !Opts.AsyncPreambleBuilds, Status, *this) { // Set a fallback command because compile command can be accessed before @@ -1055,6 +1062,9 @@ void ASTWorker::run() { Status.ASTActivity.K = ASTAction::RunningAction; Status.ASTActivity.Name = CurrentRequest->Name; }); + llvm::Optional WithProvidedContext; + if (ContextProvider) + WithProvidedContext.emplace(ContextProvider(FileName)); CurrentRequest->Action(); } @@ -1288,14 +1298,18 @@ llvm::StringMap TUScheduler::getAllFileContents() const { return Results; } -void TUScheduler::run(llvm::StringRef Name, +void TUScheduler::run(llvm::StringRef Name, llvm::StringRef Path, llvm::unique_function Action) { if (!PreambleTasks) return Action(); PreambleTasks->runAsync(Name, [this, Ctx = Context::current().clone(), + Path(Path.str()), Action = std::move(Action)]() mutable { std::lock_guard BarrierLock(Barrier); WithContext WC(std::move(Ctx)); + llvm::Optional WithProvidedContext; + if (Opts.ContextProvider) + WithProvidedContext.emplace(Opts.ContextProvider(Path)); Action(); }); } @@ -1356,6 +1370,9 @@ void TUScheduler::runWithPreamble(llvm::StringRef Name, PathRef File, WithContext Guard(std::move(Ctx)); trace::Span Tracer(Name); SPAN_ATTACH(Tracer, "file", File); + llvm::Optional WithProvidedContext; + if (Opts.ContextProvider) + WithProvidedContext.emplace(Opts.ContextProvider(File)); Action(InputsAndPreamble{Contents, Command, Preamble.get()}); }; diff --git a/clang-tools-extra/clangd/TUScheduler.h b/clang-tools-extra/clangd/TUScheduler.h index fb32c3b2edff4..05c06da13380d 100644 --- a/clang-tools-extra/clangd/TUScheduler.h +++ b/clang-tools-extra/clangd/TUScheduler.h @@ -194,7 +194,12 @@ class TUScheduler { /// Whether to run PreamblePeer asynchronously. /// No-op if AsyncThreadsCount is 0. - bool AsyncPreambleBuilds = false; + bool AsyncPreambleBuilds = true; + + /// Used to create a context that wraps each single operation. + /// Typically to inject per-file configuration. + /// If the path is empty, context sholud be "generic". + std::function ContextProvider; }; TUScheduler(const GlobalCompilationDatabase &CDB, const Options &Opts, @@ -233,7 +238,9 @@ class TUScheduler { llvm::StringMap getAllFileContents() const; /// Schedule an async task with no dependencies. - void run(llvm::StringRef Name, llvm::unique_function Action); + /// Path may be empty (it is used only to set the Context). + void run(llvm::StringRef Name, llvm::StringRef Path, + llvm::unique_function Action); /// Defines how a runWithAST action is implicitly cancelled by other actions. enum ASTActionInvalidation { @@ -301,6 +308,7 @@ class TUScheduler { // this inside clangd. // FIXME: remove this when there is proper index support via build system // integration. + // FIXME: move to ClangdServer via createProcessingContext. static llvm::Optional getFileBeingProcessedInContext(); private: diff --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp index a7bbfd4f967c5..c208e953f2ab7 100644 --- a/clang-tools-extra/clangd/XRefs.cpp +++ b/clang-tools-extra/clangd/XRefs.cpp @@ -993,7 +993,6 @@ std::vector findDocumentHighlights(ParsedAST &AST, DeclRelation::TemplatePattern | DeclRelation::Alias; auto Decls = targetDecl(N->ASTNode, Relations); if (!Decls.empty()) { - auto Refs = findRefs({Decls.begin(), Decls.end()}, AST); // FIXME: we may get multiple DocumentHighlights with the same location // and different kinds, deduplicate them. for (const auto &Ref : findRefs({Decls.begin(), Decls.end()}, AST)) @@ -1050,7 +1049,7 @@ ReferencesResult findReferences(ParsedAST &AST, Position Pos, uint32_t Limit, const auto &IDToRefs = AST.getMacros().MacroRefs; auto Refs = IDToRefs.find(*MacroSID); if (Refs != IDToRefs.end()) { - for (const auto Ref : Refs->second) { + for (const auto &Ref : Refs->second) { Location Result; Result.range = Ref; Result.uri = URIMainFile; diff --git a/clang-tools-extra/clangd/index/Background.cpp b/clang-tools-extra/clangd/index/Background.cpp index 3e68d9e9c62a3..5024ace66b7cc 100644 --- a/clang-tools-extra/clangd/index/Background.cpp +++ b/clang-tools-extra/clangd/index/Background.cpp @@ -93,9 +93,11 @@ BackgroundIndex::BackgroundIndex( Context BackgroundContext, const ThreadsafeFS &TFS, const GlobalCompilationDatabase &CDB, BackgroundIndexStorage::Factory IndexStorageFactory, size_t ThreadPoolSize, - std::function OnProgress) + std::function OnProgress, + std::function ContextProvider) : SwapIndex(std::make_unique()), TFS(TFS), CDB(CDB), BackgroundContext(std::move(BackgroundContext)), + ContextProvider(std::move(ContextProvider)), Rebuilder(this, &IndexedSymbols, ThreadPoolSize), IndexStorageFactory(std::move(IndexStorageFactory)), Queue(std::move(OnProgress)), @@ -103,10 +105,9 @@ BackgroundIndex::BackgroundIndex( CDB.watch([&](const std::vector &ChangedFiles) { enqueue(ChangedFiles); })) { - assert(Rebuilder.TUsBeforeFirstBuild > 0 && - "Thread pool size can't be zero."); + assert(ThreadPoolSize > 0 && "Thread pool size can't be zero."); assert(this->IndexStorageFactory && "Storage factory can not be null!"); - for (unsigned I = 0; I < Rebuilder.TUsBeforeFirstBuild; ++I) { + for (unsigned I = 0; I < ThreadPoolSize; ++I) { ThreadPool.runAsync("background-worker-" + llvm::Twine(I + 1), [this] { WithContext Ctx(this->BackgroundContext.clone()); Queue.work([&] { Rebuilder.idle(); }); @@ -123,6 +124,11 @@ BackgroundQueue::Task BackgroundIndex::changedFilesTask( const std::vector &ChangedFiles) { BackgroundQueue::Task T([this, ChangedFiles] { trace::Span Tracer("BackgroundIndexEnqueue"); + + llvm::Optional WithProvidedContext; + if (ContextProvider) + WithProvidedContext.emplace(ContextProvider(/*Path=*/"")); + // We're doing this asynchronously, because we'll read shards here too. log("Enqueueing {0} commands for indexing", ChangedFiles.size()); SPAN_ATTACH(Tracer, "files", int64_t(ChangedFiles.size())); @@ -148,17 +154,20 @@ static llvm::StringRef filenameWithoutExtension(llvm::StringRef Path) { return Path.drop_back(llvm::sys::path::extension(Path).size()); } -BackgroundQueue::Task -BackgroundIndex::indexFileTask(tooling::CompileCommand Cmd) { - BackgroundQueue::Task T([this, Cmd] { - // We can't use llvm::StringRef here since we are going to - // move from Cmd during the call below. - const std::string FileName = Cmd.Filename; - if (auto Error = index(std::move(Cmd))) - elog("Indexing {0} failed: {1}", FileName, std::move(Error)); +BackgroundQueue::Task BackgroundIndex::indexFileTask(std::string Path) { + std::string Tag = filenameWithoutExtension(Path).str(); + BackgroundQueue::Task T([this, Path(std::move(Path))] { + llvm::Optional WithProvidedContext; + if (ContextProvider) + WithProvidedContext.emplace(ContextProvider(Path)); + auto Cmd = CDB.getCompileCommand(Path); + if (!Cmd) + return; + if (auto Error = index(std::move(*Cmd))) + elog("Indexing {0} failed: {1}", Path, std::move(Error)); }); T.QueuePri = IndexFile; - T.Tag = std::string(filenameWithoutExtension(Cmd.Filename)); + T.Tag = std::move(Tag); return T; } @@ -343,10 +352,8 @@ llvm::Error BackgroundIndex::index(tooling::CompileCommand Cmd) { // Restores shards for \p MainFiles from index storage. Then checks staleness of // those shards and returns a list of TUs that needs to be indexed to update // staleness. -std::vector +std::vector BackgroundIndex::loadProject(std::vector MainFiles) { - std::vector NeedsReIndexing; - Rebuilder.startLoading(); // Load shards for all of the mainfiles. const std::vector Result = @@ -399,14 +406,7 @@ BackgroundIndex::loadProject(std::vector MainFiles) { TUsToIndex.insert(TUForFile); } - for (PathRef TU : TUsToIndex) { - auto Cmd = CDB.getCompileCommand(TU); - if (!Cmd) - continue; - NeedsReIndexing.emplace_back(std::move(*Cmd)); - } - - return NeedsReIndexing; + return {TUsToIndex.begin(), TUsToIndex.end()}; } } // namespace clangd diff --git a/clang-tools-extra/clangd/index/Background.h b/clang-tools-extra/clangd/index/Background.h index 9ae63828cc6bd..9adad17376863 100644 --- a/clang-tools-extra/clangd/index/Background.h +++ b/clang-tools-extra/clangd/index/Background.h @@ -56,9 +56,9 @@ class BackgroundIndexStorage { using Factory = llvm::unique_function; // Creates an Index Storage that saves shards into disk. Index storage uses - // CDBDirectory + ".clangd/index/" as the folder to save shards. CDBDirectory - // is the first directory containing a CDB in parent directories of a file, or - // user's home directory if none was found, e.g. standard library headers. + // CDBDirectory + ".cache/clangd/index/" as the folder to save shards. + // CDBDirectory is the first directory containing a CDB in parent directories + // of a file, or user cache directory if none was found, e.g. stdlib headers. static Factory createDiskBackedStorageFactory( std::function(PathRef)> GetProjectInfo); }; @@ -135,8 +135,11 @@ class BackgroundIndex : public SwapIndex { Context BackgroundContext, const ThreadsafeFS &, const GlobalCompilationDatabase &CDB, BackgroundIndexStorage::Factory IndexStorageFactory, - size_t ThreadPoolSize = 0, // 0 = use all hardware threads - std::function OnProgress = nullptr); + // Arbitrary value to ensure some concurrency in tests. + // In production an explicit value is passed. + size_t ThreadPoolSize = 4, + std::function OnProgress = nullptr, + std::function ContextProvider = nullptr); ~BackgroundIndex(); // Blocks while the current task finishes. // Enqueue translation units for indexing. @@ -181,6 +184,7 @@ class BackgroundIndex : public SwapIndex { const ThreadsafeFS &TFS; const GlobalCompilationDatabase &CDB; Context BackgroundContext; + std::function ContextProvider; llvm::Error index(tooling::CompileCommand); @@ -191,12 +195,11 @@ class BackgroundIndex : public SwapIndex { BackgroundIndexStorage::Factory IndexStorageFactory; // Tries to load shards for the MainFiles and their dependencies. - std::vector - loadProject(std::vector MainFiles); + std::vector loadProject(std::vector MainFiles); BackgroundQueue::Task changedFilesTask(const std::vector &ChangedFiles); - BackgroundQueue::Task indexFileTask(tooling::CompileCommand Cmd); + BackgroundQueue::Task indexFileTask(std::string Path); // from lowest to highest priority enum QueuePriority { diff --git a/clang-tools-extra/clangd/index/BackgroundIndexStorage.cpp b/clang-tools-extra/clangd/index/BackgroundIndexStorage.cpp index eee050b0db9ad..ed1662ff59881 100644 --- a/clang-tools-extra/clangd/index/BackgroundIndexStorage.cpp +++ b/clang-tools-extra/clangd/index/BackgroundIndexStorage.cpp @@ -95,8 +95,8 @@ class NullStorage : public BackgroundIndexStorage { }; // Creates and owns IndexStorages for multiple CDBs. -// When a CDB root is found, shards are stored in $ROOT/.clangd/index. -// When no root is found, the fallback path is ~/.cache/clangd/index. +// When a CDB root is found, shards are stored in $ROOT/.cache/clangd/index/. +// When no root is found, the fallback path is ~/.cache/clangd/index/. class DiskBackedIndexStorageManager { public: DiskBackedIndexStorageManager( @@ -115,7 +115,7 @@ class DiskBackedIndexStorageManager { llvm::SmallString<128> StorageDir(FallbackDir); if (auto PI = GetProjectInfo(File)) { StorageDir = PI->SourceRoot; - llvm::sys::path::append(StorageDir, ".clangd", "index"); + llvm::sys::path::append(StorageDir, ".cache", "clangd", "index"); } auto &IndexStorage = IndexStorageMap[StorageDir]; if (!IndexStorage) diff --git a/clang-tools-extra/clangd/index/BackgroundRebuild.h b/clang-tools-extra/clangd/index/BackgroundRebuild.h index 295f705c98e8f..bc68536c847f8 100644 --- a/clang-tools-extra/clangd/index/BackgroundRebuild.h +++ b/clang-tools-extra/clangd/index/BackgroundRebuild.h @@ -49,9 +49,7 @@ class BackgroundIndexRebuilder { public: BackgroundIndexRebuilder(SwapIndex *Target, FileSymbols *Source, unsigned Threads) - : TUsBeforeFirstBuild(llvm::heavyweight_hardware_concurrency(Threads) - .compute_thread_count()), - Target(Target), Source(Source) {} + : TUsBeforeFirstBuild(Threads), Target(Target), Source(Source) {} // Called to indicate a TU has been indexed. // May rebuild, if enough TUs have been indexed. @@ -72,7 +70,7 @@ class BackgroundIndexRebuilder { // Ensures we won't start any more rebuilds. void shutdown(); - // Thresholds for rebuilding as TUs get indexed. + // Thresholds for rebuilding as TUs get indexed. Exposed for testing. const unsigned TUsBeforeFirstBuild; // Typically one per worker thread. const unsigned TUsBeforeRebuild = 100; diff --git a/clang-tools-extra/clangd/index/FileIndex.cpp b/clang-tools-extra/clangd/index/FileIndex.cpp index 1a18af1303dd8..5f84545d7c73d 100644 --- a/clang-tools-extra/clangd/index/FileIndex.cpp +++ b/clang-tools-extra/clangd/index/FileIndex.cpp @@ -229,6 +229,7 @@ void FileSymbols::update(llvm::StringRef Key, std::unique_ptr Relations, bool CountReferences) { std::lock_guard Lock(Mutex); + ++Version; if (!Symbols) SymbolsSnapshot.erase(Key); else @@ -248,7 +249,8 @@ void FileSymbols::update(llvm::StringRef Key, } std::unique_ptr -FileSymbols::buildIndex(IndexType Type, DuplicateHandling DuplicateHandle) { +FileSymbols::buildIndex(IndexType Type, DuplicateHandling DuplicateHandle, + size_t *Version) { std::vector> SymbolSlabs; std::vector> RefSlabs; std::vector> RelationSlabs; @@ -264,6 +266,9 @@ FileSymbols::buildIndex(IndexType Type, DuplicateHandling DuplicateHandle) { } for (const auto &FileAndRelations : RelatiosSnapshot) RelationSlabs.push_back(FileAndRelations.second); + + if (Version) + *Version = this->Version; } std::vector AllSymbols; std::vector SymsStorage; @@ -390,12 +395,23 @@ void FileIndex::updatePreamble(PathRef Path, llvm::StringRef Version, std::make_unique(std::move(*IF->Relations)), /*CountReferences=*/false); } - PreambleIndex.reset( + size_t IndexVersion = 0; + auto NewIndex = PreambleSymbols.buildIndex(UseDex ? IndexType::Heavy : IndexType::Light, - DuplicateHandling::PickOne)); - vlog("Build dynamic index for header symbols with estimated memory usage of " - "{0} bytes", - PreambleIndex.estimateMemoryUsage()); + DuplicateHandling::PickOne, &IndexVersion); + { + std::lock_guard Lock(UpdateIndexMu); + if (IndexVersion <= PreambleIndexVersion) { + // We lost the race, some other thread built a later version. + return; + } + PreambleIndexVersion = IndexVersion; + PreambleIndex.reset(std::move(NewIndex)); + vlog( + "Build dynamic index for header symbols with estimated memory usage of " + "{0} bytes", + PreambleIndex.estimateMemoryUsage()); + } } void FileIndex::updateMain(PathRef Path, ParsedAST &AST) { @@ -405,11 +421,22 @@ void FileIndex::updateMain(PathRef Path, ParsedAST &AST) { std::make_unique(std::move(std::get<1>(Contents))), std::make_unique(std::move(std::get<2>(Contents))), /*CountReferences=*/true); - MainFileIndex.reset( - MainFileSymbols.buildIndex(IndexType::Light, DuplicateHandling::Merge)); - vlog("Build dynamic index for main-file symbols with estimated memory usage " - "of {0} bytes", - MainFileIndex.estimateMemoryUsage()); + size_t IndexVersion = 0; + auto NewIndex = MainFileSymbols.buildIndex( + IndexType::Light, DuplicateHandling::Merge, &IndexVersion); + { + std::lock_guard Lock(UpdateIndexMu); + if (IndexVersion <= MainIndexVersion) { + // We lost the race, some other thread built a later version. + return; + } + MainIndexVersion = IndexVersion; + MainFileIndex.reset(std::move(NewIndex)); + vlog( + "Build dynamic index for main-file symbols with estimated memory usage " + "of {0} bytes", + MainFileIndex.estimateMemoryUsage()); + } } } // namespace clangd diff --git a/clang-tools-extra/clangd/index/FileIndex.h b/clang-tools-extra/clangd/index/FileIndex.h index 65a2c305dca55..e6f8d1ef9e3d7 100644 --- a/clang-tools-extra/clangd/index/FileIndex.h +++ b/clang-tools-extra/clangd/index/FileIndex.h @@ -81,9 +81,11 @@ class FileSymbols { /// The index keeps the slabs alive. /// Will count Symbol::References based on number of references in the main /// files, while building the index with DuplicateHandling::Merge option. + /// Version is populated with an increasing sequence counter. std::unique_ptr buildIndex(IndexType, - DuplicateHandling DuplicateHandle = DuplicateHandling::PickOne); + DuplicateHandling DuplicateHandle = DuplicateHandling::PickOne, + size_t *Version = nullptr); private: struct RefSlabAndCountReferences { @@ -92,6 +94,7 @@ class FileSymbols { }; mutable std::mutex Mutex; + size_t Version = 0; llvm::StringMap> SymbolsSnapshot; llvm::StringMap RefsSnapshot; llvm::StringMap> RelatiosSnapshot; @@ -136,6 +139,12 @@ class FileIndex : public MergedIndex { // (Note that symbols *only* in the main file are not indexed). FileSymbols MainFileSymbols; SwapIndex MainFileIndex; + + // While both the FileIndex and SwapIndex are threadsafe, we need to track + // versions to ensure that we don't overwrite newer indexes with older ones. + std::mutex UpdateIndexMu; + unsigned MainIndexVersion = 0; + unsigned PreambleIndexVersion = 0; }; using SlabTuple = std::tuple; diff --git a/clang-tools-extra/clangd/index/Serialization.cpp b/clang-tools-extra/clangd/index/Serialization.cpp index 06527a615c202..11d70b550642b 100644 --- a/clang-tools-extra/clangd/index/Serialization.cpp +++ b/clang-tools-extra/clangd/index/Serialization.cpp @@ -426,20 +426,25 @@ llvm::Expected readRIFF(llvm::StringRef Data) { if (!RIFF) return RIFF.takeError(); if (RIFF->Type != riff::fourCC("CdIx")) - return makeError("wrong RIFF type"); + return makeError("wrong RIFF filetype: " + riff::fourCCStr(RIFF->Type)); llvm::StringMap Chunks; for (const auto &Chunk : RIFF->Chunks) Chunks.try_emplace(llvm::StringRef(Chunk.ID.data(), Chunk.ID.size()), Chunk.Data); - for (llvm::StringRef RequiredChunk : {"meta", "stri"}) + if (!Chunks.count("meta")) + return makeError("missing meta chunk"); + Reader Meta(Chunks.lookup("meta")); + auto SeenVersion = Meta.consume32(); + if (SeenVersion != Version) + return makeError("wrong version: want " + llvm::Twine(Version) + ", got " + + llvm::Twine(SeenVersion)); + + // meta chunk is checked above, as we prefer the "version mismatch" error. + for (llvm::StringRef RequiredChunk : {"stri"}) if (!Chunks.count(RequiredChunk)) return makeError("missing required chunk " + RequiredChunk); - Reader Meta(Chunks.lookup("meta")); - if (Meta.consume32() != Version) - return makeError("wrong version"); - auto Strings = readStringTable(Chunks.lookup("stri")); if (!Strings) return Strings.takeError(); @@ -665,7 +670,7 @@ std::unique_ptr loadIndex(llvm::StringRef SymbolFilename, trace::Span OverallTracer("LoadIndex"); auto Buffer = llvm::MemoryBuffer::getFile(SymbolFilename); if (!Buffer) { - elog("Can't open {0}", SymbolFilename); + elog("Can't open {0}: {1}", SymbolFilename, Buffer.getError().message()); return nullptr; } @@ -682,7 +687,7 @@ std::unique_ptr loadIndex(llvm::StringRef SymbolFilename, if (I->Relations) Relations = std::move(*I->Relations); } else { - elog("Bad Index: {0}", I.takeError()); + elog("Bad index file: {0}", I.takeError()); return nullptr; } } diff --git a/clang-tools-extra/clangd/index/Symbol.h b/clang-tools-extra/clangd/index/Symbol.h index 00cf496b6d53e..2d2644e31a03d 100644 --- a/clang-tools-extra/clangd/index/Symbol.h +++ b/clang-tools-extra/clangd/index/Symbol.h @@ -186,7 +186,8 @@ class SymbolSlab { const_iterator end() const { return Symbols.end(); } const_iterator find(const SymbolID &SymID) const; - size_t size() const { return Symbols.size(); } + using size_type = size_t; + size_type size() const { return Symbols.size(); } bool empty() const { return Symbols.empty(); } // Estimates the total memory usage. size_t bytes() const { diff --git a/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp b/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp index 3e25da385d7ab..6fc844c189315 100644 --- a/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp +++ b/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp @@ -32,6 +32,9 @@ llvm::cl::opt IndexLocation( llvm::cl::opt ExecCommand("c", llvm::cl::desc("Command to execute and then exit")); +llvm::cl::opt ProjectRoot("project-root", + llvm::cl::desc("Path to the project")); + static constexpr char Overview[] = R"( This is an **experimental** interactive tool to process user-provided search queries over given symbol collection obtained via clangd-indexer. The @@ -326,7 +329,8 @@ struct { std::unique_ptr openIndex(llvm::StringRef Index) { return Index.startswith("remote:") - ? remote::getClient(Index.drop_front(strlen("remote:"))) + ? remote::getClient(Index.drop_front(strlen("remote:")), + ProjectRoot) : loadIndex(Index, /*UseDex=*/true); } diff --git a/clang-tools-extra/clangd/index/remote/Client.cpp b/clang-tools-extra/clangd/index/remote/Client.cpp index 366a37a135a47..b468831930765 100644 --- a/clang-tools-extra/clangd/index/remote/Client.cpp +++ b/clang-tools-extra/clangd/index/remote/Client.cpp @@ -10,10 +10,14 @@ #include "Client.h" #include "Index.grpc.pb.h" +#include "index/Index.h" #include "index/Serialization.h" #include "marshalling/Marshalling.h" #include "support/Logger.h" #include "support/Trace.h" +#include "llvm/ADT/StringRef.h" + +#include namespace clang { namespace clangd { @@ -25,7 +29,16 @@ class IndexClient : public clangd::SymbolIndex { using StreamingCall = std::unique_ptr> ( remote::SymbolIndex::Stub::*)(grpc::ClientContext *, const RequestT &); - // FIXME(kirillbobyrev): Set deadlines for requests. + template + RequestT serializeRequest(ClangdRequestT Request) const { + return toProtobuf(Request); + } + + template <> + FuzzyFindRequest serializeRequest(clangd::FuzzyFindRequest Request) const { + return toProtobuf(Request, ProjectRoot); + } + template bool streamRPC(ClangdRequestT Request, @@ -33,8 +46,11 @@ class IndexClient : public clangd::SymbolIndex { CallbackT Callback) const { bool FinalResult = false; trace::Span Tracer(RequestT::descriptor()->name()); - const auto RPCRequest = toProtobuf(Request); + const auto RPCRequest = serializeRequest(Request); grpc::ClientContext Context; + std::chrono::system_clock::time_point Deadline = + std::chrono::system_clock::now() + DeadlineWaitingTime; + Context.set_deadline(Deadline); auto Reader = (Stub.get()->*RPCCall)(&Context, RPCRequest); llvm::BumpPtrAllocator Arena; llvm::UniqueStringSaver Strings(Arena); @@ -44,18 +60,22 @@ class IndexClient : public clangd::SymbolIndex { FinalResult = Reply.final_result(); continue; } - auto Sym = fromProtobuf(Reply.stream_result(), &Strings); - if (!Sym) + auto Response = + fromProtobuf(Reply.stream_result(), &Strings, ProjectRoot); + if (!Response) elog("Received invalid {0}", ReplyT::descriptor()->name()); - Callback(*Sym); + Callback(*Response); } SPAN_ATTACH(Tracer, "status", Reader->Finish().ok()); return FinalResult; } public: - IndexClient(std::shared_ptr Channel) - : Stub(remote::SymbolIndex::NewStub(Channel)) {} + IndexClient( + std::shared_ptr Channel, llvm::StringRef ProjectRoot, + std::chrono::milliseconds DeadlineTime = std::chrono::milliseconds(1000)) + : Stub(remote::SymbolIndex::NewStub(Channel)), ProjectRoot(ProjectRoot), + DeadlineWaitingTime(DeadlineTime) {} void lookup(const clangd::LookupRequest &Request, llvm::function_ref Callback) const { @@ -79,20 +99,26 @@ class IndexClient : public clangd::SymbolIndex { llvm::function_ref) const {} - // IndexClient does not take any space since the data is stored on the server. + // IndexClient does not take any space since the data is stored on the + // server. size_t estimateMemoryUsage() const { return 0; } private: std::unique_ptr Stub; + std::string ProjectRoot; + // Each request will be terminated if it takes too long. + std::chrono::milliseconds DeadlineWaitingTime; }; } // namespace -std::unique_ptr getClient(llvm::StringRef Address) { +std::unique_ptr getClient(llvm::StringRef Address, + llvm::StringRef ProjectRoot) { const auto Channel = grpc::CreateChannel(Address.str(), grpc::InsecureChannelCredentials()); Channel->GetState(true); - return std::unique_ptr(new IndexClient(Channel)); + return std::unique_ptr( + new IndexClient(Channel, ProjectRoot)); } } // namespace remote diff --git a/clang-tools-extra/clangd/index/remote/Client.h b/clang-tools-extra/clangd/index/remote/Client.h index 9708fdbe851ae..7b4173af6cfad 100644 --- a/clang-tools-extra/clangd/index/remote/Client.h +++ b/clang-tools-extra/clangd/index/remote/Client.h @@ -10,6 +10,7 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_REMOTE_INDEX_H #include "index/Index.h" +#include "llvm/ADT/StringRef.h" namespace clang { namespace clangd { @@ -17,12 +18,16 @@ namespace remote { /// Returns an SymbolIndex client that passes requests to remote index located /// at \p Address. The client allows synchronous RPC calls. +/// \p IndexRoot is an absolute path on the local machine to the source tree +/// described by the remote index. Paths returned by the index will be treated +/// as relative to this directory. /// /// This method attempts to resolve the address and establish the connection. /// /// \returns nullptr if the address is not resolved during the function call or /// if the project was compiled without Remote Index support. -std::unique_ptr getClient(llvm::StringRef Address); +std::unique_ptr getClient(llvm::StringRef Address, + llvm::StringRef IndexRoot); } // namespace remote } // namespace clangd diff --git a/clang-tools-extra/clangd/index/remote/Index.proto b/clang-tools-extra/clangd/index/remote/Index.proto index f3af29dcd588b..99c4e3329d670 100644 --- a/clang-tools-extra/clangd/index/remote/Index.proto +++ b/clang-tools-extra/clangd/index/remote/Index.proto @@ -71,7 +71,7 @@ message Symbol { string name = 3; SymbolLocation definition = 4; string scope = 5; - SymbolLocation canonical_declarattion = 6; + SymbolLocation canonical_declaration = 6; int32 references = 7; uint32 origin = 8; string signature = 9; @@ -99,7 +99,10 @@ message SymbolInfo { message SymbolLocation { Position start = 1; Position end = 2; - string file_uri = 3; + // clangd::SymbolLocation stores FileURI, but the protocol transmits a the + // relative path. Because paths are different on the remote and local machines + // they will be translated in the marshalling layer. + string file_path = 3; } message Position { diff --git a/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp b/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp index e95132d000ece..db895bf039bab 100644 --- a/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp +++ b/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "Marshalling.h" +#include "Headers.h" #include "Index.pb.h" #include "Protocol.h" #include "index/Serialization.h" @@ -16,7 +17,13 @@ #include "index/SymbolOrigin.h" #include "support/Logger.h" #include "clang/Index/IndexSymbol.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/Path.h" #include "llvm/Support/StringSaver.h" namespace clang { @@ -58,40 +65,66 @@ SymbolInfo toProtobuf(const clang::index::SymbolInfo &Info) { return Result; } -clangd::SymbolLocation fromProtobuf(const SymbolLocation &Message, - llvm::UniqueStringSaver *Strings) { +llvm::Optional +fromProtobuf(const SymbolLocation &Message, llvm::UniqueStringSaver *Strings, + llvm::StringRef IndexRoot) { clangd::SymbolLocation Location; + auto URIString = relativePathToURI(Message.file_path(), IndexRoot); + if (!URIString) + return llvm::None; + Location.FileURI = Strings->save(*URIString).begin(); Location.Start = fromProtobuf(Message.start()); Location.End = fromProtobuf(Message.end()); - Location.FileURI = Strings->save(Message.file_uri()).begin(); return Location; } -SymbolLocation toProtobuf(const clangd::SymbolLocation &Location) { +llvm::Optional +toProtobuf(const clangd::SymbolLocation &Location, llvm::StringRef IndexRoot) { remote::SymbolLocation Result; + auto RelativePath = uriToRelativePath(Location.FileURI, IndexRoot); + if (!RelativePath) + return llvm::None; + *Result.mutable_file_path() = *RelativePath; *Result.mutable_start() = toProtobuf(Location.Start); *Result.mutable_end() = toProtobuf(Location.End); - *Result.mutable_file_uri() = Location.FileURI; return Result; } -HeaderWithReferences -toProtobuf(const clangd::Symbol::IncludeHeaderWithReferences &IncludeHeader) { +llvm::Optional +toProtobuf(const clangd::Symbol::IncludeHeaderWithReferences &IncludeHeader, + llvm::StringRef IndexRoot) { HeaderWithReferences Result; - Result.set_header(IncludeHeader.IncludeHeader.str()); Result.set_references(IncludeHeader.References); + const std::string Header = IncludeHeader.IncludeHeader.str(); + if (isLiteralInclude(Header)) { + Result.set_header(Header); + return Result; + } + auto RelativePath = uriToRelativePath(Header, IndexRoot); + if (!RelativePath) + return llvm::None; + Result.set_header(*RelativePath); return Result; } -clangd::Symbol::IncludeHeaderWithReferences -fromProtobuf(const HeaderWithReferences &Message) { - return clangd::Symbol::IncludeHeaderWithReferences{Message.header(), +llvm::Optional +fromProtobuf(const HeaderWithReferences &Message, + llvm::UniqueStringSaver *Strings, llvm::StringRef IndexRoot) { + std::string Header = Message.header(); + if (Header.front() != '<' && Header.front() != '"') { + auto URIString = relativePathToURI(Header, IndexRoot); + if (!URIString) + return llvm::None; + Header = *URIString; + } + return clangd::Symbol::IncludeHeaderWithReferences{Strings->save(Header), Message.references()}; } } // namespace -clangd::FuzzyFindRequest fromProtobuf(const FuzzyFindRequest *Request) { +clangd::FuzzyFindRequest fromProtobuf(const FuzzyFindRequest *Request, + llvm::StringRef IndexRoot) { clangd::FuzzyFindRequest Result; Result.Query = Request->query(); for (const auto &Scope : Request->scopes()) @@ -100,24 +133,29 @@ clangd::FuzzyFindRequest fromProtobuf(const FuzzyFindRequest *Request) { if (Request->limit()) Result.Limit = Request->limit(); Result.RestrictForCodeCompletion = Request->restricted_for_code_completion(); - for (const auto &Path : Request->proximity_paths()) - Result.ProximityPaths.push_back(Path); + for (const auto &Path : Request->proximity_paths()) { + llvm::SmallString<256> LocalPath = llvm::StringRef(IndexRoot); + llvm::sys::path::append(LocalPath, Path); + Result.ProximityPaths.push_back(std::string(LocalPath)); + } for (const auto &Type : Request->preferred_types()) Result.ProximityPaths.push_back(Type); return Result; } llvm::Optional fromProtobuf(const Symbol &Message, - llvm::UniqueStringSaver *Strings) { + llvm::UniqueStringSaver *Strings, + llvm::StringRef IndexRoot) { if (!Message.has_info() || !Message.has_definition() || - !Message.has_canonical_declarattion()) { - elog("Cannot convert Symbol from Protobuf: {}", Message.ShortDebugString()); + !Message.has_canonical_declaration()) { + elog("Cannot convert Symbol from Protobuf: {0}", + Message.ShortDebugString()); return llvm::None; } clangd::Symbol Result; auto ID = SymbolID::fromStr(Message.id()); if (!ID) { - elog("Cannot convert parse SymbolID {} from Protobuf: {}", ID.takeError(), + elog("Cannot parse SymbolID {0} given Protobuf: {1}", ID.takeError(), Message.ShortDebugString()); return llvm::None; } @@ -125,9 +163,15 @@ llvm::Optional fromProtobuf(const Symbol &Message, Result.SymInfo = fromProtobuf(Message.info()); Result.Name = Message.name(); Result.Scope = Message.scope(); - Result.Definition = fromProtobuf(Message.definition(), Strings); - Result.CanonicalDeclaration = - fromProtobuf(Message.canonical_declarattion(), Strings); + auto Definition = fromProtobuf(Message.definition(), Strings, IndexRoot); + if (!Definition) + return llvm::None; + Result.Definition = *Definition; + auto Declaration = + fromProtobuf(Message.canonical_declaration(), Strings, IndexRoot); + if (!Declaration) + return llvm::None; + Result.CanonicalDeclaration = *Declaration; Result.References = Message.references(); Result.Origin = static_cast(Message.origin()); Result.Signature = Message.signature(); @@ -137,20 +181,26 @@ llvm::Optional fromProtobuf(const Symbol &Message, Result.ReturnType = Message.return_type(); Result.Type = Message.type(); for (const auto &Header : Message.headers()) { - Result.IncludeHeaders.push_back(fromProtobuf(Header)); + auto SerializedHeader = fromProtobuf(Header, Strings, IndexRoot); + if (SerializedHeader) + Result.IncludeHeaders.push_back(*SerializedHeader); } Result.Flags = static_cast(Message.flags()); return Result; } llvm::Optional fromProtobuf(const Ref &Message, - llvm::UniqueStringSaver *Strings) { + llvm::UniqueStringSaver *Strings, + llvm::StringRef IndexRoot) { if (!Message.has_location()) { elog("Cannot convert Ref from Protobuf: {}", Message.ShortDebugString()); return llvm::None; } clangd::Ref Result; - Result.Location = fromProtobuf(Message.location(), Strings); + auto Location = fromProtobuf(Message.location(), Strings, IndexRoot); + if (!Location) + return llvm::None; + Result.Location = *Location; Result.Kind = static_cast(Message.kind()); return Result; } @@ -162,7 +212,8 @@ LookupRequest toProtobuf(const clangd::LookupRequest &From) { return RPCRequest; } -FuzzyFindRequest toProtobuf(const clangd::FuzzyFindRequest &From) { +FuzzyFindRequest toProtobuf(const clangd::FuzzyFindRequest &From, + llvm::StringRef IndexRoot) { FuzzyFindRequest RPCRequest; RPCRequest.set_query(From.Query); for (const auto &Scope : From.Scopes) @@ -171,8 +222,12 @@ FuzzyFindRequest toProtobuf(const clangd::FuzzyFindRequest &From) { if (From.Limit) RPCRequest.set_limit(*From.Limit); RPCRequest.set_restricted_for_code_completion(From.RestrictForCodeCompletion); - for (const auto &Path : From.ProximityPaths) - RPCRequest.add_proximity_paths(Path); + for (const auto &Path : From.ProximityPaths) { + llvm::SmallString<256> RelativePath = llvm::StringRef(Path); + if (llvm::sys::path::replace_path_prefix(RelativePath, IndexRoot, "")) + RPCRequest.add_proximity_paths(llvm::sys::path::convert_to_slash( + RelativePath, llvm::sys::path::Style::posix)); + } for (const auto &Type : From.PreferredTypes) RPCRequest.add_preferred_types(Type); return RPCRequest; @@ -188,15 +243,18 @@ RefsRequest toProtobuf(const clangd::RefsRequest &From) { return RPCRequest; } -Symbol toProtobuf(const clangd::Symbol &From) { +Symbol toProtobuf(const clangd::Symbol &From, llvm::StringRef IndexRoot) { Symbol Result; Result.set_id(From.ID.str()); *Result.mutable_info() = toProtobuf(From.SymInfo); Result.set_name(From.Name.str()); - *Result.mutable_definition() = toProtobuf(From.Definition); + auto Definition = toProtobuf(From.Definition, IndexRoot); + if (Definition) + *Result.mutable_definition() = *Definition; Result.set_scope(From.Scope.str()); - *Result.mutable_canonical_declarattion() = - toProtobuf(From.CanonicalDeclaration); + auto Declaration = toProtobuf(From.CanonicalDeclaration, IndexRoot); + if (Declaration) + *Result.mutable_canonical_declaration() = *Declaration; Result.set_references(From.References); Result.set_origin(static_cast(From.Origin)); Result.set_signature(From.Signature.str()); @@ -207,20 +265,82 @@ Symbol toProtobuf(const clangd::Symbol &From) { Result.set_return_type(From.ReturnType.str()); Result.set_type(From.Type.str()); for (const auto &Header : From.IncludeHeaders) { + auto Serialized = toProtobuf(Header, IndexRoot); + if (!Serialized) + continue; auto *NextHeader = Result.add_headers(); - *NextHeader = toProtobuf(Header); + *NextHeader = *Serialized; } Result.set_flags(static_cast(From.Flags)); return Result; } -Ref toProtobuf(const clangd::Ref &From) { +// FIXME(kirillbobyrev): A reference without location is invalid. +// llvm::Optional here and on the server side? +Ref toProtobuf(const clangd::Ref &From, llvm::StringRef IndexRoot) { Ref Result; Result.set_kind(static_cast(From.Kind)); - *Result.mutable_location() = toProtobuf(From.Location); + auto Location = toProtobuf(From.Location, IndexRoot); + if (Location) + *Result.mutable_location() = *Location; return Result; } +llvm::Optional relativePathToURI(llvm::StringRef RelativePath, + llvm::StringRef IndexRoot) { + assert(RelativePath == llvm::sys::path::convert_to_slash( + RelativePath, llvm::sys::path::Style::posix)); + assert(IndexRoot == llvm::sys::path::convert_to_slash(IndexRoot)); + assert(IndexRoot.endswith(llvm::sys::path::get_separator())); + if (RelativePath.empty()) + return std::string(); + if (llvm::sys::path::is_absolute(RelativePath)) { + elog("Remote index client got absolute path from server: {0}", + RelativePath); + return llvm::None; + } + if (llvm::sys::path::is_relative(IndexRoot)) { + elog("Remote index client got a relative path as index root: {0}", + IndexRoot); + return llvm::None; + } + llvm::SmallString<256> FullPath = IndexRoot; + llvm::sys::path::append(FullPath, RelativePath); + auto Result = URI::createFile(FullPath); + return Result.toString(); +} + +llvm::Optional uriToRelativePath(llvm::StringRef URI, + llvm::StringRef IndexRoot) { + assert(IndexRoot.endswith(llvm::sys::path::get_separator())); + assert(IndexRoot == llvm::sys::path::convert_to_slash(IndexRoot)); + assert(!IndexRoot.empty()); + if (llvm::sys::path::is_relative(IndexRoot)) { + elog("Index root {0} is not absolute path", IndexRoot); + return llvm::None; + } + auto ParsedURI = URI::parse(URI); + if (!ParsedURI) { + elog("Remote index got bad URI from client {0}: {1}", URI, + ParsedURI.takeError()); + return llvm::None; + } + if (ParsedURI->scheme() != "file") { + elog("Remote index got URI with scheme other than \"file\" {0}: {1}", URI, + ParsedURI->scheme()); + return llvm::None; + } + llvm::SmallString<256> Result = ParsedURI->body(); + if (!llvm::sys::path::replace_path_prefix(Result, IndexRoot, "")) { + elog("Can not get relative path from the URI {0} given the index root {1}", + URI, IndexRoot); + return llvm::None; + } + // Make sure the result has UNIX slashes. + return llvm::sys::path::convert_to_slash(Result, + llvm::sys::path::Style::posix); +} + } // namespace remote } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.h b/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.h index 1bc25bf5a9de5..86cc8fa272fc5 100644 --- a/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.h +++ b/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.h @@ -6,7 +6,28 @@ // //===----------------------------------------------------------------------===// // -// Transformations between native Clangd types and Protobuf-generated classes. +// Marshalling provides translation between native clangd types into the +// Protobuf-generated classes. Most translations are 1-to-1 and wrap variables +// into appropriate Protobuf types. +// +// A notable exception is URI translation. Because paths to files are different +// on indexing machine and client machine +// ("/remote/machine/projects/llvm-project/llvm/include/HelloWorld.h" versus +// "/usr/local/username/llvm-project/llvm/include/HelloWorld.h"), they need to +// be converted appropriately. Remote machine strips the prefix from the +// absolute path and passes paths relative to the project root over the wire +// ("include/HelloWorld.h" in this example). The indexed project root is passed +// to the remote server. Client receives this relative path and constructs a URI +// that points to the relevant file in the filesystem. The relative path is +// appended to IndexRoot to construct the full path and build the final URI. +// +// Index root is the absolute path to the project and includes a trailing slash. +// The relative path passed over the wire has unix slashes. +// +// toProtobuf() functions serialize native clangd types and strip IndexRoot from +// the file paths specific to indexing machine. fromProtobuf() functions +// deserialize clangd types and translate relative paths into machine-native +// URIs. // //===----------------------------------------------------------------------===// @@ -15,24 +36,40 @@ #include "Index.pb.h" #include "index/Index.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/StringSaver.h" namespace clang { namespace clangd { namespace remote { -clangd::FuzzyFindRequest fromProtobuf(const FuzzyFindRequest *Request); +clangd::FuzzyFindRequest fromProtobuf(const FuzzyFindRequest *Request, + llvm::StringRef IndexRoot); llvm::Optional fromProtobuf(const Symbol &Message, - llvm::UniqueStringSaver *Strings); + llvm::UniqueStringSaver *Strings, + llvm::StringRef IndexRoot); llvm::Optional fromProtobuf(const Ref &Message, - llvm::UniqueStringSaver *Strings); + llvm::UniqueStringSaver *Strings, + llvm::StringRef IndexRoot); LookupRequest toProtobuf(const clangd::LookupRequest &From); -FuzzyFindRequest toProtobuf(const clangd::FuzzyFindRequest &From); +FuzzyFindRequest toProtobuf(const clangd::FuzzyFindRequest &From, + llvm::StringRef IndexRoot); RefsRequest toProtobuf(const clangd::RefsRequest &From); -Ref toProtobuf(const clangd::Ref &From); -Symbol toProtobuf(const clangd::Symbol &From); +Ref toProtobuf(const clangd::Ref &From, llvm::StringRef IndexRoot); +Symbol toProtobuf(const clangd::Symbol &From, llvm::StringRef IndexRoot); + +/// Translates \p RelativePath into the absolute path and builds URI for the +/// user machine. This translation happens on the client side with the +/// \p RelativePath received from remote index server and \p IndexRoot is +/// provided by the client. +llvm::Optional relativePathToURI(llvm::StringRef RelativePath, + llvm::StringRef IndexRoot); +/// Translates a URI from the server's backing index to a relative path suitable +/// to send over the wire to the client. +llvm::Optional uriToRelativePath(llvm::StringRef URI, + llvm::StringRef IndexRoot); } // namespace remote } // namespace clangd diff --git a/clang-tools-extra/clangd/index/remote/server/Server.cpp b/clang-tools-extra/clangd/index/remote/server/Server.cpp index 4d84eb17210ea..718d623a48456 100644 --- a/clang-tools-extra/clangd/index/remote/server/Server.cpp +++ b/clang-tools-extra/clangd/index/remote/server/Server.cpp @@ -11,6 +11,7 @@ #include "index/remote/marshalling/Marshalling.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Path.h" #include "llvm/Support/Signals.h" #include @@ -31,6 +32,9 @@ awaits gRPC lookup requests from the client. llvm::cl::opt IndexPath(llvm::cl::desc(""), llvm::cl::Positional, llvm::cl::Required); +llvm::cl::opt IndexRoot(llvm::cl::desc(""), + llvm::cl::Positional, llvm::cl::Required); + llvm::cl::opt ServerAddress( "server-address", llvm::cl::init("0.0.0.0:50051"), llvm::cl::desc("Address of the invoked server. Defaults to 0.0.0.0:50051")); @@ -41,8 +45,13 @@ std::unique_ptr openIndex(llvm::StringRef Index) { class RemoteIndexServer final : public SymbolIndex::Service { public: - RemoteIndexServer(std::unique_ptr Index) - : Index(std::move(Index)) {} + RemoteIndexServer(std::unique_ptr Index, + llvm::StringRef IndexRoot) + : Index(std::move(Index)) { + llvm::SmallString<256> NativePath = IndexRoot; + llvm::sys::path::native(NativePath); + IndexedProjectRoot = std::string(NativePath); + } private: grpc::Status Lookup(grpc::ServerContext *Context, @@ -57,7 +66,8 @@ class RemoteIndexServer final : public SymbolIndex::Service { } Index->lookup(Req, [&](const clangd::Symbol &Sym) { LookupReply NextMessage; - *NextMessage.mutable_stream_result() = toProtobuf(Sym); + *NextMessage.mutable_stream_result() = + toProtobuf(Sym, IndexedProjectRoot); Reply->Write(NextMessage); }); LookupReply LastMessage; @@ -69,10 +79,11 @@ class RemoteIndexServer final : public SymbolIndex::Service { grpc::Status FuzzyFind(grpc::ServerContext *Context, const FuzzyFindRequest *Request, grpc::ServerWriter *Reply) override { - const auto Req = fromProtobuf(Request); + const auto Req = fromProtobuf(Request, IndexedProjectRoot); bool HasMore = Index->fuzzyFind(Req, [&](const clangd::Symbol &Sym) { FuzzyFindReply NextMessage; - *NextMessage.mutable_stream_result() = toProtobuf(Sym); + *NextMessage.mutable_stream_result() = + toProtobuf(Sym, IndexedProjectRoot); Reply->Write(NextMessage); }); FuzzyFindReply LastMessage; @@ -92,7 +103,7 @@ class RemoteIndexServer final : public SymbolIndex::Service { } bool HasMore = Index->refs(Req, [&](const clangd::Ref &Reference) { RefsReply NextMessage; - *NextMessage.mutable_stream_result() = toProtobuf(Reference); + *NextMessage.mutable_stream_result() = toProtobuf(Reference, IndexRoot); Reply->Write(NextMessage); }); RefsReply LastMessage; @@ -102,11 +113,12 @@ class RemoteIndexServer final : public SymbolIndex::Service { } std::unique_ptr Index; + std::string IndexedProjectRoot; }; void runServer(std::unique_ptr Index, const std::string &ServerAddress) { - RemoteIndexServer Service(std::move(Index)); + RemoteIndexServer Service(std::move(Index), IndexRoot); grpc::EnableDefaultHealthCheckService(true); grpc::ServerBuilder Builder; @@ -128,6 +140,11 @@ int main(int argc, char *argv[]) { llvm::cl::ParseCommandLineOptions(argc, argv, Overview); llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); + if (!llvm::sys::path::is_absolute(IndexRoot)) { + llvm::outs() << "Index root should be an absolute path.\n"; + return -1; + } + std::unique_ptr Index = openIndex(IndexPath); if (!Index) { diff --git a/clang-tools-extra/clangd/index/remote/unimplemented/UnimplementedClient.cpp b/clang-tools-extra/clangd/index/remote/unimplemented/UnimplementedClient.cpp index f0fb612f6332f..a4d3127e04553 100644 --- a/clang-tools-extra/clangd/index/remote/unimplemented/UnimplementedClient.cpp +++ b/clang-tools-extra/clangd/index/remote/unimplemented/UnimplementedClient.cpp @@ -8,12 +8,14 @@ #include "index/remote/Client.h" #include "support/Logger.h" +#include "llvm/ADT/StringRef.h" namespace clang { namespace clangd { namespace remote { -std::unique_ptr getClient(llvm::StringRef Address) { +std::unique_ptr getClient(llvm::StringRef Address, + llvm::StringRef IndexRoot) { elog("Can't create SymbolIndex client without Remote Index support."); return nullptr; } diff --git a/clang-tools-extra/clangd/refactor/tweaks/CMakeLists.txt b/clang-tools-extra/clangd/refactor/tweaks/CMakeLists.txt index c5bff2f34a9a2..8f708cacfdf88 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/CMakeLists.txt +++ b/clang-tools-extra/clangd/refactor/tweaks/CMakeLists.txt @@ -36,4 +36,7 @@ add_clang_library(clangDaemonTweaks OBJECT clangToolingCore clangToolingRefactoring clangToolingSyntax + + DEPENDS + omp_gen ) diff --git a/clang-tools-extra/clangd/refactor/tweaks/DumpAST.cpp b/clang-tools-extra/clangd/refactor/tweaks/DumpAST.cpp index 616e100adf084..b2b883d645679 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/DumpAST.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/DumpAST.cpp @@ -62,7 +62,7 @@ REGISTER_TWEAK(DumpAST) llvm::Expected DumpAST::apply(const Selection &Inputs) { std::string Str; llvm::raw_string_ostream OS(Str); - Node->dump(OS, Inputs.AST->getSourceManager()); + Node->dump(OS, Inputs.AST->getASTContext()); return Effect::showMessage(std::move(OS.str())); } diff --git a/clang-tools-extra/clangd/support/ThreadsafeFS.cpp b/clang-tools-extra/clangd/support/ThreadsafeFS.cpp index a25ac773bfa27..cadda8efa0952 100644 --- a/clang-tools-extra/clangd/support/ThreadsafeFS.cpp +++ b/clang-tools-extra/clangd/support/ThreadsafeFS.cpp @@ -83,7 +83,7 @@ ThreadsafeFS::view(PathRef CWD) const { } llvm::IntrusiveRefCntPtr -RealThreadsafeFS::view(llvm::NoneType) const { +RealThreadsafeFS::viewImpl() const { // Avoid using memory-mapped files. // FIXME: Try to use a similar approach in Sema instead of relying on // propagation of the 'isVolatile' flag through all layers. diff --git a/clang-tools-extra/clangd/support/ThreadsafeFS.h b/clang-tools-extra/clangd/support/ThreadsafeFS.h index aa6825fb39990..ad0dd64258112 100644 --- a/clang-tools-extra/clangd/support/ThreadsafeFS.h +++ b/clang-tools-extra/clangd/support/ThreadsafeFS.h @@ -30,20 +30,25 @@ class ThreadsafeFS { virtual ~ThreadsafeFS() = default; /// Obtain a vfs::FileSystem with an arbitrary initial working directory. - virtual llvm::IntrusiveRefCntPtr - view(llvm::NoneType CWD) const = 0; + llvm::IntrusiveRefCntPtr + view(llvm::NoneType CWD) const { + return viewImpl(); + } /// Obtain a vfs::FileSystem with a specified working directory. /// If the working directory can't be set (e.g. doesn't exist), logs and /// returns the FS anyway. - virtual llvm::IntrusiveRefCntPtr - view(PathRef CWD) const; + llvm::IntrusiveRefCntPtr view(PathRef CWD) const; + +private: + /// Overridden by implementations to provide a vfs::FileSystem. + /// This is distinct from view(NoneType) to avoid GCC's -Woverloaded-virtual. + virtual llvm::IntrusiveRefCntPtr viewImpl() const = 0; }; class RealThreadsafeFS : public ThreadsafeFS { -public: - llvm::IntrusiveRefCntPtr - view(llvm::NoneType) const override; +private: + llvm::IntrusiveRefCntPtr viewImpl() const override; }; } // namespace clangd diff --git a/clang-tools-extra/clangd/test/background-index.test b/clang-tools-extra/clangd/test/background-index.test index 821ac7174f59d..41184443e947a 100644 --- a/clang-tools-extra/clangd/test/background-index.test +++ b/clang-tools-extra/clangd/test/background-index.test @@ -15,8 +15,8 @@ # RUN: clangd -background-index -lit-test < %t/definition.jsonrpc | FileCheck %t/definition.jsonrpc --check-prefixes=CHECK,BUILD # Test that the index is writing files in the expected location. -# RUN: ls %t/.clangd/index/foo.cpp.*.idx -# RUN: ls %t/sub_dir/.clangd/index/foo.h.*.idx +# RUN: ls %t/.cache/clangd/index/foo.cpp.*.idx +# RUN: ls %t/sub_dir/.cache/clangd/index/foo.h.*.idx # Test the index is read from disk: delete code and restart clangd. # RUN: rm %t/foo.cpp diff --git a/clang-tools-extra/clangd/test/initialize-params.test b/clang-tools-extra/clangd/test/initialize-params.test index f1f5312d10096..f0a0f791c2f68 100644 --- a/clang-tools-extra/clangd/test/initialize-params.test +++ b/clang-tools-extra/clangd/test/initialize-params.test @@ -42,8 +42,8 @@ # CHECK-NEXT: "renameProvider": true, # CHECK-NEXT: "selectionRangeProvider": true, # CHECK-NEXT: "semanticTokensProvider": { -# CHECK-NEXT: "documentProvider": { -# CHECK-NEXT: "edits": true +# CHECK-NEXT: "full": { +# CHECK-NEXT: "delta": true # CHECK-NEXT: }, # CHECK-NEXT: "legend": { # CHECK-NEXT: "tokenModifiers": [], @@ -51,7 +51,7 @@ # CHECK-NEXT: "variable", # CHECK: ] # CHECK-NEXT: }, -# CHECK-NEXT: "rangeProvider": false +# CHECK-NEXT: "range": false # CHECK-NEXT: }, # CHECK-NEXT: "signatureHelpProvider": { # CHECK-NEXT: "triggerCharacters": [ diff --git a/clang-tools-extra/clangd/test/semantic-tokens.test b/clang-tools-extra/clangd/test/semantic-tokens.test index 6fab10362b285..ed0c0d09a13ed 100644 --- a/clang-tools-extra/clangd/test/semantic-tokens.test +++ b/clang-tools-extra/clangd/test/semantic-tokens.test @@ -13,7 +13,7 @@ }}} --- # Non-incremental token request. -{"jsonrpc":"2.0","id":1,"method":"textDocument/semanticTokens","params":{"textDocument":{"uri":"test:///foo.cpp"}}} +{"jsonrpc":"2.0","id":1,"method":"textDocument/semanticTokens/full","params":{"textDocument":{"uri":"test:///foo.cpp"}}} # CHECK: "id": 1, # CHECK-NEXT: "jsonrpc": "2.0", # CHECK-NEXT: "result": { @@ -34,7 +34,7 @@ }} --- # Incremental token request, based on previous response. -{"jsonrpc":"2.0","id":2,"method":"textDocument/semanticTokens/edits","params":{ +{"jsonrpc":"2.0","id":2,"method":"textDocument/semanticTokens/full/delta","params":{ "textDocument": {"uri":"test:///foo.cpp"}, "previousResultId": "1" }} @@ -60,7 +60,7 @@ # CHECK-NEXT: } --- # Incremental token request with incorrect baseline => full tokens list. -{"jsonrpc":"2.0","id":2,"method":"textDocument/semanticTokens/edits","params":{ +{"jsonrpc":"2.0","id":2,"method":"textDocument/semanticTokens/full/delta","params":{ "textDocument": {"uri":"test:///foo.cpp"}, "previousResultId": "bogus" }} diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp index c77f92d3f183e..6e3d6a231da1e 100644 --- a/clang-tools-extra/clangd/tool/ClangdMain.cpp +++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -320,7 +320,7 @@ opt Test{ "lit-test", cat(Misc), desc("Abbreviation for -input-style=delimited -pretty -sync " - "-enable-test-scheme -log=verbose. " + "-enable-test-scheme -enable-config=0 -log=verbose. " "Intended to simplify lit tests"), init(false), Hidden, @@ -427,6 +427,20 @@ opt AsyncPreamble{ Hidden, }; +opt EnableConfig{ + "enable-config", + cat(Misc), + desc( + "Read user and project configuration from YAML files.\n" + "Project config is from a .clangd file in the project directory.\n" + "User config is from clangd/config.yaml in the following directories:\n" + "\tWindows: %USERPROFILE%\\AppData\\Local\n" + "\tMac OS: ~/Library/Preferences/\n" + "\tOthers: $XDG_CONFIG_HOME, usually ~/.config\n" + "Configuration is documented at https://clangd.llvm.org/config.html"), + init(false), +}; + /// Supports a test URI scheme with relaxed constraints for lit tests. /// The path in a test URI will be combined with a platform-specific fake /// directory to form an absolute path. For example, test:///a.cpp is resolved @@ -510,6 +524,9 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var InputStyle = JSONStreamStyle::Delimited; LogLevel = Logger::Verbose; PrettyPrint = true; + // Disable config system by default to avoid external reads. + if (!EnableConfig.getNumOccurrences()) + EnableConfig = false; // Disable background index on lit tests by default to prevent disk writes. if (!EnableBackgroundIndex.getNumOccurrences()) EnableBackgroundIndex = false; @@ -677,6 +694,23 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var CCOpts.RunParser = CodeCompletionParse; RealThreadsafeFS TFS; + std::unique_ptr Config; + if (EnableConfig) { + std::vector> ProviderStack; + ProviderStack.push_back( + config::Provider::fromAncestorRelativeYAMLFiles(".clangd", TFS)); + llvm::SmallString<256> UserConfig; + if (llvm::sys::path::user_config_directory(UserConfig)) { + llvm::sys::path::append(UserConfig, "clangd", "config.yaml"); + vlog("User config file is {0}", UserConfig); + ProviderStack.push_back(config::Provider::fromYAMLFile(UserConfig, TFS)); + } else { + elog("Couldn't determine user config file, not loading"); + } + Config = config::Provider::combine(std::move(ProviderStack)); + Opts.ConfigProvider = Config.get(); + } + // Initialize and run ClangdLSPServer. // Change stdin to binary to not lose \r\n on windows. llvm::sys::ChangeStdinToBinary(); diff --git a/clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp b/clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp index 24322e1575abd..cb4d23e0be347 100644 --- a/clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp +++ b/clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp @@ -1,3 +1,5 @@ +#include "CompileCommands.h" +#include "Config.h" #include "Headers.h" #include "SyncAPI.h" #include "TestFS.h" @@ -5,6 +7,7 @@ #include "TestTU.h" #include "index/Background.h" #include "index/BackgroundRebuild.h" +#include "clang/Tooling/ArgumentsAdjusters.h" #include "clang/Tooling/CompilationDatabase.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/Threading.h" @@ -24,6 +27,7 @@ namespace clang { namespace clangd { MATCHER_P(Named, N, "") { return arg.Name == N; } +MATCHER_P(QName, N, "") { return (arg.Scope + arg.Name).str() == N; } MATCHER(Declared, "") { return !StringRef(arg.CanonicalDeclaration.FileURI).empty(); } @@ -104,6 +108,53 @@ TEST_F(BackgroundIndexTest, NoCrashOnErrorFile) { ASSERT_TRUE(Idx.blockUntilIdleForTest()); } +TEST_F(BackgroundIndexTest, Config) { + MockFS FS; + // Set up two identical TUs, foo and bar. + // They define foo::one and bar::one. + std::vector Cmds; + for (std::string Name : {"foo", "bar"}) { + std::string Filename = Name + ".cpp"; + std::string Header = Name + ".h"; + FS.Files[Filename] = "#include \"" + Header + "\""; + FS.Files[Header] = "namespace " + Name + " { int one; }"; + tooling::CompileCommand Cmd; + Cmd.Filename = Filename; + Cmd.Directory = testRoot(); + Cmd.CommandLine = {"clang++", Filename}; + Cmds.push_back(std::move(Cmd)); + } + // Context provider that installs a configuration mutating foo's command. + // This causes it to define foo::two instead of foo::one. + auto ContextProvider = [](PathRef P) { + Config C; + if (P.endswith("foo.cpp")) + C.CompileFlags.Edits.push_back( + [](std::vector &Argv) { Argv.push_back("-Done=two"); }); + return Context::current().derive(Config::Key, std::move(C)); + }; + // Create the background index. + llvm::StringMap Storage; + size_t CacheHits = 0; + MemoryShardStorage MSS(Storage, CacheHits); + // We need the CommandMangler, because that applies the config we're testing. + OverlayCDB CDB(/*Base=*/nullptr, /*FallbackFlags=*/{}, + tooling::ArgumentsAdjuster(CommandMangler::forTests())); + BackgroundIndex Idx( + Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }, + /*ThreadPoolSize=*/4, /*OnProgress=*/nullptr, std::move(ContextProvider)); + // Index the two files. + for (auto &Cmd : Cmds) { + std::string FullPath = testPath(Cmd.Filename); + CDB.setCompileCommand(FullPath, std::move(Cmd)); + } + // Wait for both files to be indexed. + ASSERT_TRUE(Idx.blockUntilIdleForTest()); + EXPECT_THAT(runFuzzyFind(Idx, ""), + UnorderedElementsAre(QName("foo"), QName("foo::two"), + QName("bar"), QName("bar::one"))); +} + TEST_F(BackgroundIndexTest, IndexTwoFiles) { MockFS FS; // a.h yields different symbols when included by A.cc vs B.cc. diff --git a/clang-tools-extra/clangd/unittests/CMakeLists.txt b/clang-tools-extra/clangd/unittests/CMakeLists.txt index 03e09669b13f5..c25e2b7f81037 100644 --- a/clang-tools-extra/clangd/unittests/CMakeLists.txt +++ b/clang-tools-extra/clangd/unittests/CMakeLists.txt @@ -41,6 +41,9 @@ add_unittest(ClangdUnitTests ClangdTests CollectMacrosTests.cpp CompileCommandsTests.cpp CompilerTests.cpp + ConfigCompileTests.cpp + ConfigProviderTests.cpp + ConfigYAMLTests.cpp DexTests.cpp DiagnosticsTests.cpp DraftStoreTests.cpp diff --git a/clang-tools-extra/clangd/unittests/ClangdTests.cpp b/clang-tools-extra/clangd/unittests/ClangdTests.cpp index e1f02c897fe37..c21719d58bd6a 100644 --- a/clang-tools-extra/clangd/unittests/ClangdTests.cpp +++ b/clang-tools-extra/clangd/unittests/ClangdTests.cpp @@ -10,6 +10,7 @@ #include "ClangdLSPServer.h" #include "ClangdServer.h" #include "CodeComplete.h" +#include "ConfigFragment.h" #include "GlobalCompilationDatabase.h" #include "Matchers.h" #include "SyncAPI.h" @@ -19,6 +20,7 @@ #include "support/Threading.h" #include "clang/Config/config.h" #include "clang/Sema/CodeCompleteConsumer.h" +#include "clang/Tooling/ArgumentsAdjusters.h" #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" @@ -47,6 +49,7 @@ using ::testing::Field; using ::testing::Gt; using ::testing::IsEmpty; using ::testing::Pair; +using ::testing::SizeIs; using ::testing::UnorderedElementsAre; MATCHER_P2(DeclAt, File, Range, "") { @@ -273,12 +276,13 @@ int b = a; TEST_F(ClangdVFSTest, PropagatesContexts) { static Key Secret; struct ContextReadingFS : public ThreadsafeFS { - IntrusiveRefCntPtr - view(llvm::NoneType) const override { + mutable int Got; + + private: + IntrusiveRefCntPtr viewImpl() const override { Got = Context::current().getExisting(Secret); return buildTestFS({}); } - mutable int Got; } FS; struct Callbacks : public ClangdServer::Callbacks { void onDiagnosticsReady(PathRef File, llvm::StringRef Version, @@ -300,6 +304,48 @@ TEST_F(ClangdVFSTest, PropagatesContexts) { EXPECT_EQ(Callbacks.Got, 42); } +TEST(ClangdServerTest, RespectsConfig) { + // Go-to-definition will resolve as marked if FOO is defined. + Annotations Example(R"cpp( + #ifdef FOO + int [[x]]; + #else + int x; + #endif + int y = ^x; + )cpp"); + // Provide conditional config that defines FOO for foo.cc. + class ConfigProvider : public config::Provider { + std::vector + getFragments(const config::Params &, + config::DiagnosticCallback DC) const override { + config::Fragment F; + F.If.PathMatch.emplace_back(".*foo.cc"); + F.CompileFlags.Add.emplace_back("-DFOO=1"); + return {std::move(F).compile(DC)}; + } + } CfgProvider; + + auto Opts = ClangdServer::optsForTest(); + Opts.ConfigProvider = &CfgProvider; + OverlayCDB CDB(/*Base=*/nullptr, /*FallbackFlags=*/{}, + tooling::ArgumentsAdjuster(CommandMangler::forTests())); + MockFS FS; + ClangdServer Server(CDB, FS, Opts); + // foo.cc sees the expected definition, as FOO is defined. + Server.addDocument(testPath("foo.cc"), Example.code()); + auto Result = runLocateSymbolAt(Server, testPath("foo.cc"), Example.point()); + ASSERT_TRUE(bool(Result)) << Result.takeError(); + ASSERT_THAT(*Result, SizeIs(1)); + EXPECT_EQ(Result->front().PreferredDeclaration.range, Example.range()); + // bar.cc gets a different result, as FOO is not defined. + Server.addDocument(testPath("bar.cc"), Example.code()); + Result = runLocateSymbolAt(Server, testPath("bar.cc"), Example.point()); + ASSERT_TRUE(bool(Result)) << Result.takeError(); + ASSERT_THAT(*Result, SizeIs(1)); + EXPECT_NE(Result->front().PreferredDeclaration.range, Example.range()); +} + TEST_F(ClangdVFSTest, PropagatesVersion) { MockCompilationDatabase CDB; MockFS FS; @@ -877,7 +923,7 @@ void f() {} FS.Files[Path] = Code; runAddDocument(Server, Path, Code); - auto Replaces = Server.formatFile(Code, Path); + auto Replaces = runFormatFile(Server, Path, Code); EXPECT_TRUE(static_cast(Replaces)); auto Changed = tooling::applyAllReplacements(Code, *Replaces); EXPECT_TRUE(static_cast(Changed)); @@ -925,12 +971,17 @@ TEST_F(ClangdVFSTest, ChangedHeaderFromISystem) { // preamble again. (They should be using the preamble's stat-cache) TEST(ClangdTests, PreambleVFSStatCache) { class StatRecordingFS : public ThreadsafeFS { + llvm::StringMap &CountStats; + public: + // If relative paths are used, they are resolved with testPath(). + llvm::StringMap Files; + StatRecordingFS(llvm::StringMap &CountStats) : CountStats(CountStats) {} - IntrusiveRefCntPtr - view(llvm::NoneType) const override { + private: + IntrusiveRefCntPtr viewImpl() const override { class StatRecordingVFS : public llvm::vfs::ProxyFileSystem { public: StatRecordingVFS(IntrusiveRefCntPtr FS, @@ -954,10 +1005,6 @@ TEST(ClangdTests, PreambleVFSStatCache) { return IntrusiveRefCntPtr( new StatRecordingVFS(buildTestFS(Files), CountStats)); } - - // If relative paths are used, they are resolved with testPath(). - llvm::StringMap Files; - llvm::StringMap &CountStats; }; llvm::StringMap CountStats; diff --git a/clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp b/clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp index d064c941a5908..d86296b84e3f9 100644 --- a/clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp +++ b/clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp @@ -7,7 +7,9 @@ //===----------------------------------------------------------------------===// #include "CompileCommands.h" +#include "Config.h" #include "TestFS.h" +#include "support/Context.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/StringExtras.h" @@ -22,6 +24,7 @@ namespace clang { namespace clangd { namespace { +using ::testing::_; using ::testing::Contains; using ::testing::ElementsAre; using ::testing::HasSubstr; @@ -185,6 +188,25 @@ TEST(CommandMangler, ClangPathResolve) { } #endif +TEST(CommandMangler, ConfigEdits) { + auto Mangler = CommandMangler::forTests(); + std::vector Cmd = {"clang++", "foo.cc"}; + { + Config Cfg; + Cfg.CompileFlags.Edits.push_back([](std::vector &Argv) { + for (auto &Arg : Argv) + for (char &C : Arg) + C = llvm::toUpper(C); + }); + Cfg.CompileFlags.Edits.push_back( + [](std::vector &Argv) { Argv.push_back("--hello"); }); + WithContextValue WithConfig(Config::Key, std::move(Cfg)); + Mangler.adjust(Cmd); + } + // Edits are applied in given order and before other mangling. + EXPECT_THAT(Cmd, ElementsAre(_, "FOO.CC", "--hello", "-fsyntax-only")); +} + } // namespace } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp b/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp new file mode 100644 index 0000000000000..825d6878727d9 --- /dev/null +++ b/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp @@ -0,0 +1,104 @@ +//===-- ConfigCompileTests.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 "Config.h" +#include "ConfigFragment.h" +#include "ConfigTesting.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace clang { +namespace clangd { +namespace config { +namespace { +using ::testing::ElementsAre; +using ::testing::IsEmpty; +using ::testing::SizeIs; +using ::testing::StartsWith; + +class ConfigCompileTests : public ::testing::Test { +protected: + CapturedDiags Diags; + Config Conf; + Fragment Frag; + Params Parm; + + bool compileAndApply() { + Conf = Config(); + Diags.Diagnostics.clear(); + auto Compiled = std::move(Frag).compile(Diags.callback()); + return Compiled(Parm, Conf); + } +}; + +TEST_F(ConfigCompileTests, Condition) { + // No condition. + Frag = {}; + Frag.CompileFlags.Add.emplace_back("X"); + EXPECT_TRUE(compileAndApply()) << "Empty config"; + EXPECT_THAT(Diags.Diagnostics, IsEmpty()); + EXPECT_THAT(Conf.CompileFlags.Edits, SizeIs(1)); + + // Regex with no file. + Frag = {}; + Frag.If.PathMatch.emplace_back("fo*"); + EXPECT_FALSE(compileAndApply()); + EXPECT_THAT(Diags.Diagnostics, IsEmpty()); + EXPECT_THAT(Conf.CompileFlags.Edits, SizeIs(0)); + + // Following tests have a file path set. + Parm.Path = "bar"; + + // Non-matching regex. + Frag = {}; + Frag.If.PathMatch.emplace_back("fo*"); + EXPECT_FALSE(compileAndApply()); + EXPECT_THAT(Diags.Diagnostics, IsEmpty()); + + // Matching regex. + Frag = {}; + Frag.If.PathMatch.emplace_back("fo*"); + Frag.If.PathMatch.emplace_back("ba*r"); + EXPECT_TRUE(compileAndApply()); + EXPECT_THAT(Diags.Diagnostics, IsEmpty()); + + // Excluded regex. + Frag = {}; + Frag.If.PathMatch.emplace_back("b.*"); + Frag.If.PathExclude.emplace_back(".*r"); + EXPECT_FALSE(compileAndApply()) << "Included but also excluded"; + EXPECT_THAT(Diags.Diagnostics, IsEmpty()); + + // Invalid regex. + Frag = {}; + Frag.If.PathMatch.emplace_back("**]@theu"); + EXPECT_TRUE(compileAndApply()); + EXPECT_THAT(Diags.Diagnostics, SizeIs(1)); + EXPECT_THAT(Diags.Diagnostics.front().Message, StartsWith("Invalid regex")); + + // Valid regex and unknown key. + Frag = {}; + Frag.If.HasUnrecognizedCondition = true; + Frag.If.PathMatch.emplace_back("ba*r"); + EXPECT_FALSE(compileAndApply()); + EXPECT_THAT(Diags.Diagnostics, IsEmpty()); +} + +TEST_F(ConfigCompileTests, CompileCommands) { + Frag.CompileFlags.Add.emplace_back("-foo"); + std::vector Argv = {"clang", "a.cc"}; + EXPECT_TRUE(compileAndApply()); + EXPECT_THAT(Conf.CompileFlags.Edits, SizeIs(1)); + Conf.CompileFlags.Edits.front()(Argv); + EXPECT_THAT(Argv, ElementsAre("clang", "a.cc", "-foo")); +} + +} // namespace +} // namespace config +} // namespace clangd +} // namespace clang diff --git a/clang-tools-extra/clangd/unittests/ConfigProviderTests.cpp b/clang-tools-extra/clangd/unittests/ConfigProviderTests.cpp new file mode 100644 index 0000000000000..122b55cf64e01 --- /dev/null +++ b/clang-tools-extra/clangd/unittests/ConfigProviderTests.cpp @@ -0,0 +1,156 @@ +//===-- ConfigProviderTests.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 "Config.h" +#include "ConfigProvider.h" +#include "ConfigTesting.h" +#include "TestFS.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "llvm/Support/SourceMgr.h" +#include + +namespace clang { +namespace clangd { +namespace config { +namespace { +using ::testing::ElementsAre; +using ::testing::IsEmpty; + +// Provider that appends an arg to compile flags. +// The arg is prefix, where N is the times getFragments() was called. +// It also yields a diagnostic each time it's called. +class FakeProvider : public Provider { + std::string Prefix; + mutable std::atomic Index = {0}; + + std::vector + getFragments(const Params &, DiagnosticCallback DC) const override { + DC(llvm::SMDiagnostic("", llvm::SourceMgr::DK_Error, Prefix)); + CompiledFragment F = + [Arg(Prefix + std::to_string(++Index))](const Params &P, Config &C) { + C.CompileFlags.Edits.push_back( + [Arg](std::vector &Argv) { Argv.push_back(Arg); }); + return true; + }; + return {F}; + } + +public: + FakeProvider(llvm::StringRef Prefix) : Prefix(Prefix) {} +}; + +std::vector getAddedArgs(Config &C) { + std::vector Argv; + for (auto &Edit : C.CompileFlags.Edits) + Edit(Argv); + return Argv; +} + +// The provider from combine() should invoke its providers in order, and not +// cache their results. +TEST(ProviderTest, Combine) { + CapturedDiags Diags; + std::vector> Providers; + Providers.push_back(std::make_unique("foo")); + Providers.push_back(std::make_unique("bar")); + auto Combined = Provider::combine(std::move(Providers)); + Config Cfg = Combined->getConfig(Params(), Diags.callback()); + EXPECT_THAT(Diags.Diagnostics, + ElementsAre(DiagMessage("foo"), DiagMessage("bar"))); + EXPECT_THAT(getAddedArgs(Cfg), ElementsAre("foo1", "bar1")); + Diags.Diagnostics.clear(); + + Cfg = Combined->getConfig(Params(), Diags.callback()); + EXPECT_THAT(Diags.Diagnostics, + ElementsAre(DiagMessage("foo"), DiagMessage("bar"))); + EXPECT_THAT(getAddedArgs(Cfg), ElementsAre("foo2", "bar2")); +} + +const char *AddFooWithErr = R"yaml( +CompileFlags: + Add: foo + Unknown: 42 +)yaml"; + +const char *AddBarBaz = R"yaml( +CompileFlags: + Add: bar +--- +CompileFlags: + Add: baz +)yaml"; + +TEST(ProviderTest, FromYAMLFile) { + MockFS FS; + FS.Files["foo.yaml"] = AddFooWithErr; + + CapturedDiags Diags; + auto P = Provider::fromYAMLFile(testPath("foo.yaml"), FS); + auto Cfg = P->getConfig(Params(), Diags.callback()); + EXPECT_THAT(Diags.Diagnostics, + ElementsAre(DiagMessage("Unknown CompileFlags key Unknown"))); + EXPECT_THAT(getAddedArgs(Cfg), ElementsAre("foo")); + Diags.Diagnostics.clear(); + + Cfg = P->getConfig(Params(), Diags.callback()); + EXPECT_THAT(Diags.Diagnostics, IsEmpty()) << "Cached, not re-parsed"; + EXPECT_THAT(getAddedArgs(Cfg), ElementsAre("foo")); + + FS.Files["foo.yaml"] = AddBarBaz; + Cfg = P->getConfig(Params(), Diags.callback()); + EXPECT_THAT(Diags.Diagnostics, IsEmpty()) << "New config, no errors"; + EXPECT_THAT(getAddedArgs(Cfg), ElementsAre("bar", "baz")); + + FS.Files.erase("foo.yaml"); + Cfg = P->getConfig(Params(), Diags.callback()); + EXPECT_THAT(Diags.Diagnostics, IsEmpty()) << "Missing file is not an error"; + EXPECT_THAT(getAddedArgs(Cfg), IsEmpty()); +} + +TEST(ProviderTest, FromAncestorRelativeYAMLFiles) { + MockFS FS; + FS.Files["a/b/c/foo.yaml"] = AddBarBaz; + FS.Files["a/foo.yaml"] = AddFooWithErr; + + std::string ABCPath = + testPath("a/b/c/d/test.cc", llvm::sys::path::Style::posix); + Params ABCParams; + ABCParams.Path = ABCPath; + std::string APath = + testPath("a/b/e/f/test.cc", llvm::sys::path::Style::posix); + Params AParams; + AParams.Path = APath; + + CapturedDiags Diags; + auto P = Provider::fromAncestorRelativeYAMLFiles("foo.yaml", FS); + + auto Cfg = P->getConfig(Params(), Diags.callback()); + EXPECT_THAT(Diags.Diagnostics, IsEmpty()); + EXPECT_THAT(getAddedArgs(Cfg), IsEmpty()); + + Cfg = P->getConfig(ABCParams, Diags.callback()); + EXPECT_THAT(Diags.Diagnostics, + ElementsAre(DiagMessage("Unknown CompileFlags key Unknown"))); + EXPECT_THAT(getAddedArgs(Cfg), ElementsAre("foo", "bar", "baz")); + Diags.Diagnostics.clear(); + + Cfg = P->getConfig(AParams, Diags.callback()); + EXPECT_THAT(Diags.Diagnostics, IsEmpty()) << "Cached config"; + EXPECT_THAT(getAddedArgs(Cfg), ElementsAre("foo")); + + FS.Files.erase("a/foo.yaml"); + Cfg = P->getConfig(ABCParams, Diags.callback()); + EXPECT_THAT(Diags.Diagnostics, IsEmpty()); + EXPECT_THAT(getAddedArgs(Cfg), ElementsAre("bar", "baz")); +} + +} // namespace +} // namespace config +} // namespace clangd +} // namespace clang diff --git a/clang-tools-extra/clangd/unittests/ConfigTesting.h b/clang-tools-extra/clangd/unittests/ConfigTesting.h new file mode 100644 index 0000000000000..5541c6fffe596 --- /dev/null +++ b/clang-tools-extra/clangd/unittests/ConfigTesting.h @@ -0,0 +1,77 @@ +//===-- ConfigTesting.h - Helpers for configuration tests -------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_UNITTESTS_CONFIGTESTING_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_UNITTESTS_CONFIGTESTING_H + +#include "Protocol.h" +#include "llvm/Support/ScopedPrinter.h" +#include "llvm/Support/SourceMgr.h" +#include "gmock/gmock.h" +#include + +namespace clang { +namespace clangd { +namespace config { + +// Provides a DiagnosticsCallback that records diganostics. +// Unlike just pushing them into a vector, underlying storage need not survive. +struct CapturedDiags { + std::function callback() { + return [this](const llvm::SMDiagnostic &D) { + Diagnostics.emplace_back(); + Diag &Out = Diagnostics.back(); + Out.Message = D.getMessage().str(); + Out.Kind = D.getKind(); + Out.Pos.line = D.getLineNo() - 1; + Out.Pos.character = D.getColumnNo(); // Zero-based - bug in SourceMgr? + if (!D.getRanges().empty()) { + const auto &R = D.getRanges().front(); + Out.Rng.emplace(); + Out.Rng->start.line = Out.Rng->end.line = Out.Pos.line; + Out.Rng->start.character = R.first; + Out.Rng->end.character = R.second; + } + }; + } + struct Diag { + std::string Message; + llvm::SourceMgr::DiagKind Kind; + Position Pos; + llvm::Optional Rng; + + friend void PrintTo(const Diag &D, std::ostream *OS) { + *OS << (D.Kind == llvm::SourceMgr::DK_Error ? "error: " : "warning: ") + << D.Message << "@" << llvm::to_string(D.Pos); + } + }; + std::vector Diagnostics; +}; + +MATCHER_P(DiagMessage, M, "") { return arg.Message == M; } +MATCHER_P(DiagKind, K, "") { return arg.Kind == K; } +MATCHER_P(DiagPos, P, "") { return arg.Pos == P; } +MATCHER_P(DiagRange, R, "") { return arg.Rng == R; } + +inline Position toPosition(llvm::SMLoc L, const llvm::SourceMgr &SM) { + auto LineCol = SM.getLineAndColumn(L); + Position P; + P.line = LineCol.first - 1; + P.character = LineCol.second - 1; + return P; +} + +inline Range toRange(llvm::SMRange R, const llvm::SourceMgr &SM) { + return Range{toPosition(R.Start, SM), toPosition(R.End, SM)}; +} + +} // namespace config +} // namespace clangd +} // namespace clang + +#endif diff --git a/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp b/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp new file mode 100644 index 0000000000000..a9526ce2367c4 --- /dev/null +++ b/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp @@ -0,0 +1,125 @@ +//===-- ConfigYAMLTests.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 "Annotations.h" +#include "ConfigFragment.h" +#include "ConfigTesting.h" +#include "Protocol.h" +#include "llvm/Support/SMLoc.h" +#include "llvm/Support/ScopedPrinter.h" +#include "llvm/Support/SourceMgr.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace clang { +namespace clangd { +namespace config { +template void PrintTo(const Located &V, std::ostream *OS) { + *OS << ::testing::PrintToString(*V); +} + +namespace { +using ::testing::AllOf; +using ::testing::ElementsAre; +using ::testing::IsEmpty; + +MATCHER_P(Val, Value, "") { + if (*arg == Value) + return true; + *result_listener << "value is " << *arg; + return false; +} + +TEST(ParseYAML, SyntacticForms) { + CapturedDiags Diags; + const char *YAML = R"yaml( +If: + PathMatch: + - 'abc' +CompileFlags: { Add: [foo, bar] } +--- +CompileFlags: + Add: | + b + az + )yaml"; + auto Results = Fragment::parseYAML(YAML, "config.yaml", Diags.callback()); + EXPECT_THAT(Diags.Diagnostics, IsEmpty()); + ASSERT_EQ(Results.size(), 2u); + EXPECT_FALSE(Results.front().If.HasUnrecognizedCondition); + EXPECT_THAT(Results.front().If.PathMatch, ElementsAre(Val("abc"))); + EXPECT_THAT(Results.front().CompileFlags.Add, + ElementsAre(Val("foo"), Val("bar"))); + + EXPECT_THAT(Results.back().CompileFlags.Add, ElementsAre(Val("b\naz\n"))); +} + +TEST(ParseYAML, Locations) { + CapturedDiags Diags; + Annotations YAML(R"yaml( +If: + PathMatch: [['???bad***regex(((']] + )yaml"); + auto Results = + Fragment::parseYAML(YAML.code(), "config.yaml", Diags.callback()); + EXPECT_THAT(Diags.Diagnostics, IsEmpty()); + ASSERT_EQ(Results.size(), 1u); + ASSERT_NE(Results.front().Source.Manager, nullptr); + EXPECT_EQ(toRange(Results.front().If.PathMatch.front().Range, + *Results.front().Source.Manager), + YAML.range()); +} + +TEST(ParseYAML, Diagnostics) { + CapturedDiags Diags; + Annotations YAML(R"yaml( +If: + [[UnknownCondition]]: "foo" +CompileFlags: + Add: 'first' +--- +CompileFlags: {^ +)yaml"); + auto Results = + Fragment::parseYAML(YAML.code(), "config.yaml", Diags.callback()); + + ASSERT_THAT( + Diags.Diagnostics, + ElementsAre(AllOf(DiagMessage("Unknown If key UnknownCondition"), + DiagKind(llvm::SourceMgr::DK_Warning), + DiagPos(YAML.range().start), DiagRange(YAML.range())), + AllOf(DiagMessage("Unexpected token. Expected Key, Flow " + "Entry, or Flow Mapping End."), + DiagKind(llvm::SourceMgr::DK_Error), + DiagPos(YAML.point()), DiagRange(llvm::None)))); + + ASSERT_EQ(Results.size(), 1u); // invalid fragment discarded. + EXPECT_THAT(Results.front().CompileFlags.Add, ElementsAre(Val("first"))); + EXPECT_TRUE(Results.front().If.HasUnrecognizedCondition); +} + +TEST(ParseYAML, Invalid) { + CapturedDiags Diags; + const char *YAML = R"yaml( +If: + +horrible +--- +- 1 + )yaml"; + auto Results = Fragment::parseYAML(YAML, "config.yaml", Diags.callback()); + EXPECT_THAT(Diags.Diagnostics, + ElementsAre(DiagMessage("If should be a dictionary"), + DiagMessage("Config should be a dictionary"))); + ASSERT_THAT(Results, IsEmpty()); +} + +} // namespace +} // namespace config +} // namespace clangd +} // namespace clang diff --git a/clang-tools-extra/clangd/unittests/FileIndexTests.cpp b/clang-tools-extra/clangd/unittests/FileIndexTests.cpp index 1026055c5c290..955ee50be8955 100644 --- a/clang-tools-extra/clangd/unittests/FileIndexTests.cpp +++ b/clang-tools-extra/clangd/unittests/FileIndexTests.cpp @@ -22,6 +22,7 @@ #include "index/Relation.h" #include "index/Serialization.h" #include "index/Symbol.h" +#include "support/Threading.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/Utils.h" #include "clang/Index/IndexSymbol.h" @@ -509,6 +510,31 @@ TEST(FileIndexTest, StalePreambleSymbolsDeleted) { EXPECT_THAT(runFuzzyFind(M, ""), UnorderedElementsAre(QName("b"))); } +// Verifies that concurrent calls to updateMain don't "lose" any updates. +TEST(FileIndexTest, Threadsafety) { + FileIndex M; + Notification Go; + + constexpr int Count = 10; + { + // Set up workers to concurrently call updateMain() with separate files. + AsyncTaskRunner Pool; + for (unsigned I = 0; I < Count; ++I) { + auto TU = TestTU::withCode(llvm::formatv("int xxx{0};", I).str()); + TU.Filename = llvm::formatv("x{0}.c", I).str(); + Pool.runAsync(TU.Filename, [&, Filename(testPath(TU.Filename)), + AST(TU.build())]() mutable { + Go.wait(); + M.updateMain(Filename, AST); + }); + } + // On your marks, get set... + Go.notify(); + } + + EXPECT_THAT(runFuzzyFind(M, "xxx"), ::testing::SizeIs(Count)); +} + TEST(FileShardedIndexTest, Sharding) { auto AHeaderUri = URI::create(testPath("a.h")).toString(); auto BHeaderUri = URI::create(testPath("b.h")).toString(); diff --git a/clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp b/clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp index b888ba22f5bbf..31879e356ce0e 100644 --- a/clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp +++ b/clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp @@ -10,6 +10,8 @@ #include "FindSymbols.h" #include "SyncAPI.h" #include "TestFS.h" +#include "TestTU.h" +#include "llvm/ADT/StringRef.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -42,160 +44,143 @@ ::testing::Matcher Children(ChildMatchers... ChildrenM) { return Field(&DocumentSymbol::children, ElementsAre(ChildrenM...)); } -ClangdServer::Options optsForTests() { - auto ServerOpts = ClangdServer::optsForTest(); - ServerOpts.WorkspaceRoot = testRoot(); - ServerOpts.BuildDynamicSymbolIndex = true; - return ServerOpts; +std::vector getSymbols(TestTU &TU, llvm::StringRef Query, + int Limit = 0) { + auto SymbolInfos = getWorkspaceSymbols(Query, Limit, TU.index().get(), + testPath(TU.Filename)); + EXPECT_TRUE(bool(SymbolInfos)) << "workspaceSymbols returned an error"; + return *SymbolInfos; } -class WorkspaceSymbolsTest : public ::testing::Test { -public: - WorkspaceSymbolsTest() : Server(CDB, FS, optsForTests()) { - // Make sure the test root directory is created. - FS.Files[testPath("unused")] = ""; - CDB.ExtraClangFlags = {"-xc++"}; - } - -protected: - MockFS FS; - MockCompilationDatabase CDB; - ClangdServer Server; - int Limit = 0; - - std::vector getSymbols(llvm::StringRef Query) { - EXPECT_TRUE(Server.blockUntilIdleForTest()) << "Waiting for preamble"; - auto SymbolInfos = runWorkspaceSymbols(Server, Query, Limit); - EXPECT_TRUE(bool(SymbolInfos)) << "workspaceSymbols returned an error"; - return *SymbolInfos; - } - - void addFile(llvm::StringRef FileName, llvm::StringRef Contents) { - Server.addDocument(testPath(FileName), Contents); - } -}; - -} // namespace - -TEST_F(WorkspaceSymbolsTest, Macros) { - addFile("foo.cpp", R"cpp( +TEST(WorkspaceSymbols, Macros) { + TestTU TU; + TU.Code = R"cpp( #define MACRO X - )cpp"); + )cpp"; // LSP's SymbolKind doesn't have a "Macro" kind, and // indexSymbolKindToSymbolKind() currently maps macros // to SymbolKind::String. - EXPECT_THAT(getSymbols("macro"), + EXPECT_THAT(getSymbols(TU, "macro"), ElementsAre(AllOf(QName("MACRO"), WithKind(SymbolKind::String)))); } -TEST_F(WorkspaceSymbolsTest, NoLocals) { - addFile("foo.cpp", R"cpp( +TEST(WorkspaceSymbols, NoLocals) { + TestTU TU; + TU.Code = R"cpp( void test(int FirstParam, int SecondParam) { struct LocalClass {}; int local_var; - })cpp"); - EXPECT_THAT(getSymbols("l"), IsEmpty()); - EXPECT_THAT(getSymbols("p"), IsEmpty()); + })cpp"; + EXPECT_THAT(getSymbols(TU, "l"), IsEmpty()); + EXPECT_THAT(getSymbols(TU, "p"), IsEmpty()); } -TEST_F(WorkspaceSymbolsTest, Globals) { - addFile("foo.h", R"cpp( +TEST(WorkspaceSymbols, Globals) { + TestTU TU; + TU.AdditionalFiles["foo.h"] = R"cpp( int global_var; int global_func(); - struct GlobalStruct {};)cpp"); - addFile("foo.cpp", R"cpp( + struct GlobalStruct {};)cpp"; + TU.Code = R"cpp( #include "foo.h" - )cpp"); - EXPECT_THAT(getSymbols("global"), + )cpp"; + EXPECT_THAT(getSymbols(TU, "global"), UnorderedElementsAre( AllOf(QName("GlobalStruct"), WithKind(SymbolKind::Struct)), AllOf(QName("global_func"), WithKind(SymbolKind::Function)), AllOf(QName("global_var"), WithKind(SymbolKind::Variable)))); } -TEST_F(WorkspaceSymbolsTest, Unnamed) { - addFile("foo.h", R"cpp( +TEST(WorkspaceSymbols, Unnamed) { + TestTU TU; + TU.AdditionalFiles["foo.h"] = R"cpp( struct { int InUnnamed; - } UnnamedStruct;)cpp"); - addFile("foo.cpp", R"cpp( + } UnnamedStruct;)cpp"; + TU.Code = R"cpp( #include "foo.h" - )cpp"); - EXPECT_THAT(getSymbols("UnnamedStruct"), + )cpp"; + EXPECT_THAT(getSymbols(TU, "UnnamedStruct"), ElementsAre(AllOf(QName("UnnamedStruct"), WithKind(SymbolKind::Variable)))); - EXPECT_THAT(getSymbols("InUnnamed"), + EXPECT_THAT(getSymbols(TU, "InUnnamed"), ElementsAre(AllOf(QName("(anonymous struct)::InUnnamed"), WithKind(SymbolKind::Field)))); } -TEST_F(WorkspaceSymbolsTest, InMainFile) { - addFile("foo.cpp", R"cpp( +TEST(WorkspaceSymbols, InMainFile) { + TestTU TU; + TU.Code = R"cpp( int test() {} - static test2() {} - )cpp"); - EXPECT_THAT(getSymbols("test"), ElementsAre(QName("test"), QName("test2"))); + static void test2() {} + )cpp"; + EXPECT_THAT(getSymbols(TU, "test"), + ElementsAre(QName("test"), QName("test2"))); } -TEST_F(WorkspaceSymbolsTest, Namespaces) { - addFile("foo.h", R"cpp( +TEST(WorkspaceSymbols, Namespaces) { + TestTU TU; + TU.AdditionalFiles["foo.h"] = R"cpp( namespace ans1 { int ai1; namespace ans2 { int ai2; } } - )cpp"); - addFile("foo.cpp", R"cpp( + )cpp"; + TU.Code = R"cpp( #include "foo.h" - )cpp"); - EXPECT_THAT(getSymbols("a"), + )cpp"; + EXPECT_THAT(getSymbols(TU, "a"), UnorderedElementsAre(QName("ans1"), QName("ans1::ai1"), QName("ans1::ans2"), QName("ans1::ans2::ai2"))); - EXPECT_THAT(getSymbols("::"), ElementsAre(QName("ans1"))); - EXPECT_THAT(getSymbols("::a"), ElementsAre(QName("ans1"))); - EXPECT_THAT(getSymbols("ans1::"), + EXPECT_THAT(getSymbols(TU, "::"), ElementsAre(QName("ans1"))); + EXPECT_THAT(getSymbols(TU, "::a"), ElementsAre(QName("ans1"))); + EXPECT_THAT(getSymbols(TU, "ans1::"), UnorderedElementsAre(QName("ans1::ai1"), QName("ans1::ans2"))); - EXPECT_THAT(getSymbols("::ans1"), ElementsAre(QName("ans1"))); - EXPECT_THAT(getSymbols("::ans1::"), + EXPECT_THAT(getSymbols(TU, "::ans1"), ElementsAre(QName("ans1"))); + EXPECT_THAT(getSymbols(TU, "::ans1::"), UnorderedElementsAre(QName("ans1::ai1"), QName("ans1::ans2"))); - EXPECT_THAT(getSymbols("::ans1::ans2"), ElementsAre(QName("ans1::ans2"))); - EXPECT_THAT(getSymbols("::ans1::ans2::"), + EXPECT_THAT(getSymbols(TU, "::ans1::ans2"), ElementsAre(QName("ans1::ans2"))); + EXPECT_THAT(getSymbols(TU, "::ans1::ans2::"), ElementsAre(QName("ans1::ans2::ai2"))); } -TEST_F(WorkspaceSymbolsTest, AnonymousNamespace) { - addFile("foo.cpp", R"cpp( +TEST(WorkspaceSymbols, AnonymousNamespace) { + TestTU TU; + TU.Code = R"cpp( namespace { void test() {} } - )cpp"); - EXPECT_THAT(getSymbols("test"), ElementsAre(QName("test"))); + )cpp"; + EXPECT_THAT(getSymbols(TU, "test"), ElementsAre(QName("test"))); } -TEST_F(WorkspaceSymbolsTest, MultiFile) { - addFile("foo.h", R"cpp( +TEST(WorkspaceSymbols, MultiFile) { + TestTU TU; + TU.AdditionalFiles["foo.h"] = R"cpp( int foo() { } - )cpp"); - addFile("foo2.h", R"cpp( + )cpp"; + TU.AdditionalFiles["foo2.h"] = R"cpp( int foo2() { } - )cpp"); - addFile("foo.cpp", R"cpp( + )cpp"; + TU.Code = R"cpp( #include "foo.h" #include "foo2.h" - )cpp"); - EXPECT_THAT(getSymbols("foo"), + )cpp"; + EXPECT_THAT(getSymbols(TU, "foo"), UnorderedElementsAre(QName("foo"), QName("foo2"))); } -TEST_F(WorkspaceSymbolsTest, GlobalNamespaceQueries) { - addFile("foo.h", R"cpp( +TEST(WorkspaceSymbols, GlobalNamespaceQueries) { + TestTU TU; + TU.AdditionalFiles["foo.h"] = R"cpp( int foo() { } class Foo { @@ -205,21 +190,22 @@ TEST_F(WorkspaceSymbolsTest, GlobalNamespaceQueries) { int foo2() { } } - )cpp"); - addFile("foo.cpp", R"cpp( + )cpp"; + TU.Code = R"cpp( #include "foo.h" - )cpp"); - EXPECT_THAT(getSymbols("::"), + )cpp"; + EXPECT_THAT(getSymbols(TU, "::"), UnorderedElementsAre( AllOf(QName("Foo"), WithKind(SymbolKind::Class)), AllOf(QName("foo"), WithKind(SymbolKind::Function)), AllOf(QName("ns"), WithKind(SymbolKind::Namespace)))); - EXPECT_THAT(getSymbols(":"), IsEmpty()); - EXPECT_THAT(getSymbols(""), IsEmpty()); + EXPECT_THAT(getSymbols(TU, ":"), IsEmpty()); + EXPECT_THAT(getSymbols(TU, ""), IsEmpty()); } -TEST_F(WorkspaceSymbolsTest, Enums) { - addFile("foo.h", R"cpp( +TEST(WorkspaceSymbols, Enums) { + TestTU TU; + TU.AdditionalFiles["foo.h"] = R"cpp( enum { Red }; @@ -240,63 +226,66 @@ TEST_F(WorkspaceSymbolsTest, Enums) { White }; } - )cpp"); - addFile("foo.cpp", R"cpp( + )cpp"; + TU.Code = R"cpp( #include "foo.h" - )cpp"); - EXPECT_THAT(getSymbols("Red"), ElementsAre(QName("Red"))); - EXPECT_THAT(getSymbols("::Red"), ElementsAre(QName("Red"))); - EXPECT_THAT(getSymbols("Green"), ElementsAre(QName("Green"))); - EXPECT_THAT(getSymbols("Green"), ElementsAre(QName("Green"))); - EXPECT_THAT(getSymbols("Color2::Yellow"), + )cpp"; + EXPECT_THAT(getSymbols(TU, "Red"), ElementsAre(QName("Red"))); + EXPECT_THAT(getSymbols(TU, "::Red"), ElementsAre(QName("Red"))); + EXPECT_THAT(getSymbols(TU, "Green"), ElementsAre(QName("Green"))); + EXPECT_THAT(getSymbols(TU, "Green"), ElementsAre(QName("Green"))); + EXPECT_THAT(getSymbols(TU, "Color2::Yellow"), ElementsAre(QName("Color2::Yellow"))); - EXPECT_THAT(getSymbols("Yellow"), ElementsAre(QName("Color2::Yellow"))); + EXPECT_THAT(getSymbols(TU, "Yellow"), ElementsAre(QName("Color2::Yellow"))); - EXPECT_THAT(getSymbols("ns::Black"), ElementsAre(QName("ns::Black"))); - EXPECT_THAT(getSymbols("ns::Blue"), ElementsAre(QName("ns::Blue"))); - EXPECT_THAT(getSymbols("ns::Color4::White"), + EXPECT_THAT(getSymbols(TU, "ns::Black"), ElementsAre(QName("ns::Black"))); + EXPECT_THAT(getSymbols(TU, "ns::Blue"), ElementsAre(QName("ns::Blue"))); + EXPECT_THAT(getSymbols(TU, "ns::Color4::White"), ElementsAre(QName("ns::Color4::White"))); } -TEST_F(WorkspaceSymbolsTest, Ranking) { - addFile("foo.h", R"cpp( +TEST(WorkspaceSymbols, Ranking) { + TestTU TU; + TU.AdditionalFiles["foo.h"] = R"cpp( namespace ns{} void func(); - )cpp"); - addFile("foo.cpp", R"cpp( + )cpp"; + TU.Code = R"cpp( #include "foo.h" - )cpp"); - EXPECT_THAT(getSymbols("::"), ElementsAre(QName("func"), QName("ns"))); + )cpp"; + EXPECT_THAT(getSymbols(TU, "::"), ElementsAre(QName("func"), QName("ns"))); } -TEST_F(WorkspaceSymbolsTest, WithLimit) { - addFile("foo.h", R"cpp( +TEST(WorkspaceSymbols, WithLimit) { + TestTU TU; + TU.AdditionalFiles["foo.h"] = R"cpp( int foo; int foo2; - )cpp"); - addFile("foo.cpp", R"cpp( + )cpp"; + TU.Code = R"cpp( #include "foo.h" - )cpp"); + )cpp"; // Foo is higher ranked because of exact name match. - EXPECT_THAT(getSymbols("foo"), + EXPECT_THAT(getSymbols(TU, "foo"), UnorderedElementsAre( AllOf(QName("foo"), WithKind(SymbolKind::Variable)), AllOf(QName("foo2"), WithKind(SymbolKind::Variable)))); - Limit = 1; - EXPECT_THAT(getSymbols("foo"), ElementsAre(QName("foo"))); + EXPECT_THAT(getSymbols(TU, "foo", 1), ElementsAre(QName("foo"))); } -TEST_F(WorkspaceSymbolsTest, TempSpecs) { - addFile("foo.h", R"cpp( +TEST(WorkspaceSymbols, TempSpecs) { + TestTU TU; + TU.ExtraArgs = {"-xc++"}; + TU.Code = R"cpp( template class Foo {}; template class Foo {}; template <> class Foo {}; template <> class Foo {}; - )cpp"); + )cpp"; // Foo is higher ranked because of exact name match. EXPECT_THAT( - getSymbols("Foo"), + getSymbols(TU, "Foo"), UnorderedElementsAre( AllOf(QName("Foo"), WithKind(SymbolKind::Class)), AllOf(QName("Foo"), WithKind(SymbolKind::Class)), @@ -304,31 +293,14 @@ TEST_F(WorkspaceSymbolsTest, TempSpecs) { AllOf(QName("Foo"), WithKind(SymbolKind::Class)))); } -namespace { -class DocumentSymbolsTest : public ::testing::Test { -public: - DocumentSymbolsTest() : Server(CDB, FS, optsForTests()) {} - -protected: - MockFS FS; - MockCompilationDatabase CDB; - ClangdServer Server; - - std::vector getSymbols(PathRef File) { - EXPECT_TRUE(Server.blockUntilIdleForTest()) << "Waiting for preamble"; - auto SymbolInfos = runDocumentSymbols(Server, File); - EXPECT_TRUE(bool(SymbolInfos)) << "documentSymbols returned an error"; - return *SymbolInfos; - } - - void addFile(llvm::StringRef FilePath, llvm::StringRef Contents) { - Server.addDocument(FilePath, Contents); - } -}; -} // namespace +std::vector getSymbols(ParsedAST AST) { + auto SymbolInfos = getDocumentSymbols(AST); + EXPECT_TRUE(bool(SymbolInfos)) << "documentSymbols returned an error"; + return *SymbolInfos; +} -TEST_F(DocumentSymbolsTest, BasicSymbols) { - std::string FilePath = testPath("foo.cpp"); +TEST(DocumentSymbols, BasicSymbols) { + TestTU TU; Annotations Main(R"( class Foo; class Foo { @@ -372,9 +344,9 @@ TEST_F(DocumentSymbolsTest, BasicSymbols) { } // namespace foo )"); - addFile(FilePath, Main.code()); + TU.Code = Main.code().str(); EXPECT_THAT( - getSymbols(FilePath), + getSymbols(TU.build()), ElementsAreArray( {AllOf(WithName("Foo"), WithKind(SymbolKind::Class), Children()), AllOf(WithName("Foo"), WithKind(SymbolKind::Class), @@ -416,8 +388,8 @@ TEST_F(DocumentSymbolsTest, BasicSymbols) { AllOf(WithName("v2"), WithKind(SymbolKind::Namespace))))})); } -TEST_F(DocumentSymbolsTest, DeclarationDefinition) { - std::string FilePath = testPath("foo.cpp"); +TEST(DocumentSymbols, DeclarationDefinition) { + TestTU TU; Annotations Main(R"( class Foo { void $decl[[f]](); @@ -426,9 +398,9 @@ TEST_F(DocumentSymbolsTest, DeclarationDefinition) { } )"); - addFile(FilePath, Main.code()); + TU.Code = Main.code().str(); EXPECT_THAT( - getSymbols(FilePath), + getSymbols(TU.build()), ElementsAre( AllOf(WithName("Foo"), WithKind(SymbolKind::Class), Children(AllOf(WithName("f"), WithKind(SymbolKind::Method), @@ -437,48 +409,45 @@ TEST_F(DocumentSymbolsTest, DeclarationDefinition) { SymNameRange(Main.range("def"))))); } -TEST_F(DocumentSymbolsTest, Concepts) { - CDB.ExtraClangFlags = {"-std=c++20"}; - std::string FilePath = testPath("foo.cpp"); - addFile(FilePath, - "template concept C = requires(T t) { t.foo(); };"); +TEST(DocumentSymbols, Concepts) { + TestTU TU; + TU.ExtraArgs = {"-std=c++20"}; + TU.Code = "template concept C = requires(T t) { t.foo(); };"; - EXPECT_THAT(getSymbols(FilePath), ElementsAre(WithName("C"))); + EXPECT_THAT(getSymbols(TU.build()), ElementsAre(WithName("C"))); } -TEST_F(DocumentSymbolsTest, ExternSymbol) { - std::string FilePath = testPath("foo.cpp"); - addFile(testPath("foo.h"), R"cpp( +TEST(DocumentSymbols, ExternSymbol) { + TestTU TU; + TU.AdditionalFiles["foo.h"] = R"cpp( extern int var; - )cpp"); - addFile(FilePath, R"cpp( + )cpp"; + TU.Code = R"cpp( #include "foo.h" - )cpp"); + )cpp"; - EXPECT_THAT(getSymbols(FilePath), IsEmpty()); + EXPECT_THAT(getSymbols(TU.build()), IsEmpty()); } -TEST_F(DocumentSymbolsTest, NoLocals) { - std::string FilePath = testPath("foo.cpp"); - addFile(FilePath, - R"cpp( +TEST(DocumentSymbols, NoLocals) { + TestTU TU; + TU.Code = R"cpp( void test(int FirstParam, int SecondParam) { struct LocalClass {}; int local_var; - })cpp"); - EXPECT_THAT(getSymbols(FilePath), ElementsAre(WithName("test"))); + })cpp"; + EXPECT_THAT(getSymbols(TU.build()), ElementsAre(WithName("test"))); } -TEST_F(DocumentSymbolsTest, Unnamed) { - std::string FilePath = testPath("foo.h"); - addFile(FilePath, - R"cpp( +TEST(DocumentSymbols, Unnamed) { + TestTU TU; + TU.Code = R"cpp( struct { int InUnnamed; } UnnamedStruct; - )cpp"); + )cpp"; EXPECT_THAT( - getSymbols(FilePath), + getSymbols(TU.build()), ElementsAre( AllOf(WithName("(anonymous struct)"), WithKind(SymbolKind::Struct), Children(AllOf(WithName("InUnnamed"), @@ -487,26 +456,23 @@ TEST_F(DocumentSymbolsTest, Unnamed) { Children()))); } -TEST_F(DocumentSymbolsTest, InHeaderFile) { - addFile(testPath("bar.h"), R"cpp( +TEST(DocumentSymbols, InHeaderFile) { + TestTU TU; + TU.AdditionalFiles["bar.h"] = R"cpp( int foo() { } - )cpp"); - std::string FilePath = testPath("foo.h"); - addFile(FilePath, R"cpp( + )cpp"; + TU.Code = R"cpp( #include "bar.h" int test() { } - )cpp"); - addFile(testPath("foo.cpp"), R"cpp( - #include "foo.h" - )cpp"); - EXPECT_THAT(getSymbols(FilePath), ElementsAre(WithName("test"))); + )cpp"; + EXPECT_THAT(getSymbols(TU.build()), ElementsAre(WithName("test"))); } -TEST_F(DocumentSymbolsTest, Template) { - std::string FilePath = testPath("foo.cpp"); - addFile(FilePath, R"( +TEST(DocumentSymbols, Template) { + TestTU TU; + TU.Code = R"( template struct Tmpl {T x = 0;}; template <> struct Tmpl { int y = 0; @@ -523,9 +489,9 @@ TEST_F(DocumentSymbolsTest, Template) { int varTmpl = T(); template <> double varTmpl = 10.0; - )"); + )"; EXPECT_THAT( - getSymbols(FilePath), + getSymbols(TU.build()), ElementsAre( AllOf(WithName("Tmpl"), WithKind(SymbolKind::Struct), Children(AllOf(WithName("x"), WithKind(SymbolKind::Field)))), @@ -541,9 +507,9 @@ TEST_F(DocumentSymbolsTest, Template) { AllOf(WithName("varTmpl"), Children()))); } -TEST_F(DocumentSymbolsTest, Namespaces) { - std::string FilePath = testPath("foo.cpp"); - addFile(FilePath, R"cpp( +TEST(DocumentSymbols, Namespaces) { + TestTU TU; + TU.Code = R"cpp( namespace ans1 { int ai1; namespace ans2 { @@ -565,9 +531,9 @@ TEST_F(DocumentSymbolsTest, Namespaces) { class Bar {}; } } - )cpp"); + )cpp"; EXPECT_THAT( - getSymbols(FilePath), + getSymbols(TU.build()), ElementsAreArray<::testing::Matcher>( {AllOf(WithName("ans1"), Children(AllOf(WithName("ai1"), Children()), @@ -579,9 +545,9 @@ TEST_F(DocumentSymbolsTest, Namespaces) { Children(AllOf(WithName("nb"), Children(WithName("Bar")))))})); } -TEST_F(DocumentSymbolsTest, Enums) { - std::string FilePath = testPath("foo.cpp"); - addFile(FilePath, R"( +TEST(DocumentSymbols, Enums) { + TestTU TU; + TU.Code = R"( enum { Red }; @@ -596,9 +562,9 @@ TEST_F(DocumentSymbolsTest, Enums) { Black }; } - )"); + )"; EXPECT_THAT( - getSymbols(FilePath), + getSymbols(TU.build()), ElementsAre( AllOf(WithName("(anonymous enum)"), Children(WithName("Red"))), AllOf(WithName("Color"), Children(WithName("Green"))), @@ -607,8 +573,8 @@ TEST_F(DocumentSymbolsTest, Enums) { Children(WithName("Black"))))))); } -TEST_F(DocumentSymbolsTest, FromMacro) { - std::string FilePath = testPath("foo.cpp"); +TEST(DocumentSymbols, FromMacro) { + TestTU TU; Annotations Main(R"( #define FF(name) \ class name##_Test {}; @@ -620,31 +586,31 @@ TEST_F(DocumentSymbolsTest, FromMacro) { FF2(); )"); - addFile(FilePath, Main.code()); + TU.Code = Main.code().str(); EXPECT_THAT( - getSymbols(FilePath), + getSymbols(TU.build()), ElementsAre( AllOf(WithName("abc_Test"), SymNameRange(Main.range("expansion"))), AllOf(WithName("Test"), SymNameRange(Main.range("spelling"))))); } -TEST_F(DocumentSymbolsTest, FuncTemplates) { - std::string FilePath = testPath("foo.cpp"); +TEST(DocumentSymbols, FuncTemplates) { + TestTU TU; Annotations Source(R"cpp( template T foo() {} auto x = foo(); - auto y = foo() + auto y = foo(); )cpp"); - addFile(FilePath, Source.code()); + TU.Code = Source.code().str(); // Make sure we only see the template declaration, not instantiations. - EXPECT_THAT(getSymbols(FilePath), + EXPECT_THAT(getSymbols(TU.build()), ElementsAre(WithName("foo"), WithName("x"), WithName("y"))); } -TEST_F(DocumentSymbolsTest, UsingDirectives) { - std::string FilePath = testPath("foo.cpp"); +TEST(DocumentSymbols, UsingDirectives) { + TestTU TU; Annotations Source(R"cpp( namespace ns { int foo; @@ -655,24 +621,24 @@ TEST_F(DocumentSymbolsTest, UsingDirectives) { using namespace ::ns; // check we don't loose qualifiers. using namespace ns_alias; // and namespace aliases. )cpp"); - addFile(FilePath, Source.code()); - EXPECT_THAT(getSymbols(FilePath), + TU.Code = Source.code().str(); + EXPECT_THAT(getSymbols(TU.build()), ElementsAre(WithName("ns"), WithName("ns_alias"), WithName("using namespace ::ns"), WithName("using namespace ns_alias"))); } -TEST_F(DocumentSymbolsTest, TempSpecs) { - std::string FilePath = testPath("foo.cpp"); - addFile(FilePath, R"cpp( +TEST(DocumentSymbols, TempSpecs) { + TestTU TU; + TU.Code = R"cpp( template class Foo {}; template class Foo {}; template <> class Foo {}; template <> class Foo {}; - )cpp"); + )cpp"; // Foo is higher ranked because of exact name match. EXPECT_THAT( - getSymbols(FilePath), + getSymbols(TU.build()), UnorderedElementsAre( AllOf(WithName("Foo"), WithKind(SymbolKind::Class)), AllOf(WithName("Foo"), WithKind(SymbolKind::Class)), @@ -680,9 +646,9 @@ TEST_F(DocumentSymbolsTest, TempSpecs) { AllOf(WithName("Foo"), WithKind(SymbolKind::Class)))); } -TEST_F(DocumentSymbolsTest, Qualifiers) { - std::string FilePath = testPath("foo.cpp"); - addFile(FilePath, R"cpp( +TEST(DocumentSymbols, Qualifiers) { + TestTU TU; + TU.Code = R"cpp( namespace foo { namespace bar { struct Cls; @@ -702,10 +668,10 @@ TEST_F(DocumentSymbolsTest, Qualifiers) { namespace alias = foo::bar; int ::alias::func4() { return 40; } - )cpp"); + )cpp"; // All the qualifiers should be preserved exactly as written. - EXPECT_THAT(getSymbols(FilePath), + EXPECT_THAT(getSymbols(TU.build()), UnorderedElementsAre( WithName("foo"), WithName("foo::bar::Cls"), WithName("foo::bar::func1"), WithName("::foo::bar::func2"), @@ -713,9 +679,9 @@ TEST_F(DocumentSymbolsTest, Qualifiers) { WithName("alias"), WithName("::alias::func4"))); } -TEST_F(DocumentSymbolsTest, QualifiersWithTemplateArgs) { - std::string FilePath = testPath("foo.cpp"); - addFile(FilePath, R"cpp( +TEST(DocumentSymbols, QualifiersWithTemplateArgs) { + TestTU TU; + TU.Code = R"cpp( template class Foo; template <> @@ -736,9 +702,9 @@ TEST_F(DocumentSymbolsTest, QualifiersWithTemplateArgs) { using Foo_type = Foo; // If the whole type is aliased, this should be preserved too! int Foo_type::method3() { return 30; } - )cpp"); + )cpp"; EXPECT_THAT( - getSymbols(FilePath), + getSymbols(TU.build()), UnorderedElementsAre(WithName("Foo"), WithName("Foo"), WithName("int_type"), WithName("Foo::method1"), @@ -746,5 +712,6 @@ TEST_F(DocumentSymbolsTest, QualifiersWithTemplateArgs) { WithName("Foo_type::method3"))); } +} // namespace } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp index dc818ea661938..19ab6d63947b7 100644 --- a/clang-tools-extra/clangd/unittests/HoverTests.cpp +++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp @@ -26,6 +26,8 @@ namespace clang { namespace clangd { namespace { +using PassMode = HoverInfo::PassType::PassMode; + TEST(Hover, Structured) { struct { const char *const Code; @@ -696,7 +698,125 @@ class Foo {})cpp"; HI.Parameters->back().Name = "v"; HI.AccessSpecifier = "public"; }}, - }; + {// Field type initializer. + R"cpp( + struct X { int x = 2; }; + X ^[[x]]; + )cpp", + [](HoverInfo &HI) { + HI.Name = "x"; + HI.Kind = index::SymbolKind::Variable; + HI.NamespaceScope = ""; + HI.Definition = "X x"; + HI.Type = "struct X"; + }}, + {// Don't crash on null types. + R"cpp(auto [^[[x]]] = 1; /*error-ok*/)cpp", + [](HoverInfo &HI) { + HI.Name = "x"; + HI.Kind = index::SymbolKind::Variable; + HI.NamespaceScope = ""; + HI.Definition = ""; + HI.Type = "NULL TYPE"; + // Bindings are in theory public members of an anonymous struct. + HI.AccessSpecifier = "public"; + }}, + {// Extra info for function call. + R"cpp( + void fun(int arg_a, int &arg_b) {}; + void code() { + int a = 1, b = 2; + fun(a, [[^b]]); + } + )cpp", + [](HoverInfo &HI) { + HI.Name = "b"; + HI.Kind = index::SymbolKind::Variable; + HI.NamespaceScope = ""; + HI.Definition = "int b = 2"; + HI.LocalScope = "code::"; + HI.Value = "2"; + HI.Type = "int"; + HI.CalleeArgInfo.emplace(); + HI.CalleeArgInfo->Name = "arg_b"; + HI.CalleeArgInfo->Type = "int &"; + HI.CallPassType.emplace(); + HI.CallPassType->PassBy = PassMode::Ref; + HI.CallPassType->Converted = false; + }}, + {// Extra info for method call. + R"cpp( + class C { + public: + void fun(int arg_a = 3, int arg_b = 4) {} + }; + void code() { + int a = 1, b = 2; + C c; + c.fun([[^a]], b); + } + )cpp", + [](HoverInfo &HI) { + HI.Name = "a"; + HI.Kind = index::SymbolKind::Variable; + HI.NamespaceScope = ""; + HI.Definition = "int a = 1"; + HI.LocalScope = "code::"; + HI.Value = "1"; + HI.Type = "int"; + HI.CalleeArgInfo.emplace(); + HI.CalleeArgInfo->Name = "arg_a"; + HI.CalleeArgInfo->Type = "int"; + HI.CalleeArgInfo->Default = "3"; + HI.CallPassType.emplace(); + HI.CallPassType->PassBy = PassMode::Value; + HI.CallPassType->Converted = false; + }}, + {// Dont crash on invalid decl + R"cpp( + // error-ok + struct Foo { + Bar [[x^x]]; + };)cpp", + [](HoverInfo &HI) { + HI.Name = "xx"; + HI.Kind = index::SymbolKind::Field; + HI.NamespaceScope = ""; + HI.Definition = "int xx"; + HI.LocalScope = "Foo::"; + HI.Type = "int"; + HI.AccessSpecifier = "public"; + }}, + {R"cpp( + // error-ok + struct Foo { + Bar xx; + int [[y^y]]; + };)cpp", + [](HoverInfo &HI) { + HI.Name = "yy"; + HI.Kind = index::SymbolKind::Field; + HI.NamespaceScope = ""; + HI.Definition = "int yy"; + HI.LocalScope = "Foo::"; + HI.Type = "int"; + HI.AccessSpecifier = "public"; + }}, + {// No crash on InitListExpr. + R"cpp( + struct Foo { + int a[10]; + }; + constexpr Foo k2 = { + ^[[{]]1} // FIXME: why the hover range is 1 character? + }; + )cpp", + [](HoverInfo &HI) { + HI.Name = "expression"; + HI.Kind = index::SymbolKind::Unknown; + HI.Type = "int [10]"; + HI.Value = "{1}"; + }}}; for (const auto &Case : Cases) { SCOPED_TRACE(Case.Code); @@ -729,6 +849,85 @@ class Foo {})cpp"; EXPECT_EQ(H->Size, Expected.Size); EXPECT_EQ(H->Offset, Expected.Offset); EXPECT_EQ(H->AccessSpecifier, Expected.AccessSpecifier); + EXPECT_EQ(H->CalleeArgInfo, Expected.CalleeArgInfo); + EXPECT_EQ(H->CallPassType, Expected.CallPassType); + } +} + +TEST(Hover, CallPassType) { + const llvm::StringRef CodePrefix = R"cpp( +class Base {}; +class Derived : public Base {}; +class CustomClass { + public: + CustomClass() {} + CustomClass(const Base &x) {} + CustomClass(int &x) {} + CustomClass(float x) {} +}; + +void int_by_ref(int &x) {} +void int_by_const_ref(const int &x) {} +void int_by_value(int x) {} +void base_by_ref(Base &x) {} +void base_by_const_ref(const Base &x) {} +void base_by_value(Base x) {} +void float_by_value(float x) {} +void custom_by_value(CustomClass x) {} + +void fun() { + int int_x; + int &int_ref = int_x; + const int &int_const_ref = int_x; + Base base; + const Base &base_const_ref = base; + Derived derived; + float float_x; +)cpp"; + const llvm::StringRef CodeSuffix = "}"; + + struct { + const char *const Code; + HoverInfo::PassType::PassMode PassBy; + bool Converted; + } Tests[] = { + // Integer tests + {"int_by_value([[^int_x]]);", PassMode::Value, false}, + {"int_by_ref([[^int_x]]);", PassMode::Ref, false}, + {"int_by_const_ref([[^int_x]]);", PassMode::ConstRef, false}, + {"int_by_value([[^int_ref]]);", PassMode::Value, false}, + {"int_by_const_ref([[^int_ref]]);", PassMode::ConstRef, false}, + {"int_by_const_ref([[^int_ref]]);", PassMode::ConstRef, false}, + {"int_by_const_ref([[^int_const_ref]]);", PassMode::ConstRef, false}, + // Custom class tests + {"base_by_ref([[^base]]);", PassMode::Ref, false}, + {"base_by_const_ref([[^base]]);", PassMode::ConstRef, false}, + {"base_by_const_ref([[^base_const_ref]]);", PassMode::ConstRef, false}, + {"base_by_value([[^base]]);", PassMode::Value, false}, + {"base_by_value([[^base_const_ref]]);", PassMode::Value, false}, + {"base_by_ref([[^derived]]);", PassMode::Ref, false}, + {"base_by_const_ref([[^derived]]);", PassMode::ConstRef, false}, + {"base_by_value([[^derived]]);", PassMode::Value, false}, + // Converted tests + {"float_by_value([[^int_x]]);", PassMode::Value, true}, + {"float_by_value([[^int_ref]]);", PassMode::Value, true}, + {"float_by_value([[^int_const_ref]]);", PassMode::Value, true}, + {"custom_by_value([[^int_x]]);", PassMode::Ref, true}, + {"custom_by_value([[^float_x]]);", PassMode::Value, true}, + {"custom_by_value([[^base]]);", PassMode::ConstRef, true}, + }; + for (const auto &Test : Tests) { + SCOPED_TRACE(Test.Code); + + const auto Code = (CodePrefix + Test.Code + CodeSuffix).str(); + Annotations T(Code); + TestTU TU = TestTU::withCode(T.code()); + TU.ExtraArgs.push_back("-std=c++17"); + auto AST = TU.build(); + auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr); + ASSERT_TRUE(H); + EXPECT_EQ(H->CallPassType->PassBy, Test.PassBy); + EXPECT_EQ(H->CallPassType->Converted, Test.Converted); } } @@ -978,13 +1177,14 @@ TEST(Hover, All) { HI.LocalScope = "Foo::"; HI.Type = "int"; HI.Definition = "int x"; - HI.Value = "{1}"; + // FIXME: Initializer for x is a DesignatedInitListExpr, hence it is + // of struct type and omitted. }}, { R"cpp(// Field, field designator - struct Foo { int x; }; + struct Foo { int x; int y; }; int main() { - Foo bar = { .^[[x]] = 2 }; + Foo bar = { .^[[x]] = 2, .y = 2 }; } )cpp", [](HoverInfo &HI) { @@ -994,7 +1194,6 @@ TEST(Hover, All) { HI.LocalScope = "Foo::"; HI.Type = "int"; HI.Definition = "int x"; - HI.Value = "{2}"; }}, { R"cpp(// Method call @@ -1592,7 +1791,6 @@ TEST(Hover, All) { HI.LocalScope = "test::"; HI.Type = "struct Test &&"; HI.Definition = "Test &&test = {}"; - HI.Value = "{}"; }}, { R"cpp(// auto on alias @@ -1651,7 +1849,6 @@ TEST(Hover, All) { HI.NamespaceScope = ""; HI.Name = "foo"; HI.Type = "cls>>"; - HI.Value = "{}"; }}, { R"cpp(// type of nested templates. @@ -2022,6 +2219,106 @@ protected: int method())", // In namespace ns1 private: union foo {})", + }, + { + [](HoverInfo &HI) { + HI.Kind = index::SymbolKind::Variable; + HI.Name = "foo"; + HI.Definition = "int foo = 3"; + HI.LocalScope = "test::Bar::"; + HI.Value = "3"; + HI.Type = "int"; + HI.CalleeArgInfo.emplace(); + HI.CalleeArgInfo->Name = "arg_a"; + HI.CalleeArgInfo->Type = "int"; + HI.CalleeArgInfo->Default = "7"; + HI.CallPassType.emplace(); + HI.CallPassType->PassBy = PassMode::Value; + HI.CallPassType->Converted = false; + }, + R"(variable foo + +Type: int +Value = 3 +Passed as arg_a + +// In test::Bar +int foo = 3)", + }, + { + [](HoverInfo &HI) { + HI.Kind = index::SymbolKind::Variable; + HI.Name = "foo"; + HI.Definition = "int foo = 3"; + HI.LocalScope = "test::Bar::"; + HI.Value = "3"; + HI.Type = "int"; + HI.CalleeArgInfo.emplace(); + HI.CalleeArgInfo->Name = "arg_a"; + HI.CalleeArgInfo->Type = "int"; + HI.CalleeArgInfo->Default = "7"; + HI.CallPassType.emplace(); + HI.CallPassType->PassBy = PassMode::Ref; + HI.CallPassType->Converted = false; + }, + R"(variable foo + +Type: int +Value = 3 +Passed by reference as arg_a + +// In test::Bar +int foo = 3)", + }, + { + [](HoverInfo &HI) { + HI.Kind = index::SymbolKind::Variable; + HI.Name = "foo"; + HI.Definition = "int foo = 3"; + HI.LocalScope = "test::Bar::"; + HI.Value = "3"; + HI.Type = "int"; + HI.CalleeArgInfo.emplace(); + HI.CalleeArgInfo->Name = "arg_a"; + HI.CalleeArgInfo->Type = "int"; + HI.CalleeArgInfo->Default = "7"; + HI.CallPassType.emplace(); + HI.CallPassType->PassBy = PassMode::Value; + HI.CallPassType->Converted = true; + }, + R"(variable foo + +Type: int +Value = 3 +Passed as arg_a (converted to int) + +// In test::Bar +int foo = 3)", + }, + { + [](HoverInfo &HI) { + HI.Kind = index::SymbolKind::Variable; + HI.Name = "foo"; + HI.Definition = "int foo = 3"; + HI.LocalScope = "test::Bar::"; + HI.Value = "3"; + HI.Type = "int"; + HI.CalleeArgInfo.emplace(); + HI.CalleeArgInfo->Name = "arg_a"; + HI.CalleeArgInfo->Type = "int"; + HI.CalleeArgInfo->Default = "7"; + HI.CallPassType.emplace(); + HI.CallPassType->PassBy = PassMode::ConstRef; + HI.CallPassType->Converted = true; + }, + R"(variable foo + +Type: int +Value = 3 +Passed by const reference as arg_a (converted to int) + +// In test::Bar +int foo = 3)", }}; for (const auto &C : Cases) { diff --git a/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp b/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp index 2f3fbc2a029ca..65d9cffeedc73 100644 --- a/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp +++ b/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include "../../clang-tidy/ClangTidyCheck.h" #include "../../clang-tidy/ClangTidyModule.h" #include "../../clang-tidy/ClangTidyModuleRegistry.h" #include "AST.h" diff --git a/clang-tools-extra/clangd/unittests/PreambleTests.cpp b/clang-tools-extra/clangd/unittests/PreambleTests.cpp index 5bbcb292610e4..8482a1cc8237c 100644 --- a/clang-tools-extra/clangd/unittests/PreambleTests.cpp +++ b/clang-tools-extra/clangd/unittests/PreambleTests.cpp @@ -125,7 +125,7 @@ TEST(PreamblePatchTest, IncludeParsing) { #/**/include )cpp", }; - for (const auto Case : Cases) { + for (const auto &Case : Cases) { Annotations Test(Case); const auto Code = Test.code(); SCOPED_TRACE(Code); @@ -230,8 +230,8 @@ std::string getPreamblePatch(llvm::StringRef Baseline, TEST(PreamblePatchTest, Define) { // BAR should be defined while parsing the AST. struct { - llvm::StringLiteral Contents; - llvm::StringLiteral ExpectedPatch; + const char *const Contents; + const char *const ExpectedPatch; } Cases[] = { { R"cpp( @@ -270,7 +270,7 @@ TEST(PreamblePatchTest, Define) { SCOPED_TRACE(Case.Contents); Annotations Modified(Case.Contents); EXPECT_THAT(getPreamblePatch("", Modified.code()), - MatchesRegex(Case.ExpectedPatch.str())); + MatchesRegex(Case.ExpectedPatch)); auto AST = createPatchedAST("", Modified.code()); ASSERT_TRUE(AST); @@ -304,8 +304,8 @@ TEST(PreamblePatchTest, OrderingPreserved) { TEST(PreamblePatchTest, LocateMacroAtWorks) { struct { - llvm::StringLiteral Baseline; - llvm::StringLiteral Modified; + const char *const Baseline; + const char *const Modified; } Cases[] = { // Addition of new directive { @@ -417,8 +417,8 @@ TEST(PreamblePatchTest, LocateMacroAtDeletion) { TEST(PreamblePatchTest, RefsToMacros) { struct { - llvm::StringLiteral Baseline; - llvm::StringLiteral Modified; + const char *const Baseline; + const char *const Modified; } Cases[] = { // Newly added { @@ -491,8 +491,8 @@ TEST(TranslatePreamblePatchLocation, Simple) { TEST(PreamblePatch, ModifiedBounds) { struct { - llvm::StringLiteral Baseline; - llvm::StringLiteral Modified; + const char *const Baseline; + const char *const Modified; } Cases[] = { // Size increased { diff --git a/clang-tools-extra/clangd/unittests/SyncAPI.cpp b/clang-tools-extra/clangd/unittests/SyncAPI.cpp index e976b5ab93894..36b028bd4d878 100644 --- a/clang-tools-extra/clangd/unittests/SyncAPI.cpp +++ b/clang-tools-extra/clangd/unittests/SyncAPI.cpp @@ -105,23 +105,16 @@ llvm::Expected runRename(ClangdServer &Server, PathRef File, return std::move(*Result); } -std::string runDumpAST(ClangdServer &Server, PathRef File) { - llvm::Optional Result; - Server.dumpAST(File, capture(Result)); +llvm::Expected +runFormatFile(ClangdServer &Server, PathRef File, StringRef Code) { + llvm::Optional> Result; + Server.formatFile(File, Code, capture(Result)); return std::move(*Result); } -llvm::Expected> -runWorkspaceSymbols(ClangdServer &Server, llvm::StringRef Query, int Limit) { - llvm::Optional>> Result; - Server.workspaceSymbols(Query, Limit, capture(Result)); - return std::move(*Result); -} - -llvm::Expected> -runDocumentSymbols(ClangdServer &Server, PathRef File) { - llvm::Optional>> Result; - Server.documentSymbols(File, capture(Result)); +std::string runDumpAST(ClangdServer &Server, PathRef File) { + llvm::Optional Result; + Server.dumpAST(File, capture(Result)); return std::move(*Result); } diff --git a/clang-tools-extra/clangd/unittests/SyncAPI.h b/clang-tools-extra/clangd/unittests/SyncAPI.h index 22b03c6f1fa5e..e16b9d8ff19b0 100644 --- a/clang-tools-extra/clangd/unittests/SyncAPI.h +++ b/clang-tools-extra/clangd/unittests/SyncAPI.h @@ -44,13 +44,10 @@ llvm::Expected runRename(ClangdServer &Server, PathRef File, Position Pos, StringRef NewName, const clangd::RenameOptions &RenameOpts); -std::string runDumpAST(ClangdServer &Server, PathRef File); - -llvm::Expected> -runWorkspaceSymbols(ClangdServer &Server, StringRef Query, int Limit); +llvm::Expected +runFormatFile(ClangdServer &Server, PathRef File, StringRef Code); -Expected> runDocumentSymbols(ClangdServer &Server, - PathRef File); +std::string runDumpAST(ClangdServer &Server, PathRef File); SymbolSlab runFuzzyFind(const SymbolIndex &Index, StringRef Query); SymbolSlab runFuzzyFind(const SymbolIndex &Index, const FuzzyFindRequest &Req); diff --git a/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp b/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp index 53a5979c73188..f40377fd5d85b 100644 --- a/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp +++ b/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp @@ -65,8 +65,20 @@ MATCHER_P2(TUState, PreambleActivity, ASTActivity, "") { return true; } +// Dummy ContextProvider to verify the provider is invoked & contexts are used. +static Key BoundPath; +Context bindPath(PathRef F) { + return Context::current().derive(BoundPath, F.str()); +} +llvm::StringRef boundPath() { + const std::string *V = Context::current().get(BoundPath); + return V ? *V : llvm::StringRef(""); +} + TUScheduler::Options optsForTest() { - return TUScheduler::Options(ClangdServer::optsForTest()); + TUScheduler::Options Opts(ClangdServer::optsForTest()); + Opts.ContextProvider = bindPath; + return Opts; } class TUSchedulerTests : public ::testing::Test { @@ -454,6 +466,7 @@ TEST_F(TUSchedulerTests, ManyUpdates) { [File, Nonce, Version(Inputs.Version), &Mut, &TotalUpdates, &LatestDiagVersion](std::vector) { EXPECT_THAT(Context::current().get(NonceKey), Pointee(Nonce)); + EXPECT_EQ(File, boundPath()); std::lock_guard Lock(Mut); ++TotalUpdates; @@ -474,6 +487,7 @@ TEST_F(TUSchedulerTests, ManyUpdates) { [File, Inputs, Nonce, &Mut, &TotalASTReads](Expected AST) { EXPECT_THAT(Context::current().get(NonceKey), Pointee(Nonce)); + EXPECT_EQ(File, boundPath()); ASSERT_TRUE((bool)AST); EXPECT_EQ(AST->Inputs.Contents, Inputs.Contents); @@ -493,6 +507,7 @@ TEST_F(TUSchedulerTests, ManyUpdates) { [File, Inputs, Nonce, &Mut, &TotalPreambleReads](Expected Preamble) { EXPECT_THAT(Context::current().get(NonceKey), Pointee(Nonce)); + EXPECT_EQ(File, boundPath()); ASSERT_TRUE((bool)Preamble); EXPECT_EQ(Preamble->Contents, Inputs.Contents); @@ -849,18 +864,22 @@ TEST_F(TUSchedulerTests, NoChangeDiags) { } TEST_F(TUSchedulerTests, Run) { - TUScheduler S(CDB, optsForTest()); + auto Opts = optsForTest(); + Opts.ContextProvider = bindPath; + TUScheduler S(CDB, Opts); std::atomic Counter(0); - S.run("add 1", [&] { ++Counter; }); - S.run("add 2", [&] { Counter += 2; }); + S.run("add 1", /*Path=*/"", [&] { ++Counter; }); + S.run("add 2", /*Path=*/"", [&] { Counter += 2; }); ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10))); EXPECT_EQ(Counter.load(), 3); Notification TaskRun; Key TestKey; WithContextValue CtxWithKey(TestKey, 10); - S.run("props context", [&] { + const char *Path = "somepath"; + S.run("props context", Path, [&] { EXPECT_EQ(Context::current().getExisting(TestKey), 10); + EXPECT_EQ(Path, boundPath()); TaskRun.notify(); }); TaskRun.wait(); diff --git a/clang-tools-extra/clangd/unittests/TestFS.cpp b/clang-tools-extra/clangd/unittests/TestFS.cpp index c436e9a7a9510..3b2fbc142a28f 100644 --- a/clang-tools-extra/clangd/unittests/TestFS.cpp +++ b/clang-tools-extra/clangd/unittests/TestFS.cpp @@ -79,13 +79,13 @@ const char *testRoot() { #endif } -std::string testPath(PathRef File) { +std::string testPath(PathRef File, llvm::sys::path::Style Style) { assert(llvm::sys::path::is_relative(File) && "FileName should be relative"); llvm::SmallString<32> NativeFile = File; - llvm::sys::path::native(NativeFile); + llvm::sys::path::native(NativeFile, Style); llvm::SmallString<32> Path; - llvm::sys::path::append(Path, testRoot(), NativeFile); + llvm::sys::path::append(Path, Style, testRoot(), NativeFile); return std::string(Path.str()); } diff --git a/clang-tools-extra/clangd/unittests/TestFS.h b/clang-tools-extra/clangd/unittests/TestFS.h index a487a361bfe1c..7972fe37c7fed 100644 --- a/clang-tools-extra/clangd/unittests/TestFS.h +++ b/clang-tools-extra/clangd/unittests/TestFS.h @@ -33,8 +33,7 @@ buildTestFS(llvm::StringMap const &Files, // A VFS provider that returns TestFSes containing a provided set of files. class MockFS : public ThreadsafeFS { public: - IntrusiveRefCntPtr - view(llvm::NoneType) const override { + IntrusiveRefCntPtr viewImpl() const override { return buildTestFS(Files, Timestamps); } @@ -70,7 +69,8 @@ class MockCompilationDatabase : public GlobalCompilationDatabase { const char *testRoot(); // Returns a suitable absolute path for this OS. -std::string testPath(PathRef File); +std::string testPath(PathRef File, + llvm::sys::path::Style = llvm::sys::path::Style::native); // unittest: is a scheme that refers to files relative to testRoot() // This anchor is used to force the linker to link in the generated object file diff --git a/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp b/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp index 8e68cfbdbeeea..a14ff13150d37 100644 --- a/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp +++ b/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp @@ -7,85 +7,286 @@ //===----------------------------------------------------------------------===// #include "../TestTU.h" +#include "TestFS.h" +#include "index/Index.h" +#include "index/Ref.h" #include "index/Serialization.h" +#include "index/Symbol.h" +#include "index/SymbolID.h" #include "index/remote/marshalling/Marshalling.h" +#include "clang/Index/IndexSymbol.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Path.h" #include "llvm/Support/StringSaver.h" +#include "gmock/gmock.h" #include "gtest/gtest.h" +#include namespace clang { namespace clangd { namespace remote { namespace { +using llvm::sys::path::convert_to_slash; + +const char *testPathURI(llvm::StringRef Path, + llvm::UniqueStringSaver &Strings) { + auto URI = URI::createFile(testPath(Path)); + return Strings.save(URI.toString()).begin(); +} + +TEST(RemoteMarshallingTest, URITranslation) { + llvm::BumpPtrAllocator Arena; + llvm::UniqueStringSaver Strings(Arena); + clangd::Ref Original; + Original.Location.FileURI = + testPathURI("remote/machine/projects/llvm-project/clang-tools-extra/" + "clangd/unittests/remote/MarshallingTests.cpp", + Strings); + auto Serialized = + toProtobuf(Original, testPath("remote/machine/projects/llvm-project/")); + EXPECT_EQ(Serialized.location().file_path(), + "clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp"); + const std::string LocalIndexPrefix = testPath("local/machine/project/"); + auto Deserialized = fromProtobuf(Serialized, &Strings, + testPath("home/my-projects/llvm-project/")); + EXPECT_TRUE(Deserialized); + EXPECT_EQ(Deserialized->Location.FileURI, + testPathURI("home/my-projects/llvm-project/clang-tools-extra/" + "clangd/unittests/remote/MarshallingTests.cpp", + Strings)); + + clangd::Ref WithInvalidURI; + // Invalid URI results in empty path. + WithInvalidURI.Location.FileURI = "This is not a URI"; + Serialized = toProtobuf(WithInvalidURI, testPath("home/")); + EXPECT_EQ(Serialized.location().file_path(), ""); + + // Can not use URIs with scheme different from "file". + auto UnittestURI = + URI::create(testPath("project/lib/HelloWorld.cpp"), "unittest"); + EXPECT_TRUE(bool(UnittestURI)); + WithInvalidURI.Location.FileURI = + Strings.save(UnittestURI->toString()).begin(); + Serialized = toProtobuf(WithInvalidURI, testPath("project/lib/")); + EXPECT_EQ(Serialized.location().file_path(), ""); + + Ref WithAbsolutePath; + *WithAbsolutePath.mutable_location()->mutable_file_path() = + "/usr/local/user/home/HelloWorld.cpp"; + Deserialized = fromProtobuf(WithAbsolutePath, &Strings, LocalIndexPrefix); + // Paths transmitted over the wire can not be absolute, they have to be + // relative. + EXPECT_FALSE(Deserialized); +} + TEST(RemoteMarshallingTest, SymbolSerialization) { - const auto *Header = R"( - // This is a class. - class Foo { - public: - Foo(); - - int Bar; - private: - double Number; - }; - /// This is a function. - char baz(); - template - T getT (); - )"; - const auto TU = TestTU::withHeaderCode(Header); - const auto Symbols = TU.headerSymbols(); - // Sanity check: there are more than 5 symbols available. - EXPECT_GE(Symbols.size(), 5UL); + clangd::Symbol Sym; + + auto ID = SymbolID::fromStr("057557CEBF6E6B2D"); + EXPECT_TRUE(bool(ID)); + Sym.ID = *ID; + + index::SymbolInfo Info; + Info.Kind = index::SymbolKind::Function; + Info.SubKind = index::SymbolSubKind::AccessorGetter; + Info.Lang = index::SymbolLanguage::CXX; + Info.Properties = static_cast( + index::SymbolProperty::TemplateSpecialization); + Sym.SymInfo = Info; + llvm::BumpPtrAllocator Arena; llvm::UniqueStringSaver Strings(Arena); - for (auto &Sym : Symbols) { - const auto ProtobufMeessage = toProtobuf(Sym); - const auto SymToProtobufAndBack = fromProtobuf(ProtobufMeessage, &Strings); - EXPECT_TRUE(SymToProtobufAndBack.hasValue()); - EXPECT_EQ(toYAML(Sym), toYAML(*SymToProtobufAndBack)); - } + + Sym.Name = Strings.save("Foo"); + Sym.Scope = Strings.save("llvm::foo::bar::"); + + clangd::SymbolLocation Location; + Location.Start.setLine(1); + Location.Start.setColumn(15); + Location.End.setLine(3); + Location.End.setColumn(121); + Location.FileURI = testPathURI("home/Definition.cpp", Strings); + Sym.Definition = Location; + + Location.Start.setLine(42); + Location.Start.setColumn(31); + Location.End.setLine(20); + Location.End.setColumn(400); + Location.FileURI = testPathURI("home/Declaration.h", Strings); + Sym.CanonicalDeclaration = Location; + + Sym.References = 9000; + Sym.Origin = clangd::SymbolOrigin::Static; + Sym.Signature = Strings.save("(int X, char Y, Type T)"); + Sym.TemplateSpecializationArgs = Strings.save(""); + Sym.CompletionSnippetSuffix = + Strings.save("({1: int X}, {2: char Y}, {3: Type T})"); + Sym.Documentation = Strings.save("This is my amazing Foo constructor!"); + Sym.ReturnType = Strings.save("Foo"); + + Sym.Flags = clangd::Symbol::SymbolFlag::IndexedForCodeCompletion; + + // Check that symbols are exactly the same if the path to indexed project is + // the same on indexing machine and the client. + auto Serialized = toProtobuf(Sym, testPath("home/")); + auto Deserialized = fromProtobuf(Serialized, &Strings, testPath("home/")); + EXPECT_TRUE(Deserialized); + EXPECT_EQ(toYAML(Sym), toYAML(*Deserialized)); + // Serialized paths are relative and have UNIX slashes. + EXPECT_EQ(convert_to_slash(Serialized.definition().file_path(), + llvm::sys::path::Style::posix), + Serialized.definition().file_path()); + EXPECT_TRUE( + llvm::sys::path::is_relative(Serialized.definition().file_path())); + + // Fail with an invalid URI. + Location.FileURI = "Not A URI"; + Sym.Definition = Location; + Serialized = toProtobuf(Sym, testPath("home/")); + Deserialized = fromProtobuf(Serialized, &Strings, testPath("home/")); + EXPECT_FALSE(Deserialized); + + // Schemes other than "file" can not be used. + auto UnittestURI = URI::create(testPath("home/SomePath.h"), "unittest"); + EXPECT_TRUE(bool(UnittestURI)); + Location.FileURI = Strings.save(UnittestURI->toString()).begin(); + Sym.Definition = Location; + Serialized = toProtobuf(Sym, testPath("home/")); + Deserialized = fromProtobuf(Serialized, &Strings, testPath("home/")); + EXPECT_FALSE(Deserialized); + + // Passing root that is not prefix of the original file path. + Location.FileURI = testPathURI("home/File.h", Strings); + Sym.Definition = Location; + // Check that the symbol is valid and passing the correct path works. + Serialized = toProtobuf(Sym, testPath("home/")); + Deserialized = fromProtobuf(Serialized, &Strings, testPath("home/")); + EXPECT_TRUE(Deserialized); + EXPECT_EQ(Deserialized->Definition.FileURI, + testPathURI("home/File.h", Strings)); + // Fail with a wrong root. + Serialized = toProtobuf(Sym, testPath("nothome/")); + Deserialized = fromProtobuf(Serialized, &Strings, testPath("home/")); + EXPECT_FALSE(Deserialized); } -TEST(RemoteMarshallingTest, ReferenceSerialization) { - TestTU TU; - TU.HeaderCode = R"( - int foo(); - int GlobalVariable = 42; - class Foo { - public: - Foo(); - - char Symbol = 'S'; - }; - template - T getT() { return T(); } - )"; - TU.Code = R"( - int foo() { - ++GlobalVariable; - - Foo foo = Foo(); - if (foo.Symbol - 'a' == 42) { - foo.Symbol = 'b'; - } - - const auto bar = getT(); - } - )"; - const auto References = TU.headerRefs(); +TEST(RemoteMarshallingTest, RefSerialization) { + clangd::Ref Ref; + Ref.Kind = clangd::RefKind::Spelled | clangd::RefKind::Declaration; + llvm::BumpPtrAllocator Arena; llvm::UniqueStringSaver Strings(Arena); - // Sanity check: there are more than 5 references available. - EXPECT_GE(References.numRefs(), 5UL); - for (const auto &SymbolWithRefs : References) { - for (const auto &Ref : SymbolWithRefs.second) { - const auto RefToProtobufAndBack = fromProtobuf(toProtobuf(Ref), &Strings); - EXPECT_TRUE(RefToProtobufAndBack.hasValue()); - EXPECT_EQ(toYAML(Ref), toYAML(*RefToProtobufAndBack)); - } - } -} // namespace + + clangd::SymbolLocation Location; + Location.Start.setLine(124); + Location.Start.setColumn(21); + Location.End.setLine(3213); + Location.End.setColumn(541); + Location.FileURI = testPathURI( + "llvm-project/llvm/clang-tools-extra/clangd/Protocol.h", Strings); + Ref.Location = Location; + + auto Serialized = toProtobuf(Ref, testPath("llvm-project/")); + auto Deserialized = + fromProtobuf(Serialized, &Strings, testPath("llvm-project/")); + EXPECT_TRUE(Deserialized); + EXPECT_EQ(toYAML(Ref), toYAML(*Deserialized)); +} + +TEST(RemoteMarshallingTest, IncludeHeaderURIs) { + llvm::BumpPtrAllocator Arena; + llvm::UniqueStringSaver Strings(Arena); + + llvm::SmallVector + ValidHeaders; + clangd::Symbol::IncludeHeaderWithReferences Header; + Header.IncludeHeader = Strings.save( + URI::createFile("/usr/local/user/home/project/Header.h").toString()); + Header.References = 21; + ValidHeaders.push_back(Header); + Header.IncludeHeader = Strings.save(""); + Header.References = 100; + ValidHeaders.push_back(Header); + Header.IncludeHeader = Strings.save("\"cstdio\""); + Header.References = 200; + ValidHeaders.push_back(Header); + + llvm::SmallVector + InvalidHeaders; + // This is an absolute path to a header: can not be transmitted over the wire. + Header.IncludeHeader = Strings.save(testPath("project/include/Common.h")); + Header.References = 42; + InvalidHeaders.push_back(Header); + // This is not a valid header: can not be transmitted over the wire; + Header.IncludeHeader = Strings.save("NotAHeader"); + Header.References = 5; + InvalidHeaders.push_back(Header); + + clangd::Symbol Sym; + // Fill in definition and declaration, Symbool will be invalid otherwise. + clangd::SymbolLocation Location; + Location.Start.setLine(1); + Location.Start.setColumn(2); + Location.End.setLine(3); + Location.End.setColumn(4); + Location.FileURI = testPathURI("File.h", Strings); + Sym.Definition = Location; + Sym.CanonicalDeclaration = Location; + + // Try to serialize all headers but only valid ones will end up in Protobuf + // message. + auto AllHeaders = ValidHeaders; + AllHeaders.insert(AllHeaders.end(), InvalidHeaders.begin(), + InvalidHeaders.end()); + Sym.IncludeHeaders = AllHeaders; + + auto Serialized = toProtobuf(Sym, convert_to_slash("/")); + EXPECT_EQ(static_cast(Serialized.headers_size()), + ValidHeaders.size()); + auto Deserialized = fromProtobuf(Serialized, &Strings, convert_to_slash("/")); + EXPECT_TRUE(Deserialized); + + Sym.IncludeHeaders = ValidHeaders; + EXPECT_EQ(toYAML(Sym), toYAML(*Deserialized)); +} + +TEST(RemoteMarshallingTest, FuzzyFindRequestSerialization) { + clangd::FuzzyFindRequest Request; + Request.ProximityPaths = {testPath("remote/Header.h"), + testPath("remote/subdir/OtherHeader.h"), + testPath("notremote/File.h"), "Not a Path."}; + auto Serialized = toProtobuf(Request, testPath("remote/")); + EXPECT_EQ(Serialized.proximity_paths_size(), 2); + auto Deserialized = fromProtobuf(&Serialized, testPath("home/")); + EXPECT_THAT(Deserialized.ProximityPaths, + testing::ElementsAre(testPath("home/Header.h"), + testPath("home/subdir/OtherHeader.h"))); +} + +TEST(RemoteMarshallingTest, RelativePathToURITranslation) { + EXPECT_TRUE(relativePathToURI("lib/File.cpp", testPath("home/project/"))); + // RelativePath can not be absolute. + EXPECT_FALSE(relativePathToURI("/lib/File.cpp", testPath("home/project/"))); + // IndexRoot has to be absolute path. + EXPECT_FALSE(relativePathToURI("lib/File.cpp", "home/project/")); +} + +TEST(RemoteMarshallingTest, URIToRelativePathTranslation) { + llvm::BumpPtrAllocator Arena; + llvm::UniqueStringSaver Strings(Arena); + EXPECT_TRUE( + uriToRelativePath(testPathURI("home/project/lib/File.cpp", Strings), + testPath("home/project/"))); + // IndexRoot has to be absolute path. + EXPECT_FALSE(uriToRelativePath( + testPathURI("home/project/lib/File.cpp", Strings), "home/project/")); + // IndexRoot has to be be a prefix of the file path. + EXPECT_FALSE( + uriToRelativePath(testPathURI("home/project/lib/File.cpp", Strings), + testPath("home/other/project/"))); +} } // namespace } // namespace remote diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index bd898de446b9d..c08fd45c2f967 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -94,6 +94,12 @@ New checks result of a memory allocation function (``malloc()``, ``calloc()``, ``realloc()``, ``alloca()``) instead of its argument. +- New :doc:`bugprone-no-escape + ` check. + + Finds pointers with the ``noescape`` attribute that are captured by an + asynchronously-executed block. + - New :doc:`bugprone-spuriously-wake-up-functions ` check. @@ -192,13 +198,28 @@ New check aliases :doc:`bugprone-signed-char-misuse ` was added. +- New alias :doc:`llvm-else-after-return + ` to + :doc:`readability-else-after-return + ` was added. + Changes in existing checks ^^^^^^^^^^^^^^^^^^^^^^^^^^ -- Improved :doc:'readability-identifier-naming +- Improved :doc:`performance-faster-string-find + ` check. + + Now checks ``std::basic_string_view`` by default. + +- Improved :doc:`readability-else-after-return + ` check now supports a + `WarnOnConditionVariables` option to control whether to refactor condition + variables where possible. + +- Improved :doc:`readability-identifier-naming ` check. - Now able to rename member references in class template definitions with + Now able to rename member references in class template definitions with explicit access. - Improved :doc:`readability-qualified-auto diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone-no-escape.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone-no-escape.rst new file mode 100644 index 0000000000000..770a71cc04255 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone-no-escape.rst @@ -0,0 +1,19 @@ +.. title:: clang-tidy - bugprone-no-escape + +bugprone-no-escape +================== + +Finds pointers with the ``noescape`` attribute that are captured by an +asynchronously-executed block. The block arguments in ``dispatch_async()`` and +``dispatch_after()`` are guaranteed to escape, so it is an error if a pointer with the +``noescape`` attribute is captured by one of these blocks. + +The following is an example of an invalid use of the ``noescape`` attribute. + + .. code-block:: objc + + void foo(__attribute__((noescape)) int *p) { + dispatch_async(queue, ^{ + *p = 123; + }); + }); diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index 17331605aa64e..78fed1a8ed9cd 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -70,6 +70,7 @@ Clang-Tidy Checks `bugprone-misplaced-widening-cast `_, `bugprone-move-forwarding-reference `_, "Yes" `bugprone-multiple-statement-macro `_, + `bugprone-no-escape `_, "Yes" `bugprone-not-null-terminated-result `_, "Yes" `bugprone-parent-virtual-call `_, "Yes" `bugprone-posix-return `_, "Yes" @@ -133,6 +134,7 @@ Clang-Tidy Checks `clang-analyzer-valist.Uninitialized `_, `clang-analyzer-valist.Unterminated `_, `cppcoreguidelines-avoid-goto `_, + `cppcoreguidelines-avoid-non-const-global-variables `_, `cppcoreguidelines-init-variables `_, "Yes" `cppcoreguidelines-interfaces-global-init `_, `cppcoreguidelines-macro-usage `_, @@ -189,7 +191,7 @@ Clang-Tidy Checks `llvm-prefer-isa-or-dyn-cast-in-conditionals `_, "Yes" `llvm-prefer-register-over-unsigned `_, "Yes" `llvm-twine-local `_, "Yes" - `llvmlibc-callee-namespace `_, + `llvmlibc-callee-namespace `_, `llvmlibc-implementation-in-namespace `_, `llvmlibc-restrict-system-libc-headers `_, "Yes" `misc-definitions-in-headers `_, "Yes" @@ -291,7 +293,7 @@ Clang-Tidy Checks `readability-redundant-member-init `_, "Yes" `readability-redundant-preprocessor `_, `readability-redundant-smartptr-get `_, "Yes" - `readability-redundant-string-cstr `_, + `readability-redundant-string-cstr `_, "Yes" `readability-redundant-string-init `_, "Yes" `readability-simplify-boolean-expr `_, "Yes" `readability-simplify-subscript-expr `_, "Yes" @@ -300,7 +302,7 @@ Clang-Tidy Checks `readability-string-compare `_, "Yes" `readability-uniqueptr-delete-release `_, "Yes" `readability-uppercase-literal-suffix `_, "Yes" - `readability-use-anyofallof`_, "No" + `readability-use-anyofallof `_, `zircon-temporary-objects `_, @@ -390,7 +392,6 @@ Clang-Tidy Checks `clang-analyzer-unix.cstring.NullArg `_, `Clang Static Analyzer `_, `cppcoreguidelines-avoid-c-arrays `_, `modernize-avoid-c-arrays `_, `cppcoreguidelines-avoid-magic-numbers `_, `readability-magic-numbers `_, - `cppcoreguidelines-avoid-non-const-global-variables `_, , , "" `cppcoreguidelines-c-copy-assignment-signature `_, `misc-unconventional-assign-operator `_, `cppcoreguidelines-explicit-virtual-functions `_, `modernize-use-override `_, "Yes" `cppcoreguidelines-non-private-member-variables-in-classes `_, `misc-non-private-member-variables-in-classes `_, @@ -410,7 +411,7 @@ Clang-Tidy Checks `hicpp-new-delete-operators `_, `misc-new-delete-overloads `_, `hicpp-no-array-decay `_, `cppcoreguidelines-pro-bounds-array-to-pointer-decay `_, `hicpp-no-malloc `_, `cppcoreguidelines-no-malloc `_, - `hicpp-noexcept-move `_, `performance-noexcept-move-constructor `_, + `hicpp-noexcept-move `_, `performance-noexcept-move-constructor `_, "Yes" `hicpp-special-member-functions `_, `cppcoreguidelines-special-member-functions `_, `hicpp-static-assert `_, `misc-static-assert `_, "Yes" `hicpp-undelegated-constructor `_, `bugprone-undelegated-constructor `_, @@ -423,5 +424,5 @@ Clang-Tidy Checks `hicpp-use-nullptr `_, `modernize-use-nullptr `_, "Yes" `hicpp-use-override `_, `modernize-use-override `_, "Yes" `hicpp-vararg `_, `cppcoreguidelines-pro-type-vararg `_, + `llvm-else-after-return `_, `readability-else-after-return `_, "Yes" `llvm-qualified-auto `_, `readability-qualified-auto `_, "Yes" - diff --git a/clang-tools-extra/docs/clang-tidy/checks/llvm-else-after-return.rst b/clang-tools-extra/docs/clang-tidy/checks/llvm-else-after-return.rst new file mode 100644 index 0000000000000..f9af610fe50db --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/llvm-else-after-return.rst @@ -0,0 +1,11 @@ +.. title:: clang-tidy - llvm-else-after-return +.. meta:: + :http-equiv=refresh: 5;URL=readability-else-after-return.html + +llvm-else-after-return +====================== + +The llvm-else-after-return check is an alias, please see +`readability-else-after-return `_ +for more information. + diff --git a/clang-tools-extra/docs/clang-tidy/checks/openmp-use-default-none.rst b/clang-tools-extra/docs/clang-tidy/checks/openmp-use-default-none.rst index 4223a10bd6e9b..77114100ba1cb 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/openmp-use-default-none.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/openmp-use-default-none.rst @@ -51,3 +51,12 @@ Example // WARNING: OpenMP directive ``parallel`` specifies ``default(shared)`` // clause. Consider using ``default(none)`` clause instead. } + + // ``parallel`` directive can have ``default`` clause, and said clause is + // specified, but with ``firstprivate`` kind, which is not ``none``, diagnose. + void p0_3() { + #pragma omp parallel default(firstprivate) + ; + // WARNING: OpenMP directive ``parallel`` specifies ``default(firstprivate)`` + // clause. Consider using ``default(none)`` clause instead. + } diff --git a/clang-tools-extra/docs/clang-tidy/checks/performance-faster-string-find.rst b/clang-tools-extra/docs/clang-tidy/checks/performance-faster-string-find.rst index 8d7265e68beed..443da597506a7 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/performance-faster-string-find.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/performance-faster-string-find.rst @@ -23,6 +23,8 @@ Options .. option:: StringLikeClasses Semicolon-separated list of names of string-like classes. By default only - ``std::basic_string`` is considered. The list of methods to consired is - fixed. + ``::std::basic_string`` and ``::std::basic_string_view`` are considered. + The check will only consider member functions named ``find``, ``rfind``, + ``find_first_of``, ``find_first_not_of``, ``find_last_of``, or + ``find_last_not_of`` within these classes. diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability-else-after-return.rst b/clang-tools-extra/docs/clang-tidy/checks/readability-else-after-return.rst index c178a6a68ec90..4adcd7bbfa26c 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/readability-else-after-return.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/readability-else-after-return.rst @@ -59,6 +59,31 @@ Would be transformed into: } } +Options +------- + +.. option:: WarnOnUnfixable + + When `true`, emit a warning for cases where the check can't output a + Fix-It. These can occur with declarations inside the ``else`` branch that + would have an extended lifetime if the ``else`` branch was removed. + Default value is `true`. + +.. option:: WarnOnConditionVariables + + When `true`, the check will attempt to refactor a variable defined inside + the condition of the ``if`` statement that is used in the ``else`` branch + defining them just before the ``if`` statement. This can only be done if + the ``if`` statement is the last statement in its parents scope. + Default value is `true`. + + +LLVM alias +---------- + +There is an alias of this check called llvm-else-after-return. +In that version the options :option:`WarnOnUnfixable` and +:option:`WarnOnConditionVariables` are both set to `false` by default. This check helps to enforce this `LLVM Coding Standards recommendation `_. diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone-no-escape.m b/clang-tools-extra/test/clang-tidy/checkers/bugprone-no-escape.m new file mode 100644 index 0000000000000..11dba3345fa1a --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone-no-escape.m @@ -0,0 +1,28 @@ +// RUN: %check_clang_tidy %s bugprone-no-escape %t +// RUN: %check_clang_tidy %s -assume-filename=bugprone-no-escape.c bugprone-no-escape %t -- -- -fblocks + +typedef struct dispatch_queue_s *dispatch_queue_t; +typedef struct dispatch_time_s *dispatch_time_t; +typedef void (^dispatch_block_t)(void); +void dispatch_async(dispatch_queue_t queue, dispatch_block_t block); +void dispatch_after(dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block); + +extern dispatch_queue_t queue; + +void test_noescape_attribute(__attribute__((noescape)) int *p, int *q) { + dispatch_async(queue, ^{ + *p = 123; + // CHECK-MESSAGES: :[[@LINE-2]]:25: warning: pointer 'p' with attribute 'noescape' is captured by an asynchronously-executed block [bugprone-no-escape] + // CHECK-MESSAGES: :[[@LINE-4]]:30: note: the 'noescape' attribute is declared here. + }); + + dispatch_after(456, queue, ^{ + *p = 789; + // CHECK-MESSAGES: :[[@LINE-2]]:30: warning: pointer 'p' with attribute 'noescape' is captured by an asynchronously-executed block [bugprone-no-escape] + }); + + dispatch_async(queue, ^{ + *q = 0; + // CHECK-MESSAGES-NOT: :[[@LINE-2]]:25: warning: pointer 'q' with attribute 'noescape' is captured by an asynchronously-executed block + }); +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone-suspicious-memset-usage.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone-suspicious-memset-usage.cpp index f33ae5ae10a84..9a7e423f40122 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone-suspicious-memset-usage.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone-suspicious-memset-usage.cpp @@ -75,3 +75,8 @@ void foo(int xsize, int ysize) { // despite v == 0. memset(p, -1, v); } + +void *memset(int); +void NoCrash() { + memset(1); +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone-unused-raii-crash.mm b/clang-tools-extra/test/clang-tidy/checkers/bugprone-unused-raii-crash.mm new file mode 100644 index 0000000000000..432fd5329c566 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone-unused-raii-crash.mm @@ -0,0 +1,15 @@ +// RUN: clang-tidy %s -checks=-*,bugprone-unused-raii -- | count 0 + +struct CxxClass { + ~CxxClass() {} +}; + +@interface ObjcClass { +} +- (CxxClass)set:(int)p; +@end + +void test(ObjcClass *s) { + [s set:1]; // ok, no crash, no diagnostic emitted. + return; +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-init-variables.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-init-variables.cpp index 4c92e1976f917..9a06850b3f669 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-init-variables.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-init-variables.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy %s cppcoreguidelines-init-variables %t -- -- -fno-delayed-template-parsing +// RUN: %check_clang_tidy %s cppcoreguidelines-init-variables %t -- -- -fno-delayed-template-parsing -fexceptions // Ensure that function declarations are not changed. void some_func(int x, double d, bool b, const char *p); @@ -84,3 +84,10 @@ void f(RANGE r) { for (char c : r) { } } + +void catch_variable_decl() { + // Expect no warning given here. + try { + } catch (int X) { + } +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/llvm-twine-local.cpp b/clang-tools-extra/test/clang-tidy/checkers/llvm-twine-local.cpp index 06eb7613d439d..3dcf6abe0c22e 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/llvm-twine-local.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/llvm-twine-local.cpp @@ -13,6 +13,7 @@ class Twine { using namespace llvm; void foo(const Twine &x); +void bar(Twine x); static Twine Moo = Twine("bark") + "bah"; // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: twine variables are prone to use-after-free bugs diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize-avoid-bind-permissive-parameter-list.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize-avoid-bind-permissive-parameter-list.cpp index 6c81a6e9ab97d..e055fd3232306 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize-avoid-bind-permissive-parameter-list.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize-avoid-bind-permissive-parameter-list.cpp @@ -54,5 +54,5 @@ void testLiteralParameters() { auto BBB = std::bind(add, _1, 2); // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind [modernize-avoid-bind] - // CHECK-FIXES: auto BBB = [](auto && PH1, auto && ...) { return add(PH1, 2); }; + // CHECK-FIXES: auto BBB = [](auto && PH1, auto && ...) { return add(std::forward(PH1), 2); }; } diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize-avoid-bind.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize-avoid-bind.cpp index 7e00858c1acce..3334eab2d407e 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize-avoid-bind.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize-avoid-bind.cpp @@ -7,11 +7,11 @@ class bind_rt {}; template bind_rt bind(Fp &&, Arguments &&...); -} +} // namespace impl template T ref(T &t); -} +} // namespace std namespace boost { template @@ -58,12 +58,33 @@ struct F { void UseF(F); +struct G { + G() : _member(0) {} + G(int m) : _member(m) {} + + template + void operator()(T) const {} + + int _member; +}; + +template +struct H { + void operator()(T) const {}; +}; + struct placeholder {}; placeholder _1; placeholder _2; +namespace placeholders { +using ::_1; +using ::_2; +} // namespace placeholders + int add(int x, int y) { return x + y; } int addThree(int x, int y, int z) { return x + y + z; } +void sub(int &x, int y) { x += y; } // Let's fake a minimal std::function-like facility. namespace std { @@ -107,6 +128,7 @@ struct TestCaptureByValueStruct { int MemberVariable; static int StaticMemberVariable; F MemberStruct; + G MemberStructWithData; void testCaptureByValue(int Param, F f) { int x = 3; @@ -145,6 +167,11 @@ struct TestCaptureByValueStruct { auto GGG = boost::bind(UseF, MemberStruct); // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to boost::bind [modernize-avoid-bind] // CHECK-FIXES: auto GGG = [this] { return UseF(MemberStruct); }; + + auto HHH = std::bind(add, MemberStructWithData._member, 1); + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind + // Correctly distinguish data members of other classes + // CHECK-FIXES: auto HHH = [capture0 = MemberStructWithData._member] { return add(capture0, 1); }; } }; @@ -217,17 +244,38 @@ void testFunctionObjects() { auto EEE = std::bind(*D::create(), 1, 2); // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind // CHECK-FIXES: auto EEE = [Func = *D::create()] { return Func(1, 2); }; + + auto FFF = std::bind(G(), 1); + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind + // Templated function call operators may be used + // CHECK-FIXES: auto FFF = [] { return G()(1); }; + + int CTorArg = 42; + auto GGG = std::bind(G(CTorArg), 1); + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind + // Function objects with constructor arguments should be captured + // CHECK-FIXES: auto GGG = [Func = G(CTorArg)] { return Func(1); }; } +template +void testMemberFnOfClassTemplate(T) { + auto HHH = std::bind(H(), 42); + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind + // Ensure function class template arguments are preserved + // CHECK-FIXES: auto HHH = [] { return H()(42); }; +} + +template void testMemberFnOfClassTemplate(int); + void testPlaceholders() { int x = 2; auto AAA = std::bind(add, x, _1); // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind - // CHECK-FIXES: auto AAA = [x](auto && PH1) { return add(x, PH1); }; + // CHECK-FIXES: auto AAA = [x](auto && PH1) { return add(x, std::forward(PH1)); }; auto BBB = std::bind(add, _2, _1); // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind - // CHECK-FIXES: auto BBB = [](auto && PH1, auto && PH2) { return add(PH2, PH1); }; + // CHECK-FIXES: auto BBB = [](auto && PH1, auto && PH2) { return add(std::forward(PH2), std::forward(PH1)); }; // No fix is applied for reused placeholders. auto CCC = std::bind(add, _1, _1); @@ -238,7 +286,12 @@ void testPlaceholders() { // unnamed parameters. auto DDD = std::bind(add, _2, 1); // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind - // CHECK-FIXES: auto DDD = [](auto &&, auto && PH2) { return add(PH2, 1); }; + // CHECK-FIXES: auto DDD = [](auto &&, auto && PH2) { return add(std::forward(PH2), 1); }; + + // Namespace-qualified placeholders are valid too + auto EEE = std::bind(add, placeholders::_2, 1); + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind + // CHECK-FIXES: auto EEE = [](auto &&, auto && PH2) { return add(std::forward(PH2), 1); }; } void testGlobalFunctions() { @@ -267,6 +320,7 @@ void testGlobalFunctions() { void testCapturedSubexpressions() { int x = 3; int y = 3; + int *p = &x; auto AAA = std::bind(add, 1, add(2, 5)); // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind @@ -277,6 +331,11 @@ void testCapturedSubexpressions() { // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind // Results of nested calls are captured by value. // CHECK-FIXES: auto BBB = [x, capture0 = add(y, 5)] { return add(x, capture0); }; + + auto CCC = std::bind(sub, std::ref(*p), _1); + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind + // Expressions returning references are captured + // CHECK-FIXES: auto CCC = [&capture0 = *p](auto && PH1) { return sub(capture0, std::forward(PH1)); }; } struct E { diff --git a/clang-tools-extra/test/clang-tidy/checkers/openmp-use-default-none.cpp b/clang-tools-extra/test/clang-tidy/checkers/openmp-use-default-none.cpp index 35d2d17b1e0e8..d1d3b0e441f3f 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/openmp-use-default-none.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/openmp-use-default-none.cpp @@ -1,5 +1,5 @@ -// RUN: %check_clang_tidy %s openmp-use-default-none %t -- -- -fopenmp=libomp -fopenmp-version=40 -// RUN: %check_clang_tidy -std=c11 %s openmp-use-default-none %t -- -- -x c -fopenmp=libomp -fopenmp-version=40 +// RUN: %check_clang_tidy %s openmp-use-default-none %t -- -- -fopenmp=libomp -fopenmp-version=51 +// RUN: %check_clang_tidy -std=c11 %s openmp-use-default-none %t -- -- -x c -fopenmp=libomp -fopenmp-version=51 //----------------------------------------------------------------------------// // Null cases. @@ -42,6 +42,15 @@ void p0_2() { // CHECK-NOTES: :[[@LINE-3]]:22: note: existing 'default' clause specified here } +// 'parallel' directive can have 'default' clause, and said clause specified, +// but with 'firstprivate' kind, which is not 'none', diagnose. +void p0_3() { +#pragma omp parallel default(firstprivate) + ; + // CHECK-NOTES: :[[@LINE-2]]:1: warning: OpenMP directive 'parallel' specifies 'default(firstprivate)' clause, consider using 'default(none)' clause instead + // CHECK-NOTES: :[[@LINE-3]]:22: note: existing 'default' clause specified here +} + // 'task' directive. // 'task' directive can have 'default' clause, but said clause is not @@ -68,6 +77,15 @@ void p1_2() { // CHECK-NOTES: :[[@LINE-3]]:18: note: existing 'default' clause specified here } +// 'task' directive can have 'default' clause, and said clause specified, +// but with 'firstprivate' kind, which is not 'none', diagnose. +void p1_3() { +#pragma omp task default(firstprivate) + ; + // CHECK-NOTES: :[[@LINE-2]]:1: warning: OpenMP directive 'task' specifies 'default(firstprivate)' clause, consider using 'default(none)' clause instead + // CHECK-NOTES: :[[@LINE-3]]:18: note: existing 'default' clause specified here +} + // 'teams' directive. (has to be inside of 'target' directive) // 'teams' directive can have 'default' clause, but said clause is not @@ -97,6 +115,16 @@ void p2_2() { // CHECK-NOTES: :[[@LINE-3]]:19: note: existing 'default' clause specified here } +// 'teams' directive can have 'default' clause, and said clause specified, +// but with 'firstprivate' kind, which is not 'none', diagnose. +void p2_3() { +#pragma omp target +#pragma omp teams default(firstprivate) + ; + // CHECK-NOTES: :[[@LINE-2]]:1: warning: OpenMP directive 'teams' specifies 'default(firstprivate)' clause, consider using 'default(none)' clause instead + // CHECK-NOTES: :[[@LINE-3]]:19: note: existing 'default' clause specified here +} + // 'taskloop' directive. // 'taskloop' directive can have 'default' clause, but said clause is not @@ -126,6 +154,16 @@ void p3_2(const int a) { // CHECK-NOTES: :[[@LINE-4]]:22: note: existing 'default' clause specified here } +// 'taskloop' directive can have 'default' clause, and said clause specified, +// but with 'firstprivate' kind, which is not 'none', diagnose. +void p3_3(const int a) { +#pragma omp taskloop default(firstprivate) + for (int b = 0; b < a; b++) + ; + // CHECK-NOTES: :[[@LINE-3]]:1: warning: OpenMP directive 'taskloop' specifies 'default(firstprivate)' clause, consider using 'default(none)' clause instead + // CHECK-NOTES: :[[@LINE-4]]:22: note: existing 'default' clause specified here +} + //----------------------------------------------------------------------------// // Combined directives. // Let's not test every single possible permutation/combination of directives, @@ -158,3 +196,13 @@ void p4_2(const int a) { // CHECK-NOTES: :[[@LINE-3]]:1: warning: OpenMP directive 'parallel for' specifies 'default(shared)' clause, consider using 'default(none)' clause instead // CHECK-NOTES: :[[@LINE-4]]:26: note: existing 'default' clause specified here } + +// 'parallel' directive can have 'default' clause, and said clause specified, +// but with 'firstprivate' kind, which is not 'none', diagnose. +void p4_3(const int a) { +#pragma omp parallel for default(firstprivate) + for (int b = 0; b < a; b++) + ; + // CHECK-NOTES: :[[@LINE-3]]:1: warning: OpenMP directive 'parallel for' specifies 'default(firstprivate)' clause, consider using 'default(none)' clause instead + // CHECK-NOTES: :[[@LINE-4]]:26: note: existing 'default' clause specified here +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance-faster-string-find.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance-faster-string-find.cpp index b36e32301f5db..d26cd2c8ca30c 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/performance-faster-string-find.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/performance-faster-string-find.cpp @@ -1,7 +1,8 @@ -// RUN: %check_clang_tidy %s performance-faster-string-find %t -- \ +// RUN: %check_clang_tidy %s performance-faster-string-find %t +// RUN: %check_clang_tidy -check-suffix=CUSTOM %s performance-faster-string-find %t -- \ // RUN: -config="{CheckOptions: \ // RUN: [{key: performance-faster-string-find.StringLikeClasses, \ -// RUN: value: 'std::basic_string; ::llvm::StringRef;'}]}" -- +// RUN: value: '::llvm::StringRef;'}]}" namespace std { template @@ -17,6 +18,20 @@ struct basic_string { typedef basic_string string; typedef basic_string wstring; + +template +struct basic_string_view { + int find(const Char *, int = 0) const; + int find(const Char *, int, int) const; + int rfind(const Char *) const; + int find_first_of(const Char *) const; + int find_first_not_of(const Char *) const; + int find_last_of(const Char *) const; + int find_last_not_of(const Char *) const; +}; + +typedef basic_string_view string_view; +typedef basic_string_view wstring_view; } // namespace std namespace llvm { @@ -75,11 +90,25 @@ void StringFind() { // CHECK-MESSAGES: [[@LINE-1]]:13: warning: 'find' called with a string literal // CHECK-FIXES: Str.find(L'\x3A9'); + // std::string_view and std::wstring_view should work. + std::string_view StrView; + StrView.find("n"); + // CHECK-MESSAGES: [[@LINE-1]]:16: warning: 'find' called with a string literal + // CHECK-FIXES: StrView.find('n'); + std::wstring_view WStrView; + + WStrView.find(L"n"); + // CHECK-MESSAGES: [[@LINE-1]]:17: warning: 'find' called with a string literal + // CHECK-FIXES: WStrView.find(L'n'); + WStrView.find(L"\x3A9"); + // CHECK-MESSAGES: [[@LINE-1]]:17: warning: 'find' called with a string literal + // CHECK-FIXES: WStrView.find(L'\x3A9'); + // Also with other types, but only if it was specified in the options. llvm::StringRef sr; sr.find("x"); - // CHECK-MESSAGES: [[@LINE-1]]:11: warning: 'find' called with a string literal - // CHECK-FIXES: sr.find('x'); + // CHECK-MESSAGES-CUSTOM: [[@LINE-1]]:11: warning: 'find' called with a string literal + // CHECK-FIXES-CUSTOM: sr.find('x'); NotStringRef nsr; nsr.find("x"); } diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability-else-after-return-no-cond-var-refactor.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability-else-after-return-no-cond-var-refactor.cpp new file mode 100644 index 0000000000000..0d43240f1c6a6 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/readability-else-after-return-no-cond-var-refactor.cpp @@ -0,0 +1,42 @@ +// RUN: %check_clang_tidy %s readability-else-after-return %t -- \ +// RUN: -config='{CheckOptions: [ \ +// RUN: {key: readability-else-after-return.WarnOnConditionVariables, value: false}, \ +// RUN: ]}' + +bool foo(int Y) { + // Excess scopes are here so that the check would have to opportunity to + // refactor the variable out of the condition. + + // Expect warnings here as we don't need to move declaration of 'X' out of the + // if condition as its not used in the else. + { + if (int X = Y) + return X < 0; + else + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use 'else' after 'return' + return false; + } + { + if (int X = Y; X) + return X < 0; + else + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use 'else' after 'return' + return false; + } + + // Expect no warnings for these cases, as even though its safe to move + // declaration of 'X' out of the if condition, that has been disabled + // by the options. + { + if (int X = Y) + return false; + else + return X < 0; + } + { + if (int X = Y; X) + return false; + else + return X < 0; + } +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming.cpp index 3a3bfecc01fcc..24c1c4270dec8 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming.cpp @@ -562,3 +562,19 @@ void ReferenceBadNamedFunction() { } } // namespace redecls + +namespace scratchspace { +#define DUP(Tok) Tok +#define M1(Tok) DUP(badName##Tok()) + +// We don't want a warning here as the call to this in Foo is in a scratch +// buffer so its fix-it wouldn't be applied, resulting in invalid code. +void badNameWarn(); + +void Foo() { + M1(Warn); +} + +#undef M1 +#undef DUP +} // namespace scratchspace diff --git a/clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp b/clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp index a089281bf16c4..63f9a06e91bec 100644 --- a/clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp +++ b/clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp @@ -6,6 +6,20 @@ namespace clang { namespace tidy { + +enum class Colours { Red, Orange, Yellow, Green, Blue, Indigo, Violet }; + +template <> struct OptionEnumMapping { + static llvm::ArrayRef> getEnumMapping() { + static constexpr std::pair Mapping[] = { + {Colours::Red, "Red"}, {Colours::Orange, "Orange"}, + {Colours::Yellow, "Yellow"}, {Colours::Green, "Green"}, + {Colours::Blue, "Blue"}, {Colours::Indigo, "Indigo"}, + {Colours::Violet, "Violet"}}; + return makeArrayRef(Mapping); + } +}; + namespace test { TEST(ParseLineFilter, EmptyFilter) { @@ -208,16 +222,10 @@ TEST(CheckOptionsValidation, ValidIntOptions) { #undef CHECK_ERROR_INT } +// FIXME: Figure out why this test causes crashes on mac os. +#ifndef __APPLE__ TEST(ValidConfiguration, ValidEnumOptions) { - enum class Colours { Red, Orange, Yellow, Green, Blue, Indigo, Violet }; - static constexpr std::pair Mapping[] = { - {"Red", Colours::Red}, {"Orange", Colours::Orange}, - {"Yellow", Colours::Yellow}, {"Green", Colours::Green}, - {"Blue", Colours::Blue}, {"Indigo", Colours::Indigo}, - {"Violet", Colours::Violet}}; - static const auto Map = makeArrayRef(Mapping); - ClangTidyOptions Options; auto &CheckOptions = Options.CheckOptions; @@ -237,34 +245,37 @@ TEST(ValidConfiguration, ValidEnumOptions) { #define CHECK_ERROR_ENUM(Name, Expected) \ CHECK_ERROR(Name, UnparseableEnumOptionError, Expected) - CHECK_VAL(TestCheck.getLocal("Valid", Map), Colours::Red); - CHECK_VAL(TestCheck.getGlobal("GlobalValid", Map), Colours::Violet); - CHECK_VAL(TestCheck.getLocal("ValidWrongCase", Map, /*IgnoreCase*/ true), - Colours::Red); + CHECK_VAL(TestCheck.getIntLocal("Valid"), Colours::Red); + CHECK_VAL(TestCheck.getIntGlobal("GlobalValid"), Colours::Violet); + CHECK_VAL( - TestCheck.getGlobal("GlobalValidWrongCase", Map, /*IgnoreCase*/ true), - Colours::Violet); - CHECK_ERROR_ENUM(TestCheck.getLocal("Invalid", Map), + TestCheck.getIntLocal("ValidWrongCase", /*IgnoreCase*/ true), + Colours::Red); + CHECK_VAL(TestCheck.getIntGlobal("GlobalValidWrongCase", + /*IgnoreCase*/ true), + Colours::Violet); + CHECK_ERROR_ENUM(TestCheck.getIntLocal("Invalid"), "invalid configuration value " "'Scarlet' for option 'test.Invalid'"); - CHECK_ERROR_ENUM(TestCheck.getLocal("ValidWrongCase", Map), + CHECK_ERROR_ENUM(TestCheck.getIntLocal("ValidWrongCase"), "invalid configuration value 'rED' for option " "'test.ValidWrongCase'; did you mean 'Red'?"); - CHECK_ERROR_ENUM(TestCheck.getLocal("NearMiss", Map), + CHECK_ERROR_ENUM(TestCheck.getIntLocal("NearMiss"), "invalid configuration value 'Oragne' for option " "'test.NearMiss'; did you mean 'Orange'?"); - CHECK_ERROR_ENUM(TestCheck.getGlobal("GlobalInvalid", Map), + CHECK_ERROR_ENUM(TestCheck.getIntGlobal("GlobalInvalid"), "invalid configuration value " "'Purple' for option 'GlobalInvalid'"); - CHECK_ERROR_ENUM(TestCheck.getGlobal("GlobalValidWrongCase", Map), + CHECK_ERROR_ENUM(TestCheck.getIntGlobal("GlobalValidWrongCase"), "invalid configuration value 'vIOLET' for option " "'GlobalValidWrongCase'; did you mean 'Violet'?"); - CHECK_ERROR_ENUM(TestCheck.getGlobal("GlobalNearMiss", Map), + CHECK_ERROR_ENUM(TestCheck.getIntGlobal("GlobalNearMiss"), "invalid configuration value 'Yelow' for option " "'GlobalNearMiss'; did you mean 'Yellow'?"); #undef CHECK_ERROR_ENUM } +#endif #undef CHECK_VAL #undef CHECK_ERROR diff --git a/clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h b/clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h index fee2d94a4d572..b8ee9972f6f86 100644 --- a/clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h +++ b/clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h @@ -10,6 +10,7 @@ #define LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANG_TIDY_CLANGTIDYTEST_H #include "ClangTidy.h" +#include "ClangTidyCheck.h" #include "ClangTidyDiagnosticConsumer.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Frontend/CompilerInstance.h" @@ -18,7 +19,6 @@ #include "clang/Tooling/Core/Replacement.h" #include "clang/Tooling/Refactoring.h" #include "clang/Tooling/Tooling.h" -#include "llvm/ADT/Optional.h" #include "llvm/Support/Path.h" #include #include @@ -66,7 +66,9 @@ class TestClangTidyAction : public ASTFrontendAction { // that check constructors can access the context (for example, through // `getLangOpts()`). CheckFactory::createChecks(&Context, Checks); + assert(!Checks.empty() && "No checks created"); for (auto &Check : Checks) { + assert(Check.get() && "Checks can't be null"); if (!Check->isLanguageVersionSupported(Context.getLangOpts())) continue; Check->registerMatchers(&Finder); @@ -88,6 +90,7 @@ runCheckOnCode(StringRef Code, std::vector *Errors = nullptr, const ClangTidyOptions &ExtraOptions = ClangTidyOptions(), std::map PathsToContent = std::map()) { + static_assert(sizeof...(CheckTypes) > 0, "No checks specified"); ClangTidyOptions Options = ExtraOptions; Options.Checks = "*"; ClangTidyContext Context(std::make_unique( @@ -119,7 +122,7 @@ runCheckOnCode(StringRef Code, std::vector *Errors = nullptr, llvm::IntrusiveRefCntPtr Files( new FileManager(FileSystemOptions(), InMemoryFileSystem)); - SmallVector, 1> Checks; + SmallVector, sizeof...(CheckTypes)> Checks; tooling::ToolInvocation Invocation( Args, std::make_unique>(Checks, Finder, diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt index 5a5e34aacbebb..7f8e0718c2ebc 100644 --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -9,6 +9,10 @@ endif() if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR ) project(Clang) + set(CMAKE_CXX_STANDARD 14 CACHE STRING "C++ standard to conform to") + set(CMAKE_CXX_STANDARD_REQUIRED YES) + set(CMAKE_CXX_EXTENSIONS NO) + # Rely on llvm-config. set(CONFIG_OUTPUT) if(LLVM_CONFIG) @@ -517,7 +521,10 @@ add_subdirectory(include) # All targets below may depend on all tablegen'd files. get_property(CLANG_TABLEGEN_TARGETS GLOBAL PROPERTY CLANG_TABLEGEN_TARGETS) -add_custom_target(clang-tablegen-targets DEPENDS ${CLANG_TABLEGEN_TARGETS}) +add_custom_target(clang-tablegen-targets + DEPENDS + omp_gen + ${CLANG_TABLEGEN_TARGETS}) set_target_properties(clang-tablegen-targets PROPERTIES FOLDER "Misc") list(APPEND LLVM_COMMON_DEPENDS clang-tablegen-targets) diff --git a/clang/cmake/caches/Fuchsia-stage2.cmake b/clang/cmake/caches/Fuchsia-stage2.cmake index 4ef404b8aaef0..259684ff2b0d9 100644 --- a/clang/cmake/caches/Fuchsia-stage2.cmake +++ b/clang/cmake/caches/Fuchsia-stage2.cmake @@ -4,6 +4,9 @@ set(LLVM_TARGETS_TO_BUILD X86;ARM;AArch64;RISCV CACHE STRING "") set(PACKAGE_VENDOR Fuchsia CACHE STRING "") +set(LLVM_ENABLE_PROJECTS "clang;clang-tools-extra;lld;llvm" CACHE STRING "") +set(LLVM_ENABLE_RUNTIMES "compiler-rt;libcxx;libcxxabi;libunwind" CACHE STRING "") + set(LLVM_ENABLE_BACKTRACES OFF CACHE BOOL "") if(NOT APPLE) set(LLVM_ENABLE_LLD ON CACHE BOOL "") @@ -19,6 +22,10 @@ set(LLVM_INCLUDE_GO_TESTS OFF CACHE BOOL "") set(LLVM_USE_RELATIVE_PATHS_IN_FILES ON CACHE BOOL "") set(LLVM_ENABLE_Z3_SOLVER OFF CACHE BOOL "") +if(MSVC) + set(LLVM_USE_CRT_RELEASE "MT" CACHE STRING "") +endif() + set(CLANG_DEFAULT_CXX_STDLIB libc++ CACHE STRING "") if(NOT APPLE) set(CLANG_DEFAULT_LINKER lld CACHE STRING "") @@ -36,6 +43,8 @@ set(ENABLE_X86_RELAX_RELOCATIONS ON CACHE BOOL "") set(CMAKE_BUILD_TYPE Release CACHE STRING "") if (APPLE) set(MACOSX_DEPLOYMENT_TARGET 10.7 CACHE STRING "") +elseif(MSVC) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded" CACHE STRING "") endif() if(APPLE) @@ -44,6 +53,7 @@ if(APPLE) set(COMPILER_RT_ENABLE_TVOS OFF CACHE BOOL "") set(COMPILER_RT_ENABLE_WATCHOS OFF CACHE BOOL "") + set(COMPILER_RT_USE_BUILTINS_LIBRARY ON CACHE BOOL "") set(LIBUNWIND_ENABLE_SHARED OFF CACHE BOOL "") set(LIBUNWIND_INSTALL_LIBRARY OFF CACHE BOOL "") @@ -63,12 +73,34 @@ if(APPLE) set(SANITIZER_MIN_OSX_VERSION 10.7 CACHE STRING "") endif() +if(WIN32) + set(target "x86_64-pc-windows-msvc") + + list(APPEND BUILTIN_TARGETS "${target}") + set(BUILTINS_${target}_CMAKE_SYSTEM_NAME Windows CACHE STRING "") + set(BUILTINS_${target}_CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "") + + list(APPEND RUNTIME_TARGETS "${target}") + set(RUNTIMES_${target}_CMAKE_SYSTEM_NAME Windows CACHE STRING "") + set(RUNTIMES_${target}_CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "") + set(RUNTIMES_${target}_LIBCXX_ABI_VERSION 2 CACHE STRING "") + set(RUNTIMES_${target}_LIBCXX_HAS_WIN32_THREAD_API ON CACHE BOOL "") + set(RUNTIMES_${target}_LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY OFF CACHE BOOL "") + set(RUNTIMES_${target}_LIBCXX_ENABLE_FILESYSTEM OFF CACHE BOOL "") + set(RUNTIMES_${target}_LIBCXX_ENABLE_ABI_LINKER_SCRIPT OFF CACHE BOOL "") + set(RUNTIMES_${target}_LIBCXX_ENABLE_SHARED OFF CACHE BOOL "") + set(RUNTIMES_${target}_LLVM_ENABLE_RUNTIMES "compiler-rt;libcxx" CACHE STRING "") +endif() + foreach(target aarch64-unknown-linux-gnu;armv7-unknown-linux-gnueabihf;i386-unknown-linux-gnu;x86_64-unknown-linux-gnu) if(LINUX_${target}_SYSROOT) # Set the per-target builtins options. list(APPEND BUILTIN_TARGETS "${target}") set(BUILTINS_${target}_CMAKE_SYSTEM_NAME Linux CACHE STRING "") set(BUILTINS_${target}_CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "") + set(BUILTINS_${target}_CMAKE_C_FLAGS "--target=${target}" CACHE STRING "") + set(BUILTINS_${target}_CMAKE_CXX_FLAGS "--target=${target}" CACHE STRING "") + set(BUILTINS_${target}_CMAKE_ASM_FLAGS "--target=${target}" CACHE STRING "") set(BUILTINS_${target}_CMAKE_SYSROOT ${LINUX_${target}_SYSROOT} CACHE STRING "") set(BUILTINS_${target}_CMAKE_SHARED_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "") set(BUILTINS_${target}_CMAKE_MODULE_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "") @@ -78,11 +110,14 @@ foreach(target aarch64-unknown-linux-gnu;armv7-unknown-linux-gnueabihf;i386-unkn list(APPEND RUNTIME_TARGETS "${target}") set(RUNTIMES_${target}_CMAKE_SYSTEM_NAME Linux CACHE STRING "") set(RUNTIMES_${target}_CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "") + set(RUNTIMES_${target}_CMAKE_C_FLAGS "--target=${target}" CACHE STRING "") + set(RUNTIMES_${target}_CMAKE_CXX_FLAGS "--target=${target}" CACHE STRING "") + set(RUNTIMES_${target}_CMAKE_ASM_FLAGS "--target=${target}" CACHE STRING "") set(RUNTIMES_${target}_CMAKE_SYSROOT ${LINUX_${target}_SYSROOT} CACHE STRING "") set(RUNTIMES_${target}_CMAKE_SHARED_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "") set(RUNTIMES_${target}_CMAKE_MODULE_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "") set(RUNTIMES_${target}_CMAKE_EXE_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "") - set(RUNTIMES_${target}_LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "") + set(RUNTIMES_${target}_COMPILER_RT_USE_BUILTINS_LIBRARY ON CACHE BOOL "") set(RUNTIMES_${target}_LIBUNWIND_ENABLE_SHARED OFF CACHE BOOL "") set(RUNTIMES_${target}_LIBUNWIND_USE_COMPILER_RT ON CACHE BOOL "") set(RUNTIMES_${target}_LIBUNWIND_INSTALL_LIBRARY OFF CACHE BOOL "") @@ -95,9 +130,10 @@ foreach(target aarch64-unknown-linux-gnu;armv7-unknown-linux-gnueabihf;i386-unkn set(RUNTIMES_${target}_LIBCXX_ENABLE_SHARED OFF CACHE BOOL "") set(RUNTIMES_${target}_LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "") set(RUNTIMES_${target}_LIBCXX_ABI_VERSION 2 CACHE STRING "") + set(RUNTIMES_${target}_LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "") set(RUNTIMES_${target}_SANITIZER_CXX_ABI "libc++" CACHE STRING "") set(RUNTIMES_${target}_SANITIZER_CXX_ABI_INTREE ON CACHE BOOL "") - set(RUNTIMES_${target}_COMPILER_RT_USE_BUILTINS_LIBRARY ON CACHE BOOL "") + set(RUNTIMES_${target}_LLVM_ENABLE_RUNTIMES "compiler-rt;libcxx;libcxxabi;libunwind" CACHE STRING "") # Use .build-id link. list(APPEND RUNTIME_BUILD_ID_LINK "${target}") @@ -110,7 +146,7 @@ if(FUCHSIA_SDK) set(FUCHSIA_x86_64_NAME x64) set(FUCHSIA_riscv64_NAME riscv64) foreach(target i386;x86_64;aarch64;riscv64) - set(FUCHSIA_${target}_COMPILER_FLAGS "-I${FUCHSIA_SDK}/pkg/fdio/include") + set(FUCHSIA_${target}_COMPILER_FLAGS "--target=${target}-unknown-fuchsia -I${FUCHSIA_SDK}/pkg/fdio/include") set(FUCHSIA_${target}_LINKER_FLAGS "-L${FUCHSIA_SDK}/arch/${FUCHSIA_${target}_NAME}/lib") set(FUCHSIA_${target}_SYSROOT "${FUCHSIA_SDK}/arch/${FUCHSIA_${target}_NAME}/sysroot") endforeach() @@ -142,7 +178,7 @@ if(FUCHSIA_SDK) set(RUNTIMES_${target}-unknown-fuchsia_CMAKE_MODULE_LINKER_FLAGS ${FUCHSIA_${target}_LINKER_FLAGS} CACHE STRING "") set(RUNTIMES_${target}-unknown-fuchsia_CMAKE_EXE_LINKER_FLAGS ${FUCHSIA_${target}_LINKER_FLAGS} CACHE STRING "") set(RUNTIMES_${target}-unknown-fuchsia_CMAKE_SYSROOT ${FUCHSIA_${target}_SYSROOT} CACHE PATH "") - set(RUNTIMES_${target}-unknown-fuchsia_LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "") + set(RUNTIMES_${target}-unknown-fuchsia_COMPILER_RT_USE_BUILTINS_LIBRARY ON CACHE BOOL "") set(RUNTIMES_${target}-unknown-fuchsia_LIBUNWIND_USE_COMPILER_RT ON CACHE BOOL "") set(RUNTIMES_${target}-unknown-fuchsia_LIBUNWIND_HERMETIC_STATIC_LIBRARY ON CACHE BOOL "") set(RUNTIMES_${target}-unknown-fuchsia_LIBUNWIND_INSTALL_STATIC_LIBRARY OFF CACHE BOOL "") @@ -157,6 +193,8 @@ if(FUCHSIA_SDK) set(RUNTIMES_${target}-unknown-fuchsia_LIBCXX_HERMETIC_STATIC_LIBRARY ON CACHE BOOL "") set(RUNTIMES_${target}-unknown-fuchsia_LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY OFF CACHE BOOL "") set(RUNTIMES_${target}-unknown-fuchsia_LIBCXX_ABI_VERSION 2 CACHE STRING "") + set(RUNTIMES_${target}-unknown-fuchsia_LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "") + set(RUNTIMES_${target}-unknown-fuchsia_LLVM_ENABLE_RUNTIMES "compiler-rt;libcxx;libcxxabi;libunwind" CACHE STRING "") set(RUNTIMES_${target}-unknown-fuchsia+asan_LLVM_BUILD_COMPILER_RT OFF CACHE BOOL "") set(RUNTIMES_${target}-unknown-fuchsia+asan_LLVM_USE_SANITIZER "Address" CACHE STRING "") diff --git a/clang/cmake/caches/Fuchsia.cmake b/clang/cmake/caches/Fuchsia.cmake index 2a65de2039c2e..8688b71ecc753 100644 --- a/clang/cmake/caches/Fuchsia.cmake +++ b/clang/cmake/caches/Fuchsia.cmake @@ -4,6 +4,8 @@ set(LLVM_TARGETS_TO_BUILD X86;ARM;AArch64;RISCV CACHE STRING "") set(PACKAGE_VENDOR Fuchsia CACHE STRING "") +set(LLVM_ENABLE_PROJECTS "clang;clang-tools-extra;lld;llvm" CACHE STRING "") + set(LLVM_ENABLE_BACKTRACES OFF CACHE BOOL "") set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR ON CACHE BOOL "") set(LLVM_ENABLE_TERMINFO OFF CACHE BOOL "") @@ -13,6 +15,10 @@ set(LLVM_INCLUDE_DOCS OFF CACHE BOOL "") set(LLVM_INCLUDE_EXAMPLES OFF CACHE BOOL "") set(LLVM_INCLUDE_GO_TESTS OFF CACHE BOOL "") +if(MSVC) + set(LLVM_USE_CRT_RELEASE "MT" CACHE STRING "") +endif() + set(CLANG_DEFAULT_CXX_STDLIB libc++ CACHE STRING "") if(NOT APPLE) set(CLANG_DEFAULT_LINKER lld CACHE STRING "") @@ -29,8 +35,10 @@ set(ENABLE_X86_RELAX_RELOCATIONS ON CACHE BOOL "") set(LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "") set(CMAKE_BUILD_TYPE Release CACHE STRING "") -if (APPLE) +if(APPLE) set(MACOSX_DEPLOYMENT_TARGET 10.7 CACHE STRING "") +elseif(MSVC) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded" CACHE STRING "") endif() if(APPLE) @@ -49,20 +57,33 @@ set(LIBCXXABI_USE_COMPILER_RT ON CACHE BOOL "") set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "") set(LIBCXX_ABI_VERSION 2 CACHE STRING "") set(LIBCXX_ENABLE_SHARED OFF CACHE BOOL "") -set(LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "") -set(LIBCXX_USE_COMPILER_RT ON CACHE BOOL "") +if(WIN32) + set(LIBCXX_HAS_WIN32_THREAD_API ON CACHE BOOL "") + set(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY OFF CACHE BOOL "") + set(LIBCXX_ENABLE_FILESYSTEM OFF CACHE BOOL "") + set(LIBCXX_ENABLE_ABI_LINKER_SCRIPT OFF CACHE BOOL "") + set(LIBCXX_ENABLE_STATIC_ABI_LIBRARY OFF CACHE BOOL "") + set(BUILTINS_CMAKE_ARGS -DCMAKE_SYSTEM_NAME=Windows CACHE STRING "") + set(RUNTIMES_CMAKE_ARGS -DCMAKE_SYSTEM_NAME=Windows CACHE STRING "") + set(LLVM_ENABLE_RUNTIMES "compiler-rt;libcxx" CACHE STRING "") +else() + set(LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "") + set(LLVM_ENABLE_RUNTIMES "compiler-rt;libcxx;libcxxabi;libunwind" CACHE STRING "") +endif() if(BOOTSTRAP_CMAKE_SYSTEM_NAME) set(target "${BOOTSTRAP_CMAKE_CXX_COMPILER_TARGET}") if(STAGE2_LINUX_${target}_SYSROOT) + set(LLVM_BUILTIN_TARGETS "${target}" CACHE STRING "") set(BUILTINS_${target}_CMAKE_SYSTEM_NAME Linux CACHE STRING "") set(BUILTINS_${target}_CMAKE_BUILD_TYPE Release CACHE STRING "") set(BUILTINS_${target}_CMAKE_SYSROOT ${STAGE2_LINUX_${target}_SYSROOT} CACHE STRING "") - set(LLVM_BUILTIN_TARGETS "${target}" CACHE STRING "") + set(LLVM_RUNTIME_TARGETS "${target}" CACHE STRING "") set(RUNTIMES_${target}_CMAKE_SYSTEM_NAME Linux CACHE STRING "") set(RUNTIMES_${target}_CMAKE_BUILD_TYPE Release CACHE STRING "") set(RUNTIMES_${target}_CMAKE_SYSROOT ${STAGE2_LINUX_${target}_SYSROOT} CACHE STRING "") + set(RUNTIMES_${target}_COMPILER_RT_USE_BUILTINS_LIBRARY ON CACHE BOOL "") set(RUNTIMES_${target}_LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "") set(RUNTIMES_${target}_LIBUNWIND_ENABLE_SHARED OFF CACHE BOOL "") set(RUNTIMES_${target}_LIBUNWIND_USE_COMPILER_RT ON CACHE BOOL "") @@ -76,10 +97,9 @@ if(BOOTSTRAP_CMAKE_SYSTEM_NAME) set(RUNTIMES_${target}_LIBCXX_ENABLE_SHARED OFF CACHE BOOL "") set(RUNTIMES_${target}_LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "") set(RUNTIMES_${target}_LIBCXX_ABI_VERSION 2 CACHE STRING "") + set(RUNTIMES_${target}_LLVM_ENABLE_RUNTIMES "compiler-rt;libcxx;libcxxabi;libunwind" CACHE STRING "") set(RUNTIMES_${target}_SANITIZER_CXX_ABI "libc++" CACHE STRING "") set(RUNTIMES_${target}_SANITIZER_CXX_ABI_INTREE ON CACHE BOOL "") - set(RUNTIMES_${target}_COMPILER_RT_USE_BUILTINS_LIBRARY ON CACHE BOOL "") - set(LLVM_RUNTIME_TARGETS "${target}" CACHE STRING "") endif() endif() diff --git a/clang/cmake/modules/ClangConfig.cmake.in b/clang/cmake/modules/ClangConfig.cmake.in index a5a7eae503282..c5ce56274b198 100644 --- a/clang/cmake/modules/ClangConfig.cmake.in +++ b/clang/cmake/modules/ClangConfig.cmake.in @@ -8,6 +8,7 @@ find_package(LLVM REQUIRED CONFIG set(CLANG_EXPORTED_TARGETS "@CLANG_EXPORTS@") set(CLANG_CMAKE_DIR "@CLANG_CONFIG_CMAKE_DIR@") set(CLANG_INCLUDE_DIRS "@CLANG_CONFIG_INCLUDE_DIRS@") +set(CLANG_LINK_CLANG_DYLIB "@CLANG_LINK_CLANG_DYLIB@") # Provide all our library targets to users. include("@CLANG_CONFIG_EXPORTS_FILE@") diff --git a/clang/docs/ClangCommandLineReference.rst b/clang/docs/ClangCommandLineReference.rst index 67c341feffbb6..1613c8e453184 100644 --- a/clang/docs/ClangCommandLineReference.rst +++ b/clang/docs/ClangCommandLineReference.rst @@ -818,6 +818,10 @@ Discard value names in LLVM IR Enables an experimental new pass manager in LLVM. +.. option:: -fexperimental-strict-floating-point + +Enables the use of non-default rounding modes and non-default exception handling on targets that are not currently ready. + .. option:: -ffine-grained-bitfield-accesses, -fno-fine-grained-bitfield-accesses Use separate accesses for consecutive bitfield runs with legal widths and alignments. @@ -2755,6 +2759,10 @@ Generate a \_\_mcount\_loc section entry for each \_\_fentry\_\_ call. Make StdCall calling convention the default +.. option:: -mseses, -mno-seses + +Enable speculative execution side effect suppression (SESES). Includes LVI control flow integrity mitigations + .. option:: -msign-return-address= Select return address signing scope @@ -3127,6 +3135,12 @@ X86 .. option:: -maes, -mno-aes +.. option:: -mamx-bf16, -mno-amx-bf16 + +.. option:: -mamx-int8, -mno-amx-int8 + +.. option:: -mamx-tile, -mno-amx-tile + .. option:: -mavx, -mno-avx .. option:: -mavx2, -mno-avx2 diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 496e4c651921a..e84676760c300 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -2694,6 +2694,23 @@ the configuration (without a prefix: ``Auto``). Use tabs whenever we need to fill whitespace that spans at least from one tab stop to the next one. +**WhitespaceSensitiveMacros** (``std::vector``) + A vector of macros which are whitespace-sensitive and should not be touched. + + These are expected to be macros of the form: + + .. code-block:: c++ + + STRINGIZE(...) + + In the .clang-format configuration file, this can be configured like: + + .. code-block:: yaml + + WhitespaceSensitiveMacros: ['STRINGIZE', 'PP_STRINGIZE'] + + For example: BOOST_PP_STRINGIZE. + .. END_FORMAT_STYLE_OPTIONS diff --git a/clang/docs/ClangFormattedStatus.rst b/clang/docs/ClangFormattedStatus.rst index 3e140c40070c6..3e348eadd4ffa 100644 --- a/clang/docs/ClangFormattedStatus.rst +++ b/clang/docs/ClangFormattedStatus.rst @@ -17,7 +17,7 @@ Clang Formatted Status ====================== :doc:`ClangFormattedStatus` describes the state of LLVM source -tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 (`4b776a98f1a `_). +tree in terms of conformance to :doc:`ClangFormat` as of: June 27, 2020 11:36:24 (`eb50838ba08 `_). .. list-table:: LLVM Clang-Format Status @@ -91,9 +91,9 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - :none:`0%` * - clang/include/clang/AST - `113` - - `21` - - `92` - - :part:`18%` + - `20` + - `93` + - :part:`17%` * - clang/include/clang/ASTMatchers - `5` - `1` @@ -260,10 +260,10 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - `0` - :good:`100%` * - clang/include/clang/Tooling/Transformer + - `8` - `7` - - `6` - `1` - - :part:`85%` + - :part:`87%` * - clang/include/clang-c - `9` - `3` @@ -325,10 +325,10 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - `26` - :part:`23%` * - clang/lib/Basic/Targets - - `46` - - `21` + - `48` + - `23` - `25` - - :part:`45%` + - :part:`47%` * - clang/lib/CodeGen - `87` - `8` @@ -370,15 +370,15 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - `14` - :part:`12%` * - clang/lib/Driver/ToolChains - - `81` - - `25` + - `83` + - `27` - `56` - - :part:`30%` + - :part:`32%` * - clang/lib/Driver/ToolChains/Arch - - `16` - - `2` + - `18` + - `4` - `14` - - :part:`12%` + - :part:`22%` * - clang/lib/Edit - `3` - `0` @@ -545,10 +545,10 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - `1` - :part:`85%` * - clang/lib/Tooling/Transformer - - `6` - - `3` + - `7` + - `4` - `3` - - :part:`50%` + - :part:`57%` * - clang/tools/arcmt-test - `1` - `0` @@ -616,9 +616,9 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - :none:`0%` * - clang/tools/clang-import-test - `1` - - `0` - `1` - - :none:`0%` + - `0` + - :good:`100%` * - clang/tools/clang-offload-bundler - `1` - `0` @@ -720,10 +720,10 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - `1` - :part:`94%` * - clang/unittests/Frontend - - `8` - - `4` + - `9` + - `5` - `4` - - :part:`50%` + - :part:`55%` * - clang/unittests/Index - `1` - `1` @@ -886,9 +886,9 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - :none:`0%` * - clang-tools-extra/clang-tidy - `18` - - `12` - - `6` - - :part:`66%` + - `10` + - `8` + - :part:`55%` * - clang-tools-extra/clang-tidy/abseil - `40` - `28` @@ -906,8 +906,8 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - :good:`100%` * - clang-tools-extra/clang-tidy/bugprone - `105` - - `84` - - `21` + - `85` + - `20` - :part:`80%` * - clang-tools-extra/clang-tidy/cert - `29` @@ -961,9 +961,9 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - :part:`86%` * - clang-tools-extra/clang-tidy/modernize - `67` - - `45` - - `22` - - :part:`67%` + - `46` + - `21` + - :part:`68%` * - clang-tools-extra/clang-tidy/mpi - `5` - `4` @@ -1015,10 +1015,10 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - `0` - :good:`100%` * - clang-tools-extra/clangd - - `73` - - `57` - - `16` - - :part:`78%` + - `75` + - `58` + - `17` + - :part:`77%` * - clang-tools-extra/clangd/benchmarks - `1` - `1` @@ -1090,10 +1090,10 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - `0` - :good:`100%` * - clang-tools-extra/clangd/unittests - - `63` - - `50` - - `13` - - :part:`79%` + - `64` + - `52` + - `12` + - :part:`81%` * - clang-tools-extra/clangd/unittests/remote - `1` - `1` @@ -1331,9 +1331,9 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - :part:`14%` * - compiler-rt/lib/sanitizer_common/symbolizer - `2` - - `1` - - `1` - - :part:`50%` + - `2` + - `0` + - :good:`100%` * - compiler-rt/lib/sanitizer_common/tests - `38` - `1` @@ -1495,15 +1495,20 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - `0` - :good:`100%` * - flang/include/flang/Evaluate - - `21` - - `21` + - `23` + - `23` - `0` - :good:`100%` * - flang/include/flang/Lower - - `9` - - `8` + - `13` + - `12` - `1` - - :part:`88%` + - :part:`92%` + * - flang/include/flang/Lower/Support + - `1` + - `1` + - `0` + - :good:`100%` * - flang/include/flang/Optimizer/CodeGen - `1` - `1` @@ -1540,15 +1545,15 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - `0` - :good:`100%` * - flang/lib/Evaluate - - `30` - - `30` + - `32` + - `32` - `0` - :good:`100%` * - flang/lib/Lower - - `6` - - `5` + - `10` + - `9` - `1` - - :part:`83%` + - :part:`90%` * - flang/lib/Optimizer/Dialect - `4` - `4` @@ -1566,9 +1571,9 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - :good:`100%` * - flang/lib/Semantics - `68` - - `67` - - `1` - - :part:`98%` + - `65` + - `3` + - :part:`95%` * - flang/module - `1` - `0` @@ -1650,10 +1655,10 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - `0` - :good:`100%` * - libc/fuzzing/string + - `2` - `1` - - `0` - `1` - - :none:`0%` + - :part:`50%` * - libc/include - `4` - `4` @@ -1675,8 +1680,8 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - `0` - :good:`100%` * - libc/src/math - - `52` - - `52` + - `70` + - `70` - `0` - :good:`100%` * - libc/src/signal @@ -1705,10 +1710,10 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - `0` - :good:`100%` * - libc/src/string - - `12` - - `11` + - `14` + - `13` - `1` - - :part:`91%` + - :part:`92%` * - libc/src/string/memory_utils - `3` - `3` @@ -1755,10 +1760,10 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - `0` - :good:`100%` * - libc/utils/FPUtil - - `7` - - `6` - - `1` - - :part:`85%` + - `9` + - `9` + - `0` + - :good:`100%` * - libc/utils/HdrGen - `9` - `9` @@ -2651,9 +2656,9 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - :part:`50%` * - lldb/source/Plugins/Platform/MacOSX - `24` - - `8` - - `16` - - :part:`33%` + - `10` + - `14` + - :part:`41%` * - lldb/source/Plugins/Platform/MacOSX/objcxx - `1` - `1` @@ -2786,9 +2791,9 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - :part:`53%` * - lldb/source/Plugins/SymbolFile/NativePDB - `20` - - `12` - - `8` - - :part:`60%` + - `11` + - `9` + - :part:`55%` * - lldb/source/Plugins/SymbolFile/PDB - `6` - `4` @@ -2999,6 +3004,11 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - `0` - `2` - :none:`0%` + * - lldb/unittests/Language/CLanguages + - `1` + - `1` + - `0` + - :good:`100%` * - lldb/unittests/Language/CPlusPlus - `1` - `0` @@ -3390,10 +3400,10 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - `60` - :part:`28%` * - llvm/include/llvm/Analysis - - `109` - - `30` + - `113` + - `34` - `79` - - :part:`27%` + - :part:`30%` * - llvm/include/llvm/Analysis/Utils - `1` - `0` @@ -3421,9 +3431,9 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - :none:`0%` * - llvm/include/llvm/CodeGen - `141` - - `33` - - `108` - - :part:`23%` + - `32` + - `109` + - :part:`22%` * - llvm/include/llvm/CodeGen/GlobalISel - `27` - `10` @@ -3740,10 +3750,10 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - `6` - :part:`25%` * - llvm/lib/Analysis - - `106` - - `30` + - `109` + - `33` - `76` - - :part:`28%` + - :part:`30%` * - llvm/lib/AsmParser - `6` - `2` @@ -3906,9 +3916,9 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - :good:`100%` * - llvm/lib/Frontend/OpenMP - `3` - - `3` - - `0` - - :good:`100%` + - `2` + - `1` + - :part:`66%` * - llvm/lib/FuzzMutate - `5` - `2` @@ -3916,9 +3926,9 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - :part:`40%` * - llvm/lib/IR - `61` - - `9` - - `52` - - :part:`14%` + - `11` + - `50` + - :part:`18%` * - llvm/lib/IRReader - `1` - `0` @@ -3976,9 +3986,9 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - :part:`34%` * - llvm/lib/ObjectYAML - `22` - - `12` - - `10` - - :part:`54%` + - `13` + - `9` + - :part:`59%` * - llvm/lib/Option - `4` - `0` @@ -4061,9 +4071,9 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - :none:`0%` * - llvm/lib/Target/AMDGPU - `146` - - `11` - - `135` - - :part:`7%` + - `12` + - `134` + - :part:`8%` * - llvm/lib/Target/AMDGPU/AsmParser - `1` - `0` @@ -4386,9 +4396,9 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - :good:`100%` * - llvm/lib/Target/SystemZ - `40` - - `3` - - `37` - - :part:`7%` + - `4` + - `36` + - :part:`10%` * - llvm/lib/Target/SystemZ/AsmParser - `1` - `0` @@ -4436,9 +4446,9 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - :part:`50%` * - llvm/lib/Target/WebAssembly - `58` - - `42` - - `16` - - :part:`72%` + - `40` + - `18` + - :part:`68%` * - llvm/lib/Target/WebAssembly/AsmParser - `1` - `0` @@ -4461,9 +4471,9 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - :good:`100%` * - llvm/lib/Target/X86 - `75` - - `12` - - `63` - - :part:`16%` + - `11` + - `64` + - :part:`14%` * - llvm/lib/Target/X86/AsmParser - `3` - `0` @@ -4556,14 +4566,14 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - :part:`6%` * - llvm/lib/Transforms/Instrumentation - `21` - - `2` - - `19` - - :part:`9%` + - `3` + - `18` + - :part:`14%` * - llvm/lib/Transforms/IPO - `39` - - `4` - - `35` - - :part:`10%` + - `5` + - `34` + - :part:`12%` * - llvm/lib/Transforms/ObjCARC - `15` - `3` @@ -4736,9 +4746,9 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - :good:`100%` * - llvm/tools/llvm-exegesis/lib - `44` - - `34` - - `10` - - :part:`77%` + - `35` + - `9` + - :part:`79%` * - llvm/tools/llvm-exegesis/lib/AArch64 - `1` - `1` @@ -5070,10 +5080,10 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - `8` - :part:`20%` * - llvm/unittests/CodeGen/GlobalISel - - `10` + - `11` - `1` - - `9` - - :part:`10%` + - `10` + - :part:`9%` * - llvm/unittests/DebugInfo/CodeView - `3` - `1` @@ -5690,10 +5700,10 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - `0` - :good:`100%` * - llvm/utils/TableGen - - `74` - - `8` + - `75` + - `9` - `66` - - :part:`10%` + - :part:`12%` * - llvm/utils/TableGen/GlobalISel - `17` - `8` @@ -6051,9 +6061,9 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - :good:`100%` * - mlir/include/mlir/Dialect/Linalg/EDSC - `3` - - `2` - - `1` - - :part:`66%` + - `3` + - `0` + - :good:`100%` * - mlir/include/mlir/Dialect/Linalg/IR - `3` - `2` @@ -6175,10 +6185,10 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - `6` - :none:`0%` * - mlir/include/mlir/Support - - `9` - - `5` + - `10` - `4` - - :part:`55%` + - `6` + - :part:`40%` * - mlir/include/mlir/TableGen - `18` - `17` @@ -6286,9 +6296,9 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - :good:`100%` * - mlir/lib/Conversion/SPIRVToLLVM - `2` - - `2` - - `0` - - :good:`100%` + - `1` + - `1` + - :part:`50%` * - mlir/lib/Conversion/StandardToLLVM - `1` - `1` @@ -6435,23 +6445,23 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - `0` - :good:`100%` * - mlir/lib/Dialect/Shape/Transforms - - `2` - - `2` + - `3` + - `3` - `0` - :good:`100%` * - mlir/lib/Dialect/SPIRV - `8` - - `5` - - `3` - - :part:`62%` + - `6` + - `2` + - :part:`75%` * - mlir/lib/Dialect/SPIRV/Serialization - `4` - `2` - `2` - :part:`50%` * - mlir/lib/Dialect/SPIRV/Transforms - - `4` - - `4` + - `5` + - `5` - `0` - :good:`100%` * - mlir/lib/Dialect/StandardOps/EDSC @@ -6465,8 +6475,8 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - `0` - :good:`100%` * - mlir/lib/Dialect/StandardOps/Transforms - - `3` - - `3` + - `4` + - `4` - `0` - :good:`100%` * - mlir/lib/Dialect/Vector @@ -6481,9 +6491,9 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - :good:`100%` * - mlir/lib/EDSC - `2` - - `2` - - `0` - - :good:`100%` + - `1` + - `1` + - :part:`50%` * - mlir/lib/ExecutionEngine - `5` - `5` @@ -6526,14 +6536,14 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - :good:`100%` * - mlir/lib/Transforms - `19` - - `17` - - `2` - - :part:`89%` + - `16` + - `3` + - :part:`84%` * - mlir/lib/Transforms/Utils - `7` - - `7` - - `0` - - :good:`100%` + - `6` + - `1` + - :part:`85%` * - mlir/lib/Translation - `1` - `1` @@ -6571,9 +6581,9 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - :good:`100%` * - mlir/tools/mlir-tblgen - `16` - - `14` - - `2` - - :part:`87%` + - `16` + - `0` + - :good:`100%` * - mlir/tools/mlir-translate - `1` - `1` @@ -6850,7 +6860,7 @@ tree in terms of conformance to :doc:`ClangFormat` as of: June 17, 2020 22:15:52 - `4` - :part:`81%` * - Total - - :total:`13959` - - :total:`6696` - - :total:`7263` - - :total:`47%` + - :total:`14021` + - :total:`6759` + - :total:`7262` + - :total:`48%` diff --git a/clang/docs/CommandGuide/clang.rst b/clang/docs/CommandGuide/clang.rst index de0e0eda90974..5978650c32888 100644 --- a/clang/docs/CommandGuide/clang.rst +++ b/clang/docs/CommandGuide/clang.rst @@ -474,6 +474,16 @@ Code Generation Options optimization. With "thin", :doc:`ThinLTO <../ThinLTO>` compilation is invoked instead. + .. note:: + + On Darwin, when using :option:`-flto` along with :option:`-g` and + compiling and linking in separate steps, you also need to pass + ``-Wl,-object_path_lto,.o`` at the linking step to instruct the + ld64 linker not to delete the temporary object file generated during Link + Time Optimization (this flag is automatically passed to the linker by Clang + if compilation and linking are done in a single step). This allows debugging + the executable as well as generating the ``.dSYM`` bundle using :manpage:`dsymutil(1)`. + Driver Options ~~~~~~~~~~~~~~ diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html index bb5e4984fcdf4..60ff6ffe60567 100644 --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -676,9 +676,10 @@

Node Matchers

#pragma omp parallel default(none) #pragma omp parallel default(shared) + #pragma omp parallel default(firstprivate) #pragma omp parallel -``ompDefaultClause()`` matches ``default(none)`` and ``default(shared)``. +``ompDefaultClause()`` matches ``default(none)``, ``default(shared)``, and ``default(firstprivate)``. @@ -1226,6 +1227,11 @@

Node Matchers

+Matcher<Stmt>fixedPointLiteralMatcher<FixedPointLiteral>... +
Matches fixed point literals
+
+ + Matcher<Stmt>floatLiteralMatcher<FloatingLiteral>...
Matches float literals of all sizes / encodings, e.g.
 1.0, 1.0f, 1.0L and 1e10.
@@ -3002,7 +3008,7 @@ 

Narrowing Matchers

-Matcher<Decl>isExpansionInFileMatchingstd::string RegExp +Matcher<Decl>isExpansionInFileMatchingStringRef RegExp, Regex::RegexFlags Flags = NoFlags
Matches AST nodes that were expanded within files whose name is
 partially matching a given regex.
 
@@ -3014,6 +3020,10 @@ 

Narrowing Matchers

class Y {}; Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc> + +If the matcher is used in clang-query, RegexFlags parameter +should be passed as a quoted string. e.g: "NoFlags". +Flags can be combined with '|' example "IgnoreCase | BasicRegex"
@@ -3720,7 +3730,7 @@

Narrowing Matchers

-Matcher<NamedDecl>matchesNamestd::string RegExp +Matcher<NamedDecl>matchesNameStringRef RegExp, Regex::RegexFlags Flags = NoFlags
Matches NamedDecl nodes whose fully qualified names contain
 a substring matched by the given RegExp.
 
@@ -3733,6 +3743,10 @@ 

Narrowing Matchers

Example matches X (regexp is one of "::X", "^foo::.*X", among others) namespace foo { namespace bar { class X; } } + +If the matcher is used in clang-query, RegexFlags parameter +should be passed as a quoted string. e.g: "NoFlags". +Flags can be combined with '|' example "IgnoreCase | BasicRegex"
@@ -3770,6 +3784,7 @@

Narrowing Matchers

#pragma omp parallel #pragma omp parallel default(none) #pragma omp parallel default(shared) + #pragma omp parallel default(firstprivate) ``ompDefaultClause(isNoneKind())`` matches only ``default(none)``. @@ -3783,11 +3798,26 @@

Narrowing Matchers

#pragma omp parallel #pragma omp parallel default(none) #pragma omp parallel default(shared) + #pragma omp parallel default(firstprivate) ``ompDefaultClause(isSharedKind())`` matches only ``default(shared)``. +Matcher<OMPDefaultClause>isSharedKind +
Matches if the OpenMP ``default`` clause has ``firstprivate`` kind specified.
+
+Given
+
+  #pragma omp parallel
+  #pragma omp parallel default(none)
+  #pragma omp parallel default(shared)
+  #pragma omp parallel default(firstprivate)
+
+``ompDefaultClause(isFirstPrivateKind())`` matches only ``default(firstprivate)``.
+
+ + Matcher<OMPExecutableDirective>isAllowedToContainClauseKindOpenMPClauseKind CKind
Matches if the OpenMP directive is allowed to contain the specified OpenMP
 clause kind.
@@ -3927,12 +3957,16 @@ 

Narrowing Matchers

-Matcher<ObjCMessageExpr>matchesSelectorstd::string RegExp +Matcher<ObjCMessageExpr>matchesSelectorStringRef RegExp, Regex::RegexFlags Flags = NoFlags
Matches ObjC selectors whose name contains
 a substring matched by the given RegExp.
  matcher = objCMessageExpr(matchesSelector("loadHTMLStringmatches the outer message expr in the code below, but NOT the message
  invocation for self.bodyView.
     [self.bodyView loadHTMLString:html baseURL:NULL];
+
+If the matcher is used in clang-query, RegexFlags parameter
+should be passed as a quoted string. e.g: "NoFlags".
+Flags can be combined with '|' example "IgnoreCase | BasicRegex"
 
@@ -4016,6 +4050,23 @@

Narrowing Matchers

+Matcher<ParmVarDecl>isAtPositionunsigned N +
Matches the ParmVarDecl nodes that are at the N'th position in the parameter
+list. The parameter list could be that of either a block, function, or
+objc-method.
+
+
+Given
+
+void f(int a, int b, int c) {
+}
+
+``parmVarDecl(isAtPosition(0))`` matches ``int a``.
+
+``parmVarDecl(isAtPosition(1))`` matches ``int b``.
+
+ + Matcher<QualType>asStringstd::string Name
Matches if the matched type is represented by the given string.
 
@@ -4206,7 +4257,7 @@ 

Narrowing Matchers

-Matcher<Stmt>isExpansionInFileMatchingstd::string RegExp +Matcher<Stmt>isExpansionInFileMatchingStringRef RegExp, Regex::RegexFlags Flags = NoFlags
Matches AST nodes that were expanded within files whose name is
 partially matching a given regex.
 
@@ -4218,6 +4269,10 @@ 

Narrowing Matchers

class Y {}; Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc> + +If the matcher is used in clang-query, RegexFlags parameter +should be passed as a quoted string. e.g: "NoFlags". +Flags can be combined with '|' example "IgnoreCase | BasicRegex"
@@ -4388,7 +4443,7 @@

Narrowing Matchers

-Matcher<TypeLoc>isExpansionInFileMatchingstd::string RegExp +Matcher<TypeLoc>isExpansionInFileMatchingStringRef RegExp, Regex::RegexFlags Flags = NoFlags
Matches AST nodes that were expanded within files whose name is
 partially matching a given regex.
 
@@ -4400,6 +4455,10 @@ 

Narrowing Matchers

class Y {}; Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc> + +If the matcher is used in clang-query, RegexFlags parameter +should be passed as a quoted string. e.g: "NoFlags". +Flags can be combined with '|' example "IgnoreCase | BasicRegex"
@@ -4755,23 +4814,6 @@

Narrowing Matchers

Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl> - -Matcher<clang::ParmVarDecl>isAtPositionunsigned N -
Matches the ParmVarDecl nodes that are at the N'th position in the parameter
-list. The parameter list could be that of either a block, function, or
-objc-method.
-
-
-Given
-
-void f(int a, int b, int c) {
-}
-
-``parmVarDecl(isAtPosition(0))`` matches ``int a``.
-
-``parmVarDecl(isAtPosition(1))`` matches ``int b``.
-
- @@ -5632,18 +5674,33 @@

AST Traversal Matchers

Matcher<CXXRecordDecl>hasAnyBaseMatcher<CXXBaseSpecifier> BaseSpecMatcher
Matches C++ classes that have a direct or indirect base matching BaseSpecMatcher.
 
-Example matches DirectlyDerived, IndirectlyDerived (BaseSpecMatcher ==
-hasType(cxxRecordDecl(hasName("SpecialBase")))) class Foo;
+Example:
+matcher hasAnyBase(hasType(cxxRecordDecl(hasName("SpecialBase"))))
+  class Foo;
   class Bar : Foo {};
   class Baz : Bar {};
   class SpecialBase;
-  class DirectlyDerived : SpecialBase {};  // directly derived
-  class IndirectlyDerived : DirectlyDerived {};  // indirectly derived
+  class Proxy : SpecialBase {};  // matches Proxy
+  class IndirectlyDerived : Proxy {};  //matches IndirectlyDerived
 
 FIXME: Refactor this and isDerivedFrom to reuse implementation.
 
+Matcher<CXXRecordDecl>hasDirectBaseMatcher<CXXBaseSpecifier> BaseSpecMatcher +
Matches C++ classes that have a direct base matching BaseSpecMatcher.
+
+Example:
+matcher hasDirectBase(hasType(cxxRecordDecl(hasName("SpecialBase"))))
+  class Foo;
+  class Bar : Foo {};
+  class Baz : Bar {};
+  class SpecialBase;
+  class Proxy : SpecialBase {};  // matches Proxy
+  class IndirectlyDerived : Proxy {};  // doesn't match
+
+ + Matcher<CXXRecordDecl>hasMethodMatcher<CXXMethodDecl> InnerMatcher
Matches the first method of a class or struct that satisfies InnerMatcher.
 
diff --git a/clang/docs/MatrixTypes.rst b/clang/docs/MatrixTypes.rst
index 54099e5aae930..5d022af441210 100644
--- a/clang/docs/MatrixTypes.rst
+++ b/clang/docs/MatrixTypes.rst
@@ -245,8 +245,8 @@ and if omitted ``row`` is used as ``columnStride``.
 **Preconditions**: ``columnStride`` is greater than or equal to the number of rows in ``M``.
 
 **Remarks**: The type ``T`` is the const-unqualified version of the matrix
-argument’s element type. The paramter ``columnStride`` is optional and if
-ommitted, the number of rows of ``M`` is used as ``columnStride``.
+argument’s element type. The parameter ``columnStride`` is optional and if
+omitted, the number of rows of ``M`` is used as ``columnStride``.
 
 **Effects**: Equivalent to:
 
diff --git a/clang/docs/OpenMPSupport.rst b/clang/docs/OpenMPSupport.rst
index f56980faaee8a..000f23141af30 100644
--- a/clang/docs/OpenMPSupport.rst
+++ b/clang/docs/OpenMPSupport.rst
@@ -131,7 +131,7 @@ implementation.
 +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+
 | loop extension               | clause: if for SIMD directives                               | :good:`done`             |                                                                       |
 +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+
-| loop extension               | inclusive scan extension (matching C++17 PSTL)               | :none:`claimed`          |                                                                       |
+| loop extension               | inclusive scan extension (matching C++17 PSTL)               | :good:`done`             |                                                                       |
 +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+
 | memory mangagement           | memory allocators                                            | :good:`done`             | r341687,r357929                                                       |
 +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+
@@ -268,3 +268,5 @@ want to help with the implementation.
 +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+
 | loop extension               | Loop tiling transformation                                   | :part:`claimed`          |                                                                       |
 +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+
+| device extension             | 'present' map type modifier                                  | :part:`claimed`          |                                                                       |
++------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 15e6d35117b42..8a9a58aa01f8f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -94,8 +94,8 @@ New Compiler Flags
 ------------------
 
 - -fstack-clash-protection will provide a protection against the stack clash
-  attack for x86 and s390x architectures through automatic probing of each page
-  of allocated stack.
+  attack for x86, s390x and ppc64 architectures through automatic probing of
+  each page of allocated stack.
 
 - -ffp-exception-behavior={ignore,maytrap,strict} allows the user to specify
   the floating-point exception behavior. The default setting is ``ignore``.
@@ -104,6 +104,10 @@ New Compiler Flags
   simplify access to the many single purpose floating point options. The default
   setting is ``precise``.
 
+- The default module cache has moved from /tmp to a per-user cache directory.
+  By default, this is ~/.cache but on some platforms or installations, this
+  might be elsewhere. The -fmodules-cache-path=... flag continues to work.
+
 Deprecated Compiler Flags
 -------------------------
 
@@ -239,6 +243,34 @@ These are major API changes that have happened since the 10.0.0 release of
 Clang. If upgrading an external codebase that uses Clang as a library,
 this section should help get you past the largest hurdles of upgrading.
 
+- ``RecursiveASTVisitor`` no longer calls separate methods to visit specific
+  operator kinds. Previously, ``RecursiveASTVisitor`` treated unary, binary,
+  and compound assignment operators as if they were subclasses of the
+  corresponding AST node. For example, the binary operator plus was treated as
+  if it was a ``BinAdd`` subclass of the ``BinaryOperator`` class: during AST
+  traversal of a ``BinaryOperator`` AST node that had a ``BO_Add`` opcode,
+  ``RecursiveASTVisitor`` was calling the ``TraverseBinAdd`` method instead of
+  ``TraverseBinaryOperator``. This feature was contributing a non-trivial
+  amount of complexity to the implementation of ``RecursiveASTVisitor``, it was
+  used only in a minor way in Clang, was not tested, and as a result it was
+  buggy. Furthermore, this feature was creating a non-uniformity in the API.
+  Since this feature was not documented, it was quite difficult to figure out
+  how to use ``RecursiveASTVisitor`` to visit operators.
+
+  To update your code to the new uniform API, move the code from separate
+  visitation methods into methods that correspond to the actual AST node and
+  perform case analysis based on the operator opcode as needed:
+
+  * ``TraverseUnary*() => TraverseUnaryOperator()``
+  * ``WalkUpFromUnary*() => WalkUpFromUnaryOperator()``
+  * ``VisitUnary*() => VisiUnaryOperator()``
+  * ``TraverseBin*() => TraverseBinaryOperator()``
+  * ``WalkUpFromBin*() => WalkUpFromBinaryOperator()``
+  * ``VisitBin*() => VisiBinaryOperator()``
+  * ``TraverseBin*Assign() => TraverseCompoundAssignOperator()``
+  * ``WalkUpFromBin*Assign() => WalkUpFromCompoundAssignOperator()``
+  * ``VisitBin*Assign() => VisiCompoundAssignOperator()``
+
 Build System Changes
 --------------------
 
@@ -254,44 +286,7 @@ release of Clang. Users of the build system should adjust accordingly.
 AST Matchers
 ------------
 
-- Traversal in AST Matchers was simplified to use the
-  ``TK_IgnoreUnlessSpelledInSource`` mode by default, instead of ``TK_AsIs``.
-  This means that many uses of the ``ignoringImplicit()`` and similar matchers
-  is no longer necessary.  Clients of AST Matchers which wish to match on
-  implicit AST nodes can wrap their matcher in ``traverse(TK_AsIs, ...)`` or
-  use ``TraversalKindScope`` if appropriate.  The ``clang-query`` tool also
-  uses ``IgnoreUnlessSpelledInSource`` by default.  The mode can be changed
-  using ``set traversal AsIs`` in the ``clang-query`` environment.
-
-  As this change requires downstream tools which use AST Matchers to adapt
-  to the new default, a porting guide may be useful for downstream tools
-  needing to adapt.
-
-  Note that although there are many steps below, only the first is
-  non-optional. The steps are intentionally extemely granular to facilitate
-  understanding of the guide itself. It is reasonable to do some of the
-  steps at the same time if you understand the guide:
-
-  1. Use ``(your ASTContext instance).getParentMapContext().setTraversalKind(TK_AsIs)``
-     to restore the previous behavior for your tool.  All further steps in
-     this porting guide are optional.
-  2. Wrap your existing matcher expressions with ``traverse(TK_AsIs, ...)``
-     before passing them to ``ASTMatchFinder::addMatcher``.
-  3. Remove ``(your ASTContext instance).getParentMapContext().setTraversalKind(TK_AsIs)``
-     from your tool so that the default behavior of your tool matches the
-     default behavior of upstream clang. This is made possible by wrapping
-     your matchers in ``traverse(TK_AsIs, ...)`` from step (2).
-  4. Audit your matcher expressions and remove ``traverse(TK_AsIs, ...)``
-     where not needed.
-  5. Audit your matcher expressions and remove calls to ``ignoring*()``
-     matchers where not needed.
-  6. Audit your matcher expressions and consider whether the matcher is
-     better using the ``TK_AsIs`` mode or if it can be better expressed in
-     the default mode. For example, some matchers explicitly match
-     ``has(implicitCastExpr(has(...)))``. Such matchers are sometimes
-     written by author who were unaware of the existence of the
-     ``ignoring*()`` matchers.
-
+- ...
 
 clang-format
 ------------
diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst
index d13d4180a1128..8615a77596b4f 100644
--- a/clang/docs/UsersManual.rst
+++ b/clang/docs/UsersManual.rst
@@ -1220,7 +1220,7 @@ are listed below.
 
    * ``-fno-math-errno``
 
-   * ``-ffinite-math``
+   * ``-ffinite-math-only``
 
    * ``-fassociative-math``
 
@@ -1306,14 +1306,14 @@ are listed below.
 **-f[no-]honor-infinities**
 
    If both ``-fno-honor-infinities`` and ``-fno-honor-nans`` are used,
-   has the same effect as specifying ``-ffinite-math``.
+   has the same effect as specifying ``-ffinite-math-only``.
 
 .. _opt_fhonor-nans:
 
 **-f[no-]honor-nans**
 
    If both ``-fno-honor-infinities`` and ``-fno-honor-nans`` are used,
-   has the same effect as specifying ``-ffinite-math``.
+   has the same effect as specifying ``-ffinite-math-only``.
 
 .. _opt_fsigned-zeros:
 
@@ -1351,9 +1351,9 @@ are listed below.
 
    Defaults to ``-fno-unsafe-math-optimizations``.
 
-.. _opt_ffinite-math:
+.. _opt_ffinite-math-only:
 
-**-f[no-]finite-math**
+**-f[no-]finite-math-only**
 
    Allow floating-point optimizations that assume arguments and results are
    not NaNs or +-Inf.  This defines the ``__FINITE_MATH_ONLY__`` preprocessor macro.
@@ -1362,7 +1362,7 @@ are listed below.
    * ``-fno-honor-infinities``
    * ``-fno-honor-nans``
 
-   Defaults to ``-fno-finite-math``.
+   Defaults to ``-fno-finite-math-only``.
 
 .. _opt_frounding-math:
 
@@ -3132,7 +3132,7 @@ Global objects must be constructed before the first kernel using the global obje
 is executed and destroyed just after the last kernel using the program objects is
 executed. In OpenCL v2.0 drivers there is no specific API for invoking global
 constructors. However, an easy workaround would be to enqueue a constructor
-initialization kernel that has a name ``@_GLOBAL__sub_I_``.
+initialization kernel that has a name ``_GLOBAL__sub_I_``.
 This kernel is only present if there are any global objects to be initialized in
 the compiled binary. One way to check this is by passing ``CL_PROGRAM_KERNEL_NAMES``
 to ``clGetProgramInfo`` (OpenCL v2.0 s5.8.7).
@@ -3148,7 +3148,7 @@ before running any kernels in which the objects are used.
      clang -cl-std=clc++ test.cl
 
 If there are any global objects to be initialized, the final binary will contain
-the ``@_GLOBAL__sub_I_test.cl`` kernel to be enqueued.
+the ``_GLOBAL__sub_I_test.cl`` kernel to be enqueued.
 
 Global destructors can not be invoked in OpenCL v2.0 drivers. However, all memory used
 for program scope objects is released on ``clReleaseProgram``.
diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst
index d14bd2d68af9a..1583da7aff098 100644
--- a/clang/docs/analyzer/checkers.rst
+++ b/clang/docs/analyzer/checkers.rst
@@ -1836,6 +1836,19 @@ Check unreachable code.
    [x retain]; // warn
  }
 
+.. _alpha-cplusplus-SmartPtr:
+
+alpha.cplusplus.SmartPtr (C++)
+""""""""""""""""""""""""""""""
+Check for dereference of null smart pointers.
+
+.. code-block:: cpp
+
+ void deref_smart_ptr() {
+   std::unique_ptr P;
+   *P; // warn: dereference of a default constructed smart unique_ptr
+ }
+
 alpha.llvm
 ^^^^^^^^^^
 
diff --git a/clang/docs/tools/dump_ast_matchers.py b/clang/docs/tools/dump_ast_matchers.py
index baba4cf7a232c..045833be76739 100755
--- a/clang/docs/tools/dump_ast_matchers.py
+++ b/clang/docs/tools/dump_ast_matchers.py
@@ -230,6 +230,28 @@ def act_on_decl(declaration, comment, allowed_types):
         add_matcher(result_type, name, args, comment)
       return
 
+    m = re.match(r"""^\s*AST_POLYMORPHIC_MATCHER_REGEX(?:_OVERLOAD)?\(
+                          \s*([^\s,]+)\s*,
+                          \s*AST_POLYMORPHIC_SUPPORTED_TYPES\(([^)]*)\),
+                          \s*([^\s,]+)\s*
+                       (?:,\s*\d+\s*)?
+                      \)\s*{\s*$""", declaration, flags=re.X)
+
+    if m:
+      name, results, arg_name = m.groups()[0:3]
+      result_types = [r.strip() for r in results.split(',')]
+      if allowed_types and allowed_types != result_types:
+        raise Exception('Inconsistent documentation for: %s' % name)
+      arg = "StringRef %s, Regex::RegexFlags Flags = NoFlags" % arg_name
+      comment += """
+If the matcher is used in clang-query, RegexFlags parameter
+should be passed as a quoted string. e.g: "NoFlags".
+Flags can be combined with '|' example \"IgnoreCase | BasicRegex\"
+"""
+      for result_type in result_types:
+        add_matcher(result_type, name, arg, comment)
+      return
+
     m = re.match(r"""^\s*AST_MATCHER_FUNCTION(_P)?(.?)(?:_OVERLOAD)?\(
                        (?:\s*([^\s,]+)\s*,)?
                           \s*([^\s,]+)\s*
@@ -275,6 +297,31 @@ def act_on_decl(declaration, comment, allowed_types):
         add_matcher(result_type, name, args, comment)
       return
 
+    m = re.match(r"""^\s*AST_MATCHER_REGEX(?:_OVERLOAD)?\(
+                       \s*([^\s,]+)\s*,
+                       \s*([^\s,]+)\s*,
+                       \s*([^\s,]+)\s*
+                       (?:,\s*\d+\s*)?
+                      \)\s*{""", declaration, flags=re.X)
+    if m:
+      result, name, arg_name = m.groups()[0:3]
+      if not result:
+        if not allowed_types:
+          raise Exception('Did not find allowed result types for: %s' % name)
+        result_types = allowed_types
+      else:
+        result_types = [result]
+      arg = "StringRef %s, Regex::RegexFlags Flags = NoFlags" % arg_name
+      comment += """
+If the matcher is used in clang-query, RegexFlags parameter
+should be passed as a quoted string. e.g: "NoFlags".
+Flags can be combined with '|' example \"IgnoreCase | BasicRegex\"
+"""
+
+      for result_type in result_types:
+        add_matcher(result_type, name, arg, comment)
+      return
+
     # Parse ArgumentAdapting matchers.
     m = re.match(
         r"""^.*ArgumentAdaptingMatcherFunc<.*>\s*
diff --git a/clang/docs/tools/generate_formatted_state.py b/clang/docs/tools/generate_formatted_state.py
index 1b620a84ac0b4..41d5cd9d40043 100755
--- a/clang/docs/tools/generate_formatted_state.py
+++ b/clang/docs/tools/generate_formatted_state.py
@@ -72,6 +72,8 @@ def get_style(count, passed):
      - {style2}`{percent}%`
 """
 
+FNULL = open(os.devnull, 'w')
+
 with open(DOC_FILE, 'wb') as output:
     sha = get_git_revision_short_hash()
     today = datetime.now().strftime("%B %d, %Y %H:%M:%S")
@@ -85,14 +87,22 @@ def get_style(count, passed):
         for subdir in subdirs:
             if any(sd == subdir for sd in skipped_dirs):
                 subdirs.remove(subdir)
+            else:
+                act_sub_dir = os.path.join(root, subdir)
+                # Check the git index to see if the directory contains tracked
+                # files. Reditect the output to a null descriptor as we aren't
+                # interested in it, just the return code.
+                git_check = subprocess.Popen(
+                    ["git", "ls-files", "--error-unmatch", act_sub_dir],
+                    stdout=FNULL,
+                    stderr=FNULL)
+                if git_check.wait() != 0:
+                    print("Skipping directory: ", act_sub_dir)
+                    subdirs.remove(subdir)
 
         path = os.path.relpath(root, TOP_DIR)
         path = path.replace('\\', '/')
 
-        head, _ = os.path.split(root)
-        while head:
-            head, _ = os.path.split(head)
-
         file_count = 0
         file_pass = 0
         file_fail = 0
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index 19471af4a675c..5fa728d6d66c8 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -2167,7 +2167,7 @@ enum CXCursorKind {
    */
   CXCursor_ObjCSelfExpr = 147,
 
-  /** OpenMP 4.0 [2.4, Array Section].
+  /** OpenMP 5.0 [2.1.5, Array Section].
    */
   CXCursor_OMPArraySectionExpr = 148,
 
@@ -5934,6 +5934,7 @@ typedef void *CXEvalResult;
  * If cursor is a statement declaration tries to evaluate the
  * statement and if its variable, tries to evaluate its initializer,
  * into its corresponding type.
+ * If it's an expression, tries to evaluate the expression.
  */
 CINDEX_LINKAGE CXEvalResult clang_Cursor_Evaluate(CXCursor C);
 
diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h
index 63359294ef632..cca92b5f82352 100644
--- a/clang/include/clang/AST/APValue.h
+++ b/clang/include/clang/AST/APValue.h
@@ -372,7 +372,7 @@ class APValue {
   bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
 
   void dump() const;
-  void dump(raw_ostream &OS) const;
+  void dump(raw_ostream &OS, const ASTContext &Context) const;
 
   void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const;
   std::string getAsString(const ASTContext &Ctx, QualType Ty) const;
diff --git a/clang/include/clang/AST/ASTDumper.h b/clang/include/clang/AST/ASTDumper.h
index f46ffb960db6a..a154bc2db3a7e 100644
--- a/clang/include/clang/AST/ASTDumper.h
+++ b/clang/include/clang/AST/ASTDumper.h
@@ -24,18 +24,11 @@ class ASTDumper : public ASTNodeTraverser {
   const bool ShowColors;
 
 public:
-  ASTDumper(raw_ostream &OS, const comments::CommandTraits *Traits,
-            const SourceManager *SM)
-      : ASTDumper(OS, Traits, SM, SM && SM->getDiagnostics().getShowColors()) {}
-
-  ASTDumper(raw_ostream &OS, const comments::CommandTraits *Traits,
-            const SourceManager *SM, bool ShowColors)
-      : ASTDumper(OS, Traits, SM, ShowColors, LangOptions()) {}
-  ASTDumper(raw_ostream &OS, const comments::CommandTraits *Traits,
-            const SourceManager *SM, bool ShowColors,
-            const PrintingPolicy &PrintPolicy)
-      : NodeDumper(OS, ShowColors, SM, PrintPolicy, Traits), OS(OS),
-        ShowColors(ShowColors) {}
+  ASTDumper(raw_ostream &OS, const ASTContext &Context, bool ShowColors)
+      : NodeDumper(OS, Context, ShowColors), OS(OS), ShowColors(ShowColors) {}
+
+  ASTDumper(raw_ostream &OS, bool ShowColors)
+      : NodeDumper(OS, ShowColors), OS(OS), ShowColors(ShowColors) {}
 
   TextNodeDumper &doGetNodeDelegate() { return NodeDumper; }
 
diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h
index c146c24a3d36f..26656b7162b61 100644
--- a/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/clang/include/clang/AST/ASTNodeTraverser.h
@@ -22,10 +22,13 @@
 #include "clang/AST/LocInfoType.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/AST/TemplateArgumentVisitor.h"
+#include "clang/AST/Type.h"
 #include "clang/AST/TypeVisitor.h"
 
 namespace clang {
 
+class APValue;
+
 /**
 
 ASTNodeTraverser traverses the Clang AST for dumping purposes.
@@ -50,6 +53,7 @@ struct {
   void Visit(const OMPClause *C);
   void Visit(const BlockDecl::Capture &C);
   void Visit(const GenericSelectionExpr::ConstAssociation &A);
+  void Visit(const APValue &Value, QualType Ty);
 };
 */
 template 
@@ -211,6 +215,10 @@ class ASTNodeTraverser
     });
   }
 
+  void Visit(const APValue &Value, QualType Ty) {
+    getNodeDelegate().AddChild([=] { getNodeDelegate().Visit(Value, Ty); });
+  }
+
   void Visit(const comments::Comment *C, const comments::FullComment *FC) {
     getNodeDelegate().AddChild([=] {
       getNodeDelegate().Visit(C, FC);
@@ -352,8 +360,6 @@ class ASTNodeTraverser
   void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
     for (const auto &Arg : *T)
       Visit(Arg);
-    if (T->isTypeAlias())
-      Visit(T->getAliasedType());
   }
   void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
     Visit(T->getPointeeType());
@@ -682,6 +688,15 @@ class ASTNodeTraverser
         Visit(A);
   }
 
+  void VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E) {
+    Visit(E->getParameter());
+  }
+  void VisitSubstNonTypeTemplateParmPackExpr(
+      const SubstNonTypeTemplateParmPackExpr *E) {
+    Visit(E->getParameterPack());
+    Visit(E->getArgumentPack());
+  }
+
   void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
     if (const VarDecl *CatchParam = Node->getCatchParamDecl())
       Visit(CatchParam);
@@ -690,6 +705,11 @@ class ASTNodeTraverser
   void VisitExpressionTemplateArgument(const TemplateArgument &TA) {
     Visit(TA.getAsExpr());
   }
+
+  void VisitTypeTemplateArgument(const TemplateArgument &TA) {
+    Visit(TA.getAsType());
+  }
+
   void VisitPackTemplateArgument(const TemplateArgument &TA) {
     for (const auto &TArg : TA.pack_elements())
       Visit(TArg);
diff --git a/clang/include/clang/AST/ASTTypeTraits.h b/clang/include/clang/AST/ASTTypeTraits.h
index 67fa4ab1b6a4f..328b7bce6ba50 100644
--- a/clang/include/clang/AST/ASTTypeTraits.h
+++ b/clang/include/clang/AST/ASTTypeTraits.h
@@ -278,7 +278,7 @@ class DynTypedNode {
   void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const;
 
   /// Dumps the node to the given output stream.
-  void dump(llvm::raw_ostream &OS, SourceManager &SM) const;
+  void dump(llvm::raw_ostream &OS, const ASTContext &Context) const;
 
   /// For nodes which represent textual entities in the source code,
   /// return their SourceRange.  For all other nodes, return SourceRange().
diff --git a/clang/include/clang/AST/Comment.h b/clang/include/clang/AST/Comment.h
index cd9c1ce2bce0c..54a4b0a9cfe66 100644
--- a/clang/include/clang/AST/Comment.h
+++ b/clang/include/clang/AST/Comment.h
@@ -209,9 +209,7 @@ class Comment {
 
   void dump() const;
   void dumpColor() const;
-  void dump(const ASTContext &Context) const;
-  void dump(raw_ostream &OS, const CommandTraits *Traits,
-            const SourceManager *SM) const;
+  void dump(raw_ostream &OS, const ASTContext &Context) const;
 
   SourceRange getSourceRange() const LLVM_READONLY { return Range; }
 
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 6c39f6aab1b9c..28faa2c1fc780 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -2618,7 +2618,13 @@ class FunctionDecl : public DeclaratorDecl,
   /// Retrieve the function declaration from which this function could
   /// be instantiated, if it is an instantiation (rather than a non-template
   /// or a specialization, for example).
-  FunctionDecl *getTemplateInstantiationPattern() const;
+  ///
+  /// If \p ForDefinition is \c false, explicit specializations will be treated
+  /// as if they were implicit instantiations. This will then find the pattern
+  /// corresponding to non-definition portions of the declaration, such as
+  /// default arguments and the exception specification.
+  FunctionDecl *
+  getTemplateInstantiationPattern(bool ForDefinition = true) const;
 
   /// Retrieve the primary template that this function template
   /// specialization either specializes or was instantiated from.
diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h
index ba84f27617f5f..4f33ff104ffd6 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -66,6 +66,7 @@ class SourceManager;
 class Stmt;
 class StoredDeclsMap;
 class TemplateDecl;
+class TemplateParameterList;
 class TranslationUnitDecl;
 class UsingDirectiveDecl;
 
@@ -862,6 +863,10 @@ class alignas(8) Decl {
   // within the scope of a template parameter).
   bool isTemplated() const;
 
+  /// Determine the number of levels of template parameter surrounding this
+  /// declaration.
+  unsigned getTemplateDepth() const;
+
   /// isDefinedOutsideFunctionOrMethod - This predicate returns true if this
   /// scoped decl is defined outside the current function or method.  This is
   /// roughly global variables and functions, but also handles enums (which
@@ -870,15 +875,19 @@ class alignas(8) Decl {
     return getParentFunctionOrMethod() == nullptr;
   }
 
-  /// Returns true if this declaration is lexically inside a function or inside
-  /// a variable initializer. It recognizes non-defining declarations as well
-  /// as members of local classes and lambdas:
+  /// Determine whether a substitution into this declaration would occur as
+  /// part of a substitution into a dependent local scope. Such a substitution
+  /// transitively substitutes into all constructs nested within this
+  /// declaration.
+  ///
+  /// This recognizes non-defining declarations as well as members of local
+  /// classes and lambdas:
   /// \code
-  ///     void foo() { void bar(); }
-  ///     void foo2() { class ABC { void bar(); }; }
-  ///     inline int x = [](){ return 0; }();
+  ///     template void foo() { void bar(); }
+  ///     template void foo2() { class ABC { void bar(); }; }
+  ///     template inline int x = [](){ return 0; }();
   /// \endcode
-  bool isInLocalScope() const;
+  bool isInLocalScopeForInstantiation() const;
 
   /// If this decl is defined inside a function/method/block it returns
   /// the corresponding DeclContext, otherwise it returns null.
@@ -1038,8 +1047,16 @@ class alignas(8) Decl {
 
   /// If this is a declaration that describes some template, this
   /// method returns that template declaration.
+  ///
+  /// Note that this returns nullptr for partial specializations, because they
+  /// are not modeled as TemplateDecls. Use getDescribedTemplateParams to handle
+  /// those cases.
   TemplateDecl *getDescribedTemplate() const;
 
+  /// If this is a declaration that describes some template or partial
+  /// specialization, this returns the corresponding template parameter list.
+  const TemplateParameterList *getDescribedTemplateParams() const;
+
   /// Returns the function itself, or the templated function if this is a
   /// function template.
   FunctionDecl *getAsFunction() LLVM_READONLY;
diff --git a/clang/include/clang/AST/DependenceFlags.h b/clang/include/clang/AST/DependenceFlags.h
index 0b24bae6df9b1..3601cb90bb765 100644
--- a/clang/include/clang/AST/DependenceFlags.h
+++ b/clang/include/clang/AST/DependenceFlags.h
@@ -70,12 +70,13 @@ using TypeDependence = TypeDependenceScope::TypeDependence;
       UnexpandedPack = 1,                                                      \
       Instantiation = 2,                                                       \
       Dependent = 4,                                                           \
+      Error = 8,                                                               \
                                                                                \
       None = 0,                                                                \
       DependentInstantiation = Dependent | Instantiation,                      \
-      All = 7,                                                                 \
+      All = 15,                                                                \
                                                                                \
-      LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Dependent)                    \
+      LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error)                        \
     };                                                                         \
   };                                                                           \
   using NAME = NAME##Scope::NAME;
@@ -118,10 +119,10 @@ class Dependence {
 
   Dependence(TypeDependence D)
       : V(translate(D, TypeDependence::UnexpandedPack, UnexpandedPack) |
-             translate(D, TypeDependence::Instantiation, Instantiation) |
-             translate(D, TypeDependence::Dependent, Dependent) |
-             translate(D, TypeDependence::VariablyModified, VariablyModified)) {
-  }
+          translate(D, TypeDependence::Instantiation, Instantiation) |
+          translate(D, TypeDependence::Dependent, Dependent) |
+          translate(D, TypeDependence::Error, Error) |
+          translate(D, TypeDependence::VariablyModified, VariablyModified)) {}
 
   Dependence(ExprDependence D)
       : V(translate(D, ExprDependence::UnexpandedPack, UnexpandedPack) |
@@ -133,17 +134,20 @@ class Dependence {
   Dependence(NestedNameSpecifierDependence D) :
     V ( translate(D, NNSDependence::UnexpandedPack, UnexpandedPack) |
             translate(D, NNSDependence::Instantiation, Instantiation) |
-            translate(D, NNSDependence::Dependent, Dependent)){}
+            translate(D, NNSDependence::Dependent, Dependent) |
+            translate(D, NNSDependence::Error, Error)) {}
 
   Dependence(TemplateArgumentDependence D)
       : V(translate(D, TADependence::UnexpandedPack, UnexpandedPack) |
-             translate(D, TADependence::Instantiation, Instantiation) |
-             translate(D, TADependence::Dependent, Dependent)) {}
+          translate(D, TADependence::Instantiation, Instantiation) |
+          translate(D, TADependence::Dependent, Dependent) |
+          translate(D, TADependence::Error, Error)) {}
 
   Dependence(TemplateNameDependence D)
       : V(translate(D, TNDependence::UnexpandedPack, UnexpandedPack) |
              translate(D, TNDependence::Instantiation, Instantiation) |
-             translate(D, TNDependence::Dependent, Dependent)) {}
+             translate(D, TNDependence::Dependent, Dependent) |
+             translate(D, TNDependence::Error, Error)) {}
 
   TypeDependence type() const {
     return translate(V, UnexpandedPack, TypeDependence::UnexpandedPack) |
@@ -164,19 +168,22 @@ class Dependence {
   NestedNameSpecifierDependence nestedNameSpecifier() const {
     return translate(V, UnexpandedPack, NNSDependence::UnexpandedPack) |
            translate(V, Instantiation, NNSDependence::Instantiation) |
-           translate(V, Dependent, NNSDependence::Dependent);
+           translate(V, Dependent, NNSDependence::Dependent) |
+           translate(V, Error, NNSDependence::Error);
   }
 
   TemplateArgumentDependence templateArgument() const {
     return translate(V, UnexpandedPack, TADependence::UnexpandedPack) |
            translate(V, Instantiation, TADependence::Instantiation) |
-           translate(V, Dependent, TADependence::Dependent);
+           translate(V, Dependent, TADependence::Dependent) |
+           translate(V, Error, TADependence::Error);
   }
 
   TemplateNameDependence templateName() const {
     return translate(V, UnexpandedPack, TNDependence::UnexpandedPack) |
            translate(V, Instantiation, TNDependence::Instantiation) |
-           translate(V, Dependent, TNDependence::Dependent);
+           translate(V, Dependent, TNDependence::Dependent) |
+           translate(V, Error, TNDependence::Error);
   }
 
 private:
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 8ee8aa96ae638..66eafaaab715e 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -2118,21 +2118,21 @@ class ParenExpr : public Expr {
 ///
 class UnaryOperator final
     : public Expr,
-      private llvm::TrailingObjects {
+      private llvm::TrailingObjects {
   Stmt *Val;
 
-  size_t numTrailingObjects(OverloadToken) const {
+  size_t numTrailingObjects(OverloadToken) const {
     return UnaryOperatorBits.HasFPFeatures ? 1 : 0;
   }
 
-  FPOptions &getTrailingFPFeatures() {
+  FPOptionsOverride &getTrailingFPFeatures() {
     assert(UnaryOperatorBits.HasFPFeatures);
-    return *getTrailingObjects();
+    return *getTrailingObjects();
   }
 
-  const FPOptions &getTrailingFPFeatures() const {
+  const FPOptionsOverride &getTrailingFPFeatures() const {
     assert(UnaryOperatorBits.HasFPFeatures);
-    return *getTrailingObjects();
+    return *getTrailingObjects();
   }
 
 public:
@@ -2141,7 +2141,7 @@ class UnaryOperator final
 protected:
   UnaryOperator(const ASTContext &Ctx, Expr *input, Opcode opc, QualType type,
                 ExprValueKind VK, ExprObjectKind OK, SourceLocation l,
-                bool CanOverflow, FPOptions FPFeatures);
+                bool CanOverflow, FPOptionsOverride FPFeatures);
 
   /// Build an empty unary operator.
   explicit UnaryOperator(bool HasFPFeatures, EmptyShell Empty)
@@ -2156,7 +2156,7 @@ class UnaryOperator final
   static UnaryOperator *Create(const ASTContext &C, Expr *input, Opcode opc,
                                QualType type, ExprValueKind VK,
                                ExprObjectKind OK, SourceLocation l,
-                               bool CanOverflow, FPOptions FPFeatures);
+                               bool CanOverflow, FPOptionsOverride FPFeatures);
 
   Opcode getOpcode() const {
     return static_cast(UnaryOperatorBits.Opc);
@@ -2182,13 +2182,13 @@ class UnaryOperator final
   // Get the FP contractability status of this operator. Only meaningful for
   // operations on floating point types.
   bool isFPContractableWithinStatement(const LangOptions &LO) const {
-    return getFPFeatures(LO).allowFPContractWithinStatement();
+    return getFPFeaturesInEffect(LO).allowFPContractWithinStatement();
   }
 
   // Get the FENV_ACCESS status of this operator. Only meaningful for
   // operations on floating point types.
   bool isFEnvAccessOn(const LangOptions &LO) const {
-    return getFPFeatures(LO).allowFEnvAccess();
+    return getFPFeaturesInEffect(LO).getAllowFEnvAccess();
   }
 
   /// isPostfix - Return true if this is a postfix operation, like x++.
@@ -2263,19 +2263,26 @@ class UnaryOperator final
 
 protected:
   /// Get FPFeatures from trailing storage
-  FPOptions getStoredFPFeatures() const { return getTrailingFPFeatures(); }
+  FPOptionsOverride getStoredFPFeatures() const {
+    return getTrailingFPFeatures();
+  }
 
   /// Set FPFeatures in trailing storage, used only by Serialization
-  void setStoredFPFeatures(FPOptions F) { getTrailingFPFeatures() = F; }
+  void setStoredFPFeatures(FPOptionsOverride F) { getTrailingFPFeatures() = F; }
 
 public:
   // Get the FP features status of this operator. Only meaningful for
   // operations on floating point types.
-  FPOptions getFPFeatures(const LangOptions &LO) const {
+  FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
     if (UnaryOperatorBits.HasFPFeatures)
-      return getStoredFPFeatures();
+      return getStoredFPFeatures().applyOverrides(LO);
     return FPOptions::defaultWithoutTrailingStorage(LO);
   }
+  FPOptionsOverride getFPOptionsOverride() const {
+    if (UnaryOperatorBits.HasFPFeatures)
+      return getStoredFPFeatures();
+    return FPOptionsOverride();
+  }
 
   friend TrailingObjects;
   friend class ASTReader;
@@ -3633,14 +3640,14 @@ class BinaryOperator : public Expr {
   size_t offsetOfTrailingStorage() const;
 
   /// Return a pointer to the trailing FPOptions
-  FPOptions *getTrailingFPFeatures() {
+  FPOptionsOverride *getTrailingFPFeatures() {
     assert(BinaryOperatorBits.HasFPFeatures);
-    return reinterpret_cast(reinterpret_cast(this) +
-                                         offsetOfTrailingStorage());
+    return reinterpret_cast(
+        reinterpret_cast(this) + offsetOfTrailingStorage());
   }
-  const FPOptions *getTrailingFPFeatures() const {
+  const FPOptionsOverride *getTrailingFPFeatures() const {
     assert(BinaryOperatorBits.HasFPFeatures);
-    return reinterpret_cast(
+    return reinterpret_cast(
         reinterpret_cast(this) + offsetOfTrailingStorage());
   }
 
@@ -3648,7 +3655,7 @@ class BinaryOperator : public Expr {
   /// allocated for the trailing objects when needed.
   BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc,
                  QualType ResTy, ExprValueKind VK, ExprObjectKind OK,
-                 SourceLocation opLoc, FPOptions FPFeatures);
+                 SourceLocation opLoc, FPOptionsOverride FPFeatures);
 
   /// Construct an empty binary operator.
   explicit BinaryOperator(EmptyShell Empty) : Expr(BinaryOperatorClass, Empty) {
@@ -3661,7 +3668,7 @@ class BinaryOperator : public Expr {
   static BinaryOperator *Create(const ASTContext &C, Expr *lhs, Expr *rhs,
                                 Opcode opc, QualType ResTy, ExprValueKind VK,
                                 ExprObjectKind OK, SourceLocation opLoc,
-                                FPOptions FPFeatures);
+                                FPOptionsOverride FPFeatures);
   SourceLocation getExprLoc() const { return getOperatorLoc(); }
   SourceLocation getOperatorLoc() const { return BinaryOperatorBits.OpLoc; }
   void setOperatorLoc(SourceLocation L) { BinaryOperatorBits.OpLoc = L; }
@@ -3808,40 +3815,48 @@ class BinaryOperator : public Expr {
   bool hasStoredFPFeatures() const { return BinaryOperatorBits.HasFPFeatures; }
 
   /// Get FPFeatures from trailing storage
-  FPOptions getStoredFPFeatures() const {
+  FPOptionsOverride getStoredFPFeatures() const {
     assert(hasStoredFPFeatures());
     return *getTrailingFPFeatures();
   }
   /// Set FPFeatures in trailing storage, used only by Serialization
-  void setStoredFPFeatures(FPOptions F) {
+  void setStoredFPFeatures(FPOptionsOverride F) {
     assert(BinaryOperatorBits.HasFPFeatures);
     *getTrailingFPFeatures() = F;
   }
 
   // Get the FP features status of this operator. Only meaningful for
   // operations on floating point types.
-  FPOptions getFPFeatures(const LangOptions &LO) const {
+  FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
     if (BinaryOperatorBits.HasFPFeatures)
-      return getStoredFPFeatures();
+      return getStoredFPFeatures().applyOverrides(LO);
     return FPOptions::defaultWithoutTrailingStorage(LO);
   }
 
+  // This is used in ASTImporter
+  FPOptionsOverride getFPFeatures(const LangOptions &LO) const {
+    if (BinaryOperatorBits.HasFPFeatures)
+      return getStoredFPFeatures();
+    return FPOptionsOverride();
+  }
+
   // Get the FP contractability status of this operator. Only meaningful for
   // operations on floating point types.
   bool isFPContractableWithinStatement(const LangOptions &LO) const {
-    return getFPFeatures(LO).allowFPContractWithinStatement();
+    return getFPFeaturesInEffect(LO).allowFPContractWithinStatement();
   }
 
   // Get the FENV_ACCESS status of this operator. Only meaningful for
   // operations on floating point types.
   bool isFEnvAccessOn(const LangOptions &LO) const {
-    return getFPFeatures(LO).allowFEnvAccess();
+    return getFPFeaturesInEffect(LO).getAllowFEnvAccess();
   }
 
 protected:
   BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc,
                  QualType ResTy, ExprValueKind VK, ExprObjectKind OK,
-                 SourceLocation opLoc, FPOptions FPFeatures, bool dead2);
+                 SourceLocation opLoc, FPOptionsOverride FPFeatures,
+                 bool dead2);
 
   /// Construct an empty BinaryOperator, SC is CompoundAssignOperator.
   BinaryOperator(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) {
@@ -3851,7 +3866,7 @@ class BinaryOperator : public Expr {
   /// Return the size in bytes needed for the trailing objects.
   /// Used to allocate the right amount of storage.
   static unsigned sizeOfTrailingObjects(bool HasFPFeatures) {
-    return HasFPFeatures * sizeof(FPOptions);
+    return HasFPFeatures * sizeof(FPOptionsOverride);
   }
 };
 
@@ -3873,7 +3888,7 @@ class CompoundAssignOperator : public BinaryOperator {
 protected:
   CompoundAssignOperator(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc,
                          QualType ResType, ExprValueKind VK, ExprObjectKind OK,
-                         SourceLocation OpLoc, FPOptions FPFeatures,
+                         SourceLocation OpLoc, FPOptionsOverride FPFeatures,
                          QualType CompLHSType, QualType CompResultType)
       : BinaryOperator(C, lhs, rhs, opc, ResType, VK, OK, OpLoc, FPFeatures,
                        true),
@@ -3889,7 +3904,7 @@ class CompoundAssignOperator : public BinaryOperator {
   static CompoundAssignOperator *
   Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
          ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc,
-         FPOptions FPFeatures, QualType CompLHSType = QualType(),
+         FPOptionsOverride FPFeatures, QualType CompLHSType = QualType(),
          QualType CompResultType = QualType());
 
   // The two computation types are the type the LHS is converted
diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
index 4c65daaa63fc3..178f4db770618 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -84,6 +84,7 @@ class CXXOperatorCallExpr final : public CallExpr {
   friend class ASTStmtWriter;
 
   SourceRange Range;
+  FPOptionsOverride Overrides;
 
   // CXXOperatorCallExpr has some trailing objects belonging
   // to CallExpr. See CallExpr for the details.
@@ -92,7 +93,7 @@ class CXXOperatorCallExpr final : public CallExpr {
 
   CXXOperatorCallExpr(OverloadedOperatorKind OpKind, Expr *Fn,
                       ArrayRef Args, QualType Ty, ExprValueKind VK,
-                      SourceLocation OperatorLoc, FPOptions FPFeatures,
+                      SourceLocation OperatorLoc, FPOptionsOverride FPFeatures,
                       ADLCallKind UsesADL);
 
   CXXOperatorCallExpr(unsigned NumArgs, EmptyShell Empty);
@@ -101,7 +102,7 @@ class CXXOperatorCallExpr final : public CallExpr {
   static CXXOperatorCallExpr *
   Create(const ASTContext &Ctx, OverloadedOperatorKind OpKind, Expr *Fn,
          ArrayRef Args, QualType Ty, ExprValueKind VK,
-         SourceLocation OperatorLoc, FPOptions FPFeatures,
+         SourceLocation OperatorLoc, FPOptionsOverride FPFeatures,
          ADLCallKind UsesADL = NotADL);
 
   static CXXOperatorCallExpr *CreateEmpty(const ASTContext &Ctx,
@@ -164,20 +165,10 @@ class CXXOperatorCallExpr final : public CallExpr {
     return T->getStmtClass() == CXXOperatorCallExprClass;
   }
 
-  // Set the FP contractability status of this operator. Only meaningful for
+  // Set the FPFeatures status of this operator. Only meaningful for
   // operations on floating point types.
-  void setFPFeatures(FPOptions F) {
-    CXXOperatorCallExprBits.FPFeatures = F.getAsOpaqueInt();
-  }
-  FPOptions getFPFeatures() const {
-    return FPOptions(CXXOperatorCallExprBits.FPFeatures);
-  }
-
-  // Get the FP contractability status of this operator. Only meaningful for
-  // operations on floating point types.
-  bool isFPContractableWithinStatement() const {
-    return getFPFeatures().allowFPContractWithinStatement();
-  }
+  void setFPFeatures(FPOptionsOverride F) { Overrides = F; }
+  FPOptionsOverride getFPFeatures() const { return Overrides; }
 };
 
 /// Represents a call to a member function that
@@ -1861,6 +1852,8 @@ class LambdaExpr final : public Expr,
   Stmt **getStoredStmts() { return getTrailingObjects(); }
   Stmt *const *getStoredStmts() const { return getTrailingObjects(); }
 
+  void initBodyIfNeeded() const;
+
 public:
   friend class ASTStmtReader;
   friend class ASTStmtWriter;
@@ -2009,17 +2002,12 @@ class LambdaExpr final : public Expr,
   /// a \p CompoundStmt, but can also be \p CoroutineBodyStmt wrapping
   /// a \p CompoundStmt. Note that unlike functions, lambda-expressions
   /// cannot have a function-try-block.
-  Stmt *getBody() const { return getStoredStmts()[capture_size()]; }
+  Stmt *getBody() const;
 
   /// Retrieve the \p CompoundStmt representing the body of the lambda.
   /// This is a convenience function for callers who do not need
   /// to handle node(s) which may wrap a \p CompoundStmt.
-  const CompoundStmt *getCompoundStmtBody() const {
-    Stmt *Body = getBody();
-    if (const auto *CoroBody = dyn_cast(Body))
-      return cast(CoroBody->getBody());
-    return cast(Body);
-  }
+  const CompoundStmt *getCompoundStmtBody() const;
   CompoundStmt *getCompoundStmtBody() {
     const auto *ConstThis = this;
     return const_cast(ConstThis->getCompoundStmtBody());
@@ -2048,15 +2036,9 @@ class LambdaExpr final : public Expr,
 
   SourceLocation getEndLoc() const LLVM_READONLY { return ClosingBrace; }
 
-  child_range children() {
-    // Includes initialization exprs plus body stmt
-    return child_range(getStoredStmts(), getStoredStmts() + capture_size() + 1);
-  }
-
-  const_child_range children() const {
-    return const_child_range(getStoredStmts(),
-                             getStoredStmts() + capture_size() + 1);
-  }
+  /// Includes the captures and the body of the lambda.
+  child_range children();
+  const_child_range children() const;
 };
 
 /// An expression "T()" which creates a value-initialized rvalue of type
diff --git a/clang/include/clang/AST/ExprOpenMP.h b/clang/include/clang/AST/ExprOpenMP.h
index a2b59a6f26962..be5dda9923346 100644
--- a/clang/include/clang/AST/ExprOpenMP.h
+++ b/clang/include/clang/AST/ExprOpenMP.h
@@ -17,46 +17,61 @@
 #include "clang/AST/Expr.h"
 
 namespace clang {
-/// OpenMP 4.0 [2.4, Array Sections].
+/// OpenMP 5.0 [2.1.5, Array Sections].
 /// To specify an array section in an OpenMP construct, array subscript
 /// expressions are extended with the following syntax:
 /// \code
+/// [ lower-bound : length : stride ]
+/// [ lower-bound : length : ]
 /// [ lower-bound : length ]
+/// [ lower-bound : : stride ]
+/// [ lower-bound : : ]
 /// [ lower-bound : ]
+/// [ : length : stride ]
+/// [ : length : ]
 /// [ : length ]
+/// [ : : stride ]
+/// [ : : ]
 /// [ : ]
 /// \endcode
 /// The array section must be a subset of the original array.
 /// Array sections are allowed on multidimensional arrays. Base language array
 /// subscript expressions can be used to specify length-one dimensions of
 /// multidimensional array sections.
-/// The lower-bound and length are integral type expressions. When evaluated
+/// Each of the lower-bound, length, and stride expressions if specified must be
+/// an integral type expressions of the base language. When evaluated
 /// they represent a set of integer values as follows:
 /// \code
-/// { lower-bound, lower-bound + 1, lower-bound + 2,... , lower-bound + length -
-/// 1 }
+/// { lower-bound, lower-bound + stride, lower-bound + 2 * stride,... ,
+/// lower-bound + ((length - 1) * stride) }
 /// \endcode
 /// The lower-bound and length must evaluate to non-negative integers.
+/// The stride must evaluate to a positive integer.
 /// When the size of the array dimension is not known, the length must be
 /// specified explicitly.
-/// When the length is absent, it defaults to the size of the array dimension
-/// minus the lower-bound.
-/// When the lower-bound is absent it defaults to 0.
+/// When the stride is absent it defaults to 1.
+/// When the length is absent it defaults to ⌈(size − lower-bound)/stride⌉,
+/// where size is the size of the array dimension. When the lower-bound is
+/// absent it defaults to 0.
 class OMPArraySectionExpr : public Expr {
-  enum { BASE, LOWER_BOUND, LENGTH, END_EXPR };
+  enum { BASE, LOWER_BOUND, LENGTH, STRIDE, END_EXPR };
   Stmt *SubExprs[END_EXPR];
-  SourceLocation ColonLoc;
+  SourceLocation ColonLocFirst;
+  SourceLocation ColonLocSecond;
   SourceLocation RBracketLoc;
 
 public:
-  OMPArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, QualType Type,
-                      ExprValueKind VK, ExprObjectKind OK,
-                      SourceLocation ColonLoc, SourceLocation RBracketLoc)
-      : Expr(OMPArraySectionExprClass, Type, VK, OK), ColonLoc(ColonLoc),
+  OMPArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, Expr *Stride,
+                      QualType Type, ExprValueKind VK, ExprObjectKind OK,
+                      SourceLocation ColonLocFirst,
+                      SourceLocation ColonLocSecond, SourceLocation RBracketLoc)
+      : Expr(OMPArraySectionExprClass, Type, VK, OK),
+        ColonLocFirst(ColonLocFirst), ColonLocSecond(ColonLocSecond),
         RBracketLoc(RBracketLoc) {
     SubExprs[BASE] = Base;
     SubExprs[LOWER_BOUND] = LowerBound;
     SubExprs[LENGTH] = Length;
+    SubExprs[STRIDE] = Stride;
     setDependence(computeDependence(this));
   }
 
@@ -89,13 +104,22 @@ class OMPArraySectionExpr : public Expr {
   /// Set length of the array section.
   void setLength(Expr *E) { SubExprs[LENGTH] = E; }
 
+  /// Get stride of array section.
+  Expr *getStride() { return cast_or_null(SubExprs[STRIDE]); }
+  const Expr *getStride() const { return cast_or_null(SubExprs[STRIDE]); }
+  /// Set length of the array section.
+  void setStride(Expr *E) { SubExprs[STRIDE] = E; }
+
   SourceLocation getBeginLoc() const LLVM_READONLY {
     return getBase()->getBeginLoc();
   }
   SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; }
 
-  SourceLocation getColonLoc() const { return ColonLoc; }
-  void setColonLoc(SourceLocation L) { ColonLoc = L; }
+  SourceLocation getColonLocFirst() const { return ColonLocFirst; }
+  void setColonLocFirst(SourceLocation L) { ColonLocFirst = L; }
+
+  SourceLocation getColonLocSecond() const { return ColonLocSecond; }
+  void setColonLocSecond(SourceLocation L) { ColonLocSecond = L; }
 
   SourceLocation getRBracketLoc() const { return RBracketLoc; }
   void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
diff --git a/clang/include/clang/AST/JSONNodeDumper.h b/clang/include/clang/AST/JSONNodeDumper.h
index ae7b4c9a17ea7..4e7162992418a 100644
--- a/clang/include/clang/AST/JSONNodeDumper.h
+++ b/clang/include/clang/AST/JSONNodeDumper.h
@@ -23,10 +23,13 @@
 #include "clang/AST/CommentVisitor.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/Mangle.h"
+#include "clang/AST/Type.h"
 #include "llvm/Support/JSON.h"
 
 namespace clang {
 
+class APValue;
+
 class NodeStreamer {
   bool FirstChild = true;
   bool TopLevel = true;
@@ -201,6 +204,7 @@ class JSONNodeDumper
   void Visit(const OMPClause *C);
   void Visit(const BlockDecl::Capture &C);
   void Visit(const GenericSelectionExpr::ConstAssociation &A);
+  void Visit(const APValue &Value, QualType Ty);
 
   void VisitTypedefType(const TypedefType *TT);
   void VisitFunctionType(const FunctionType *T);
diff --git a/clang/include/clang/AST/NestedNameSpecifier.h b/clang/include/clang/AST/NestedNameSpecifier.h
index 47f5268c938b5..540ac3df48fe0 100644
--- a/clang/include/clang/AST/NestedNameSpecifier.h
+++ b/clang/include/clang/AST/NestedNameSpecifier.h
@@ -214,6 +214,9 @@ class NestedNameSpecifier : public llvm::FoldingSetNode {
   /// parameter pack (for C++11 variadic templates).
   bool containsUnexpandedParameterPack() const;
 
+  /// Whether this nested name specifier contains an error.
+  bool containsErrors() const;
+
   /// Print this nested name specifier to the given output stream. If
   /// `ResolveTemplateArguments` is true, we'll print actual types, e.g.
   /// `ns::SomeTemplate` instead of
diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h
index 6c2ca1cb10088..6de7b6deb5149 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -7556,6 +7556,8 @@ class OMPClauseVisitorBase {
   case llvm::omp::Clause::Enum:                                                \
     break;
 #include "llvm/Frontend/OpenMP/OMPKinds.def"
+    default:
+      break;
     }
   }
   // Base case, ignore it. :)
diff --git a/clang/include/clang/AST/ParentMapContext.h b/clang/include/clang/AST/ParentMapContext.h
index 5f9936b28e8fb..be4d75df7b999 100644
--- a/clang/include/clang/AST/ParentMapContext.h
+++ b/clang/include/clang/AST/ParentMapContext.h
@@ -67,7 +67,7 @@ class ParentMapContext {
 private:
   ASTContext &ASTCtx;
   class ParentMap;
-  TraversalKind Traversal = TK_IgnoreUnlessSpelledInSource;
+  TraversalKind Traversal = TK_AsIs;
   std::unique_ptr Parents;
 };
 
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index 9bbd390f61cde..3dcfc9fee629a 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -48,29 +48,6 @@
 #include 
 #include 
 
-// The following three macros are used for meta programming.  The code
-// using them is responsible for defining macro OPERATOR().
-
-// All unary operators.
-#define UNARYOP_LIST()                                                         \
-  OPERATOR(PostInc) OPERATOR(PostDec) OPERATOR(PreInc) OPERATOR(PreDec)        \
-      OPERATOR(AddrOf) OPERATOR(Deref) OPERATOR(Plus) OPERATOR(Minus)          \
-      OPERATOR(Not) OPERATOR(LNot) OPERATOR(Real) OPERATOR(Imag)               \
-      OPERATOR(Extension) OPERATOR(Coawait)
-
-// All binary operators (excluding compound assign operators).
-#define BINOP_LIST()                                                           \
-  OPERATOR(PtrMemD) OPERATOR(PtrMemI) OPERATOR(Mul) OPERATOR(Div)              \
-      OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) OPERATOR(Shr)    \
-      OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) OPERATOR(GE) OPERATOR(EQ)         \
-      OPERATOR(NE) OPERATOR(Cmp) OPERATOR(And) OPERATOR(Xor) OPERATOR(Or)      \
-      OPERATOR(LAnd) OPERATOR(LOr) OPERATOR(Assign) OPERATOR(Comma)
-
-// All compound assign operators.
-#define CAO_LIST()                                                             \
-  OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub)        \
-      OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or) OPERATOR(Xor)
-
 namespace clang {
 
 // A helper macro to implement short-circuiting when recursing.  It
@@ -83,6 +60,42 @@ namespace clang {
       return false;                                                            \
   } while (false)
 
+namespace detail {
+
+template 
+struct has_same_member_pointer_type : std::false_type {};
+template 
+struct has_same_member_pointer_type
+    : std::true_type {};
+
+template  struct is_same_method_impl {
+  template 
+  static bool isSameMethod(FirstMethodPtrTy FirstMethodPtr,
+                           SecondMethodPtrTy SecondMethodPtr) {
+    return false;
+  }
+};
+
+template <> struct is_same_method_impl {
+  template 
+  static bool isSameMethod(FirstMethodPtrTy FirstMethodPtr,
+                           SecondMethodPtrTy SecondMethodPtr) {
+    return FirstMethodPtr == SecondMethodPtr;
+  }
+};
+
+/// Returns true if and only if \p FirstMethodPtr and \p SecondMethodPtr
+/// are pointers to the same non-static member function.
+template 
+bool isSameMethod(FirstMethodPtrTy FirstMethodPtr,
+                  SecondMethodPtrTy SecondMethodPtr) {
+  return is_same_method_impl::value>::isSameMethod(FirstMethodPtr, SecondMethodPtr);
+}
+
+} // end namespace detail
+
 /// A class that does preorder or postorder
 /// depth-first traversal on the entire Clang AST and visits each node.
 ///
@@ -325,23 +338,17 @@ template  class RecursiveASTVisitor {
   Stmt::child_range getStmtChildren(Stmt *S) { return S->children(); }
 
 private:
-  template
-  struct has_same_member_pointer_type : std::false_type {};
-  template
-  struct has_same_member_pointer_type
-      : std::true_type {};
-
   // Traverse the given statement. If the most-derived traverse function takes a
   // data recursion queue, pass it on; otherwise, discard it. Note that the
   // first branch of this conditional must compile whether or not the derived
   // class can take a queue, so if we're taking the second arm, make the first
   // arm call our function rather than the derived class version.
 #define TRAVERSE_STMT_BASE(NAME, CLASS, VAR, QUEUE)                            \
-  (has_same_member_pointer_type::value     \
+  (::clang::detail::has_same_member_pointer_type<                              \
+       decltype(&RecursiveASTVisitor::Traverse##NAME),                         \
+       decltype(&Derived::Traverse##NAME)>::value                              \
        ? static_cast::value,                   \
              Derived &, RecursiveASTVisitor &>>(*this)                         \
@@ -377,60 +384,6 @@ template  class RecursiveASTVisitor {
   bool Visit##CLASS(CLASS *S) { return true; }
 #include "clang/AST/StmtNodes.inc"
 
-// Define Traverse*(), WalkUpFrom*(), and Visit*() for unary
-// operator methods.  Unary operators are not classes in themselves
-// (they're all opcodes in UnaryOperator) but do have visitors.
-#define OPERATOR(NAME)                                                         \
-  bool TraverseUnary##NAME(UnaryOperator *S,                                   \
-                           DataRecursionQueue *Queue = nullptr) {              \
-    if (!getDerived().shouldTraversePostOrder())                               \
-      TRY_TO(WalkUpFromUnary##NAME(S));                                        \
-    TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getSubExpr());                          \
-    return true;                                                               \
-  }                                                                            \
-  bool WalkUpFromUnary##NAME(UnaryOperator *S) {                               \
-    TRY_TO(WalkUpFromUnaryOperator(S));                                        \
-    TRY_TO(VisitUnary##NAME(S));                                               \
-    return true;                                                               \
-  }                                                                            \
-  bool VisitUnary##NAME(UnaryOperator *S) { return true; }
-
-  UNARYOP_LIST()
-#undef OPERATOR
-
-// Define Traverse*(), WalkUpFrom*(), and Visit*() for binary
-// operator methods.  Binary operators are not classes in themselves
-// (they're all opcodes in BinaryOperator) but do have visitors.
-#define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE)                               \
-  bool TraverseBin##NAME(BINOP_TYPE *S, DataRecursionQueue *Queue = nullptr) { \
-    if (!getDerived().shouldTraversePostOrder())                               \
-      TRY_TO(WalkUpFromBin##NAME(S));                                          \
-    TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLHS());                              \
-    TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRHS());                              \
-    return true;                                                               \
-  }                                                                            \
-  bool WalkUpFromBin##NAME(BINOP_TYPE *S) {                                    \
-    TRY_TO(WalkUpFrom##BINOP_TYPE(S));                                         \
-    TRY_TO(VisitBin##NAME(S));                                                 \
-    return true;                                                               \
-  }                                                                            \
-  bool VisitBin##NAME(BINOP_TYPE *S) { return true; }
-
-#define OPERATOR(NAME) GENERAL_BINOP_FALLBACK(NAME, BinaryOperator)
-  BINOP_LIST()
-#undef OPERATOR
-
-// Define Traverse*(), WalkUpFrom*(), and Visit*() for compound
-// assignment methods.  Compound assignment operators are not
-// classes in themselves (they're all opcodes in
-// CompoundAssignOperator) but do have visitors.
-#define OPERATOR(NAME)                                                         \
-  GENERAL_BINOP_FALLBACK(NAME##Assign, CompoundAssignOperator)
-
-  CAO_LIST()
-#undef OPERATOR
-#undef GENERAL_BINOP_FALLBACK
-
 // ---- Methods on Types ----
 // FIXME: revamp to take TypeLoc's rather than Types.
 
@@ -549,42 +502,6 @@ template  class RecursiveASTVisitor {
 template 
 bool RecursiveASTVisitor::dataTraverseNode(Stmt *S,
                                                     DataRecursionQueue *Queue) {
-#define DISPATCH_STMT(NAME, CLASS, VAR)                                        \
-  return TRAVERSE_STMT_BASE(NAME, CLASS, VAR, Queue);
-
-  // If we have a binary expr, dispatch to the subcode of the binop.  A smart
-  // optimizer (e.g. LLVM) will fold this comparison into the switch stmt
-  // below.
-  if (BinaryOperator *BinOp = dyn_cast(S)) {
-    switch (BinOp->getOpcode()) {
-#define OPERATOR(NAME)                                                         \
-  case BO_##NAME:                                                              \
-    DISPATCH_STMT(Bin##NAME, BinaryOperator, S);
-
-      BINOP_LIST()
-#undef OPERATOR
-#undef BINOP_LIST
-
-#define OPERATOR(NAME)                                                         \
-  case BO_##NAME##Assign:                                                      \
-    DISPATCH_STMT(Bin##NAME##Assign, CompoundAssignOperator, S);
-
-      CAO_LIST()
-#undef OPERATOR
-#undef CAO_LIST
-    }
-  } else if (UnaryOperator *UnOp = dyn_cast(S)) {
-    switch (UnOp->getOpcode()) {
-#define OPERATOR(NAME)                                                         \
-  case UO_##NAME:                                                              \
-    DISPATCH_STMT(Unary##NAME, UnaryOperator, S);
-
-      UNARYOP_LIST()
-#undef OPERATOR
-#undef UNARYOP_LIST
-    }
-  }
-
   // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
   switch (S->getStmtClass()) {
   case Stmt::NoStmtClass:
@@ -592,7 +509,7 @@ bool RecursiveASTVisitor::dataTraverseNode(Stmt *S,
 #define ABSTRACT_STMT(STMT)
 #define STMT(CLASS, PARENT)                                                    \
   case Stmt::CLASS##Class:                                                     \
-    DISPATCH_STMT(CLASS, CLASS, S);
+    return TRAVERSE_STMT_BASE(CLASS, CLASS, S, Queue);
 #include "clang/AST/StmtNodes.inc"
   }
 
@@ -603,23 +520,44 @@ bool RecursiveASTVisitor::dataTraverseNode(Stmt *S,
 
 template 
 bool RecursiveASTVisitor::PostVisitStmt(Stmt *S) {
+  // In pre-order traversal mode, each Traverse##STMT method is responsible for
+  // calling WalkUpFrom. Therefore, if the user overrides Traverse##STMT and
+  // does not call the default implementation, the WalkUpFrom callback is not
+  // called. Post-order traversal mode should provide the same behavior
+  // regarding method overrides.
+  //
+  // In post-order traversal mode the Traverse##STMT method, when it receives a
+  // DataRecursionQueue, can't call WalkUpFrom after traversing children because
+  // it only enqueues the children and does not traverse them. TraverseStmt
+  // traverses the enqueued children, and we call WalkUpFrom here.
+  //
+  // However, to make pre-order and post-order modes identical with regards to
+  // whether they call WalkUpFrom at all, we call WalkUpFrom if and only if the
+  // user did not override the Traverse##STMT method. We implement the override
+  // check with isSameMethod calls below.
+
   switch (S->getStmtClass()) {
   case Stmt::NoStmtClass:
     break;
 #define ABSTRACT_STMT(STMT)
 #define STMT(CLASS, PARENT)                                                    \
   case Stmt::CLASS##Class:                                                     \
-    TRY_TO(WalkUpFrom##CLASS(static_cast(S))); break;
+    if (::clang::detail::isSameMethod(&RecursiveASTVisitor::Traverse##CLASS,   \
+                                      &Derived::Traverse##CLASS)) {            \
+      TRY_TO(WalkUpFrom##CLASS(static_cast(S)));                      \
+    }                                                                          \
+    break;
 #define INITLISTEXPR(CLASS, PARENT)                                            \
   case Stmt::CLASS##Class:                                                     \
-    {                                                                          \
+    if (::clang::detail::isSameMethod(&RecursiveASTVisitor::Traverse##CLASS,   \
+                                      &Derived::Traverse##CLASS)) {            \
       auto ILE = static_cast(S);                                      \
       if (auto Syn = ILE->isSemanticForm() ? ILE->getSyntacticForm() : ILE)    \
         TRY_TO(WalkUpFrom##CLASS(Syn));                                        \
       if (auto Sem = ILE->isSemanticForm() ? ILE : ILE->getSemanticForm())     \
         TRY_TO(WalkUpFrom##CLASS(Sem));                                        \
-      break;                                                                   \
-    }
+    }                                                                          \
+    break;
 #include "clang/AST/StmtNodes.inc"
   }
 
@@ -669,9 +607,6 @@ bool RecursiveASTVisitor::TraverseStmt(Stmt *S,
   return true;
 }
 
-#define DISPATCH(NAME, CLASS, VAR)                                             \
-  return getDerived().Traverse##NAME(static_cast(VAR))
-
 template 
 bool RecursiveASTVisitor::TraverseType(QualType T) {
   if (T.isNull())
@@ -681,7 +616,8 @@ bool RecursiveASTVisitor::TraverseType(QualType T) {
 #define ABSTRACT_TYPE(CLASS, BASE)
 #define TYPE(CLASS, BASE)                                                      \
   case Type::CLASS:                                                            \
-    DISPATCH(CLASS##Type, CLASS##Type, const_cast(T.getTypePtr()));
+    return getDerived().Traverse##CLASS##Type(                                 \
+        static_cast(const_cast(T.getTypePtr())));
 #include "clang/AST/TypeNodes.inc"
   }
 
@@ -731,8 +667,6 @@ bool RecursiveASTVisitor::TraverseDecl(Decl *D) {
   return true;
 }
 
-#undef DISPATCH
-
 template 
 bool RecursiveASTVisitor::TraverseNestedNameSpecifier(
     NestedNameSpecifier *NNS) {
@@ -2220,8 +2154,13 @@ DEF_TRAVERSE_DECL(RequiresExprBodyDecl, {})
         TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt);                              \
       }                                                                        \
     }                                                                          \
-    if (!Queue && ReturnValue && getDerived().shouldTraversePostOrder())       \
+    /* Call WalkUpFrom if TRY_TO_TRAVERSE_OR_ENQUEUE_STMT has traversed the    \
+     * children already. If TRY_TO_TRAVERSE_OR_ENQUEUE_STMT only enqueued the  \
+     * children, PostVisitStmt will call WalkUpFrom after we are done visiting \
+     * children. */                                                            \
+    if (!Queue && ReturnValue && getDerived().shouldTraversePostOrder()) {     \
       TRY_TO(WalkUpFrom##STMT(S));                                             \
+    }                                                                          \
     return ReturnValue;                                                        \
   }
 
@@ -2392,6 +2331,9 @@ bool RecursiveASTVisitor::TraverseSynOrSemInitListExpr(
     for (Stmt *SubStmt : S->children()) {
       TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt);
     }
+
+    if (!Queue && getDerived().shouldTraversePostOrder())
+      TRY_TO(WalkUpFromInitListExpr(S));
   }
   return true;
 }
@@ -3004,6 +2946,8 @@ bool RecursiveASTVisitor::TraverseOMPClause(OMPClause *C) {
   case llvm::omp::Clause::Enum:                                                \
     break;
 #include "llvm/Frontend/OpenMP/OMPKinds.def"
+  default:
+    break;
   }
   return true;
 }
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index a226790aa76cb..d3fad58fcf596 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -614,9 +614,6 @@ class alignas(void *) Stmt {
     /// The kind of this overloaded operator. One of the enumerator
     /// value of OverloadedOperatorKind.
     unsigned OperatorKind : 6;
-
-    // Only meaningful for floating point types.
-    unsigned FPFeatures : 14;
   };
 
   class CXXRewrittenBinaryOperatorBitfields {
@@ -1169,9 +1166,7 @@ class alignas(void *) Stmt {
   /// Dumps the specified AST fragment and all subtrees to
   /// \c llvm::errs().
   void dump() const;
-  void dump(SourceManager &SM) const;
-  void dump(raw_ostream &OS, SourceManager &SM) const;
-  void dump(raw_ostream &OS) const;
+  void dump(raw_ostream &OS, const ASTContext &Context) const;
 
   /// \return Unique reproducible object identifier
   int64_t getID(const ASTContext &Context) const;
@@ -2282,6 +2277,8 @@ class WhileStmt final : public Stmt,
   enum { VarOffset = 0, BodyOffsetFromCond = 1 };
   enum { NumMandatoryStmtPtr = 2 };
 
+  SourceLocation LParenLoc, RParenLoc;
+
   unsigned varOffset() const { return VarOffset; }
   unsigned condOffset() const { return VarOffset + hasVarStorage(); }
   unsigned bodyOffset() const { return condOffset() + BodyOffsetFromCond; }
@@ -2292,7 +2289,8 @@ class WhileStmt final : public Stmt,
 
   /// Build a while statement.
   WhileStmt(const ASTContext &Ctx, VarDecl *Var, Expr *Cond, Stmt *Body,
-            SourceLocation WL);
+            SourceLocation WL, SourceLocation LParenLoc,
+            SourceLocation RParenLoc);
 
   /// Build an empty while statement.
   explicit WhileStmt(EmptyShell Empty, bool HasVar);
@@ -2300,7 +2298,8 @@ class WhileStmt final : public Stmt,
 public:
   /// Create a while statement.
   static WhileStmt *Create(const ASTContext &Ctx, VarDecl *Var, Expr *Cond,
-                           Stmt *Body, SourceLocation WL);
+                           Stmt *Body, SourceLocation WL,
+                           SourceLocation LParenLoc, SourceLocation RParenLoc);
 
   /// Create an empty while statement optionally with storage for
   /// a condition variable.
@@ -2364,6 +2363,11 @@ class WhileStmt final : public Stmt,
   SourceLocation getWhileLoc() const { return WhileStmtBits.WhileLoc; }
   void setWhileLoc(SourceLocation L) { WhileStmtBits.WhileLoc = L; }
 
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+  void setLParenLoc(SourceLocation L) { LParenLoc = L; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
   SourceLocation getBeginLoc() const { return getWhileLoc(); }
   SourceLocation getEndLoc() const LLVM_READONLY {
     return getBody()->getEndLoc();
diff --git a/clang/include/clang/AST/TextNodeDumper.h b/clang/include/clang/AST/TextNodeDumper.h
index b069bd09287a8..b4cfb5a380d17 100644
--- a/clang/include/clang/AST/TextNodeDumper.h
+++ b/clang/include/clang/AST/TextNodeDumper.h
@@ -22,10 +22,13 @@
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/AST/TemplateArgumentVisitor.h"
+#include "clang/AST/Type.h"
 #include "clang/AST/TypeVisitor.h"
 
 namespace clang {
 
+class APValue;
+
 class TextTreeStructure {
   raw_ostream &OS;
   const bool ShowColors;
@@ -139,19 +142,29 @@ class TextNodeDumper
   const char *LastLocFilename = "";
   unsigned LastLocLine = ~0U;
 
-  const SourceManager *SM;
+  /// \p Context, \p SM, and \p Traits can be null. This is because we want
+  /// to be able to call \p dump() in a debugger without having to pass the
+  /// \p ASTContext to \p dump. Not all parts of the AST dump output will be
+  /// available without the \p ASTContext.
+  const ASTContext *Context = nullptr;
+  const SourceManager *SM = nullptr;
 
   /// The policy to use for printing; can be defaulted.
-  PrintingPolicy PrintPolicy;
+  PrintingPolicy PrintPolicy = LangOptions();
 
-  const comments::CommandTraits *Traits;
+  const comments::CommandTraits *Traits = nullptr;
 
   const char *getCommandName(unsigned CommandID);
 
+  void dumpAPValueChildren(const APValue &Value, QualType Ty,
+                           const APValue &(*IdxToChildFun)(const APValue &,
+                                                           unsigned),
+                           unsigned NumChildren, StringRef LabelSingular,
+                           StringRef LabelPlurial);
+
 public:
-  TextNodeDumper(raw_ostream &OS, bool ShowColors, const SourceManager *SM,
-                 const PrintingPolicy &PrintPolicy,
-                 const comments::CommandTraits *Traits);
+  TextNodeDumper(raw_ostream &OS, const ASTContext &Context, bool ShowColors);
+  TextNodeDumper(raw_ostream &OS, bool ShowColors);
 
   void Visit(const comments::Comment *C, const comments::FullComment *FC);
 
@@ -176,6 +189,8 @@ class TextNodeDumper
 
   void Visit(const GenericSelectionExpr::ConstAssociation &A);
 
+  void Visit(const APValue &Value, QualType Ty);
+
   void dumpPointer(const void *Ptr);
   void dumpLocation(SourceLocation Loc);
   void dumpSourceRange(SourceRange R);
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 10b8b41efeeb0..0fc50e0e799ff 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -1058,7 +1058,7 @@ class QualType {
 
   void dump(const char *s) const;
   void dump() const;
-  void dump(llvm::raw_ostream &OS) const;
+  void dump(llvm::raw_ostream &OS, const ASTContext &Context) const;
 
   void Profile(llvm::FoldingSetNodeID &ID) const {
     ID.AddPointer(getAsOpaquePtr());
@@ -2471,7 +2471,7 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
 
   CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h
   void dump() const;
-  void dump(llvm::raw_ostream &OS) const;
+  void dump(llvm::raw_ostream &OS, const ASTContext &Context) const;
 };
 
 /// This will check for a TypedefType by removing any existing sugar
diff --git a/clang/include/clang/AST/VTableBuilder.h b/clang/include/clang/AST/VTableBuilder.h
index e6557e4389196..241dd13f903e5 100644
--- a/clang/include/clang/AST/VTableBuilder.h
+++ b/clang/include/clang/AST/VTableBuilder.h
@@ -354,6 +354,9 @@ class VTableContextBase {
   }
 
   bool IsMicrosoftABI;
+
+  /// Determine whether this function should be assigned a vtable slot.
+  static bool hasVtableSlot(const CXXMethodDecl *MD);
 };
 
 class ItaniumVTableContext : public VTableContextBase {
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index 6dbcc01442ed6..643419743a119 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -283,9 +283,10 @@ AST_POLYMORPHIC_MATCHER(isExpansionInSystemHeader,
 /// \endcode
 ///
 /// Usable as: Matcher, Matcher, Matcher
-AST_POLYMORPHIC_MATCHER_P(isExpansionInFileMatching,
-                          AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc),
-                          std::string, RegExp) {
+AST_POLYMORPHIC_MATCHER_REGEX(isExpansionInFileMatching,
+                              AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt,
+                                                              TypeLoc),
+                              RegExp) {
   auto &SourceManager = Finder->getASTContext().getSourceManager();
   auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getBeginLoc());
   if (ExpansionLoc.isInvalid()) {
@@ -298,8 +299,7 @@ AST_POLYMORPHIC_MATCHER_P(isExpansionInFileMatching,
   }
 
   auto Filename = FileEntry->getName();
-  llvm::Regex RE(RegExp);
-  return RE.match(Filename);
+  return RegExp->match(Filename);
 }
 
 /// Matches statements that are (transitively) expanded from the named macro.
@@ -2748,11 +2748,9 @@ extern const internal::VariadicFunction, StringRef,
 /// \code
 ///   namespace foo { namespace bar { class X; } }
 /// \endcode
-AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp) {
-  assert(!RegExp.empty());
+AST_MATCHER_REGEX(NamedDecl, matchesName, RegExp) {
   std::string FullNameString = "::" + Node.getQualifiedNameAsString();
-  llvm::Regex RE(RegExp);
-  return RE.match(FullNameString);
+  return RegExp->match(FullNameString);
 }
 
 /// Matches overloaded operator names.
@@ -2864,7 +2862,7 @@ AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
 /// BaseSpecMatcher.
 ///
 /// Example:
-/// matcher hasAnyBase(hasType(cxxRecordDecl(hasName("SpecialBase")))))
+/// matcher hasAnyBase(hasType(cxxRecordDecl(hasName("SpecialBase"))))
 /// \code
 ///   class Foo;
 ///   class Bar : Foo {};
@@ -2880,6 +2878,26 @@ AST_MATCHER_P(CXXRecordDecl, hasAnyBase, internal::Matcher,
   return internal::matchesAnyBase(Node, BaseSpecMatcher, Finder, Builder);
 }
 
+/// Matches C++ classes that have a direct base matching \p BaseSpecMatcher.
+///
+/// Example:
+/// matcher hasDirectBase(hasType(cxxRecordDecl(hasName("SpecialBase"))))
+/// \code
+///   class Foo;
+///   class Bar : Foo {};
+///   class Baz : Bar {};
+///   class SpecialBase;
+///   class Proxy : SpecialBase {};  // matches Proxy
+///   class IndirectlyDerived : Proxy {};  // doesn't match
+/// \endcode
+AST_MATCHER_P(CXXRecordDecl, hasDirectBase, internal::Matcher,
+              BaseSpecMatcher) {
+  return Node.hasDefinition() &&
+         llvm::any_of(Node.bases(), [&](const CXXBaseSpecifier &Base) {
+           return BaseSpecMatcher.matches(Base, Finder, Builder);
+         });
+}
+
 /// Similar to \c isDerivedFrom(), but also matches classes that directly
 /// match \c Base.
 AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
@@ -3373,11 +3391,9 @@ extern const internal::VariadicFunction,
 /// \code
 ///     [self.bodyView loadHTMLString:html baseURL:NULL];
 /// \endcode
-AST_MATCHER_P(ObjCMessageExpr, matchesSelector, std::string, RegExp) {
-  assert(!RegExp.empty());
+AST_MATCHER_REGEX(ObjCMessageExpr, matchesSelector, RegExp) {
   std::string SelectorString = Node.getSelector().getAsString();
-  llvm::Regex RE(RegExp);
-  return RE.match(SelectorString);
+  return RegExp->match(SelectorString);
 }
 
 /// Matches when the selector is the empty selector
@@ -4323,7 +4339,7 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParam,
 /// ``parmVarDecl(isAtPosition(0))`` matches ``int a``.
 ///
 /// ``parmVarDecl(isAtPosition(1))`` matches ``int b``.
-AST_MATCHER_P(clang::ParmVarDecl, isAtPosition, unsigned, N) {
+AST_MATCHER_P(ParmVarDecl, isAtPosition, unsigned, N) {
   const clang::DeclContext *Context = Node.getParentFunctionOrMethod();
 
   if (const auto *Decl = dyn_cast_or_null(Context))
@@ -7174,10 +7190,12 @@ AST_MATCHER_P(OMPExecutableDirective, hasAnyClause,
 /// \code
 ///   #pragma omp parallel default(none)
 ///   #pragma omp parallel default(shared)
+///   #pragma omp parallel default(firstprivate)
 ///   #pragma omp parallel
 /// \endcode
 ///
-/// ``ompDefaultClause()`` matches ``default(none)`` and ``default(shared)``.
+/// ``ompDefaultClause()`` matches ``default(none)``, ``default(shared)``, and
+/// ``default(firstprivate)``
 extern const internal::VariadicDynCastAllOfMatcher
     ompDefaultClause;
 
@@ -7189,6 +7207,7 @@ extern const internal::VariadicDynCastAllOfMatcher
 ///   #pragma omp parallel
 ///   #pragma omp parallel default(none)
 ///   #pragma omp parallel default(shared)
+///   #pragma omp parallel default(firstprivate)
 /// \endcode
 ///
 /// ``ompDefaultClause(isNoneKind())`` matches only ``default(none)``.
@@ -7204,6 +7223,7 @@ AST_MATCHER(OMPDefaultClause, isNoneKind) {
 ///   #pragma omp parallel
 ///   #pragma omp parallel default(none)
 ///   #pragma omp parallel default(shared)
+///   #pragma omp parallel default(firstprivate)
 /// \endcode
 ///
 /// ``ompDefaultClause(isSharedKind())`` matches only ``default(shared)``.
@@ -7211,6 +7231,24 @@ AST_MATCHER(OMPDefaultClause, isSharedKind) {
   return Node.getDefaultKind() == llvm::omp::OMP_DEFAULT_shared;
 }
 
+/// Matches if the OpenMP ``default`` clause has ``firstprivate`` kind
+/// specified.
+///
+/// Given
+///
+/// \code
+///   #pragma omp parallel
+///   #pragma omp parallel default(none)
+///   #pragma omp parallel default(shared)
+///   #pragma omp parallel default(firstprivate)
+/// \endcode
+///
+/// ``ompDefaultClause(isFirstPrivateKind())`` matches only
+/// ``default(firstprivate)``.
+AST_MATCHER(OMPDefaultClause, isFirstPrivateKind) {
+  return Node.getDefaultKind() == llvm::omp::OMP_DEFAULT_firstprivate;
+}
+
 /// Matches if the OpenMP directive is allowed to contain the specified OpenMP
 /// clause kind.
 ///
diff --git a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
index fc41407ba2961..3992850c992de 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -40,7 +40,6 @@
 #include "clang/AST/DeclFriend.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
-#include "clang/AST/ExprObjC.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/NestedNameSpecifier.h"
@@ -61,11 +60,13 @@
 #include "llvm/ADT/iterator.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Regex.h"
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1948,6 +1949,10 @@ bool matchesAnyBase(const CXXRecordDecl &Node,
                     const Matcher &BaseSpecMatcher,
                     ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder);
 
+std::shared_ptr createAndVerifyRegex(StringRef Regex,
+                                                  llvm::Regex::RegexFlags Flags,
+                                                  StringRef MatcherID);
+
 } // namespace internal
 
 } // namespace ast_matchers
diff --git a/clang/include/clang/ASTMatchers/ASTMatchersMacros.h b/clang/include/clang/ASTMatchers/ASTMatchersMacros.h
index 4977bf32e9f6e..45e8b1a88b81a 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchersMacros.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchersMacros.h
@@ -438,4 +438,122 @@
       ReturnTypesF>::Func MatcherName##Loc;                                    \
   AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF)
 
+/// AST_MATCHER_REGEX(Type, DefineMatcher, Param) { ... }
+/// defines a function named DefineMatcher() that takes a regular expression
+/// string paramater and an optional RegexFlags parameter and returns a
+/// Matcher object.
+///
+/// The code between the curly braces has access to the following variables:
+///
+///   Node:                  the AST node being matched; its type is Type.
+///   Param:                 a pointer to an \ref llvm::Regex object
+///   Finder:                an ASTMatchFinder*.
+///   Builder:               a BoundNodesTreeBuilder*.
+///
+/// The code should return true if 'Node' matches.
+#define AST_MATCHER_REGEX(Type, DefineMatcher, Param)                          \
+  AST_MATCHER_REGEX_OVERLOAD(Type, DefineMatcher, Param, 0)
+
+#define AST_MATCHER_REGEX_OVERLOAD(Type, DefineMatcher, Param, OverloadId)     \
+  namespace internal {                                                         \
+  class matcher_##DefineMatcher##OverloadId##Matcher                           \
+      : public ::clang::ast_matchers::internal::MatcherInterface {       \
+  public:                                                                      \
+    explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
+        std::shared_ptr RE)                                       \
+        : Param(std::move(RE)) {}                                              \
+    bool matches(const Type &Node,                                             \
+                 ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \
+                 ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \
+                     *Builder) const override;                                 \
+                                                                               \
+  private:                                                                     \
+    std::shared_ptr const Param;                                  \
+  };                                                                           \
+  }                                                                            \
+  inline ::clang::ast_matchers::internal::Matcher DefineMatcher(         \
+      llvm::StringRef Param, llvm::Regex::RegexFlags RegexFlags) {             \
+    return ::clang::ast_matchers::internal::makeMatcher(                       \
+        new internal::matcher_##DefineMatcher##OverloadId##Matcher(            \
+            ::clang::ast_matchers::internal::createAndVerifyRegex(             \
+                Param, RegexFlags, #DefineMatcher)));                          \
+  }                                                                            \
+  inline ::clang::ast_matchers::internal::Matcher DefineMatcher(         \
+      llvm::StringRef Param) {                                                 \
+    return DefineMatcher(Param, llvm::Regex::NoFlags);                         \
+  }                                                                            \
+                                                                               \
+  typedef ::clang::ast_matchers::internal::Matcher (                     \
+      &DefineMatcher##_Type##OverloadId##Flags)(llvm::StringRef,               \
+                                                llvm::Regex::RegexFlags);      \
+  typedef ::clang::ast_matchers::internal::Matcher (                     \
+      &DefineMatcher##_Type##OverloadId)(llvm::StringRef);                     \
+  inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
+      const Type &Node,                                                        \
+      ::clang::ast_matchers::internal::ASTMatchFinder *Finder,                 \
+      ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
+
+/// AST_POLYMORPHIC_MATCHER_REGEX(DefineMatcher, ReturnTypesF, Param) { ... }
+/// defines a function named DefineMatcher() that takes a regular expression
+/// string paramater and an optional RegexFlags parameter that is polymorphic in
+/// the return type.
+///
+/// The variables are the same as for
+/// AST_MATCHER_REGEX, with the addition of NodeType, which specifies the node
+/// type of the matcher Matcher returned by the function matcher().
+#define AST_POLYMORPHIC_MATCHER_REGEX(DefineMatcher, ReturnTypesF, Param)      \
+  AST_POLYMORPHIC_MATCHER_REGEX_OVERLOAD(DefineMatcher, ReturnTypesF, Param, 0)
+
+#define AST_POLYMORPHIC_MATCHER_REGEX_OVERLOAD(DefineMatcher, ReturnTypesF,    \
+                                               Param, OverloadId)              \
+  namespace internal {                                                         \
+  template                                 \
+  class matcher_##DefineMatcher##OverloadId##Matcher                           \
+      : public ::clang::ast_matchers::internal::MatcherInterface {   \
+  public:                                                                      \
+    explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
+        std::shared_ptr RE)                                       \
+        : Param(std::move(RE)) {}                                              \
+    bool matches(const NodeType &Node,                                         \
+                 ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \
+                 ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \
+                     *Builder) const override;                                 \
+                                                                               \
+  private:                                                                     \
+    std::shared_ptr const Param;                                  \
+  };                                                                           \
+  }                                                                            \
+  inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1<        \
+      internal::matcher_##DefineMatcher##OverloadId##Matcher,                  \
+      std::shared_ptr, ReturnTypesF>                              \
+  DefineMatcher(llvm::StringRef Param, llvm::Regex::RegexFlags RegexFlags) {   \
+    return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1<      \
+        internal::matcher_##DefineMatcher##OverloadId##Matcher,                \
+        std::shared_ptr, ReturnTypesF>(                           \
+        ::clang::ast_matchers::internal::createAndVerifyRegex(                 \
+            Param, RegexFlags, #DefineMatcher));                               \
+  }                                                                            \
+  inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1<        \
+      internal::matcher_##DefineMatcher##OverloadId##Matcher,                  \
+      std::shared_ptr, ReturnTypesF>                              \
+  DefineMatcher(llvm::StringRef Param) {                                       \
+    return DefineMatcher(Param, llvm::Regex::NoFlags);                         \
+  }                                                                            \
+  typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1<       \
+      internal::matcher_##DefineMatcher##OverloadId##Matcher,                  \
+      std::shared_ptr, ReturnTypesF> (                            \
+      &DefineMatcher##_Type##OverloadId##Flags)(                               \
+      llvm::StringRef Param, llvm::Regex::RegexFlags RegexFlags);              \
+  typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1<       \
+      internal::matcher_##DefineMatcher##OverloadId##Matcher,                  \
+      std::shared_ptr, ReturnTypesF> (                            \
+      &DefineMatcher##_Type##OverloadId)(llvm::StringRef Param);               \
+  template                                 \
+  bool internal::                                                              \
+      matcher_##DefineMatcher##OverloadId##Matcher::matches( \
+          const NodeType &Node,                                                \
+          ::clang::ast_matchers::internal::ASTMatchFinder *Finder,             \
+          ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder)     \
+          const
+
 #endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
diff --git a/clang/include/clang/Analysis/Analyses/Dominators.h b/clang/include/clang/Analysis/Analyses/Dominators.h
index 061c98137da29..95a661138df4d 100644
--- a/clang/include/clang/Analysis/Analyses/Dominators.h
+++ b/clang/include/clang/Analysis/Analyses/Dominators.h
@@ -167,9 +167,7 @@ class CFGDominatorTreeImpl : public ManagedAnalysis {
   }
 
   /// Releases the memory held by the dominator tree.
-  virtual void releaseMemory() {
-    DT.releaseMemory();
-  }
+  virtual void releaseMemory() { DT.reset(); }
 
   /// Converts the dominator tree to human readable form.
   virtual void print(raw_ostream &OS, const llvm::Module* M= nullptr) const {
@@ -351,7 +349,7 @@ ClangCFGPostDomReverseChildrenGetter::Get(
 ///
 template <> struct GraphTraits {
   using NodeRef = ::clang::DomTreeNode *;
-  using ChildIteratorType = ::clang::DomTreeNode::iterator;
+  using ChildIteratorType = ::clang::DomTreeNode::const_iterator;
 
   static NodeRef getEntryNode(NodeRef N) { return N; }
   static ChildIteratorType child_begin(NodeRef N) { return N->begin(); }
diff --git a/clang/include/clang/Basic/AArch64SVEACLETypes.def b/clang/include/clang/Basic/AArch64SVEACLETypes.def
index 0640da83ebb3f..b98a07436e941 100644
--- a/clang/include/clang/Basic/AArch64SVEACLETypes.def
+++ b/clang/include/clang/Basic/AArch64SVEACLETypes.def
@@ -66,7 +66,7 @@ SVE_VECTOR_TYPE("__SVFloat16_t", "__SVFloat16_t", SveFloat16, SveFloat16Ty, 8, 1
 SVE_VECTOR_TYPE("__SVFloat32_t", "__SVFloat32_t", SveFloat32, SveFloat32Ty, 4, 32, true, true, false)
 SVE_VECTOR_TYPE("__SVFloat64_t", "__SVFloat64_t", SveFloat64, SveFloat64Ty, 2, 64, true, true, false)
 
-SVE_VECTOR_TYPE("__SVBFloat16_t", "__SVBFloat16_t", SveBFloat16, SveBFloat16Ty, 8, 16, false, false, true)
+SVE_VECTOR_TYPE("__SVBFloat16_t", "__SVBFloat16_t", SveBFloat16, SveBFloat16Ty, 8, 16, true, false, true)
 
 //
 // x2
@@ -85,6 +85,7 @@ SVE_VECTOR_TYPE("__clang_svfloat16x2_t", "svfloat16x2_t", SveFloat16x2, SveFloat
 SVE_VECTOR_TYPE("__clang_svfloat32x2_t", "svfloat32x2_t", SveFloat32x2, SveFloat32x2Ty, 8, 32, true, true, false)
 SVE_VECTOR_TYPE("__clang_svfloat64x2_t", "svfloat64x2_t", SveFloat64x2, SveFloat64x2Ty, 4, 64, true, true, false)
 
+SVE_VECTOR_TYPE("__clang_svbfloat16x2_t", "svbfloat16x2_t", SveBFloat16x2, SveBFloat16x2Ty, 16, 16, true, false, true)
 //
 // x3
 //
@@ -102,6 +103,7 @@ SVE_VECTOR_TYPE("__clang_svfloat16x3_t", "svfloat16x3_t", SveFloat16x3, SveFloat
 SVE_VECTOR_TYPE("__clang_svfloat32x3_t", "svfloat32x3_t", SveFloat32x3, SveFloat32x3Ty, 12, 32, true, true, false)
 SVE_VECTOR_TYPE("__clang_svfloat64x3_t", "svfloat64x3_t", SveFloat64x3, SveFloat64x3Ty, 6, 64, true, true, false)
 
+SVE_VECTOR_TYPE("__clang_svbfloat16x3_t", "svbfloat16x3_t", SveBFloat16x3, SveBFloat16x3Ty, 24, 16, true, false, true)
 //
 // x4
 //
@@ -119,6 +121,8 @@ SVE_VECTOR_TYPE("__clang_svfloat16x4_t", "svfloat16x4_t", SveFloat16x4, SveFloat
 SVE_VECTOR_TYPE("__clang_svfloat32x4_t", "svfloat32x4_t", SveFloat32x4, SveFloat32x4Ty, 16, 32, true, true, false)
 SVE_VECTOR_TYPE("__clang_svfloat64x4_t", "svfloat64x4_t", SveFloat64x4, SveFloat64x4Ty, 8, 64, true, true, false)
 
+SVE_VECTOR_TYPE("__clang_svbfloat16x4_t", "svbfloat16x4_t", SveBFloat16x4, SveBFloat16x4Ty, 32, 16, true, false, true)
+
 SVE_PREDICATE_TYPE("__SVBool_t", "__SVBool_t", SveBool, SveBoolTy, 16)
 
 #undef SVE_VECTOR_TYPE
diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def
index ac9af60288675..1416a64543a41 100644
--- a/clang/include/clang/Basic/Builtins.def
+++ b/clang/include/clang/Basic/Builtins.def
@@ -65,6 +65,7 @@
 // & -> reference (optionally followed by an address space number)
 // C -> const
 // D -> volatile
+// R -> restrict
 
 // The third value provided to the macro specifies information about attributes
 // of the function.  These must be kept in sync with the predicates in the
@@ -566,6 +567,7 @@ BUILTIN(__builtin___vprintf_chk, "iicC*a", "FP:1:")
 
 BUILTIN(__builtin_unpredictable, "LiLi"   , "nc")
 BUILTIN(__builtin_expect, "LiLiLi"   , "nc")
+BUILTIN(__builtin_expect_with_probability, "LiLiLid", "nc")
 BUILTIN(__builtin_prefetch, "vvC*.", "nc")
 BUILTIN(__builtin_readcyclecounter, "ULLi", "n")
 BUILTIN(__builtin_trap, "v", "nr")
diff --git a/clang/include/clang/Basic/BuiltinsAMDGPU.def b/clang/include/clang/Basic/BuiltinsAMDGPU.def
index 9add10c64962a..042a86368559a 100644
--- a/clang/include/clang/Basic/BuiltinsAMDGPU.def
+++ b/clang/include/clang/Basic/BuiltinsAMDGPU.def
@@ -60,11 +60,11 @@ BUILTIN(__builtin_amdgcn_ds_gws_sema_br, "vUiUi", "n")
 BUILTIN(__builtin_amdgcn_ds_gws_sema_p, "vUi", "n")
 BUILTIN(__builtin_amdgcn_fence, "vUicC*", "n")
 
-BUILTIN(__builtin_amdgcn_atomic_inc32, "ZiZiD*ZiUicC*", "n")
-BUILTIN(__builtin_amdgcn_atomic_inc64, "WiWiD*WiUicC*", "n")
+BUILTIN(__builtin_amdgcn_atomic_inc32, "UZiUZiD*UZiUicC*", "n")
+BUILTIN(__builtin_amdgcn_atomic_inc64, "UWiUWiD*UWiUicC*", "n")
 
-BUILTIN(__builtin_amdgcn_atomic_dec32, "ZiZiD*ZiUicC*", "n")
-BUILTIN(__builtin_amdgcn_atomic_dec64, "WiWiD*WiUicC*", "n")
+BUILTIN(__builtin_amdgcn_atomic_dec32, "UZiUZiD*UZiUicC*", "n")
+BUILTIN(__builtin_amdgcn_atomic_dec64, "UWiUWiD*UWiUicC*", "n")
 
 // FIXME: Need to disallow constant address space.
 BUILTIN(__builtin_amdgcn_div_scale, "dddbb*", "n")
@@ -77,6 +77,8 @@ BUILTIN(__builtin_amdgcn_trig_preop, "ddi", "nc")
 BUILTIN(__builtin_amdgcn_trig_preopf, "ffi", "nc")
 BUILTIN(__builtin_amdgcn_rcp, "dd", "nc")
 BUILTIN(__builtin_amdgcn_rcpf, "ff", "nc")
+BUILTIN(__builtin_amdgcn_sqrt, "dd", "nc")
+BUILTIN(__builtin_amdgcn_sqrtf, "ff", "nc")
 BUILTIN(__builtin_amdgcn_rsq, "dd", "nc")
 BUILTIN(__builtin_amdgcn_rsqf, "ff", "nc")
 BUILTIN(__builtin_amdgcn_rsq_clamp, "dd", "nc")
@@ -162,6 +164,7 @@ BUILTIN(__builtin_amdgcn_interp_mov, "fUiUiUiUi", "nc")
 
 TARGET_BUILTIN(__builtin_amdgcn_div_fixuph, "hhhh", "nc", "16-bit-insts")
 TARGET_BUILTIN(__builtin_amdgcn_rcph, "hh", "nc", "16-bit-insts")
+TARGET_BUILTIN(__builtin_amdgcn_sqrth, "hh", "nc", "16-bit-insts")
 TARGET_BUILTIN(__builtin_amdgcn_rsqh, "hh", "nc", "16-bit-insts")
 TARGET_BUILTIN(__builtin_amdgcn_sinh, "hh", "nc", "16-bit-insts")
 TARGET_BUILTIN(__builtin_amdgcn_cosh, "hh", "nc", "16-bit-insts")
diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def
index 238e56b6dfce0..d0df5fcd15523 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -302,10 +302,40 @@ BUILTIN(__builtin_altivec_vrldnm, "V2ULLiV2ULLiV2ULLi", "")
 BUILTIN(__builtin_altivec_vpdepd, "V2ULLiV2ULLiV2ULLi", "")
 BUILTIN(__builtin_altivec_vpextd, "V2ULLiV2ULLiV2ULLi", "")
 
+// P10 Vector Centrifuge built-in.
+BUILTIN(__builtin_altivec_vcfuged, "V2ULLiV2ULLiV2ULLi", "")
+
+// P10 Vector Gather Every N-th Bit built-in.
+BUILTIN(__builtin_altivec_vgnb, "ULLiV1ULLLiIi", "")
+
 // P10 Vector Clear Bytes built-ins.
 BUILTIN(__builtin_altivec_vclrlb, "V16cV16cUi", "")
 BUILTIN(__builtin_altivec_vclrrb, "V16cV16cUi", "")
 
+// P10 Vector Count Leading / Trailing Zeroes under bit Mask built-ins.
+BUILTIN(__builtin_altivec_vclzdm, "V2ULLiV2ULLiV2ULLi", "")
+BUILTIN(__builtin_altivec_vctzdm, "V2ULLiV2ULLiV2ULLi", "")
+
+// P10 Vector Shift built-ins.
+BUILTIN(__builtin_altivec_vsldbi, "V16UcV16UcV16UcIi", "")
+BUILTIN(__builtin_altivec_vsrdbi, "V16UcV16UcV16UcIi", "")
+
+// P10 Vector Insert built-ins.
+BUILTIN(__builtin_altivec_vinsblx, "V16UcV16UcULLiULLi", "")
+BUILTIN(__builtin_altivec_vinsbrx, "V16UcV16UcULLiULLi", "")
+BUILTIN(__builtin_altivec_vinshlx, "V8UsV8UsULLiULLi", "")
+BUILTIN(__builtin_altivec_vinshrx, "V8UsV8UsULLiULLi", "")
+BUILTIN(__builtin_altivec_vinswlx, "V4UiV4UiULLiULLi", "")
+BUILTIN(__builtin_altivec_vinswrx, "V4UiV4UiULLiULLi", "")
+BUILTIN(__builtin_altivec_vinsdlx, "V2ULLiV2ULLiULLiULLi", "")
+BUILTIN(__builtin_altivec_vinsdrx, "V2ULLiV2ULLiULLiULLi", "")
+BUILTIN(__builtin_altivec_vinsbvlx, "V16UcV16UcULLiV16Uc", "")
+BUILTIN(__builtin_altivec_vinsbvrx, "V16UcV16UcULLiV16Uc", "")
+BUILTIN(__builtin_altivec_vinshvlx, "V8UsV8UsULLiV8Us", "")
+BUILTIN(__builtin_altivec_vinshvrx, "V8UsV8UsULLiV8Us", "")
+BUILTIN(__builtin_altivec_vinswvlx, "V4UiV4UiULLiV4Ui", "")
+BUILTIN(__builtin_altivec_vinswvrx, "V4UiV4UiULLiV4Ui", "")
+
 // VSX built-ins.
 
 BUILTIN(__builtin_vsx_lxvd2x, "V2divC*", "")
@@ -399,6 +429,11 @@ BUILTIN(__builtin_vsx_xvcpsgnsp, "V4fV4fV4f", "")
 BUILTIN(__builtin_vsx_xvabssp, "V4fV4f", "")
 BUILTIN(__builtin_vsx_xvabsdp, "V2dV2d", "")
 
+BUILTIN(__builtin_vsx_xxgenpcvbm, "V16UcV16Uci", "")
+BUILTIN(__builtin_vsx_xxgenpcvhm, "V8UsV8Usi", "")
+BUILTIN(__builtin_vsx_xxgenpcvwm, "V4UiV4Uii", "")
+BUILTIN(__builtin_vsx_xxgenpcvdm, "V2ULLiV2ULLii", "")
+
 // vector Insert/Extract exponent/significand builtins
 BUILTIN(__builtin_vsx_xviexpdp, "V2dV2ULLiV2ULLi", "")
 BUILTIN(__builtin_vsx_xviexpsp, "V4fV4UiV4Ui", "")
@@ -430,6 +465,17 @@ BUILTIN(__builtin_vsx_extractuword, "V2ULLiV16UcIi", "")
 BUILTIN(__builtin_vsx_xxpermdi, "v.", "t")
 BUILTIN(__builtin_vsx_xxsldwi, "v.", "t")
 
+BUILTIN(__builtin_vsx_xxeval, "V2ULLiV2ULLiV2ULLiV2ULLiIi", "")
+
+// P10 Vector Permute Extended built-in.
+BUILTIN(__builtin_vsx_xxpermx, "V16UcV16UcV16UcV16UcIi", "")
+
+// P10 Vector Blend built-ins.
+BUILTIN(__builtin_vsx_xxblendvb, "V16UcV16UcV16UcV16Uc", "")
+BUILTIN(__builtin_vsx_xxblendvh, "V8UsV8UsV8UsV8Us", "")
+BUILTIN(__builtin_vsx_xxblendvw, "V4UiV4UiV4UiV4Ui", "")
+BUILTIN(__builtin_vsx_xxblendvd, "V2ULLiV2ULLiV2ULLiV2ULLi", "")
+
 // Float 128 built-ins
 BUILTIN(__builtin_sqrtf128_round_to_odd, "LLdLLd", "")
 BUILTIN(__builtin_addf128_round_to_odd, "LLdLLdLLd", "")
@@ -480,6 +526,9 @@ BUILTIN(__builtin_divdeu, "ULLiULLiULLi", "")
 BUILTIN(__builtin_bpermd, "SLLiSLLiSLLi", "")
 BUILTIN(__builtin_pdepd, "ULLiULLiULLi", "")
 BUILTIN(__builtin_pextd, "ULLiULLiULLi", "")
+BUILTIN(__builtin_cfuged, "ULLiULLiULLi", "")
+BUILTIN(__builtin_cntlzdm, "ULLiULLiULLi", "")
+BUILTIN(__builtin_cnttzdm, "ULLiULLiULLi", "")
 
 // Vector int128 (un)pack
 BUILTIN(__builtin_unpack_vector_int128, "ULLiV1LLLii", "")
diff --git a/clang/include/clang/Basic/BuiltinsWebAssembly.def b/clang/include/clang/Basic/BuiltinsWebAssembly.def
index 5e6f0d90ab46f..ecee7782920f6 100644
--- a/clang/include/clang/Basic/BuiltinsWebAssembly.def
+++ b/clang/include/clang/Basic/BuiltinsWebAssembly.def
@@ -25,10 +25,6 @@
 BUILTIN(__builtin_wasm_memory_size, "zIi", "n")
 BUILTIN(__builtin_wasm_memory_grow, "zIiz", "n")
 
-// Bulk memory builtins
-TARGET_BUILTIN(__builtin_wasm_memory_init, "vIUiIUiv*UiUi", "", "bulk-memory")
-TARGET_BUILTIN(__builtin_wasm_data_drop, "vIUi", "", "bulk-memory")
-
 // Thread-local storage
 TARGET_BUILTIN(__builtin_wasm_tls_size, "z", "nc", "bulk-memory")
 TARGET_BUILTIN(__builtin_wasm_tls_align, "z", "nc", "bulk-memory")
diff --git a/clang/include/clang/Basic/BuiltinsX86.def b/clang/include/clang/Basic/BuiltinsX86.def
index 7dcbcf086ede4..35fb98352ec2b 100644
--- a/clang/include/clang/Basic/BuiltinsX86.def
+++ b/clang/include/clang/Basic/BuiltinsX86.def
@@ -1934,6 +1934,15 @@ TARGET_HEADER_BUILTIN(__readgsword,  "UsUNi", "nh", "intrin.h", ALL_MS_LANGUAGES
 TARGET_HEADER_BUILTIN(__readgsdword, "UNiUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
 TARGET_HEADER_BUILTIN(__readgsqword, "ULLiUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
 
+TARGET_HEADER_BUILTIN(_InterlockedAnd64,         "WiWiD*Wi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement64,   "WiWiD*",   "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange64,    "WiWiD*Wi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64, "WiWiD*Wi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeSub64, "WiWiD*Wi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement64,   "WiWiD*",   "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr64,          "WiWiD*Wi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor64,         "WiWiD*Wi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
 #undef BUILTIN
 #undef TARGET_BUILTIN
 #undef TARGET_HEADER_BUILTIN
diff --git a/clang/include/clang/Basic/BuiltinsX86_64.def b/clang/include/clang/Basic/BuiltinsX86_64.def
index c535f43203e56..f66ae78f7e81f 100644
--- a/clang/include/clang/Basic/BuiltinsX86_64.def
+++ b/clang/include/clang/Basic/BuiltinsX86_64.def
@@ -33,14 +33,6 @@ TARGET_HEADER_BUILTIN(__faststorefence, "v", "nh", "intrin.h", ALL_MS_LANGUAGES,
 TARGET_HEADER_BUILTIN(__shiftleft128, "ULLiULLiULLiUc", "nch", "intrin.h", ALL_MS_LANGUAGES, "")
 TARGET_HEADER_BUILTIN(__shiftright128, "ULLiULLiULLiUc", "nch", "intrin.h", ALL_MS_LANGUAGES, "")
 
-TARGET_HEADER_BUILTIN(_InterlockedAnd64,         "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedDecrement64,   "LLiLLiD*",    "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange64,    "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeSub64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedIncrement64,   "LLiLLiD*",    "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr64,          "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor64,         "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
 TARGET_HEADER_BUILTIN(_InterlockedCompareExchange128, "UcLLiD*LLiLLiLLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "cx16")
 
 TARGET_BUILTIN(__builtin_ia32_readeflags_u64, "UOi", "n", "")
@@ -101,6 +93,22 @@ TARGET_BUILTIN(__builtin_ia32_cvtsi2ss64, "V4fV4fOiIi", "ncV:128:", "avx512f")
 TARGET_BUILTIN(__builtin_ia32_cvtusi2sd64, "V2dV2dUOiIi", "ncV:128:", "avx512f")
 TARGET_BUILTIN(__builtin_ia32_cvtusi2ss64, "V4fV4fUOiIi", "ncV:128:", "avx512f")
 TARGET_BUILTIN(__builtin_ia32_directstore_u64, "vULi*ULi", "n", "movdiri")
+
+// AMX
+TARGET_BUILTIN(__builtin_ia32_tile_loadconfig, "vvC*", "n", "amx-tile")
+TARGET_BUILTIN(__builtin_ia32_tile_storeconfig, "vvC*", "n", "amx-tile")
+TARGET_BUILTIN(__builtin_ia32_tilerelease, "v", "n", "amx-tile")
+TARGET_BUILTIN(__builtin_ia32_tilezero, "vUc", "n", "amx-tile")
+
+TARGET_BUILTIN(__builtin_ia32_tileloadd64, "vIUcvC*z", "n", "amx-tile")
+TARGET_BUILTIN(__builtin_ia32_tileloaddt164, "vIUcvC*z", "n", "amx-tile")
+TARGET_BUILTIN(__builtin_ia32_tilestored64, "vIUcv*z", "n", "amx-tile")
+
+TARGET_BUILTIN(__builtin_ia32_tdpbssd, "vIUcIUcIUc", "n", "amx-int8")
+TARGET_BUILTIN(__builtin_ia32_tdpbsud, "vIUcIUcIUc", "n", "amx-int8")
+TARGET_BUILTIN(__builtin_ia32_tdpbusd, "vIUcIUcIUc", "n", "amx-int8")
+TARGET_BUILTIN(__builtin_ia32_tdpbuud, "vIUcIUcIUc", "n", "amx-int8")
+TARGET_BUILTIN(__builtin_ia32_tdpbf16ps, "vIUcIUcIUc", "n", "amx-bf16")
 TARGET_BUILTIN(__builtin_ia32_ptwrite64, "vUOi", "n", "ptwrite")
 
 #undef BUILTIN
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index d465e00d4c70f..c7e01eb128518 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -58,6 +58,8 @@ CODEGENOPT(DisableLLVMPasses , 1, 0) ///< Don't run any LLVM IR passes to get
                                      ///< frontend.
 CODEGENOPT(DisableLifetimeMarkers, 1, 0) ///< Don't emit any lifetime markers
 CODEGENOPT(DisableO0ImplyOptNone , 1, 0) ///< Don't annonate function with optnone at O0
+CODEGENOPT(ExperimentalStrictFloatingPoint, 1, 0) ///< Enables the new, experimental
+                                                  ///< strict floating point.
 CODEGENOPT(ExperimentalNewPassManager, 1, 0) ///< Enables the new, experimental
                                              ///< pass manager.
 CODEGENOPT(DebugPassManager, 1, 0) ///< Prints debug information for the new
@@ -252,7 +254,6 @@ CODEGENOPT(UnwindTables      , 1, 0) ///< Emit unwind tables.
 CODEGENOPT(VectorizeLoop     , 1, 0) ///< Run loop vectorizer.
 CODEGENOPT(VectorizeSLP      , 1, 0) ///< Run SLP vectorizer.
 CODEGENOPT(ProfileSampleAccurate, 1, 0) ///< Sample profile is accurate.
-CODEGENOPT(CallGraphProfile  , 1, 0) ///< Run call graph profile.
 
   /// Attempt to use register sized accesses to bit-fields in structures, when
   /// possible.
diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td
index 75c4d0e0a139e..10bedaaf7aba7 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -101,8 +101,16 @@ def note_constexpr_null_subobject : Note<
   "access array element of|perform pointer arithmetic on|"
   "access real component of|"
   "access imaginary component of}0 null pointer">;
+def note_constexpr_function_param_value_unknown : Note<
+  "function parameter %0 with unknown value cannot be used in a constant "
+  "expression">;
+def note_constexpr_var_init_unknown : Note<
+  "initializer of %0 is unknown">;
 def note_constexpr_var_init_non_constant : Note<
   "initializer of %0 is not a constant expression">;
+def note_constexpr_var_init_weak : Note<
+  "initializer of weak variable %0 is not considered constant because "
+  "it may be different at runtime">;
 def note_constexpr_typeid_polymorphic : Note<
   "typeid applied to expression of polymorphic type %0 is "
   "not allowed in a constant expression in C++ standards before C++20">;
@@ -159,6 +167,9 @@ def note_constexpr_access_mutable : Note<
   "mutable member %1 is not allowed in a constant expression">;
 def note_constexpr_ltor_non_const_int : Note<
   "read of non-const variable %0 is not allowed in a constant expression">;
+def note_constexpr_ltor_non_integral : Note<
+  "read of variable %0 of non-integral, non-enumeration type %1 "
+  "is not allowed in a constant expression">;
 def note_constexpr_ltor_non_constexpr : Note<
   "read of non-constexpr variable %0 is not allowed in a constant expression">;
 def note_constexpr_ltor_incomplete_type : Note<
@@ -346,6 +357,9 @@ def err_experimental_clang_interp_failed : Error<
 def warn_integer_constant_overflow : Warning<
   "overflow in expression; result is %0 with type %1">,
   InGroup>;
+def warn_fixedpoint_constant_overflow : Warning<
+  "overflow in expression; result is %0 with type %1">,
+  InGroup>;
 
 // This is a temporary diagnostic, and shall be removed once our
 // implementation is complete, and like the preceding constexpr notes belongs
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index dcb3b96cd057e..558639ecad6aa 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -56,12 +56,12 @@ def err_drv_no_cuda_libdevice : Error<
   "cannot find libdevice for %0. Provide path to different CUDA installation "
   "via --cuda-path, or pass -nocudalib to build without linking with libdevice.">;
 
-def err_drv_no_rocm_installation : Error<
-  "cannot find ROCm installation.  Provide its path via --rocm-path, or pass "
-  "-nogpulib and -nogpuinc to build without ROCm device library and HIP includes.">;
 def err_drv_no_rocm_device_lib : Error<
-  "cannot find device library for %0. Provide path to different ROCm installation "
-  "via --rocm-path, or pass -nogpulib to build without linking default libraries.">;
+  "cannot find ROCm device library%select{| for %1}0. Provide its path via --rocm-path or "
+  "--rocm-device-lib-path, or pass -nogpulib to build without ROCm device library.">;
+def err_drv_no_hip_runtime : Error<
+  "cannot find HIP runtime. Provide its path via --rocm-path, or pass "
+  "-nogpuinc to build without HIP runtime.">;
 
 def err_drv_cuda_version_unsupported : Error<
   "GPU arch %0 is supported by CUDA versions between %1 and %2 (inclusive), "
@@ -509,4 +509,6 @@ def warn_drv_libstdcxx_not_found : Warning<
   InGroup>;
 
 def err_drv_cannot_mix_options : Error<"cannot specify '%1' along with '%0'">;
+
+def err_drv_invalid_object_mode : Error<"OBJECT_MODE setting %0 is not recognized and is not a valid setting.">;
 }
diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index 687c60c9c5367..b202d2abffa00 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -37,6 +37,12 @@ def note_fe_backend_plugin: Note<"%0">, BackendInfo;
 def warn_fe_override_module : Warning<
     "overriding the module target triple with %0">,
     InGroup>;
+def warn_fe_backend_unsupported_fp_rounding : Warning<
+    "overriding currently unsupported rounding mode on this target">,
+    InGroup;
+def warn_fe_backend_unsupported_fp_exceptions : Warning<
+    "overriding currently unsupported use of floating point exceptions "
+    "on this target">, InGroup;
 
 def remark_fe_backend_optimization_remark : Remark<"%0">, BackendInfo,
     InGroup;
@@ -119,6 +125,9 @@ def warn_fe_serialized_diag_merge_failure : Warning<
 def warn_fe_serialized_diag_failure : Warning<
     "unable to open file %0 for serializing diagnostics (%1)">,
     InGroup;
+def warn_fe_serialized_diag_failure_during_finalisation : Warning<
+    "Received warning after diagnostic serialization teardown was underway: %0">,
+    InGroup;
 
 def err_verify_missing_line : Error<
     "missing or invalid line number following '@' in expected %0">;
@@ -240,6 +249,12 @@ def err_function_needs_feature : Error<
   "always_inline function %1 requires target feature '%2', but would "
   "be inlined into function %0 that is compiled without support for '%2'">;
 
+def warn_avx_calling_convention
+    : Warning<"AVX vector %select{return|argument}0 of type %1 without '%2' "
+              "enabled changes the ABI">,
+      InGroup>;
+def err_avx_calling_convention : Error;
+
 def err_alias_to_undefined : Error<
   "%select{alias|ifunc}0 must point to a defined "
   "%select{variable or |}1function">;
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 23f530dd4e1fc..1e829be4028e4 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -107,6 +107,7 @@ def DoublePromotion : DiagGroup<"double-promotion">;
 def EnumTooLarge : DiagGroup<"enum-too-large">;
 def UnsupportedNan : DiagGroup<"unsupported-nan">;
 def UnsupportedAbs : DiagGroup<"unsupported-abs">;
+def UnsupportedFPOpt : DiagGroup<"unsupported-floating-point-opt">;
 def UnsupportedCB : DiagGroup<"unsupported-cb">;
 def UnsupportedGPOpt : DiagGroup<"unsupported-gpopt">;
 def UnsupportedTargetOpt : DiagGroup<"unsupported-target-opt">;
@@ -279,9 +280,12 @@ def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic",
 
 def CXX11Narrowing : DiagGroup<"c++11-narrowing">;
 
-def CXX11WarnOverrideDestructor :
+def CXX11WarnInconsistentOverrideDestructor :
   DiagGroup<"inconsistent-missing-destructor-override">;
-def CXX11WarnOverrideMethod : DiagGroup<"inconsistent-missing-override">;
+def CXX11WarnInconsistentOverrideMethod :
+  DiagGroup<"inconsistent-missing-override">;
+def CXX11WarnSuggestOverrideDestructor : DiagGroup<"suggest-destructor-override">;
+def CXX11WarnSuggestOverride : DiagGroup<"suggest-override">;
 
 // Original name of this warning in Clang
 def : DiagGroup<"c++0x-narrowing", [CXX11Narrowing]>;
@@ -382,6 +386,8 @@ def IncompleteModule : DiagGroup<"incomplete-module",
 def PrivateModule : DiagGroup<"private-module">;
 
 def CXX11InlineNamespace : DiagGroup<"c++11-inline-namespace">;
+def InlineNamespaceReopenedNoninline
+    : DiagGroup<"inline-namespace-reopened-noninline">;
 def InvalidNoreturn : DiagGroup<"invalid-noreturn">;
 def InvalidSourceEncoding : DiagGroup<"invalid-source-encoding">;
 def KNRPromotedParameter : DiagGroup<"knr-promoted-parameter">;
@@ -1097,6 +1103,11 @@ def ObjCSignedCharBool : DiagGroup<"objc-signed-char-bool",
    ObjCBoolConstantConversion,
    TautologicalObjCBoolCompare]>;
 
+def ObjCPotentiallyDirectSelector : DiagGroup<"potentially-direct-selector">;
+def ObjCStrictPotentiallyDirectSelector :
+  DiagGroup<"strict-potentially-direct-selector",
+            [ObjCPotentiallyDirectSelector]>;
+
 // Inline ASM warnings.
 def ASMOperandWidths : DiagGroup<"asm-operand-widths">;
 def ASM : DiagGroup<"asm", [
diff --git a/clang/include/clang/Basic/DiagnosticIDs.h b/clang/include/clang/Basic/DiagnosticIDs.h
index 46f0fa423a391..00c939650e549 100644
--- a/clang/include/clang/Basic/DiagnosticIDs.h
+++ b/clang/include/clang/Basic/DiagnosticIDs.h
@@ -33,7 +33,7 @@ namespace clang {
       DIAG_SIZE_SERIALIZATION =  120,
       DIAG_SIZE_LEX           =  400,
       DIAG_SIZE_PARSE         =  600,
-      DIAG_SIZE_AST           =  200,
+      DIAG_SIZE_AST           =  250,
       DIAG_SIZE_COMMENT       =  100,
       DIAG_SIZE_CROSSTU       =  100,
       DIAG_SIZE_SEMA          = 4000,
diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td
index fa07e9ae76c85..9cb06cf5b5e11 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -312,6 +312,9 @@ def pp_macro_not_used : Warning<"macro is not used">, DefaultIgnore,
 def warn_pp_undef_identifier : Warning<
   "%0 is not defined, evaluates to 0">,
   InGroup>, DefaultIgnore;
+def warn_pp_undef_prefix : Warning<
+  "%0 is not defined, evaluates to 0">,
+  InGroup>, DefaultIgnore;
 def warn_pp_ambiguous_macro : Warning<
   "ambiguous expansion of macro %0">, InGroup;
 def note_pp_ambiguous_macro_chosen : Note<
diff --git a/clang/include/clang/Basic/DiagnosticOptions.def b/clang/include/clang/Basic/DiagnosticOptions.def
index 6d1a1af92821b..a946b5c6be8ef 100644
--- a/clang/include/clang/Basic/DiagnosticOptions.def
+++ b/clang/include/clang/Basic/DiagnosticOptions.def
@@ -65,6 +65,7 @@ VALUE_DIAGOPT(ShowCategories, 2, 0) /// Show categories: 0 -> none, 1 -> Number,
 ENUM_DIAGOPT(Format, TextDiagnosticFormat, 2, Clang) /// Format for diagnostics:
 
 DIAGOPT(ShowColors, 1, 0)       /// Show diagnostics with ANSI color sequences.
+DIAGOPT(UseANSIEscapeCodes, 1, 0)
 ENUM_DIAGOPT(ShowOverloads, OverloadsShown, 1,
              Ovl_All)    /// Overload candidates to show.
 DIAGOPT(VerifyDiagnostics, 1, 0) /// Check that diagnostics match the expected
diff --git a/clang/include/clang/Basic/DiagnosticOptions.h b/clang/include/clang/Basic/DiagnosticOptions.h
index 3e3c4e50a9e0f..7fbe534c5994b 100644
--- a/clang/include/clang/Basic/DiagnosticOptions.h
+++ b/clang/include/clang/Basic/DiagnosticOptions.h
@@ -98,6 +98,10 @@ class DiagnosticOptions : public RefCountedBase{
   /// prefixes removed.
   std::vector Warnings;
 
+  /// The list of prefixes from -Wundef-prefix=... used to generate warnings
+  /// for undefined macros.
+  std::vector UndefPrefixes;
+
   /// The list of -R... options used to alter the diagnostic mappings, with the
   /// prefixes removed.
   std::vector Remarks;
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 5d57cfd6e71d1..1038a4119d4cb 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -194,6 +194,8 @@ def err_function_declared_typedef : Error<
 def err_at_defs_cxx : Error<"@defs is not supported in Objective-C++">;
 def err_at_in_class : Error<"unexpected '@' in member specification">;
 def err_unexpected_semi : Error<"unexpected ';' before %0">;
+def err_postfix_after_unary_requires_parens : Error<
+  "expression cannot be followed by a postfix %0 operator; add parentheses">;
 def err_unparenthesized_non_primary_expr_in_requires_clause : Error<
   "parentheses are required around this expression in a requires clause">;
 def note_unparenthesized_non_primary_expr_in_requires_clause : Note<
@@ -1332,6 +1334,8 @@ def warn_omp_more_one_device_type_clause
       InGroup;
 def err_omp_variant_ctx_second_match_extension : Error<
   "only a single match extension allowed per OpenMP context selector">;
+def err_omp_invalid_dsa: Error<
+  "data-sharing attribute '%0' in '%1' clause requires OpenMP version %2 or above">;
 
 // Pragma loop support.
 def err_pragma_loop_missing_argument : Error<
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 7c72eba8c2c11..71517edd6659b 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -259,6 +259,9 @@ def err_invalid_vector_float_decl_spec : Error<
 def err_invalid_vector_double_decl_spec : Error <
   "use of 'double' with '__vector' requires VSX support to be enabled "
   "(available on POWER7 or later)">;
+def err_invalid_vector_bool_int128_decl_spec : Error <
+  "use of '__int128' with '__vector bool' requires VSX support enabled (on "
+  "POWER10 or later)">;
 def err_invalid_vector_long_long_decl_spec : Error <
   "use of 'long long' with '__vector bool' requires VSX support (available on "
   "POWER7 or later) or extended Altivec support (available on POWER8 or later) "
@@ -827,8 +830,8 @@ def err_opencl_half_load_store : Error<
 def err_opencl_cast_to_half : Error<"casting to type %0 is not allowed">;
 def err_opencl_half_declaration : Error<
   "declaring variable of type %0 is not allowed">;
-def err_opencl_half_param : Error<
-  "declaring function parameter of type %0 is not allowed; did you forget * ?">;
+def err_opencl_invalid_param : Error<
+  "declaring function parameter of type %0 is not allowed%select{; did you forget * ?|}1">;
 def err_opencl_invalid_return : Error<
   "declaring function return value of type %0 is not allowed %select{; did you forget * ?|}1">;
 def warn_enum_value_overflow : Warning<"overflow in enumeration value">;
@@ -1375,8 +1378,14 @@ def warn_multiple_selectors: Warning<
   "several methods with selector %0 of mismatched types are found "
   "for the @selector expression">,
   InGroup, DefaultIgnore;
-def err_direct_selector_expression: Error<
+def err_direct_selector_expression : Error<
   "@selector expression formed with direct selector %0">;
+def warn_potentially_direct_selector_expression : Warning<
+  "@selector expression formed with potentially direct selector %0">,
+  InGroup;
+def warn_strict_potentially_direct_selector_expression : Warning<
+  warn_potentially_direct_selector_expression.Text>,
+  InGroup, DefaultIgnore;
 
 def err_objc_kindof_nonobject : Error<
   "'__kindof' specifier cannot be applied to non-object type %0">;
@@ -1411,7 +1420,8 @@ def warn_cxx14_compat_inline_variable : Warning<
   DefaultIgnore, InGroup;
 
 def warn_inline_namespace_reopened_noninline : Warning<
-  "inline namespace reopened as a non-inline namespace">;
+  "inline namespace reopened as a non-inline namespace">,
+  InGroup;
 def err_inline_namespace_mismatch : Error<
   "non-inline namespace cannot be reopened as inline">;
 
@@ -2357,12 +2367,22 @@ def override_keyword_hides_virtual_member_function : Error<
   "%select{function|functions}1">;
 def err_function_marked_override_not_overriding : Error<
   "%0 marked 'override' but does not override any member functions">;
-def warn_destructor_marked_not_override_overriding : Warning <
-  "%0 overrides a destructor but is not marked 'override'">,
-  InGroup, DefaultIgnore;
-def warn_function_marked_not_override_overriding : Warning <
-  "%0 overrides a member function but is not marked 'override'">,
-  InGroup;
+def warn_destructor_marked_not_override_overriding : TextSubstitution <
+  "%0 overrides a destructor but is not marked 'override'">;
+def warn_function_marked_not_override_overriding : TextSubstitution <
+  "%0 overrides a member function but is not marked 'override'">;
+def warn_inconsistent_destructor_marked_not_override_overriding : Warning <
+  "%sub{warn_destructor_marked_not_override_overriding}0">,
+  InGroup, DefaultIgnore;
+def warn_inconsistent_function_marked_not_override_overriding : Warning <
+  "%sub{warn_function_marked_not_override_overriding}0">,
+  InGroup;
+def warn_suggest_destructor_marked_not_override_overriding : Warning <
+  "%sub{warn_destructor_marked_not_override_overriding}0">,
+  InGroup, DefaultIgnore;
+def warn_suggest_function_marked_not_override_overriding : Warning <
+  "%sub{warn_function_marked_not_override_overriding}0">,
+  InGroup, DefaultIgnore;
 def err_class_marked_final_used_as_base : Error<
   "base %0 is marked '%select{final|sealed}1'">;
 def warn_abstract_final_class : Warning<
@@ -5385,9 +5405,6 @@ def ext_typecheck_zero_array_size : Extension<
   "zero size arrays are an extension">, InGroup;
 def err_typecheck_zero_array_size : Error<
   "zero-length arrays are not permitted in C++">;
-def warn_typecheck_zero_static_array_size : Warning<
-  "'static' has no effect on zero-length arrays">,
-  InGroup;
 def err_array_size_non_int : Error<"size of array has non-integer type %0">;
 def err_init_element_not_constant : Error<
   "initializer element is not a compile-time constant">;
@@ -7989,6 +8006,10 @@ def err_ref_bad_target : Error<
 def err_ref_bad_target_global_initializer : Error<
   "reference to %select{__device__|__global__|__host__|__host__ __device__}0 "
   "function %1 in global initializer">;
+def err_capture_bad_target : Error<
+  "capture host variable %0 by reference in device or host device lambda function">;
+def err_capture_bad_target_this_ptr : Error<
+  "capture host side class data member by this pointer in device or host device lambda function">;
 def warn_kern_is_method : Extension<
   "kernel function %0 is a member function; this may not be accepted by nvcc">,
   InGroup;
@@ -9338,6 +9359,8 @@ def err_x86_builtin_invalid_rounding : Error<
   "invalid rounding argument">;
 def err_x86_builtin_invalid_scale : Error<
   "scale argument must be 1, 2, 4, or 8">;
+def err_x86_builtin_tile_arg_duplicate : Error<
+  "tile arguments must refer to different tiles">;
 
 def err_builtin_target_unsupported : Error<
   "builtin is not supported on this target">;
@@ -10048,6 +10071,8 @@ def err_omp_section_not_subset_of_array : Error<
   "array section must be a subset of the original array">;
 def err_omp_section_length_negative : Error<
   "section length is evaluated to a negative value %0">;
+def err_omp_section_stride_non_positive : Error<
+  "section stride is evaluated to a non-positive value %0">;
 def err_omp_section_length_undefined : Error<
   "section length is unspecified and cannot be inferred because subscripted value is %select{not an array|an array of unknown bound}0">;
 def err_omp_wrong_linear_modifier : Error<
@@ -10523,7 +10548,16 @@ def err_await_suspend_invalid_return_type : Error<
 def note_await_ready_no_bool_conversion : Note<
   "return type of 'await_ready' is required to be contextually convertible to 'bool'"
 >;
-}
+def warn_coroutine_handle_address_invalid_return_type : Warning <
+  "return type of 'coroutine_handle<>::address should be 'void*' (have %0) in order to get capability with existing async C API.">,
+  InGroup;
+def err_coroutine_promise_final_suspend_requires_nothrow : Error<
+  "the expression 'co_await __promise.final_suspend()' is required to be non-throwing"
+>;
+def note_coroutine_function_declare_noexcept : Note<
+  "must be declared with 'noexcept'"
+>;
+} // end of coroutines issue category
 
 let CategoryName = "Documentation Issue" in {
 def warn_not_a_doxygen_trailing_member_comment : Warning<
@@ -10780,35 +10814,28 @@ def err_matrix_separate_incomplete_index: Error<
   "matrix row and column subscripts cannot be separated by any expression">;
 def err_matrix_subscript_comma: Error<
   "comma expressions are not allowed as indices in matrix subscript expressions">;
-
-def warn_mismatched_import : Warning<
-  "import %select{module|name}0 (%1) does not match the import %select{module|name}0 (%2) of the "
-  "previous declaration">,
-  InGroup;
-def warn_import_on_definition : Warning<
-  "import %select{module|name}0 cannot be applied to a function with a definition">,
-  InGroup;
-
-def err_builtin_matrix_arg: Error<"first argument must be a matrix">;
-
+def err_builtin_matrix_arg: Error<"1st argument must be a matrix">;
 def err_builtin_matrix_scalar_unsigned_arg: Error<
   "%0 argument must be a constant unsigned integer expression">;
-
 def err_builtin_matrix_pointer_arg: Error<
-  "%0 argument must be a pointer to a valid matrix element type">;
-
+  "%ordinal0 argument must be a pointer to a valid matrix element type">;
 def err_builtin_matrix_pointer_arg_mismatch: Error<
-  "the pointee of the second argument must match the element type of the first argument (%0 != %1)">;
-
+  "the pointee of the 2nd argument must match the element type of the 1st argument (%0 != %1)">;
 def err_builtin_matrix_store_to_const: Error<
   "cannot store matrix to read-only pointer">;
-
 def err_builtin_matrix_stride_too_small: Error<
   "stride must be greater or equal to the number of rows">;
-
 def err_builtin_matrix_invalid_dimension: Error<
   "%0 dimension is outside the allowed range [1, %1]">;
 
+def warn_mismatched_import : Warning<
+  "import %select{module|name}0 (%1) does not match the import %select{module|name}0 (%2) of the "
+  "previous declaration">,
+  InGroup;
+def warn_import_on_definition : Warning<
+  "import %select{module|name}0 cannot be applied to a function with a definition">,
+  InGroup;
+
 def err_preserve_field_info_not_field : Error<
   "__builtin_preserve_field_info argument %0 not a field access">;
 def err_preserve_field_info_not_const: Error<
@@ -10839,4 +10866,12 @@ def err_ext_int_bad_size : Error<"%select{signed|unsigned}0 _ExtInt must "
                                  "have a bit size of at least %select{2|1}0">;
 def err_ext_int_max_size : Error<"%select{signed|unsigned}0 _ExtInt of bit "
                                  "sizes greater than %1 not supported">;
+
+// errors of expect.with.probability
+def err_probability_not_constant_float : Error<
+   "probability argument to __builtin_expect_with_probability must be constant "
+   "floating-point expression">;
+def err_probability_out_of_range : Error<
+   "probability argument to __builtin_expect_with_probability is outside the "
+   "range [0.0, 1.0]">;
 } // end of sema component.
diff --git a/clang/include/clang/Basic/FPOptions.def b/clang/include/clang/Basic/FPOptions.def
new file mode 100644
index 0000000000000..6b6789b8ecc87
--- /dev/null
+++ b/clang/include/clang/Basic/FPOptions.def
@@ -0,0 +1,26 @@
+//===--- FPOptions.def - Floating Point Options database --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This file defines the Floating Point language options. Users of this file
+//  must define the FPOPT macro to make use of this information.
+#ifndef OPTION
+#  error Define the OPTION macro to handle floating point language options
+#endif
+
+// OPTION(name, type, width, previousName)
+OPTION(FPContractMode, LangOptions::FPModeKind, 2, First)
+OPTION(RoundingMode, RoundingMode, 3, FPContractMode)
+OPTION(FPExceptionMode, LangOptions::FPExceptionModeKind, 2, RoundingMode)
+OPTION(AllowFEnvAccess, bool, 1, FPExceptionMode)
+OPTION(AllowFPReassociate, bool, 1, AllowFEnvAccess)
+OPTION(NoHonorNaNs, bool, 1, AllowFPReassociate)
+OPTION(NoHonorInfs, bool, 1, NoHonorNaNs)
+OPTION(NoSignedZero, bool, 1, NoHonorInfs)
+OPTION(AllowReciprocal, bool, 1, NoSignedZero)
+OPTION(AllowApproxFunc, bool, 1, AllowReciprocal)
+#undef OPTION
diff --git a/clang/include/clang/Basic/FixedPoint.h b/clang/include/clang/Basic/FixedPoint.h
index 55465c604a7dc..0d181f30907fe 100644
--- a/clang/include/clang/Basic/FixedPoint.h
+++ b/clang/include/clang/Basic/FixedPoint.h
@@ -28,8 +28,8 @@ class QualType;
 /// The fixed point semantics work similarly to llvm::fltSemantics. The width
 /// specifies the whole bit width of the underlying scaled integer (with padding
 /// if any). The scale represents the number of fractional bits in this type.
-/// When HasUnsignedPadding is true and this type is signed, the first bit
-/// in the value this represents is treaded as padding.
+/// When HasUnsignedPadding is true and this type is unsigned, the first bit
+/// in the value this represents is treated as padding.
 class FixedPointSemantics {
 public:
   FixedPointSemantics(unsigned Width, unsigned Scale, bool IsSigned,
@@ -93,49 +93,52 @@ class FixedPointSemantics {
 /// point types and should eventually be moved to LLVM if fixed point types gain
 /// native IR support.
 class APFixedPoint {
- public:
-   APFixedPoint(const llvm::APInt &Val, const FixedPointSemantics &Sema)
-       : Val(Val, !Sema.isSigned()), Sema(Sema) {
-     assert(Val.getBitWidth() == Sema.getWidth() &&
-            "The value should have a bit width that matches the Sema width");
-   }
-
-   APFixedPoint(uint64_t Val, const FixedPointSemantics &Sema)
-       : APFixedPoint(llvm::APInt(Sema.getWidth(), Val, Sema.isSigned()),
-                      Sema) {}
-
-   // Zero initialization.
-   APFixedPoint(const FixedPointSemantics &Sema) : APFixedPoint(0, Sema) {}
-
-   llvm::APSInt getValue() const { return llvm::APSInt(Val, !Sema.isSigned()); }
-   inline unsigned getWidth() const { return Sema.getWidth(); }
-   inline unsigned getScale() const { return Sema.getScale(); }
-   inline bool isSaturated() const { return Sema.isSaturated(); }
-   inline bool isSigned() const { return Sema.isSigned(); }
-   inline bool hasPadding() const { return Sema.hasUnsignedPadding(); }
-   FixedPointSemantics getSemantics() const { return Sema; }
-
-   bool getBoolValue() const { return Val.getBoolValue(); }
-
-   // Convert this number to match the semantics provided. If the overflow
-   // parameter is provided, set this value to true or false to indicate if this
-   // operation results in an overflow.
-   APFixedPoint convert(const FixedPointSemantics &DstSema,
-                        bool *Overflow = nullptr) const;
-
-   // Perform binary operations on a fixed point type. The resulting fixed point
-   // value will be in the common, full precision semantics that can represent
-   // the precision and ranges os both input values. See convert() for an
-   // explanation of the Overflow parameter.
-   APFixedPoint add(const APFixedPoint &Other, bool *Overflow = nullptr) const;
-
-   /// Perform a unary negation (-X) on this fixed point type, taking into
-   /// account saturation if applicable.
-   APFixedPoint negate(bool *Overflow = nullptr) const;
-
-   APFixedPoint shr(unsigned Amt) const {
-     return APFixedPoint(Val >> Amt, Sema);
-   }
+public:
+  APFixedPoint(const llvm::APInt &Val, const FixedPointSemantics &Sema)
+      : Val(Val, !Sema.isSigned()), Sema(Sema) {
+    assert(Val.getBitWidth() == Sema.getWidth() &&
+           "The value should have a bit width that matches the Sema width");
+  }
+
+  APFixedPoint(uint64_t Val, const FixedPointSemantics &Sema)
+      : APFixedPoint(llvm::APInt(Sema.getWidth(), Val, Sema.isSigned()),
+                     Sema) {}
+
+  // Zero initialization.
+  APFixedPoint(const FixedPointSemantics &Sema) : APFixedPoint(0, Sema) {}
+
+  llvm::APSInt getValue() const { return llvm::APSInt(Val, !Sema.isSigned()); }
+  inline unsigned getWidth() const { return Sema.getWidth(); }
+  inline unsigned getScale() const { return Sema.getScale(); }
+  inline bool isSaturated() const { return Sema.isSaturated(); }
+  inline bool isSigned() const { return Sema.isSigned(); }
+  inline bool hasPadding() const { return Sema.hasUnsignedPadding(); }
+  FixedPointSemantics getSemantics() const { return Sema; }
+
+  bool getBoolValue() const { return Val.getBoolValue(); }
+
+  // Convert this number to match the semantics provided. If the overflow
+  // parameter is provided, set this value to true or false to indicate if this
+  // operation results in an overflow.
+  APFixedPoint convert(const FixedPointSemantics &DstSema,
+                       bool *Overflow = nullptr) const;
+
+  // Perform binary operations on a fixed point type. The resulting fixed point
+  // value will be in the common, full precision semantics that can represent
+  // the precision and ranges of both input values. See convert() for an
+  // explanation of the Overflow parameter.
+  APFixedPoint add(const APFixedPoint &Other, bool *Overflow = nullptr) const;
+  APFixedPoint sub(const APFixedPoint &Other, bool *Overflow = nullptr) const;
+  APFixedPoint mul(const APFixedPoint &Other, bool *Overflow = nullptr) const;
+  APFixedPoint div(const APFixedPoint &Other, bool *Overflow = nullptr) const;
+
+  /// Perform a unary negation (-X) on this fixed point type, taking into
+  /// account saturation if applicable.
+  APFixedPoint negate(bool *Overflow = nullptr) const;
+
+  APFixedPoint shr(unsigned Amt) const {
+    return APFixedPoint(Val >> Amt, Sema);
+  }
 
   APFixedPoint shl(unsigned Amt) const {
     return APFixedPoint(Val << Amt, Sema);
diff --git a/clang/include/clang/Basic/IdentifierTable.h b/clang/include/clang/Basic/IdentifierTable.h
index 31849bbdd5456..fc554a35e721b 100644
--- a/clang/include/clang/Basic/IdentifierTable.h
+++ b/clang/include/clang/Basic/IdentifierTable.h
@@ -48,7 +48,7 @@ using IdentifierLocPair = std::pair;
 /// of a pointer to one of these classes.
 enum { IdentifierInfoAlignment = 8 };
 
-static constexpr int ObjCOrBuiltinIDBits = 14;
+static constexpr int ObjCOrBuiltinIDBits = 15;
 
 /// One of these records is kept for each identifier that
 /// is lexed.  This contains information about whether the token was \#define'd,
diff --git a/clang/include/clang/Basic/JsonSupport.h b/clang/include/clang/Basic/JsonSupport.h
index 1b118b45a0498..8b02e440df447 100644
--- a/clang/include/clang/Basic/JsonSupport.h
+++ b/clang/include/clang/Basic/JsonSupport.h
@@ -13,7 +13,7 @@
 #include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/raw_ostream.h"
-
+#include 
 
 namespace clang {
 
@@ -98,7 +98,16 @@ inline void printSourceLocationAsJson(raw_ostream &Out, SourceLocation Loc,
     if (AddBraces)
       Out << "{ ";
     std::string filename(PLoc.getFilename());
-#ifdef _WIN32 // Handle windows-specific path delimiters.
+#ifdef _WIN32
+    // Remove forbidden Windows path characters
+    auto RemoveIt =
+        std::remove_if(filename.begin(), filename.end(), [](auto Char) {
+          static const char ForbiddenChars[] = "<>*?\"|";
+          return std::find(std::begin(ForbiddenChars), std::end(ForbiddenChars),
+                           Char) != std::end(ForbiddenChars);
+        });
+    filename.erase(RemoveIt, filename.end());
+    // Handle windows-specific path delimiters.
     std::replace(filename.begin(), filename.end(), '\\', '/');
 #endif
     Out << "\"line\": " << PLoc.getLine()
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index bc0c17a147891..70f68d664bb71 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -193,12 +193,12 @@ COMPATIBLE_LANGOPT(Deprecated        , 1, 0, "__DEPRECATED predefined macro")
 COMPATIBLE_LANGOPT(FastMath          , 1, 0, "fast FP math optimizations, and __FAST_MATH__ predefined macro")
 COMPATIBLE_LANGOPT(FiniteMathOnly    , 1, 0, "__FINITE_MATH_ONLY__ predefined macro")
 COMPATIBLE_LANGOPT(UnsafeFPMath      , 1, 0, "Unsafe Floating Point Math")
-COMPATIBLE_LANGOPT(AllowFPReassoc    , 1, 0, "Permit Floating Point reassociation")
-COMPATIBLE_LANGOPT(NoHonorNaNs       , 1, 0, "Permit Floating Point optimization without regard to NaN")
-COMPATIBLE_LANGOPT(NoHonorInfs       , 1, 0, "Permit Floating Point optimization without regard to infinities")
-COMPATIBLE_LANGOPT(NoSignedZero      , 1, 0, "Permit Floating Point optimization without regard to signed zeros")
-COMPATIBLE_LANGOPT(AllowRecip        , 1, 0, "Permit Floating Point reciprocal")
-COMPATIBLE_LANGOPT(ApproxFunc        , 1, 0, "Permit Floating Point approximation")
+BENIGN_LANGOPT(AllowFPReassoc    , 1, 0, "Permit Floating Point reassociation")
+BENIGN_LANGOPT(NoHonorNaNs       , 1, 0, "Permit Floating Point optimization without regard to NaN")
+BENIGN_LANGOPT(NoHonorInfs       , 1, 0, "Permit Floating Point optimization without regard to infinities")
+BENIGN_LANGOPT(NoSignedZero      , 1, 0, "Permit Floating Point optimization without regard to signed zeros")
+BENIGN_LANGOPT(AllowRecip        , 1, 0, "Permit Floating Point reciprocal")
+BENIGN_LANGOPT(ApproxFunc        , 1, 0, "Permit Floating Point approximation")
 
 BENIGN_LANGOPT(ObjCGCBitmapPrint , 1, 0, "printing of GC's bitmap layout for __weak/__strong ivars")
 
@@ -231,6 +231,7 @@ LANGOPT(OpenMPCUDANumSMs  , 32, 0, "Number of SMs for CUDA devices.")
 LANGOPT(OpenMPCUDABlocksPerSM  , 32, 0, "Number of blocks per SM for CUDA devices.")
 LANGOPT(OpenMPCUDAReductionBufNum , 32, 1024, "Number of the reduction records in the intermediate reduction buffer used for the teams reductions.")
 LANGOPT(OpenMPOptimisticCollapse  , 1, 0, "Use at most 32 bits to represent the collapsed loop nest counter.")
+LANGOPT(OpenMPCUDATargetParallel, 1, 0, "Support parallel execution of target region on Cuda-based devices.")
 LANGOPT(RenderScript      , 1, 0, "RenderScript")
 
 LANGOPT(CUDAIsDevice      , 1, 0, "compiling for CUDA device")
@@ -270,9 +271,10 @@ BENIGN_LANGOPT(SpellChecking , 1, 1, "spell-checking")
 LANGOPT(SinglePrecisionConstants , 1, 0, "treating double-precision floating point constants as single precision constants")
 LANGOPT(FastRelaxedMath , 1, 0, "OpenCL fast relaxed math")
 /// FP_CONTRACT mode (on/off/fast).
-ENUM_LANGOPT(DefaultFPContractMode, FPModeKind, 2, FPM_Off, "FP contraction type")
-ENUM_LANGOPT(FPRoundingMode, RoundingMode, 3, RoundingMode::NearestTiesToEven, "FP Rounding Mode type")
-ENUM_LANGOPT(FPExceptionMode, FPExceptionModeKind, 2, FPE_Ignore, "FP Exception Behavior Mode type")
+BENIGN_ENUM_LANGOPT(DefaultFPContractMode, FPModeKind, 2, FPM_Off, "FP contraction type")
+COMPATIBLE_LANGOPT(ExpStrictFP, 1, false, "Enable experimental strict floating point")
+BENIGN_ENUM_LANGOPT(FPRoundingMode, RoundingMode, 3, RoundingMode::NearestTiesToEven, "FP Rounding Mode type")
+BENIGN_ENUM_LANGOPT(FPExceptionMode, FPExceptionModeKind, 2, FPE_Ignore, "FP Exception Behavior Mode type")
 LANGOPT(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment")
 LANGOPT(HexagonQdsp6Compat , 1, 0, "hexagon-qdsp6 backward compatibility")
 LANGOPT(ObjCAutoRefCount , 1, 0, "Objective-C automated reference counting")
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index 7b92a8964862b..a9213b7d86680 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -366,175 +366,176 @@ class LangOptions : public LangOptionsBase {
 };
 
 /// Floating point control options
+class FPOptionsOverride;
 class FPOptions {
+public:
+  // We start by defining the layout.
+  using storage_type = uint16_t;
+
   using RoundingMode = llvm::RoundingMode;
 
-public:
-  FPOptions()
-      : fp_contract(LangOptions::FPM_Off), fenv_access(LangOptions::FPM_Off),
-        rounding(LangOptions::FPR_ToNearest),
-        exceptions(LangOptions::FPE_Ignore), allow_reassoc(0), no_nans(0),
-        no_infs(0), no_signed_zeros(0), allow_reciprocal(0), approx_func(0) {}
+  // Define a fake option named "First" so that we have a PREVIOUS even for the
+  // real first option.
+  static constexpr storage_type FirstShift = 0, FirstWidth = 0;
+#define OPTION(NAME, TYPE, WIDTH, PREVIOUS)                                    \
+  static constexpr storage_type NAME##Shift =                                  \
+      PREVIOUS##Shift + PREVIOUS##Width;                                       \
+  static constexpr storage_type NAME##Width = WIDTH;                           \
+  static constexpr storage_type NAME##Mask = ((1 << NAME##Width) - 1)          \
+                                             << NAME##Shift;
+#include "clang/Basic/FPOptions.def"
 
+private:
+  storage_type Value;
+
+public:
+  FPOptions() : Value(0) {
+    setFPContractMode(LangOptions::FPM_Off);
+    setRoundingMode(static_cast(LangOptions::FPR_ToNearest));
+    setFPExceptionMode(LangOptions::FPE_Ignore);
+  }
   // Used for serializing.
   explicit FPOptions(unsigned I) { getFromOpaqueInt(I); }
 
-  explicit FPOptions(const LangOptions &LangOpts)
-      : fp_contract(LangOpts.getDefaultFPContractMode()),
-        fenv_access(LangOptions::FPM_Off),
-        rounding(static_cast(LangOpts.getFPRoundingMode())),
-        exceptions(LangOpts.getFPExceptionMode()),
-        allow_reassoc(LangOpts.AllowFPReassoc), no_nans(LangOpts.NoHonorNaNs),
-        no_infs(LangOpts.NoHonorInfs), no_signed_zeros(LangOpts.NoSignedZero),
-        allow_reciprocal(LangOpts.AllowRecip),
-        approx_func(LangOpts.ApproxFunc) {}
-  // FIXME: Use getDefaultFEnvAccessMode() when available.
-
-  void setFastMath(bool B = true) {
-    allow_reassoc = no_nans = no_infs = no_signed_zeros = approx_func =
-        allow_reciprocal = B;
+  explicit FPOptions(const LangOptions &LO) {
+    Value = 0;
+    setFPContractMode(LO.getDefaultFPContractMode());
+    setRoundingMode(LO.getFPRoundingMode());
+    setFPExceptionMode(LO.getFPExceptionMode());
+    setAllowFEnvAccess(LangOptions::FPM_Off),
+        setAllowFPReassociate(LO.AllowFPReassoc);
+    setNoHonorNaNs(LO.NoHonorNaNs);
+    setNoHonorInfs(LO.NoHonorInfs);
+    setNoSignedZero(LO.NoSignedZero);
+    setAllowReciprocal(LO.AllowRecip);
+    setAllowApproxFunc(LO.ApproxFunc);
   }
 
-  /// Return the default value of FPOptions that's used when trailing
-  /// storage isn't required.
-  static FPOptions defaultWithoutTrailingStorage(const LangOptions &LO);
-
-  /// Does this FPOptions require trailing storage when stored in various
-  /// AST nodes, or can it be recreated using `defaultWithoutTrailingStorage`?
-  bool requiresTrailingStorage(const LangOptions &LO);
-
   bool allowFPContractWithinStatement() const {
-    return fp_contract == LangOptions::FPM_On;
+    return getFPContractMode() == LangOptions::FPM_On;
+  }
+  void setAllowFPContractWithinStatement() {
+    setFPContractMode(LangOptions::FPM_On);
   }
 
   bool allowFPContractAcrossStatement() const {
-    return fp_contract == LangOptions::FPM_Fast;
+    return getFPContractMode() == LangOptions::FPM_Fast;
   }
-
-  void setAllowFPContractWithinStatement() {
-    fp_contract = LangOptions::FPM_On;
+  void setAllowFPContractAcrossStatement() {
+    setFPContractMode(LangOptions::FPM_Fast);
   }
 
-  void setAllowFPContractAcrossStatement() {
-    fp_contract = LangOptions::FPM_Fast;
+  bool isFPConstrained() const {
+    return getRoundingMode() !=
+               static_cast(RoundingMode::NearestTiesToEven) ||
+           getFPExceptionMode() != LangOptions::FPE_Ignore ||
+           getAllowFEnvAccess();
   }
 
-  void setDisallowFPContract() { fp_contract = LangOptions::FPM_Off; }
+  bool operator==(FPOptions other) const { return Value == other.Value; }
 
-  bool allowFEnvAccess() const { return fenv_access == LangOptions::FPM_On; }
+  /// Return the default value of FPOptions that's used when trailing
+  /// storage isn't required.
+  static FPOptions defaultWithoutTrailingStorage(const LangOptions &LO);
 
-  void setAllowFEnvAccess() { fenv_access = LangOptions::FPM_On; }
+  storage_type getAsOpaqueInt() const { return Value; }
+  void getFromOpaqueInt(storage_type value) { Value = value; }
 
-  void setFPPreciseEnabled(bool Value) {
-    if (Value) {
-      /* Precise mode implies fp_contract=on and disables ffast-math */
-      setFastMath(false);
-      setAllowFPContractWithinStatement();
-    } else {
-      /* Precise mode implies fp_contract=fast and enables ffast-math */
-      setFastMath(true);
-      setAllowFPContractAcrossStatement();
-    }
+  // We can define most of the accessors automatically:
+#define OPTION(NAME, TYPE, WIDTH, PREVIOUS)                                    \
+  unsigned get##NAME() const {                                                 \
+    return static_cast(TYPE((Value & NAME##Mask) >> NAME##Shift));   \
+  }                                                                            \
+  void set##NAME(TYPE value) {                                                 \
+    Value = (Value & ~NAME##Mask) | (storage_type(value) << NAME##Shift);      \
   }
+#include "clang/Basic/FPOptions.def"
+  LLVM_DUMP_METHOD void dump();
+};
 
-  void setDisallowFEnvAccess() { fenv_access = LangOptions::FPM_Off; }
+/// The FPOptions override type is value of the new FPOptions
+///  plus a mask showing which fields are actually set in it:
+class FPOptionsOverride {
+  FPOptions Options;
+  FPOptions::storage_type OverrideMask = 0;
 
-  RoundingMode getRoundingMode() const {
-    return static_cast(rounding);
-  }
+public:
+  using RoundingMode = llvm::RoundingMode;
+  FPOptionsOverride() {}
 
-  void setRoundingMode(RoundingMode RM) {
-    rounding = static_cast(RM);
-  }
+  // Used for serializing.
+  explicit FPOptionsOverride(unsigned I) { getFromOpaqueInt(I); }
+
+  bool requiresTrailingStorage() const { return OverrideMask != 0; }
 
-  LangOptions::FPExceptionModeKind getExceptionMode() const {
-    return static_cast(exceptions);
+  void setAllowFPContractWithinStatement() {
+    setFPContractModeOverride(LangOptions::FPM_On);
   }
 
-  void setExceptionMode(LangOptions::FPExceptionModeKind EM) {
-    exceptions = EM;
+  void setAllowFPContractAcrossStatement() {
+    setFPContractModeOverride(LangOptions::FPM_Fast);
   }
 
-  /// FMF Flag queries
-  bool allowAssociativeMath() const { return allow_reassoc; }
-  bool noHonorNaNs() const { return no_nans; }
-  bool noHonorInfs() const { return no_infs; }
-  bool noSignedZeros() const { return no_signed_zeros; }
-  bool allowReciprocalMath() const { return allow_reciprocal; }
-  bool allowApproximateFunctions() const { return approx_func; }
-
-  /// Flag setters
-  void setAllowAssociativeMath(bool B = true) { allow_reassoc = B; }
-  void setNoHonorNaNs(bool B = true) { no_nans = B; }
-  void setNoHonorInfs(bool B = true) { no_infs = B; }
-  void setNoSignedZeros(bool B = true) { no_signed_zeros = B; }
-  void setAllowReciprocalMath(bool B = true) { allow_reciprocal = B; }
-  void setAllowApproximateFunctions(bool B = true) { approx_func = B; }
+  void setDisallowFPContract() {
+    setFPContractModeOverride(LangOptions::FPM_Off);
+  }
 
-  bool isFPConstrained() const {
-    return getRoundingMode() != RoundingMode::NearestTiesToEven ||
-           getExceptionMode() != LangOptions::FPE_Ignore ||
-           allowFEnvAccess();
+  void setFPPreciseEnabled(bool Value) {
+    setAllowFPReassociateOverride(!Value);
+    setNoHonorNaNsOverride(!Value);
+    setNoHonorInfsOverride(!Value);
+    setNoSignedZeroOverride(!Value);
+    setAllowReciprocalOverride(!Value);
+    setAllowApproxFuncOverride(!Value);
+    if (Value)
+      /* Precise mode implies fp_contract=on and disables ffast-math */
+      setAllowFPContractWithinStatement();
+    else
+      /* Precise mode disabled sets fp_contract=fast and enables ffast-math */
+      setAllowFPContractAcrossStatement();
   }
 
-  /// Used to serialize this.
   unsigned getAsOpaqueInt() const {
-    return fp_contract | (fenv_access << 2) | (rounding << 3) |
-           (exceptions << 6) | (allow_reassoc << 8) | (no_nans << 9) |
-           (no_infs << 10) | (no_signed_zeros << 11) |
-           (allow_reciprocal << 12) | (approx_func << 13);
+    return Options.getAsOpaqueInt() << 16 | OverrideMask;
   }
-
-  /// Used with getAsOpaqueInt() to manage the float_control pragma stack.
   void getFromOpaqueInt(unsigned I) {
-    fp_contract = (static_cast(I & 3));
-    fenv_access = ((I >> 2) & 1);
-    rounding = static_cast(static_cast((I >> 3) & 7));
-    exceptions = (static_cast((I >> 6) & 3));
-    allow_reassoc = ((I >> 8) & 1);
-    no_nans = ((I >> 9) & 1);
-    no_infs = ((I >> 10) & 1);
-    no_signed_zeros = ((I >> 11) & 1);
-    allow_reciprocal = ((I >> 12) & 1);
-    approx_func = ((I >> 13) & 1);
+    OverrideMask = I & 0xffff;
+    Options.getFromOpaqueInt(I >> 16);
   }
 
-private:
-  /// Adjust BinaryOperatorBitfields::FPFeatures and
-  /// CXXOperatorCallExprBitfields::FPFeatures to match the total bit-field size
-  /// of these fields.
-  unsigned fp_contract : 2;
-  unsigned fenv_access : 1;
-  unsigned rounding : 3;
-  unsigned exceptions : 2;
-  /// Allow reassociation transformations for floating-point instructions
-  /// across multiple statements.
-  unsigned allow_reassoc : 1;
-  /// No NaNs - Allow optimizations to assume the arguments and result
-  /// are not NaN. If an argument is a nan, or the result would be a nan,
-  /// it produces a :ref:`poison value ` instead.
-  unsigned no_nans : 1;
-  /// No Infs - Allow optimizations to assume the arguments and result
-  /// are not +/-Inf. If an argument is +/-Inf, or the result would be +/-Inf,
-  /// it produces a :ref:`poison value ` instead.
-  unsigned no_infs : 1;
-  /// No Signed Zeros - Allow optimizations to treat the sign of a zero
-  /// argument or result as insignificant.
-  unsigned no_signed_zeros : 1;
-  /// Allow Reciprocal - Allow optimizations to use the reciprocal
-  /// of an argument rather than perform division.
-  unsigned allow_reciprocal : 1;
-  /// Approximate functions - Allow substitution of approximate calculations
-  /// for functions (sin, log, sqrt, etc).
-  unsigned approx_func : 1;
-};
+  FPOptions applyOverrides(const LangOptions &LO) {
+    FPOptions Base(LO);
+    FPOptions result((Base.getAsOpaqueInt() & ~OverrideMask) |
+                     (Options.getAsOpaqueInt() & OverrideMask));
+    return result;
+  }
 
-inline bool operator==(FPOptions LHS, FPOptions RHS) {
-  return LHS.getAsOpaqueInt() == RHS.getAsOpaqueInt();
-}
-inline bool operator!=(FPOptions LHS, FPOptions RHS) {
-  return LHS.getAsOpaqueInt() != RHS.getAsOpaqueInt();
-}
+  bool operator==(FPOptionsOverride other) const {
+    return Options == other.Options && OverrideMask == other.OverrideMask;
+  }
+  bool operator!=(FPOptionsOverride other) const { return !(*this == other); }
+
+#define OPTION(NAME, TYPE, WIDTH, PREVIOUS)                                    \
+  bool has##NAME##Override() const {                                           \
+    return OverrideMask & FPOptions::NAME##Mask;                               \
+  }                                                                            \
+  unsigned get##NAME##Override() const {                                       \
+    assert(has##NAME##Override());                                             \
+    return Options.get##NAME();                                                \
+  }                                                                            \
+  void clear##NAME##Override() {                                               \
+    /* Clear the actual value so that we don't have spurious differences when  \
+     * testing equality. */                                                    \
+    Options.set##NAME(TYPE(0));                                                \
+    OverrideMask &= ~FPOptions::NAME##Mask;                                    \
+  }                                                                            \
+  void set##NAME##Override(TYPE value) {                                       \
+    Options.set##NAME(value);                                                  \
+    OverrideMask |= FPOptions::NAME##Mask;                                     \
+  }
+#include "clang/Basic/FPOptions.def"
+  LLVM_DUMP_METHOD void dump();
+};
 
 /// Describes the kind of translation unit being processed.
 enum TranslationUnitKind {
diff --git a/clang/include/clang/Basic/ObjCRuntime.h b/clang/include/clang/Basic/ObjCRuntime.h
index 1c4a69269deea..26403bfa98c9d 100644
--- a/clang/include/clang/Basic/ObjCRuntime.h
+++ b/clang/include/clang/Basic/ObjCRuntime.h
@@ -476,6 +476,10 @@ class ObjCRuntime {
   friend bool operator!=(const ObjCRuntime &left, const ObjCRuntime &right) {
     return !(left == right);
   }
+
+  friend llvm::hash_code hash_value(const ObjCRuntime &OCR) {
+    return llvm::hash_combine(OCR.getKind(), OCR.getVersion());
+  }
 };
 
 raw_ostream &operator<<(raw_ostream &out, const ObjCRuntime &value);
diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h
index 693ae4f938e11..5c666c1760b47 100644
--- a/clang/include/clang/Basic/SourceManager.h
+++ b/clang/include/clang/Basic/SourceManager.h
@@ -1645,8 +1645,7 @@ class SourceManager : public RefCountedBase {
   unsigned local_sloc_entry_size() const { return LocalSLocEntryTable.size(); }
 
   /// Get a local SLocEntry. This is exposed for indexing.
-  const SrcMgr::SLocEntry &getLocalSLocEntry(unsigned Index,
-                                             bool *Invalid = nullptr) const {
+  const SrcMgr::SLocEntry &getLocalSLocEntry(unsigned Index) const {
     assert(Index < LocalSLocEntryTable.size() && "Invalid index");
     return LocalSLocEntryTable[Index];
   }
@@ -1739,12 +1738,13 @@ class SourceManager : public RefCountedBase {
   const SrcMgr::SLocEntry &loadSLocEntry(unsigned Index, bool *Invalid) const;
 
   /// Get the entry with the given unwrapped FileID.
+  /// Invalid will not be modified for Local IDs.
   const SrcMgr::SLocEntry &getSLocEntryByID(int ID,
                                             bool *Invalid = nullptr) const {
     assert(ID != -1 && "Using FileID sentinel value");
     if (ID < 0)
       return getLoadedSLocEntryByID(ID, Invalid);
-    return getLocalSLocEntry(static_cast(ID), Invalid);
+    return getLocalSLocEntry(static_cast(ID));
   }
 
   const SrcMgr::SLocEntry &
diff --git a/clang/include/clang/Basic/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h
index eba055c302a7f..b472547012f0d 100644
--- a/clang/include/clang/Basic/TargetBuiltins.h
+++ b/clang/include/clang/Basic/TargetBuiltins.h
@@ -119,6 +119,11 @@ namespace clang {
   };
   }
 
+  /// VE builtins
+  namespace VE {
+  enum { LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, LastTSBuiltin };
+  }
+
   /// Flags to identify the types for overloaded Neon builtins.
   ///
   /// These must be kept in sync with the flags in utils/TableGen/NeonEmitter.h.
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 140f55ff66b10..2ee3b16596302 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -192,6 +192,7 @@ class TargetInfo : public virtual TransferrableTargetInfo,
   bool HasFloat128;
   bool HasFloat16;
   bool HasBFloat16;
+  bool HasStrictFP;
 
   unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth;
   unsigned short SimdDefaultAlign;
@@ -577,6 +578,9 @@ class TargetInfo : public virtual TransferrableTargetInfo,
   /// Determine whether the _BFloat16 type is supported on this target.
   virtual bool hasBFloat16Type() const { return HasBFloat16; }
 
+  /// Determine whether constrained floating point is supported on this target.
+  virtual bool hasStrictFP() const { return HasStrictFP; }
+
   /// Return the alignment that is suitable for storing any
   /// object with a fundamental alignment requirement.
   unsigned getSuitableAlign() const { return SuitableAlign; }
diff --git a/clang/include/clang/Basic/arm_neon.td b/clang/include/clang/Basic/arm_neon.td
index 289f5ea47b926..d0269f31c32dd 100644
--- a/clang/include/clang/Basic/arm_neon.td
+++ b/clang/include/clang/Basic/arm_neon.td
@@ -190,28 +190,20 @@ def OP_SCALAR_QRDMLAH_LN : Op<(call "vqadd", $p0, (call "vqrdmulh", $p1,
 def OP_SCALAR_QRDMLSH_LN : Op<(call "vqsub", $p0, (call "vqrdmulh", $p1,
                               (call "vget_lane", $p2, $p3)))>;
 
-multiclass ScalarGetSetLaneOpsF16 {
-  def _GET_LN  : Op<(bitcast scalarTy,
-                        (call "vget_lane",
-                            (bitcast "int16x4_t", $p0), $p1))>;
-  def _GET_LNQ : Op<(bitcast scalarTy,
-                        (call "vget_lane",
-                            (bitcast "int16x8_t", $p0), $p1))>;
-  def _SET_LN  : Op<(bitcast vectorTy4,
-                        (call "vset_lane",
-                            (bitcast "int16_t", $p0),
-                            (bitcast "int16x4_t", $p1), $p2))>;
-  def _SET_LNQ : Op<(bitcast vectorTy8,
-                        (call "vset_lane",
-                            (bitcast "int16_t", $p0),
-                            (bitcast "int16x8_t", $p1), $p2))>;
-}
-
-defm OP_SCALAR_HALF: ScalarGetSetLaneOpsF16<"float16_t",
-                                            "float16x4_t", "float16x8_t">;
-defm OP_SCALAR_BF16: ScalarGetSetLaneOpsF16<"bfloat16_t",
-                                            "bfloat16x4_t", "bfloat16x8_t">;
+def OP_SCALAR_HALF_GET_LN : Op<(bitcast "float16_t",
+                                   (call "vget_lane",
+                                         (bitcast "int16x4_t", $p0), $p1))>;
+def OP_SCALAR_HALF_GET_LNQ : Op<(bitcast "float16_t",
+                                    (call "vget_lane",
+                                          (bitcast "int16x8_t", $p0), $p1))>;
+def OP_SCALAR_HALF_SET_LN : Op<(bitcast "float16x4_t",
+                                   (call "vset_lane",
+                                         (bitcast "int16_t", $p0),
+                                         (bitcast "int16x4_t", $p1), $p2))>;
+def OP_SCALAR_HALF_SET_LNQ : Op<(bitcast "float16x8_t",
+                                    (call "vset_lane",
+                                          (bitcast "int16_t", $p0),
+                                          (bitcast "int16x8_t", $p1), $p2))>;
 
 def OP_DOT_LN
     : Op<(call "vdot", $p0, $p1,
@@ -260,6 +252,34 @@ def OP_BFMLALT_LN
     : Op<(call "vbfmlalt", $p0, $p1,
           (dup_typed $p1, (call "vget_lane", $p2, $p3)))>;
 
+def OP_VCVT_F32_BF16
+    : Op<(bitcast "R",
+          (call "vshll_n", (bitcast "int16x4_t", $p0),
+                           (literal "int32_t", "16")))>;
+def OP_VCVT_F32_BF16_LO
+    : Op<(call "vcvt_f32_bf16", (call "vget_low", $p0))>;
+def OP_VCVT_F32_BF16_HI
+    : Op<(call "vcvt_f32_bf16", (call "vget_high", $p0))>;
+
+def OP_VCVT_BF16_F32_LO_A64
+    : Op<(call "__a64_vcvtq_low_bf16", $p0)>;
+def OP_VCVT_BF16_F32_A64
+    : Op<(call "vget_low", (call "__a64_vcvtq_low_bf16", $p0))>;
+
+def OP_VCVT_BF16_F32_A32
+    : Op<(call "__a32_vcvt_bf16", $p0)>;
+
+def OP_VCVT_BF16_F32_LO_A32
+    : Op<(call "vcombine", (cast "bfloat16x4_t", (literal "uint64_t", "0ULL")),
+                           (call "__a32_vcvt_bf16", $p0))>;
+def OP_VCVT_BF16_F32_HI_A32
+    : Op<(call "vcombine", (call "__a32_vcvt_bf16", $p1),
+                           (call "vget_low", $p0))>;
+
+def OP_CVT_F32_BF16
+    : Op<(bitcast "R", (op "<<", (bitcast "int32_t", $p0),
+                                 (literal "int32_t", "16")))>;
+
 //===----------------------------------------------------------------------===//
 // Auxiliary Instructions
 //===----------------------------------------------------------------------===//
@@ -1918,10 +1938,12 @@ let ArchGuard = "defined(__ARM_FEATURE_BF16_VECTOR_ARITHMETIC)" in {
   def VGET_HIGH_BF : NoTestOpInst<"vget_high", ".Q", "b", OP_HI>;
   def VGET_LOW_BF  : NoTestOpInst<"vget_low", ".Q", "b", OP_LO>;
 
-  def VGET_LANE_BF : IOpInst<"vget_lane", "1.I", "b", OP_SCALAR_BF16_GET_LN>;
-  def VSET_LANE_BF : IOpInst<"vset_lane", ".1.I", "b", OP_SCALAR_BF16_SET_LN>;
-  def VGET_LANEQ_BF : IOpInst<"vget_lane", "1.I", "Qb", OP_SCALAR_BF16_GET_LNQ>;
-  def VSET_LANEQ_BF : IOpInst<"vset_lane", ".1.I", "Qb", OP_SCALAR_BF16_SET_LNQ>;
+  def VGET_LANE_BF : IInst<"vget_lane", "1.I", "bQb">;
+  def VSET_LANE_BF : IInst<"vset_lane", ".1.I", "bQb">;
+  def SCALAR_VDUP_LANE_BF : IInst<"vdup_lane", "1.I", "Sb">;
+  def SCALAR_VDUP_LANEQ_BF : IInst<"vdup_laneq", "1QI", "Sb"> {
+    let isLaneQ = 1;
+  }
 
   def VLD1_BF : WInst<"vld1", ".(c*!)", "bQb">;
   def VLD2_BF : WInst<"vld2", "2(c*!)", "bQb">;
@@ -1955,18 +1977,31 @@ let ArchGuard = "defined(__ARM_FEATURE_BF16_VECTOR_ARITHMETIC)" in {
   def VLD3_DUP_BF : WInst<"vld3_dup", "3(c*!)", "bQb">;
   def VLD4_DUP_BF : WInst<"vld4_dup", "4(c*!)", "bQb">;
 
+  def VCVT_F32_BF16 : SOpInst<"vcvt_f32_bf16", "(F>)(Bq!)",  "Qb", OP_VCVT_F32_BF16>;
+  def VCVT_LOW_F32_BF16 : SOpInst<"vcvt_low_f32", "(F>)(BQ!)",  "Qb", OP_VCVT_F32_BF16_LO>;
+  def VCVT_HIGH_F32_BF16 : SOpInst<"vcvt_high_f32", "(F>)(BQ!)", "Qb", OP_VCVT_F32_BF16_HI>;
+
+  def SCALAR_CVT_BF16_F32 : SInst<"vcvth_bf16", "(1B)1", "f">;
+  def SCALAR_CVT_F32_BF16 : SOpInst<"vcvtah_f32", "(1F>)(1!)", "b", OP_CVT_F32_BF16>;
 }
 
 let ArchGuard = "defined(__ARM_FEATURE_BF16_VECTOR_ARITHMETIC) && !defined(__aarch64__)" in {
-  def SCALAR_VDUP_LANE_BF_A32 : IOpInst<"vduph_lane", "1.I", "b", OP_SCALAR_BF16_GET_LN>;
-  def SCALAR_VDUP_LANEQ_BF_A32 : IOpInst<"vduph_laneq", "1.I", "Hb", OP_SCALAR_BF16_GET_LNQ>;
+  def VCVT_BF16_F32_A32_INTERNAL : WInst<"__a32_vcvt_bf16", "BQ", "f">;
+  def VCVT_BF16_F32_A32 : SOpInst<"vcvt_bf16", "BQ", "f", OP_VCVT_BF16_F32_A32>;
+  def VCVT_LOW_BF16_F32_A32 : SOpInst<"vcvt_low_bf16",  "BQ", "Qf", OP_VCVT_BF16_F32_LO_A32>;
+  def VCVT_HIGH_BF16_F32_A32 : SOpInst<"vcvt_high_bf16", "BBQ", "Qf", OP_VCVT_BF16_F32_HI_A32>;
 }
 
 let ArchGuard = "defined(__ARM_FEATURE_BF16_VECTOR_ARITHMETIC) && defined(__aarch64__)" in {
-  def SCALAR_VDUP_LANE_BF_A64 : IInst<"vdup_lane", "1.I", "Sb">;
-  def SCALAR_VDUP_LANEQ_BF_A64 : IInst<"vdup_laneq", "1QI", "Sb"> {
-    let isLaneQ = 1;
-  }
+  def VCVT_LOW_BF16_F32_A64_INTERNAL : WInst<"__a64_vcvtq_low_bf16", "BQ", "Hf">;
+  def VCVT_LOW_BF16_F32_A64 : SOpInst<"vcvt_low_bf16", "BQ", "Qf", OP_VCVT_BF16_F32_LO_A64>;
+  def VCVT_HIGH_BF16_F32_A64 : SInst<"vcvt_high_bf16", "BBQ", "Qf">;
+  def VCVT_BF16_F32 : SOpInst<"vcvt_bf16",    "BQ", "f", OP_VCVT_BF16_F32_A64>;
+
+  def COPY_LANE_BF16 : IOpInst<"vcopy_lane", "..I.I", "b", OP_COPY_LN>;
+  def COPYQ_LANE_BF16 : IOpInst<"vcopy_lane", "..IqI", "Qb", OP_COPY_LN>;
+  def COPY_LANEQ_BF16 : IOpInst<"vcopy_laneq", "..IQI", "b", OP_COPY_LN>;
+  def COPYQ_LANEQ_BF16 : IOpInst<"vcopy_laneq", "..I.I", "Qb", OP_COPY_LN>;
 }
 
 let ArchGuard = "defined(__ARM_FEATURE_BF16) && !defined(__aarch64__)" in {
diff --git a/clang/include/clang/Basic/arm_sve.td b/clang/include/clang/Basic/arm_sve.td
index 8b64db87190f9..19a42e79c36ab 100644
--- a/clang/include/clang/Basic/arm_sve.td
+++ b/clang/include/clang/Basic/arm_sve.td
@@ -271,6 +271,11 @@ def SVLD1UH : MInst<"svld1uh_{d}", "dPX", "ilUiUl",          [IsLoad, IsZExtRetu
 def SVLD1SW : MInst<"svld1sw_{d}", "dPU", "lUl",             [IsLoad],               MemEltTyInt32,   "aarch64_sve_ld1">;
 def SVLD1UW : MInst<"svld1uw_{d}", "dPY", "lUl",             [IsLoad, IsZExtReturn], MemEltTyInt32,   "aarch64_sve_ld1">;
 
+let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+  def SVLD1_BF      : MInst<"svld1[_{2}]",      "dPc",  "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ld1">;
+  def SVLD1_VNUM_BF : MInst<"svld1_vnum[_{2}]", "dPcl", "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ld1">;
+}
+
 // Load one vector (scalar base, VL displacement)
 def SVLD1_VNUM   : MInst<"svld1_vnum[_{2}]", "dPcl", "csilUcUsUiUlhfd", [IsLoad],               MemEltTyDefault, "aarch64_sve_ld1">;
 def SVLD1SB_VNUM : MInst<"svld1sb_vnum_{d}", "dPSl", "silUsUiUl",       [IsLoad],               MemEltTyInt8,    "aarch64_sve_ld1">;
@@ -376,6 +381,11 @@ def SVLDFF1UH_VNUM : MInst<"svldff1uh_vnum_{d}", "dPXl", "ilUiUl",          [IsL
 def SVLDFF1SW_VNUM : MInst<"svldff1sw_vnum_{d}", "dPUl", "lUl",             [IsLoad],               MemEltTyInt32,   "aarch64_sve_ldff1">;
 def SVLDFF1UW_VNUM : MInst<"svldff1uw_vnum_{d}", "dPYl", "lUl",             [IsLoad, IsZExtReturn], MemEltTyInt32,   "aarch64_sve_ldff1">;
 
+let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+  def SVLDFF1_BF      : MInst<"svldff1[_{2}]",      "dPc",  "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ldff1">;
+  def SVLDFF1_VNUM_BF : MInst<"svldff1_vnum[_{2}]", "dPcl", "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ldff1">;
+}
+
 // First-faulting load one vector (vector base)
 def SVLDFF1_GATHER_BASES_U   : MInst<"svldff1_gather[_{2}base]_{d}",   "dPu", "ilUiUlfd", [IsGatherLoad],               MemEltTyDefault, "aarch64_sve_ldff1_gather_scalar_offset">;
 def SVLDFF1SB_GATHER_BASES_U : MInst<"svldff1sb_gather[_{2}base]_{d}", "dPu", "ilUiUl",   [IsGatherLoad],               MemEltTyInt8,    "aarch64_sve_ldff1_gather_scalar_offset">;
@@ -471,32 +481,67 @@ def SVLDNF1UH_VNUM : MInst<"svldnf1uh_vnum_{d}", "dPXl", "ilUiUl",          [IsL
 def SVLDNF1SW_VNUM : MInst<"svldnf1sw_vnum_{d}", "dPUl", "lUl",             [IsLoad],               MemEltTyInt32,   "aarch64_sve_ldnf1">;
 def SVLDNF1UW_VNUM : MInst<"svldnf1uw_vnum_{d}", "dPYl", "lUl",             [IsLoad, IsZExtReturn], MemEltTyInt32,   "aarch64_sve_ldnf1">;
 
+let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+  def SVLDNF1_BF      : MInst<"svldnf1[_{2}]",      "dPc",  "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ldnf1">;
+  def SVLDNF1_VNUM_BF : MInst<"svldnf1_vnum[_{2}]", "dPcl", "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ldnf1">;
+}
+
 // Load one vector, unextended load, non-temporal (scalar base)
 def SVLDNT1 : MInst<"svldnt1[_{2}]", "dPc", "csilUcUsUiUlhfd", [IsLoad], MemEltTyDefault, "aarch64_sve_ldnt1">;
 
 // Load one vector, unextended load, non-temporal (scalar base, VL displacement)
 def SVLDNT1_VNUM : MInst<"svldnt1_vnum[_{2}]", "dPcl", "csilUcUsUiUlhfd", [IsLoad], MemEltTyDefault, "aarch64_sve_ldnt1">;
 
+let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+  def SVLDNT1_BF      : MInst<"svldnt1[_{2}]",      "dPc",  "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ldnt1">;
+  def SVLDNT1_VNUM_BF : MInst<"svldnt1_vnum[_{2}]", "dPcl", "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ldnt1">;
+}
+
 // Load one quadword and replicate (scalar base)
 def SVLD1RQ : SInst<"svld1rq[_{2}]", "dPc", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_ld1rq">;
 
+let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+  def SVLD1RQ_BF : SInst<"svld1rq[_{2}]", "dPc",  "b", MergeNone, "aarch64_sve_ld1rq">;
+}
+
+multiclass StructLoad {
+  def : SInst;
+  let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+    def: SInst;
+  }
+}
+
 // Load N-element structure into N vectors (scalar base)
-def SVLD2 : SInst<"svld2[_{2}]", "2Pc", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_ld2", [IsStructLoad]>;
-def SVLD3 : SInst<"svld3[_{2}]", "3Pc", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_ld3", [IsStructLoad]>;
-def SVLD4 : SInst<"svld4[_{2}]", "4Pc", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_ld4", [IsStructLoad]>;
+defm SVLD2 : StructLoad<"svld2[_{2}]", "2Pc", "aarch64_sve_ld2">;
+defm SVLD3 : StructLoad<"svld3[_{2}]", "3Pc", "aarch64_sve_ld3">;
+defm SVLD4 : StructLoad<"svld4[_{2}]", "4Pc", "aarch64_sve_ld4">;
 
 // Load N-element structure into N vectors (scalar base, VL displacement)
-def SVLD2_VNUM : SInst<"svld2_vnum[_{2}]", "2Pcl", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_ld2", [IsStructLoad]>;
-def SVLD3_VNUM : SInst<"svld3_vnum[_{2}]", "3Pcl", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_ld3", [IsStructLoad]>;
-def SVLD4_VNUM : SInst<"svld4_vnum[_{2}]", "4Pcl", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_ld4", [IsStructLoad]>;
+defm SVLD2_VNUM : StructLoad<"svld2_vnum[_{2}]", "2Pcl", "aarch64_sve_ld2">;
+defm SVLD3_VNUM : StructLoad<"svld3_vnum[_{2}]", "3Pcl", "aarch64_sve_ld3">;
+defm SVLD4_VNUM : StructLoad<"svld4_vnum[_{2}]", "4Pcl", "aarch64_sve_ld4">;
 
 // Load one octoword and replicate (scalar base)
 let ArchGuard = "defined(__ARM_FEATURE_SVE_MATMUL_FP64)" in {
   def SVLD1RO : SInst<"svld1ro[_{2}]", "dPc", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_ld1ro">;
 }
-let ArchGuard = "defined(__ARM_FEATURE_SVE_MATMUL_FP64) && defined(__ARM_FEATURE_BF16_SCALAR_ARITHMETIC)" in {
-  def SVLD1RO_BF : SInst<"svld1ro[_{2}]", "dPc", "b", MergeNone, "aarch64_sve_ld1ro">;
+let ArchGuard = "defined(__ARM_FEATURE_SVE_MATMUL_FP64) && defined(__ARM_FEATURE_SVE_BF16)" in {
+  def SVLD1RO_BF16 : SInst<"svld1ro[_{2}]", "dPc", "b", MergeNone, "aarch64_sve_ld1ro">;
+}
+
+let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+  def SVBFDOT        : SInst<"svbfdot[_{0}]",        "MMdd",  "b", MergeNone, "aarch64_sve_bfdot",        [IsOverloadNone]>;
+  def SVBFMLALB      : SInst<"svbfmlalb[_{0}]",      "MMdd",  "b", MergeNone, "aarch64_sve_bfmlalb",      [IsOverloadNone]>;
+  def SVBFMLALT      : SInst<"svbfmlalt[_{0}]",      "MMdd",  "b", MergeNone, "aarch64_sve_bfmlalt",      [IsOverloadNone]>;
+  def SVBFMMLA       : SInst<"svbfmmla[_{0}]",       "MMdd",  "b", MergeNone, "aarch64_sve_bfmmla",       [IsOverloadNone]>;
+  def SVBFDOT_N      : SInst<"svbfdot[_n_{0}]",      "MMda",  "b", MergeNone, "aarch64_sve_bfdot",        [IsOverloadNone]>;
+  def SVBFMLAL_N     : SInst<"svbfmlalb[_n_{0}]",    "MMda",  "b", MergeNone, "aarch64_sve_bfmlalb",      [IsOverloadNone]>;
+  def SVBFMLALT_N    : SInst<"svbfmlalt[_n_{0}]",    "MMda",  "b", MergeNone, "aarch64_sve_bfmlalt",      [IsOverloadNone]>;
+  def SVBFDOT_LANE   : SInst<"svbfdot_lane[_{0}]",   "MMddn", "b", MergeNone, "aarch64_sve_bfdot_lane",   [IsOverloadNone], [ImmCheck<3, ImmCheck0_3>]>;
+  def SVBFMLALB_LANE : SInst<"svbfmlalb_lane[_{0}]", "MMddn", "b", MergeNone, "aarch64_sve_bfmlalb_lane", [IsOverloadNone], [ImmCheck<3, ImmCheck0_7>]>;
+  def SVBFMLALT_LANE : SInst<"svbfmlalt_lane[_{0}]", "MMddn", "b", MergeNone, "aarch64_sve_bfmlalt_lane", [IsOverloadNone], [ImmCheck<3, ImmCheck0_7>]>;
 }
+
 ////////////////////////////////////////////////////////////////////////////////
 // Stores
 
@@ -518,6 +563,11 @@ def SVST1H_VNUM_U : MInst<"svst1h_vnum[_{d}]", "vPFld", "UiUl",            [IsSt
 def SVST1W_VNUM_S : MInst<"svst1w_vnum[_{d}]", "vPCld", "l",               [IsStore], MemEltTyInt32,   "aarch64_sve_st1">;
 def SVST1W_VNUM_U : MInst<"svst1w_vnum[_{d}]", "vPGld", "Ul",              [IsStore], MemEltTyInt32,   "aarch64_sve_st1">;
 
+let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+  def SVST1_BF      : MInst<"svst1[_{d}]",      "vPpd",  "b", [IsStore], MemEltTyDefault, "aarch64_sve_st1">;
+  def SVST1_VNUM_BF : MInst<"svst1_vnum[_{d}]", "vPpld", "b", [IsStore], MemEltTyDefault, "aarch64_sve_st1">;
+}
+
 // Store one vector (vector base)
 def SVST1_SCATTER_BASES_U     : MInst<"svst1_scatter[_{2}base_{d}]",  "vPud",  "ilUiUlfd", [IsScatterStore], MemEltTyDefault, "aarch64_sve_st1_scatter_scalar_offset">;
 def SVST1B_SCATTER_BASES_U    : MInst<"svst1b_scatter[_{2}base_{d}]", "vPud",  "ilUiUl",   [IsScatterStore], MemEltTyInt8,    "aarch64_sve_st1_scatter_scalar_offset">;
@@ -587,15 +637,21 @@ def SVST1_SCATTER_INDEX_S     : MInst<"svst1_scatter[_{2}base]_index[_{d}]",  "v
 def SVST1H_SCATTER_INDEX_S    : MInst<"svst1h_scatter[_{2}base]_index[_{d}]", "vPuld", "ilUiUl",   [IsScatterStore], MemEltTyInt16,   "aarch64_sve_st1_scatter_scalar_offset">;
 def SVST1W_SCATTER_INDEX_S    : MInst<"svst1w_scatter[_{2}base]_index[_{d}]", "vPuld", "lUl",      [IsScatterStore], MemEltTyInt32,   "aarch64_sve_st1_scatter_scalar_offset">;
 
+multiclass StructStore {
+  def : SInst;
+  let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+    def: SInst;
+  }
+}
 // Store N vectors into N-element structure (scalar base)
-def SVST2 : SInst<"svst2[_{d}]", "vPp2", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_st2", [IsStructStore]>;
-def SVST3 : SInst<"svst3[_{d}]", "vPp3", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_st3", [IsStructStore]>;
-def SVST4 : SInst<"svst4[_{d}]", "vPp4", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_st4", [IsStructStore]>;
+defm SVST2 : StructStore<"svst2[_{d}]", "vPp2", "aarch64_sve_st2">;
+defm SVST3 : StructStore<"svst3[_{d}]", "vPp3", "aarch64_sve_st3">;
+defm SVST4 : StructStore<"svst4[_{d}]", "vPp4", "aarch64_sve_st4">;
 
 // Store N vectors into N-element structure (scalar base, VL displacement)
-def SVST2_VNUM : SInst<"svst2_vnum[_{d}]", "vPpl2", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_st2", [IsStructStore]>;
-def SVST3_VNUM : SInst<"svst3_vnum[_{d}]", "vPpl3", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_st3", [IsStructStore]>;
-def SVST4_VNUM : SInst<"svst4_vnum[_{d}]", "vPpl4", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_st4", [IsStructStore]>;
+defm SVST2_VNUM : StructStore<"svst2_vnum[_{d}]", "vPpl2", "aarch64_sve_st2">;
+defm SVST3_VNUM : StructStore<"svst3_vnum[_{d}]", "vPpl3", "aarch64_sve_st3">;
+defm SVST4_VNUM : StructStore<"svst4_vnum[_{d}]", "vPpl4", "aarch64_sve_st4">;
 
 // Store one vector, with no truncation, non-temporal (scalar base)
 def SVSTNT1 : MInst<"svstnt1[_{d}]", "vPpd", "csilUcUsUiUlhfd", [IsStore], MemEltTyDefault, "aarch64_sve_stnt1">;
@@ -603,6 +659,11 @@ def SVSTNT1 : MInst<"svstnt1[_{d}]", "vPpd", "csilUcUsUiUlhfd", [IsStore], MemEl
 // Store one vector, with no truncation, non-temporal (scalar base, VL displacement)
 def SVSTNT1_VNUM : MInst<"svstnt1_vnum[_{d}]", "vPpld", "csilUcUsUiUlhfd", [IsStore], MemEltTyDefault, "aarch64_sve_stnt1">;
 
+let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+  def SVSTNT1_BF      : MInst<"svstnt1[_{d}]",      "vPpd",  "b", [IsStore], MemEltTyDefault, "aarch64_sve_stnt1">;
+  def SVSTNT1_VNUM_BF : MInst<"svstnt1_vnum[_{d}]", "vPpld", "b", [IsStore], MemEltTyDefault, "aarch64_sve_stnt1">;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Prefetches
 
@@ -664,13 +725,23 @@ def SVADRD : SInst<"svadrd[_{0}base]_[{2}]index",  "uud", "ilUiUl", MergeNone, "
 
 def SVDUPQ_8  : SInst<"svdupq[_n]_{d}", "dssssssssssssssss",  "cUc", MergeNone>;
 def SVDUPQ_16 : SInst<"svdupq[_n]_{d}", "dssssssss",  "sUsh", MergeNone>;
+let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+  def SVDUPQ_BF16 : SInst<"svdupq[_n]_{d}", "dssssssss",  "b", MergeNone>;
+}
 def SVDUPQ_32 : SInst<"svdupq[_n]_{d}", "dssss",  "iUif", MergeNone>;
 def SVDUPQ_64 : SInst<"svdupq[_n]_{d}", "dss",  "lUld", MergeNone>;
 
-def SVDUP   : SInst<"svdup[_n]_{d}", "ds",   "csilUcUsUiUlhfd", MergeNone,    "aarch64_sve_dup_x">;
-def SVDUP_M : SInst<"svdup[_n]_{d}", "ddPs", "csilUcUsUiUlhfd", MergeOp1,     "aarch64_sve_dup">;
-def SVDUP_X : SInst<"svdup[_n]_{d}", "dPs",  "csilUcUsUiUlhfd", MergeAnyExp,  "aarch64_sve_dup">;
-def SVDUP_Z : SInst<"svdup[_n]_{d}", "dPs",  "csilUcUsUiUlhfd", MergeZeroExp, "aarch64_sve_dup">;
+multiclass svdup_base {
+  def NAME : SInst;
+  let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+    def _BF16: SInst;
+  }
+}
+
+defm SVDUP   : svdup_base<"svdup[_n]_{d}", "ds",   MergeNone,    "aarch64_sve_dup_x">;
+defm SVDUP_M : svdup_base<"svdup[_n]_{d}", "ddPs", MergeOp1,     "aarch64_sve_dup">;
+defm SVDUP_X : svdup_base<"svdup[_n]_{d}", "dPs",  MergeAnyExp,  "aarch64_sve_dup">;
+defm SVDUP_Z : svdup_base<"svdup[_n]_{d}", "dPs",  MergeZeroExp, "aarch64_sve_dup">;
 
 def SVINDEX : SInst<"svindex_{d}",   "dss",  "csilUcUsUiUl",    MergeNone,    "aarch64_sve_index">;
 
@@ -789,8 +860,11 @@ defm SVLSR : SInst_SHIFT<"svlsr", "aarch64_sve_lsr", "UcUsUiUl", "UcUsUi">;
 def SVASRD_M : SInst<"svasrd[_n_{d}]", "dPdi", "csil",            MergeOp1,  "aarch64_sve_asrd", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
 def SVASRD_X : SInst<"svasrd[_n_{d}]", "dPdi", "csil",            MergeAny,  "aarch64_sve_asrd", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
 def SVASRD_Z : SInst<"svasrd[_n_{d}]", "dPdi", "csil",            MergeZero, "aarch64_sve_asrd", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
-def SVINSR   : SInst<"svinsr[_n_{d}]", "dds",  "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_insr">;
 
+def SVINSR : SInst<"svinsr[_n_{d}]", "dds", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_insr">;
+let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+  def SVINSR_BF16 : SInst<"svinsr[_n_{d}]", "dds",  "b", MergeNone, "aarch64_sve_insr">;
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 // Integer reductions
@@ -877,6 +951,10 @@ defm SVCLS : SInstCLS<"svcls", "csil",            "aarch64_sve_cls">;
 defm SVCLZ : SInstCLS<"svclz", "csilUcUsUiUl",    "aarch64_sve_clz">;
 defm SVCNT : SInstCLS<"svcnt", "csilUcUsUiUlhfd", "aarch64_sve_cnt">;
 
+let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+  defm SVCNT_BF16 : SInstCLS<"svcnt", "b", "aarch64_sve_cnt">;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Conversion
 
@@ -1030,6 +1108,11 @@ defm SVFCVTZS_S64_F16 : SInstCvtMXZ<"svcvt_s64[_f16]", "ddPO", "dPO", "l",  "aar
 defm SVFCVTZS_S32_F32 : SInstCvtMXZ<"svcvt_s32[_f32]", "ddPM", "dPM", "i",  "aarch64_sve_fcvtzs", [IsOverloadCvt]>;
 defm SVFCVTZS_S64_F32 : SInstCvtMXZ<"svcvt_s64[_f32]", "ddPM", "dPM", "l",  "aarch64_sve_fcvtzs_i64f32">;
 
+let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+  defm SVCVT_BF16_F32   : SInstCvtMXZ<"svcvt_bf16[_f32]",  "ddPM", "dPM", "b",  "aarch64_sve_fcvt_bf16f32">;
+  def SVCVTNT_BF16_F32 : SInst<"svcvtnt_bf16[_f32]", "ddPM", "b",  MergeOp1, "aarch64_sve_fcvtnt_bf16f32", [IsOverloadNone]>;
+}
+
 // svcvt_s##_f64
 defm SVFCVTZS_S32_F64 : SInstCvtMXZ<"svcvt_s32[_f64]", "ttPd", "tPd", "d",  "aarch64_sve_fcvtzs_i32f64">;
 defm SVFCVTZS_S64_F64 : SInstCvtMXZ<"svcvt_s64[_f64]", "ddPN", "dPN", "l",  "aarch64_sve_fcvtzs", [IsOverloadCvt]>;
@@ -1103,24 +1186,45 @@ def SVCVTXNT_F32    : SInst<"svcvtxnt_f32[_f64]", "MMPd", "d", MergeOp1, "aarch6
 ////////////////////////////////////////////////////////////////////////////////
 // Permutations and selection
 
-def SVCLASTA     : SInst<"svclasta[_{d}]",    "dPdd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_clasta">;
-def SVCLASTA_N   : SInst<"svclasta[_n_{d}]",  "sPsd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_clasta_n">;
-def SVCLASTB     : SInst<"svclastb[_{d}]",    "dPdd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_clastb">;
-def SVCLASTB_N   : SInst<"svclastb[_n_{d}]",  "sPsd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_clastb_n">;
+multiclass SVEPerm {
+  def : SInst;
+  let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+    def: SInst;
+  }
+}
+
+defm SVCLASTA    : SVEPerm<"svclasta[_{d}]",   "dPdd", "aarch64_sve_clasta">;
+defm SVCLASTA_N  : SVEPerm<"svclasta[_n_{d}]", "sPsd", "aarch64_sve_clasta_n">;
+defm SVCLASTB    : SVEPerm<"svclastb[_{d}]",   "dPdd", "aarch64_sve_clastb">;
+defm SVCLASTB_N  : SVEPerm<"svclastb[_n_{d}]", "sPsd", "aarch64_sve_clastb_n">;
+
 def SVCOMPACT    : SInst<"svcompact[_{d}]",   "dPd",  "ilUiUlfd",        MergeNone, "aarch64_sve_compact">;
 // Note: svdup_lane is implemented using the intrinsic for TBL to represent a
 // splat of any possible lane. It is upto LLVM to pick a more efficient
 // instruction such as DUP (indexed) if the lane index fits the range of the
 // instruction's immediate.
 def SVDUP_LANE   : SInst<"svdup_lane[_{d}]",  "ddL",  "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tbl">;
+let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+def SVDUP_LANE_BF16 :
+                   SInst<"svdup_lane[_{d}]",  "ddL",  "b",               MergeNone, "aarch64_sve_tbl">;
+}
+
 def SVDUPQ_LANE  : SInst<"svdupq_lane[_{d}]", "ddn",  "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_dupq_lane">;
+let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+  def SVDUPQ_LANE_BF16  : SInst<"svdupq_lane[_{d}]", "ddn",  "b", MergeNone, "aarch64_sve_dupq_lane">;
+}
 def SVEXT        : SInst<"svext[_{d}]",       "dddi", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_ext", [], [ImmCheck<2, ImmCheckExtract, 1>]>;
-def SVLASTA      : SInst<"svlasta[_{d}]",     "sPd",  "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_lasta">;
-def SVLASTB      : SInst<"svlastb[_{d}]",     "sPd",  "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_lastb">;
+defm SVLASTA     : SVEPerm<"svlasta[_{d}]",   "sPd",  "aarch64_sve_lasta">;
+defm SVLASTB     : SVEPerm<"svlastb[_{d}]",   "sPd",  "aarch64_sve_lastb">;
 def SVREV        : SInst<"svrev[_{d}]",       "dd",   "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_rev">;
 def SVSEL        : SInst<"svsel[_{d}]",       "dPdd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_sel">;
 def SVSPLICE     : SInst<"svsplice[_{d}]",    "dPdd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_splice">;
 def SVTBL        : SInst<"svtbl[_{d}]",       "ddu",  "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tbl">;
+
+let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+  def SVTBL_BF16 : SInst<"svtbl[_{d}]",       "ddu",  "b",               MergeNone, "aarch64_sve_tbl">;
+}
+
 def SVTRN1       : SInst<"svtrn1[_{d}]",      "ddd",  "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_trn1">;
 def SVTRN2       : SInst<"svtrn2[_{d}]",      "ddd",  "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_trn2">;
 def SVUNPKHI_S   : SInst<"svunpkhi[_{d}]",    "dh",   "sil",             MergeNone, "aarch64_sve_sunpkhi">;
@@ -1132,6 +1236,19 @@ def SVUZP2       : SInst<"svuzp2[_{d}]",      "ddd",  "csilUcUsUiUlhfd", MergeNo
 def SVZIP1       : SInst<"svzip1[_{d}]",      "ddd",  "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_zip1">;
 def SVZIP2       : SInst<"svzip2[_{d}]",      "ddd",  "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_zip2">;
 
+let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+def SVEXT_BF16    : SInst<"svext[_{d}]",    "dddi", "b", MergeNone, "aarch64_sve_ext", [], [ImmCheck<2, ImmCheckExtract, 1>]>;
+def SVREV_BF16    : SInst<"svrev[_{d}]",    "dd",   "b", MergeNone, "aarch64_sve_rev">;
+def SVSEL_BF16    : SInst<"svsel[_{d}]",    "dPdd", "b", MergeNone, "aarch64_sve_sel">;
+def SVSPLICE_BF16 : SInst<"svsplice[_{d}]", "dPdd", "b", MergeNone, "aarch64_sve_splice">;
+def SVTRN1_BF16   : SInst<"svtrn1[_{d}]",   "ddd",  "b", MergeNone, "aarch64_sve_trn1">;
+def SVTRN2_BF16   : SInst<"svtrn2[_{d}]",   "ddd",  "b", MergeNone, "aarch64_sve_trn2">;
+def SVUZP1_BF16   : SInst<"svuzp1[_{d}]",   "ddd",  "b", MergeNone, "aarch64_sve_uzp1">;
+def SVUZP2_BF16   : SInst<"svuzp2[_{d}]",   "ddd",  "b", MergeNone, "aarch64_sve_uzp2">;
+def SVZIP1_BF16   : SInst<"svzip1[_{d}]",   "ddd",  "b", MergeNone, "aarch64_sve_zip1">;
+def SVZIP2_BF16   : SInst<"svzip2[_{d}]",   "ddd",  "b", MergeNone, "aarch64_sve_zip2">;
+}
+
 def SVREV_B   : SInst<"svrev_{d}",      "PP",   "PcPsPiPl", MergeNone, "aarch64_sve_rev">;
 def SVSEL_B   : SInst<"svsel[_b]",      "PPPP", "Pc",       MergeNone, "aarch64_sve_sel">;
 def SVTRN1_B  : SInst<"svtrn1_{d}",     "PPP",  "PcPsPiPl", MergeNone, "aarch64_sve_trn1">;
@@ -1213,6 +1330,10 @@ def SVCNTD : SInst<"svcntd", "n", "", MergeNone, "aarch64_sve_cntd", [IsAppendSV
 def SVCNTP : SInst<"svcntp_{d}",  "nPP", "PcPsPiPl",        MergeNone, "aarch64_sve_cntp">;
 def SVLEN  : SInst<"svlen[_{d}]", "nd",  "csilUcUsUiUlhfd", MergeNone>;
 
+let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+def SVLEN_BF16 : SInst<"svlen[_{d}]", "nd", "b", MergeNone>;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Saturating scalar arithmetic
 
@@ -1303,6 +1424,15 @@ def SVZIP1Q      : SInst<"svzip1q[_{d}]",     "ddd",  "csilUcUsUiUlhfd", MergeNo
 def SVZIP2Q      : SInst<"svzip2q[_{d}]",     "ddd",  "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_zip2q">;
 }
 
+let ArchGuard = "defined(__ARM_FEATURE_SVE_MATMUL_FP64) && defined(__ARM_FEATURE_SVE_BF16)" in {
+def SVTRN1Q_BF16      : SInst<"svtrn1q[_{d}]",     "ddd",  "b", MergeNone, "aarch64_sve_trn1q">;
+def SVTRN2Q_BF16      : SInst<"svtrn2q[_{d}]",     "ddd",  "b", MergeNone, "aarch64_sve_trn2q">;
+def SVUZP1Q_BF16      : SInst<"svuzp1q[_{d}]",     "ddd",  "b", MergeNone, "aarch64_sve_uzp1q">;
+def SVUZP2Q_BF16      : SInst<"svuzp2q[_{d}]",     "ddd",  "b", MergeNone, "aarch64_sve_uzp2q">;
+def SVZIP1Q_BF16      : SInst<"svzip1q[_{d}]",     "ddd",  "b", MergeNone, "aarch64_sve_zip1q">;
+def SVZIP2Q_BF16      : SInst<"svzip2q[_{d}]",     "ddd",  "b", MergeNone, "aarch64_sve_zip2q">;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Vector creation
 def SVUNDEF_1 : SInst<"svundef_{d}",  "d", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef]>;
@@ -1314,6 +1444,16 @@ def SVCREATE_2 : SInst<"svcreate2[_{d}]", "2dd",   "csilUcUsUiUlhfd", MergeNone,
 def SVCREATE_3 : SInst<"svcreate3[_{d}]", "3ddd",  "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tuple_create3", [IsTupleCreate]>;
 def SVCREATE_4 : SInst<"svcreate4[_{d}]", "4dddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tuple_create4", [IsTupleCreate]>;
 
+let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+def SVUNDEF_1_BF16 : SInst<"svundef_{d}",  "d", "b", MergeNone, "", [IsUndef]>;
+def SVUNDEF_2_BF16 : SInst<"svundef2_{d}", "2", "b", MergeNone, "", [IsUndef]>;
+def SVUNDEF_3_BF16 : SInst<"svundef3_{d}", "3", "b", MergeNone, "", [IsUndef]>;
+def SVUNDEF_4_BF16 : SInst<"svundef4_{d}", "4", "b", MergeNone, "", [IsUndef]>;
+
+def SVCREATE_2_BF16 : SInst<"svcreate2[_{d}]", "2dd",   "b", MergeNone, "aarch64_sve_tuple_create2", [IsTupleCreate]>;
+def SVCREATE_3_BF16 : SInst<"svcreate3[_{d}]", "3ddd",  "b", MergeNone, "aarch64_sve_tuple_create3", [IsTupleCreate]>;
+def SVCREATE_4_BF16 : SInst<"svcreate4[_{d}]", "4dddd", "b", MergeNone, "aarch64_sve_tuple_create4", [IsTupleCreate]>;
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 // Vector insertion and extraction
@@ -1325,6 +1465,16 @@ def SVSET_2 : SInst<"svset2[_{d}]", "22id", "csilUcUsUiUlhfd", MergeNone, "aarch
 def SVSET_3 : SInst<"svset3[_{d}]", "33id", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tuple_set", [IsTupleSet], [ImmCheck<1, ImmCheck0_2>]>;
 def SVSET_4 : SInst<"svset4[_{d}]", "44id", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tuple_set", [IsTupleSet], [ImmCheck<1, ImmCheck0_3>]>;
 
+let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+def SVGET_2_BF16 : SInst<"svget2[_{d}]", "d2i", "b", MergeNone, "aarch64_sve_tuple_get", [IsTupleGet], [ImmCheck<1, ImmCheck0_1>]>;
+def SVGET_3_BF16 : SInst<"svget3[_{d}]", "d3i", "b", MergeNone, "aarch64_sve_tuple_get", [IsTupleGet], [ImmCheck<1, ImmCheck0_2>]>;
+def SVGET_4_BF16 : SInst<"svget4[_{d}]", "d4i", "b", MergeNone, "aarch64_sve_tuple_get", [IsTupleGet], [ImmCheck<1, ImmCheck0_3>]>;
+
+def SVSET_2_BF16 : SInst<"svset2[_{d}]", "22id", "b", MergeNone, "aarch64_sve_tuple_set", [IsTupleSet], [ImmCheck<1, ImmCheck0_1>]>;
+def SVSET_3_BF16 : SInst<"svset3[_{d}]", "33id", "b", MergeNone, "aarch64_sve_tuple_set", [IsTupleSet], [ImmCheck<1, ImmCheck0_2>]>;
+def SVSET_4_BF16 : SInst<"svset4[_{d}]", "44id", "b", MergeNone, "aarch64_sve_tuple_set", [IsTupleSet], [ImmCheck<1, ImmCheck0_3>]>;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // SVE2 WhileGE/GT
 let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in {
@@ -1881,6 +2031,11 @@ def SVWHILEWR_S : SInst<"svwhilewr[_{1}]", "Pcc", "iUif", MergeNone, "aarch64_sv
 def SVWHILEWR_D : SInst<"svwhilewr[_{1}]", "Pcc", "lUld", MergeNone, "aarch64_sve_whilewr_d", [IsOverloadWhileRW]>;
 }
 
+let ArchGuard = "defined(__ARM_FEATURE_SVE2) && defined(__ARM_FEATURE_BF16_SCALAR_ARITHMETIC)" in {
+def SVWHILERW_H_BF16 : SInst<"svwhilerw[_{1}]", "Pcc", "b", MergeNone, "aarch64_sve_whilerw_h", [IsOverloadWhileRW]>;
+def SVWHILEWR_H_BF16 : SInst<"svwhilewr[_{1}]", "Pcc", "b", MergeNone, "aarch64_sve_whilewr_h", [IsOverloadWhileRW]>;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // SVE2 - Extended table lookup/permute
 let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in {
@@ -1888,6 +2043,11 @@ def SVTBL2 : SInst<"svtbl2[_{d}]", "d2u",  "csilUcUsUiUlhfd", MergeNone>;
 def SVTBX  : SInst<"svtbx[_{d}]",  "dddu", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tbx">;
 }
 
+let ArchGuard = "defined(__ARM_FEATURE_SVE2) && defined(__ARM_FEATURE_SVE_BF16)" in {
+def SVTBL2_BF16 : SInst<"svtbl2[_{d}]", "d2u",  "b", MergeNone>;
+def SVTBX_BF16  : SInst<"svtbx[_{d}]",  "dddu", "b", MergeNone, "aarch64_sve_tbx">;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // SVE2 - Optional
 
diff --git a/clang/include/clang/CodeGen/CodeGenABITypes.h b/clang/include/clang/CodeGen/CodeGenABITypes.h
index 0201f92074ecb..3c745fadbe78f 100644
--- a/clang/include/clang/CodeGen/CodeGenABITypes.h
+++ b/clang/include/clang/CodeGen/CodeGenABITypes.h
@@ -25,7 +25,9 @@
 
 #include "clang/AST/CanonicalType.h"
 #include "clang/AST/Type.h"
+#include "clang/Basic/ABI.h"
 #include "clang/CodeGen/CGFunctionInfo.h"
+#include "llvm/IR/BasicBlock.h"
 
 namespace llvm {
 class AttrBuilder;
@@ -40,6 +42,7 @@ class Type;
 namespace clang {
 class ASTContext;
 class CXXConstructorDecl;
+class CXXDestructorDecl;
 class CXXRecordDecl;
 class CXXMethodDecl;
 class CodeGenOptions;
@@ -90,6 +93,12 @@ const CGFunctionInfo &arrangeFreeFunctionCall(CodeGenModule &CGM,
 ImplicitCXXConstructorArgs
 getImplicitCXXConstructorArgs(CodeGenModule &CGM, const CXXConstructorDecl *D);
 
+llvm::Value *
+getCXXDestructorImplicitParam(CodeGenModule &CGM, llvm::BasicBlock *InsertBlock,
+                              llvm::BasicBlock::iterator InsertPoint,
+                              const CXXDestructorDecl *D, CXXDtorType Type,
+                              bool ForVirtualBase, bool Delegating);
+
 /// Returns null if the function type is incomplete and can't be lowered.
 llvm::FunctionType *convertFreeFunctionType(CodeGenModule &CGM,
                                             const FunctionDecl *FD);
diff --git a/clang/include/clang/Driver/Action.h b/clang/include/clang/Driver/Action.h
index 8ccbb6c2bbfa2..27c95c6f89d41 100644
--- a/clang/include/clang/Driver/Action.h
+++ b/clang/include/clang/Driver/Action.h
@@ -73,9 +73,10 @@ class Action {
     OffloadBundlingJobClass,
     OffloadUnbundlingJobClass,
     OffloadWrapperJobClass,
+    StaticLibJobClass,
 
     JobClassFirst = PreprocessJobClass,
-    JobClassLast = OffloadWrapperJobClass
+    JobClassLast = StaticLibJobClass
   };
 
   // The offloading kind determines if this action is binded to a particular
@@ -637,6 +638,17 @@ class OffloadWrapperJobAction : public JobAction {
   }
 };
 
+class StaticLibJobAction : public JobAction {
+  void anchor() override;
+
+public:
+  StaticLibJobAction(ActionList &Inputs, types::ID Type);
+
+  static bool classof(const Action *A) {
+    return A->getKind() == StaticLibJobClass;
+  }
+};
+
 } // namespace driver
 } // namespace clang
 
diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td
deleted file mode 100644
index 9d2bfbf949efd..0000000000000
--- a/clang/include/clang/Driver/CC1Options.td
+++ /dev/null
@@ -1,941 +0,0 @@
-//===--- CC1Options.td - Options for clang -cc1 ---------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file defines the options accepted by clang -cc1 and clang -cc1as.
-//
-//===----------------------------------------------------------------------===//
-
-let Flags = [CC1Option, NoDriverOption] in {
-
-//===----------------------------------------------------------------------===//
-// Target Options
-//===----------------------------------------------------------------------===//
-
-let Flags = [CC1Option, CC1AsOption, NoDriverOption] in {
-
-def target_cpu : Separate<["-"], "target-cpu">,
-  HelpText<"Target a specific cpu type">;
-def target_feature : Separate<["-"], "target-feature">,
-  HelpText<"Target specific attributes">;
-def triple : Separate<["-"], "triple">,
-  HelpText<"Specify target triple (e.g. i686-apple-darwin9)">;
-def target_abi : Separate<["-"], "target-abi">,
-  HelpText<"Target a particular ABI type">;
-def target_sdk_version_EQ : Joined<["-"], "target-sdk-version=">,
-  HelpText<"The version of target SDK used for compilation">;
-
-}
-
-def target_linker_version : Separate<["-"], "target-linker-version">,
-  HelpText<"Target linker version">;
-def triple_EQ : Joined<["-"], "triple=">, Alias;
-def mfpmath : Separate<["-"], "mfpmath">,
-  HelpText<"Which unit to use for fp math">;
-
-def fpadding_on_unsigned_fixed_point : Flag<["-"], "fpadding-on-unsigned-fixed-point">,
-  HelpText<"Force each unsigned fixed point type to have an extra bit of padding to align their scales with those of signed fixed point types">;
-def fno_padding_on_unsigned_fixed_point : Flag<["-"], "fno-padding-on-unsigned-fixed-point">;
-
-//===----------------------------------------------------------------------===//
-// Analyzer Options
-//===----------------------------------------------------------------------===//
-
-def analysis_UnoptimizedCFG : Flag<["-"], "unoptimized-cfg">,
-  HelpText<"Generate unoptimized CFGs for all analyses">;
-def analysis_CFGAddImplicitDtors : Flag<["-"], "cfg-add-implicit-dtors">,
-  HelpText<"Add C++ implicit destructors to CFGs for all analyses">;
-
-def analyzer_store : Separate<["-"], "analyzer-store">,
-  HelpText<"Source Code Analysis - Abstract Memory Store Models">;
-def analyzer_store_EQ : Joined<["-"], "analyzer-store=">, Alias;
-
-def analyzer_constraints : Separate<["-"], "analyzer-constraints">,
-  HelpText<"Source Code Analysis - Symbolic Constraint Engines">;
-def analyzer_constraints_EQ : Joined<["-"], "analyzer-constraints=">,
-  Alias;
-
-def analyzer_output : Separate<["-"], "analyzer-output">,
-  HelpText<"Source Code Analysis - Output Options">;
-def analyzer_output_EQ : Joined<["-"], "analyzer-output=">,
-  Alias;
-
-def analyzer_purge : Separate<["-"], "analyzer-purge">,
-  HelpText<"Source Code Analysis - Dead Symbol Removal Frequency">;
-def analyzer_purge_EQ : Joined<["-"], "analyzer-purge=">, Alias;
-
-def analyzer_opt_analyze_headers : Flag<["-"], "analyzer-opt-analyze-headers">,
-  HelpText<"Force the static analyzer to analyze functions defined in header files">;
-def analyzer_opt_analyze_nested_blocks : Flag<["-"], "analyzer-opt-analyze-nested-blocks">,
-  HelpText<"Analyze the definitions of blocks in addition to functions">;
-def analyzer_display_progress : Flag<["-"], "analyzer-display-progress">,
-  HelpText<"Emit verbose output about the analyzer's progress">;
-def analyze_function : Separate<["-"], "analyze-function">,
-  HelpText<"Run analysis on specific function (for C++ include parameters in name)">;
-def analyze_function_EQ : Joined<["-"], "analyze-function=">, Alias;
-def trim_egraph : Flag<["-"], "trim-egraph">,
-  HelpText<"Only show error-related paths in the analysis graph">;
-def analyzer_viz_egraph_graphviz : Flag<["-"], "analyzer-viz-egraph-graphviz">,
-  HelpText<"Display exploded graph using GraphViz">;
-def analyzer_dump_egraph : Separate<["-"], "analyzer-dump-egraph">,
-  HelpText<"Dump exploded graph to the specified file">;
-def analyzer_dump_egraph_EQ : Joined<["-"], "analyzer-dump-egraph=">, Alias;
-
-def analyzer_inline_max_stack_depth : Separate<["-"], "analyzer-inline-max-stack-depth">,
-  HelpText<"Bound on stack depth while inlining (4 by default)">;
-def analyzer_inline_max_stack_depth_EQ : Joined<["-"], "analyzer-inline-max-stack-depth=">,
-  Alias;
-
-def analyzer_inlining_mode : Separate<["-"], "analyzer-inlining-mode">,
-  HelpText<"Specify the function selection heuristic used during inlining">;
-def analyzer_inlining_mode_EQ : Joined<["-"], "analyzer-inlining-mode=">, Alias;
-
-def analyzer_disable_retry_exhausted : Flag<["-"], "analyzer-disable-retry-exhausted">,
-  HelpText<"Do not re-analyze paths leading to exhausted nodes with a different strategy (may decrease code coverage)">;
-
-def analyzer_max_loop : Separate<["-"], "analyzer-max-loop">,
-  HelpText<"The maximum number of times the analyzer will go through a loop">;
-def analyzer_stats : Flag<["-"], "analyzer-stats">,
-  HelpText<"Print internal analyzer statistics.">;
-
-def analyzer_checker : Separate<["-"], "analyzer-checker">,
-  HelpText<"Choose analyzer checkers to enable">,
-  ValuesCode<[{
-    const char *Values =
-    #define GET_CHECKERS
-    #define CHECKER(FULLNAME, CLASS, HT, DOC_URI, IS_HIDDEN)  FULLNAME ","
-    #include "clang/StaticAnalyzer/Checkers/Checkers.inc"
-    #undef GET_CHECKERS
-    #define GET_PACKAGES
-    #define PACKAGE(FULLNAME)  FULLNAME ","
-    #include "clang/StaticAnalyzer/Checkers/Checkers.inc"
-    #undef GET_PACKAGES
-    ;
-  }]>;
-def analyzer_checker_EQ : Joined<["-"], "analyzer-checker=">,
-  Alias;
-
-def analyzer_disable_checker : Separate<["-"], "analyzer-disable-checker">,
-  HelpText<"Choose analyzer checkers to disable">;
-def analyzer_disable_checker_EQ : Joined<["-"], "analyzer-disable-checker=">,
-  Alias;
-
-def analyzer_disable_all_checks : Flag<["-"], "analyzer-disable-all-checks">,
-  HelpText<"Disable all static analyzer checks">;
-
-def analyzer_checker_help : Flag<["-"], "analyzer-checker-help">,
-  HelpText<"Display the list of analyzer checkers that are available">;
-
-def analyzer_checker_help_alpha : Flag<["-"], "analyzer-checker-help-alpha">,
-  HelpText<"Display the list of in development analyzer checkers. These "
-           "are NOT considered safe, they are unstable and will emit incorrect "
-           "reports. Enable ONLY FOR DEVELOPMENT purposes">;
-
-def analyzer_checker_help_developer : Flag<["-"], "analyzer-checker-help-developer">,
-  HelpText<"Display the list of developer-only checkers such as modeling "
-           "and debug checkers">;
-
-def analyzer_config_help : Flag<["-"], "analyzer-config-help">,
-  HelpText<"Display the list of -analyzer-config options. These are meant for "
-           "development purposes only!">;
-
-def analyzer_list_enabled_checkers : Flag<["-"], "analyzer-list-enabled-checkers">,
-  HelpText<"Display the list of enabled analyzer checkers">;
-
-def analyzer_config : Separate<["-"], "analyzer-config">,
-  HelpText<"Choose analyzer options to enable">;
-
-def analyzer_checker_option_help : Flag<["-"], "analyzer-checker-option-help">,
-  HelpText<"Display the list of checker and package options">;
-
-def analyzer_checker_option_help_alpha : Flag<["-"], "analyzer-checker-option-help-alpha">,
-  HelpText<"Display the list of in development checker and package options. "
-           "These are NOT considered safe, they are unstable and will emit "
-           "incorrect reports. Enable ONLY FOR DEVELOPMENT purposes">;
-
-def analyzer_checker_option_help_developer : Flag<["-"], "analyzer-checker-option-help-developer">,
-  HelpText<"Display the list of checker and package options meant for "
-           "development purposes only">;
-
-def analyzer_config_compatibility_mode : Separate<["-"], "analyzer-config-compatibility-mode">,
-  HelpText<"Don't emit errors on invalid analyzer-config inputs">;
-
-def analyzer_config_compatibility_mode_EQ : Joined<["-"], "analyzer-config-compatibility-mode=">,
-  Alias;
-
-def analyzer_werror : Flag<["-"], "analyzer-werror">,
-  HelpText<"Emit analyzer results as errors rather than warnings">;
-
-//===----------------------------------------------------------------------===//
-// Migrator Options
-//===----------------------------------------------------------------------===//
-def migrator_no_nsalloc_error : Flag<["-"], "no-ns-alloc-error">,
-  HelpText<"Do not error on use of NSAllocateCollectable/NSReallocateCollectable">;
-
-def migrator_no_finalize_removal : Flag<["-"], "no-finalize-removal">,
-  HelpText<"Do not remove finalize method in gc mode">;
-
-//===----------------------------------------------------------------------===//
-// CodeGen Options
-//===----------------------------------------------------------------------===//
-
-let Flags = [CC1Option, CC1AsOption, NoDriverOption] in {
-def debug_info_kind_EQ : Joined<["-"], "debug-info-kind=">;
-def debug_info_macro : Flag<["-"], "debug-info-macro">,
-  HelpText<"Emit macro debug information">;
-def default_function_attr : Separate<["-"], "default-function-attr">,
-  HelpText<"Apply given attribute to all functions">;
-def dwarf_version_EQ : Joined<["-"], "dwarf-version=">;
-def debugger_tuning_EQ : Joined<["-"], "debugger-tuning=">;
-def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">,
-  HelpText<"The string to embed in the Dwarf debug flags record.">;
-def record_command_line : Separate<["-"], "record-command-line">,
-  HelpText<"The string to embed in the .LLVM.command.line section.">;
-def compress_debug_sections : Flag<["-", "--"], "compress-debug-sections">,
-    HelpText<"DWARF debug sections compression">;
-def compress_debug_sections_EQ : Joined<["-", "--"], "compress-debug-sections=">,
-    HelpText<"DWARF debug sections compression type">;
-def mno_exec_stack : Flag<["-"], "mnoexecstack">,
-  HelpText<"Mark the file as not needing an executable stack">;
-def massembler_no_warn : Flag<["-"], "massembler-no-warn">,
-  HelpText<"Make assembler not emit warnings">;
-def massembler_fatal_warnings : Flag<["-"], "massembler-fatal-warnings">,
-  HelpText<"Make assembler warnings fatal">;
-def mrelax_relocations : Flag<["--"], "mrelax-relocations">,
-    HelpText<"Use relaxable elf relocations">;
-def msave_temp_labels : Flag<["-"], "msave-temp-labels">,
-  HelpText<"Save temporary labels in the symbol table. "
-           "Note this may change .s semantics and shouldn't generally be used "
-           "on compiler-generated code.">;
-def mrelocation_model : Separate<["-"], "mrelocation-model">,
-  HelpText<"The relocation model to use">, Values<"static,pic,ropi,rwpi,ropi-rwpi,dynamic-no-pic">;
-def fno_math_builtin : Flag<["-"], "fno-math-builtin">,
-  HelpText<"Disable implicit builtin knowledge of math functions">;
-}
-
-def disable_llvm_verifier : Flag<["-"], "disable-llvm-verifier">,
-  HelpText<"Don't run the LLVM IR verifier pass">;
-def disable_llvm_passes : Flag<["-"], "disable-llvm-passes">,
-  HelpText<"Use together with -emit-llvm to get pristine LLVM IR from the "
-           "frontend by not running any LLVM passes at all">;
-def disable_llvm_optzns : Flag<["-"], "disable-llvm-optzns">,
-  Alias;
-def disable_lifetimemarkers : Flag<["-"], "disable-lifetime-markers">,
-  HelpText<"Disable lifetime-markers emission even when optimizations are "
-           "enabled">;
-def disable_O0_optnone : Flag<["-"], "disable-O0-optnone">,
-  HelpText<"Disable adding the optnone attribute to functions at O0">;
-def disable_red_zone : Flag<["-"], "disable-red-zone">,
-  HelpText<"Do not emit code that uses the red zone.">;
-def dwarf_column_info : Flag<["-"], "dwarf-column-info">,
-  HelpText<"Turn on column location information.">;
-def dwarf_ext_refs : Flag<["-"], "dwarf-ext-refs">,
-  HelpText<"Generate debug info with external references to clang modules"
-           " or precompiled headers">;
-def dwarf_explicit_import : Flag<["-"], "dwarf-explicit-import">,
-  HelpText<"Generate explicit import from anonymous namespace to containing"
-           " scope">;
-def debug_forward_template_params : Flag<["-"], "debug-forward-template-params">,
-  HelpText<"Emit complete descriptions of template parameters in forward"
-           " declarations">;
-def fforbid_guard_variables : Flag<["-"], "fforbid-guard-variables">,
-  HelpText<"Emit an error if a C++ static local initializer would need a guard variable">;
-def no_implicit_float : Flag<["-"], "no-implicit-float">,
-  HelpText<"Don't generate implicit floating point instructions">;
-def fdump_vtable_layouts : Flag<["-"], "fdump-vtable-layouts">,
-  HelpText<"Dump the layouts of all vtables that will be emitted in a translation unit">;
-def fmerge_functions : Flag<["-"], "fmerge-functions">,
-  HelpText<"Permit merging of identical functions when optimizing.">;
-def femit_coverage_notes : Flag<["-"], "femit-coverage-notes">,
-  HelpText<"Emit a gcov coverage notes file when compiling.">;
-def femit_coverage_data: Flag<["-"], "femit-coverage-data">,
-  HelpText<"Instrument the program to emit gcov coverage data when run.">;
-def coverage_data_file : Separate<["-"], "coverage-data-file">,
-  HelpText<"Emit coverage data to this filename.">;
-def coverage_data_file_EQ : Joined<["-"], "coverage-data-file=">,
-  Alias;
-def coverage_notes_file : Separate<["-"], "coverage-notes-file">,
-  HelpText<"Emit coverage notes to this filename.">;
-def coverage_notes_file_EQ : Joined<["-"], "coverage-notes-file=">,
-  Alias;
-def coverage_version_EQ : Joined<["-"], "coverage-version=">,
-  HelpText<"Four-byte version string for gcov files.">;
-def test_coverage : Flag<["-"], "test-coverage">,
-  HelpText<"Do not generate coverage files or remove coverage changes from IR">;
-def dump_coverage_mapping : Flag<["-"], "dump-coverage-mapping">,
-  HelpText<"Dump the coverage mapping records, for testing">;
-def fuse_register_sized_bitfield_access: Flag<["-"], "fuse-register-sized-bitfield-access">,
-  HelpText<"Use register sized accesses to bit-fields, when possible.">;
-def relaxed_aliasing : Flag<["-"], "relaxed-aliasing">,
-  HelpText<"Turn off Type Based Alias Analysis">;
-def no_struct_path_tbaa : Flag<["-"], "no-struct-path-tbaa">,
-  HelpText<"Turn off struct-path aware Type Based Alias Analysis">;
-def new_struct_path_tbaa : Flag<["-"], "new-struct-path-tbaa">,
-  HelpText<"Enable enhanced struct-path aware Type Based Alias Analysis">;
-def mdebug_pass : Separate<["-"], "mdebug-pass">,
-  HelpText<"Enable additional debug output">;
-def mframe_pointer_EQ : Joined<["-"], "mframe-pointer=">,
-  HelpText<"Specify which frame pointers to retain (all, non-leaf, none).">, Values<"all,non-leaf,none">;
-def mdisable_tail_calls : Flag<["-"], "mdisable-tail-calls">,
-  HelpText<"Disable tail call optimization, keeping the call stack accurate">;
-def menable_no_infinities : Flag<["-"], "menable-no-infs">,
-  HelpText<"Allow optimization to assume there are no infinities.">;
-def menable_no_nans : Flag<["-"], "menable-no-nans">,
-  HelpText<"Allow optimization to assume there are no NaNs.">;
-def menable_unsafe_fp_math : Flag<["-"], "menable-unsafe-fp-math">,
-  HelpText<"Allow unsafe floating-point math optimizations which may decrease "
-           "precision">;
-def mreassociate : Flag<["-"], "mreassociate">,
-  HelpText<"Allow reassociation transformations for floating-point instructions">;
-def mabi_EQ_ieeelongdouble : Flag<["-"], "mabi=ieeelongdouble">,
-  HelpText<"Use IEEE 754 quadruple-precision for long double">;
-def mfloat_abi : Separate<["-"], "mfloat-abi">,
-  HelpText<"The float ABI to use">;
-def mtp : Separate<["-"], "mtp">,
-  HelpText<"Mode for reading thread pointer">;
-def mlimit_float_precision : Separate<["-"], "mlimit-float-precision">,
-  HelpText<"Limit float precision to the given value">;
-def split_stacks : Flag<["-"], "split-stacks">,
-  HelpText<"Try to use a split stack if possible.">;
-def mno_zero_initialized_in_bss : Flag<["-"], "mno-zero-initialized-in-bss">,
-  HelpText<"Do not put zero initialized data in the BSS">;
-def mregparm : Separate<["-"], "mregparm">,
-  HelpText<"Limit the number of registers available for integer arguments">;
-def msmall_data_limit : Separate<["-"], "msmall-data-limit">,
-  HelpText<"Put global and static data smaller than the limit into a special section">;
-def munwind_tables : Flag<["-"], "munwind-tables">,
-  HelpText<"Generate unwinding tables for all functions">;
-def mconstructor_aliases : Flag<["-"], "mconstructor-aliases">,
-  HelpText<"Emit complete constructors and destructors as aliases when possible">;
-def mlink_bitcode_file : Separate<["-"], "mlink-bitcode-file">,
-  HelpText<"Link the given bitcode file before performing optimizations.">;
-def mlink_builtin_bitcode : Separate<["-"], "mlink-builtin-bitcode">,
-  HelpText<"Link and internalize needed symbols from the given bitcode file "
-           "before performing optimizations.">;
-def mlink_cuda_bitcode : Separate<["-"], "mlink-cuda-bitcode">,
-  Alias;
-def vectorize_loops : Flag<["-"], "vectorize-loops">,
-  HelpText<"Run the Loop vectorization passes">;
-def vectorize_slp : Flag<["-"], "vectorize-slp">,
-  HelpText<"Run the SLP vectorization passes">;
-def dependent_lib : Joined<["--"], "dependent-lib=">,
-  HelpText<"Add dependent library">;
-def linker_option : Joined<["--"], "linker-option=">,
-  HelpText<"Add linker option">;
-def fsanitize_coverage_type : Joined<["-"], "fsanitize-coverage-type=">,
-                              HelpText<"Sanitizer coverage type">;
-def fsanitize_coverage_indirect_calls
-    : Flag<["-"], "fsanitize-coverage-indirect-calls">,
-      HelpText<"Enable sanitizer coverage for indirect calls">;
-def fsanitize_coverage_trace_bb
-    : Flag<["-"], "fsanitize-coverage-trace-bb">,
-      HelpText<"Enable basic block tracing in sanitizer coverage">;
-def fsanitize_coverage_trace_cmp
-    : Flag<["-"], "fsanitize-coverage-trace-cmp">,
-      HelpText<"Enable cmp instruction tracing in sanitizer coverage">;
-def fsanitize_coverage_trace_div
-    : Flag<["-"], "fsanitize-coverage-trace-div">,
-      HelpText<"Enable div instruction tracing in sanitizer coverage">;
-def fsanitize_coverage_trace_gep
-    : Flag<["-"], "fsanitize-coverage-trace-gep">,
-      HelpText<"Enable gep instruction tracing in sanitizer coverage">;
-def fsanitize_coverage_8bit_counters
-    : Flag<["-"], "fsanitize-coverage-8bit-counters">,
-      HelpText<"Enable frequency counters in sanitizer coverage">;
-def fsanitize_coverage_inline_8bit_counters
-    : Flag<["-"], "fsanitize-coverage-inline-8bit-counters">,
-      HelpText<"Enable inline 8-bit counters in sanitizer coverage">;
-def fsanitize_coverage_inline_bool_flag
-    : Flag<["-"], "fsanitize-coverage-inline-bool-flag">,
-      HelpText<"Enable inline bool flag in sanitizer coverage">;
-def fsanitize_coverage_pc_table
-    : Flag<["-"], "fsanitize-coverage-pc-table">,
-      HelpText<"Create a table of coverage-instrumented PCs">;
-def fsanitize_coverage_trace_pc
-    : Flag<["-"], "fsanitize-coverage-trace-pc">,
-      HelpText<"Enable PC tracing in sanitizer coverage">;
-def fsanitize_coverage_trace_pc_guard
-    : Flag<["-"], "fsanitize-coverage-trace-pc-guard">,
-      HelpText<"Enable PC tracing with guard in sanitizer coverage">;
-def fsanitize_coverage_no_prune
-    : Flag<["-"], "fsanitize-coverage-no-prune">,
-      HelpText<"Disable coverage pruning (i.e. instrument all blocks/edges)">;
-def fsanitize_coverage_stack_depth
-    : Flag<["-"], "fsanitize-coverage-stack-depth">,
-      HelpText<"Enable max stack depth tracing">;
-def fpatchable_function_entry_offset_EQ
-    : Joined<["-"], "fpatchable-function-entry-offset=">, MetaVarName<"">,
-      HelpText<"Generate M NOPs before function entry">;
-def fprofile_instrument_EQ : Joined<["-"], "fprofile-instrument=">,
-    HelpText<"Enable PGO instrumentation. The accepted value is clang, llvm, "
-             "or none">, Values<"none,clang,llvm">;
-def fprofile_instrument_path_EQ : Joined<["-"], "fprofile-instrument-path=">,
-    HelpText<"Generate instrumented code to collect execution counts into "
-             " (overridden by LLVM_PROFILE_FILE env var)">;
-def fprofile_instrument_use_path_EQ :
-    Joined<["-"], "fprofile-instrument-use-path=">,
-    HelpText<"Specify the profile path in PGO use compilation">;
-def flto_visibility_public_std:
-    Flag<["-"], "flto-visibility-public-std">,
-    HelpText<"Use public LTO visibility for classes in std and stdext namespaces">;
-def flto_unit: Flag<["-"], "flto-unit">,
-    HelpText<"Emit IR to support LTO unit features (CFI, whole program vtable opt)">;
-def fno_lto_unit: Flag<["-"], "fno-lto-unit">;
-def fdebug_pass_manager : Flag<["-"], "fdebug-pass-manager">,
-    HelpText<"Prints debug information for the new pass manager">;
-def fno_debug_pass_manager : Flag<["-"], "fno-debug-pass-manager">,
-    HelpText<"Disables debug printing for the new pass manager">;
-// The driver option takes the key as a parameter to the -msign-return-address=
-// and -mbranch-protection= options, but CC1 has a separate option so we
-// don't have to parse the parameter twice.
-def msign_return_address_key_EQ : Joined<["-"], "msign-return-address-key=">,
-    Values<"a_key,b_key">;
-def mbranch_target_enforce : Flag<["-"], "mbranch-target-enforce">;
-def fno_dllexport_inlines : Flag<["-"], "fno-dllexport-inlines">;
-def cfguard_no_checks : Flag<["-"], "cfguard-no-checks">,
-    HelpText<"Emit Windows Control Flow Guard tables only (no checks)">;
-def cfguard : Flag<["-"], "cfguard">,
-    HelpText<"Emit Windows Control Flow Guard tables and checks">;
-
-def fdenormal_fp_math_f32_EQ : Joined<["-"], "fdenormal-fp-math-f32=">,
-   Group;
-
-//===----------------------------------------------------------------------===//
-// Dependency Output Options
-//===----------------------------------------------------------------------===//
-
-def sys_header_deps : Flag<["-"], "sys-header-deps">,
-  HelpText<"Include system headers in dependency output">;
-def module_file_deps : Flag<["-"], "module-file-deps">,
-  HelpText<"Include module files in dependency output">;
-def header_include_file : Separate<["-"], "header-include-file">,
-  HelpText<"Filename (or -) to write header include output to">;
-def show_includes : Flag<["--"], "show-includes">,
-  HelpText<"Print cl.exe style /showIncludes to stdout">;
-
-//===----------------------------------------------------------------------===//
-// Diagnostic Options
-//===----------------------------------------------------------------------===//
-
-def diagnostic_log_file : Separate<["-"], "diagnostic-log-file">,
-  HelpText<"Filename (or -) to log diagnostics to">;
-def diagnostic_serialized_file : Separate<["-"], "serialize-diagnostic-file">,
-  MetaVarName<"">,
-  HelpText<"File for serializing diagnostics in a binary format">;
-
-def fdiagnostics_format : Separate<["-"], "fdiagnostics-format">,
-  HelpText<"Change diagnostic formatting to match IDE and command line tools">, Values<"clang,msvc,msvc-fallback,vi">;
-def fdiagnostics_show_category : Separate<["-"], "fdiagnostics-show-category">,
-  HelpText<"Print diagnostic category">, Values<"none,id,name">;
-def fno_diagnostics_use_presumed_location : Flag<["-"], "fno-diagnostics-use-presumed-location">,
-  HelpText<"Ignore #line directives when displaying diagnostic locations">;
-def ftabstop : Separate<["-"], "ftabstop">, MetaVarName<"">,
-  HelpText<"Set the tab stop distance.">;
-def ferror_limit : Separate<["-"], "ferror-limit">, MetaVarName<"">,
-  HelpText<"Set the maximum number of errors to emit before stopping (0 = no limit).">;
-def fmacro_backtrace_limit : Separate<["-"], "fmacro-backtrace-limit">, MetaVarName<"">,
-  HelpText<"Set the maximum number of entries to print in a macro expansion backtrace (0 = no limit).">;
-def ftemplate_backtrace_limit : Separate<["-"], "ftemplate-backtrace-limit">, MetaVarName<"">,
-  HelpText<"Set the maximum number of entries to print in a template instantiation backtrace (0 = no limit).">;
-def fconstexpr_backtrace_limit : Separate<["-"], "fconstexpr-backtrace-limit">, MetaVarName<"">,
-  HelpText<"Set the maximum number of entries to print in a constexpr evaluation backtrace (0 = no limit).">;
-def fspell_checking_limit : Separate<["-"], "fspell-checking-limit">, MetaVarName<"">,
-  HelpText<"Set the maximum number of times to perform spell checking on unrecognized identifiers (0 = no limit).">;
-def fcaret_diagnostics_max_lines :
-  Separate<["-"], "fcaret-diagnostics-max-lines">, MetaVarName<"">,
-  HelpText<"Set the maximum number of source lines to show in a caret diagnostic">;
-def verify_EQ : CommaJoined<["-"], "verify=">,
-  MetaVarName<"">,
-  HelpText<"Verify diagnostic output using comment directives that start with"
-           " prefixes in the comma-separated sequence ">;
-def verify : Flag<["-"], "verify">,
-  HelpText<"Equivalent to -verify=expected">;
-def verify_ignore_unexpected : Flag<["-"], "verify-ignore-unexpected">,
-  HelpText<"Ignore unexpected diagnostic messages">;
-def verify_ignore_unexpected_EQ : CommaJoined<["-"], "verify-ignore-unexpected=">,
-  HelpText<"Ignore unexpected diagnostic messages">;
-def Wno_rewrite_macros : Flag<["-"], "Wno-rewrite-macros">,
-  HelpText<"Silence ObjC rewriting warnings">;
-
-//===----------------------------------------------------------------------===//
-// Frontend Options
-//===----------------------------------------------------------------------===//
-
-// This isn't normally used, it is just here so we can parse a
-// CompilerInvocation out of a driver-derived argument vector.
-def cc1 : Flag<["-"], "cc1">;
-def cc1as : Flag<["-"], "cc1as">;
-
-def ast_merge : Separate<["-"], "ast-merge">,
-  MetaVarName<"">,
-  HelpText<"Merge the given AST file into the translation unit being compiled.">;
-def aux_target_cpu : Separate<["-"], "aux-target-cpu">,
-  HelpText<"Target a specific auxiliary cpu type">;
-def aux_target_feature : Separate<["-"], "aux-target-feature">,
-  HelpText<"Target specific auxiliary attributes">;
-def aux_triple : Separate<["-"], "aux-triple">,
-  HelpText<"Auxiliary target triple.">;
-def code_completion_at : Separate<["-"], "code-completion-at">,
-  MetaVarName<"::">,
-  HelpText<"Dump code-completion information at a location">;
-def remap_file : Separate<["-"], "remap-file">,
-  MetaVarName<";">,
-  HelpText<"Replace the contents of the  file with the contents of the  file">;
-def code_completion_at_EQ : Joined<["-"], "code-completion-at=">,
-  Alias;
-def code_completion_macros : Flag<["-"], "code-completion-macros">,
-  HelpText<"Include macros in code-completion results">;
-def code_completion_patterns : Flag<["-"], "code-completion-patterns">,
-  HelpText<"Include code patterns in code-completion results">;
-def no_code_completion_globals : Flag<["-"], "no-code-completion-globals">,
-  HelpText<"Do not include global declarations in code-completion results.">;
-def no_code_completion_ns_level_decls : Flag<["-"], "no-code-completion-ns-level-decls">,
-  HelpText<"Do not include declarations inside namespaces (incl. global namespace) in the code-completion results.">;
-def code_completion_brief_comments : Flag<["-"], "code-completion-brief-comments">,
-  HelpText<"Include brief documentation comments in code-completion results.">;
-def code_completion_with_fixits : Flag<["-"], "code-completion-with-fixits">,
-  HelpText<"Include code completion results which require small fix-its.">;
-def disable_free : Flag<["-"], "disable-free">,
-  HelpText<"Disable freeing of memory on exit">;
-def discard_value_names : Flag<["-"], "discard-value-names">,
-  HelpText<"Discard value names in LLVM IR">;
-def load : Separate<["-"], "load">, MetaVarName<"">,
-  HelpText<"Load the named plugin (dynamic shared object)">;
-def plugin : Separate<["-"], "plugin">, MetaVarName<"">,
-  HelpText<"Use the named plugin action instead of the default action (use \"help\" to list available options)">;
-def plugin_arg : JoinedAndSeparate<["-"], "plugin-arg-">,
-    MetaVarName<" ">,
-    HelpText<"Pass  to plugin ">;
-def add_plugin : Separate<["-"], "add-plugin">, MetaVarName<"">,
-  HelpText<"Use the named plugin action in addition to the default action">;
-def ast_dump_filter : Separate<["-"], "ast-dump-filter">,
-  MetaVarName<"">,
-  HelpText<"Use with -ast-dump or -ast-print to dump/print only AST declaration"
-           " nodes having a certain substring in a qualified name. Use"
-           " -ast-list to list all filterable declaration node names.">;
-def fno_modules_global_index : Flag<["-"], "fno-modules-global-index">,
-  HelpText<"Do not automatically generate or update the global module index">;
-def fno_modules_error_recovery : Flag<["-"], "fno-modules-error-recovery">,
-  HelpText<"Do not automatically import modules for error recovery">;
-def fmodule_map_file_home_is_cwd : Flag<["-"], "fmodule-map-file-home-is-cwd">,
-  HelpText<"Use the current working directory as the home directory of "
-           "module maps specified by -fmodule-map-file=">;
-def fmodule_feature : Separate<["-"], "fmodule-feature">,
-  MetaVarName<"">,
-  HelpText<"Enable  in module map requires declarations">;
-def fmodules_embed_file_EQ : Joined<["-"], "fmodules-embed-file=">,
-  MetaVarName<"">,
-  HelpText<"Embed the contents of the specified file into the module file "
-           "being compiled.">;
-def fmodules_embed_all_files : Joined<["-"], "fmodules-embed-all-files">,
-  HelpText<"Embed the contents of all files read by this compilation into "
-           "the produced module file.">;
-def fmodules_local_submodule_visibility :
-  Flag<["-"], "fmodules-local-submodule-visibility">,
-  HelpText<"Enforce name visibility rules across submodules of the same "
-           "top-level module.">;
-def fmodules_codegen :
-  Flag<["-"], "fmodules-codegen">,
-  HelpText<"Generate code for uses of this module that assumes an explicit "
-           "object file will be built for the module">;
-def fmodules_debuginfo :
-  Flag<["-"], "fmodules-debuginfo">,
-  HelpText<"Generate debug info for types in an object file built from this "
-           "module and do not generate them elsewhere">;
-def fmodule_format_EQ : Joined<["-"], "fmodule-format=">,
-  HelpText<"Select the container format for clang modules and PCH. "
-           "Supported options are 'raw' and 'obj'.">;
-def ftest_module_file_extension_EQ :
-  Joined<["-"], "ftest-module-file-extension=">,
-  HelpText<"introduce a module file extension for testing purposes. "
-           "The argument is parsed as blockname:major:minor:hashed:user info">;
-def fconcepts_ts : Flag<["-"], "fconcepts-ts">,
-  HelpText<"Enable C++ Extensions for Concepts. (deprecated - use -std=c++2a)">;
-def fno_concept_satisfaction_caching : Flag<["-"],
-                                            "fno-concept-satisfaction-caching">,
-  HelpText<"Disable satisfaction caching for C++2a Concepts.">;
-
-def frecovery_ast : Flag<["-"], "frecovery-ast">,
-  HelpText<"Preserve expressions in AST rather than dropping them when "
-           "encountering semantic errors">;
-def fno_recovery_ast : Flag<["-"], "fno-recovery-ast">;
-def frecovery_ast_type : Flag<["-"], "frecovery-ast-type">,
-  HelpText<"Preserve the type for recovery expressions when possible "
-          "(experimental)">;
-def fno_recovery_ast_type : Flag<["-"], "fno-recovery-ast-type">;
-
-let Group = Action_Group in {
-
-def Eonly : Flag<["-"], "Eonly">,
-  HelpText<"Just run preprocessor, no output (for timings)">;
-def dump_raw_tokens : Flag<["-"], "dump-raw-tokens">,
-  HelpText<"Lex file in raw mode and dump raw tokens">;
-def analyze : Flag<["-"], "analyze">,
-  HelpText<"Run static analysis engine">;
-def dump_tokens : Flag<["-"], "dump-tokens">,
-  HelpText<"Run preprocessor, dump internal rep of tokens">;
-def init_only : Flag<["-"], "init-only">,
-  HelpText<"Only execute frontend initialization">;
-def fixit : Flag<["-"], "fixit">,
-  HelpText<"Apply fix-it advice to the input source">;
-def fixit_EQ : Joined<["-"], "fixit=">,
-  HelpText<"Apply fix-it advice creating a file with the given suffix">;
-def print_preamble : Flag<["-"], "print-preamble">,
-  HelpText<"Print the \"preamble\" of a file, which is a candidate for implicit"
-           " precompiled headers.">;
-def emit_html : Flag<["-"], "emit-html">,
-  HelpText<"Output input source as HTML">;
-def ast_print : Flag<["-"], "ast-print">,
-  HelpText<"Build ASTs and then pretty-print them">;
-def ast_list : Flag<["-"], "ast-list">,
-  HelpText<"Build ASTs and print the list of declaration node qualified names">;
-def ast_dump : Flag<["-"], "ast-dump">,
-  HelpText<"Build ASTs and then debug dump them">;
-def ast_dump_EQ : Joined<["-"], "ast-dump=">,
-  HelpText<"Build ASTs and then debug dump them in the specified format. "
-           "Supported formats include: default, json">;
-def ast_dump_all : Flag<["-"], "ast-dump-all">,
-  HelpText<"Build ASTs and then debug dump them, forcing deserialization">;
-def ast_dump_all_EQ : Joined<["-"], "ast-dump-all=">,
-  HelpText<"Build ASTs and then debug dump them in the specified format, "
-           "forcing deserialization. Supported formats include: default, json">;
-def templight_dump : Flag<["-"], "templight-dump">,
-  HelpText<"Dump templight information to stdout">;
-def ast_dump_lookups : Flag<["-"], "ast-dump-lookups">,
-  HelpText<"Build ASTs and then debug dump their name lookup tables">;
-def ast_view : Flag<["-"], "ast-view">,
-  HelpText<"Build ASTs and view them with GraphViz">;
-def emit_module : Flag<["-"], "emit-module">,
-  HelpText<"Generate pre-compiled module file from a module map">;
-def emit_module_interface : Flag<["-"], "emit-module-interface">,
-  HelpText<"Generate pre-compiled module file from a C++ module interface">;
-def emit_header_module : Flag<["-"], "emit-header-module">,
-  HelpText<"Generate pre-compiled module file from a set of header files">;
-def emit_pch : Flag<["-"], "emit-pch">,
-  HelpText<"Generate pre-compiled header file">;
-def emit_llvm_bc : Flag<["-"], "emit-llvm-bc">,
-  HelpText<"Build ASTs then convert to LLVM, emit .bc file">;
-def emit_llvm_only : Flag<["-"], "emit-llvm-only">,
-  HelpText<"Build ASTs and convert to LLVM, discarding output">;
-def emit_codegen_only : Flag<["-"], "emit-codegen-only">,
-  HelpText<"Generate machine code, but discard output">;
-def emit_obj : Flag<["-"], "emit-obj">,
-  HelpText<"Emit native object files">;
-def rewrite_test : Flag<["-"], "rewrite-test">,
-  HelpText<"Rewriter playground">;
-def rewrite_macros : Flag<["-"], "rewrite-macros">,
-  HelpText<"Expand macros without full preprocessing">;
-def migrate : Flag<["-"], "migrate">,
-  HelpText<"Migrate source code">;
-def compiler_options_dump : Flag<["-"], "compiler-options-dump">,
-  HelpText<"Dump the compiler configuration options">;
-def print_dependency_directives_minimized_source : Flag<["-"],
-  "print-dependency-directives-minimized-source">,
-  HelpText<"Print the output of the dependency directives source minimizer">;
-}
-
-def emit_llvm_uselists : Flag<["-"], "emit-llvm-uselists">,
-  HelpText<"Preserve order of LLVM use-lists when serializing">;
-def no_emit_llvm_uselists : Flag<["-"], "no-emit-llvm-uselists">,
-  HelpText<"Don't preserve order of LLVM use-lists when serializing">;
-
-def mt_migrate_directory : Separate<["-"], "mt-migrate-directory">,
-  HelpText<"Directory for temporary files produced during ARC or ObjC migration">;
-def arcmt_check : Flag<["-"], "arcmt-check">,
-  HelpText<"Check for ARC migration issues that need manual handling">;
-def arcmt_modify : Flag<["-"], "arcmt-modify">,
-  HelpText<"Apply modifications to files to conform to ARC">;
-def arcmt_migrate : Flag<["-"], "arcmt-migrate">,
-  HelpText<"Apply modifications and produces temporary files that conform to ARC">;
-
-def opt_record_file : Separate<["-"], "opt-record-file">,
-  HelpText<"File name to use for YAML optimization record output">;
-def opt_record_passes : Separate<["-"], "opt-record-passes">,
-  HelpText<"Only record remark information for passes whose names match the given regular expression">;
-def opt_record_format : Separate<["-"], "opt-record-format">,
-  HelpText<"The format used for serializing remarks (default: YAML)">;
-
-def print_stats : Flag<["-"], "print-stats">,
-  HelpText<"Print performance metrics and statistics">;
-def stats_file : Joined<["-"], "stats-file=">,
-  HelpText<"Filename to write statistics to">;
-def fdump_record_layouts : Flag<["-"], "fdump-record-layouts">,
-  HelpText<"Dump record layout information">;
-def fdump_record_layouts_simple : Flag<["-"], "fdump-record-layouts-simple">,
-  HelpText<"Dump record layout information in a simple form used for testing">;
-def fix_what_you_can : Flag<["-"], "fix-what-you-can">,
-  HelpText<"Apply fix-it advice even in the presence of unfixable errors">;
-def fix_only_warnings : Flag<["-"], "fix-only-warnings">,
-  HelpText<"Apply fix-it advice only for warnings, not errors">;
-def fixit_recompile : Flag<["-"], "fixit-recompile">,
-  HelpText<"Apply fix-it changes and recompile">;
-def fixit_to_temp : Flag<["-"], "fixit-to-temporary">,
-  HelpText<"Apply fix-it changes to temporary files">;
-
-def foverride_record_layout_EQ : Joined<["-"], "foverride-record-layout=">,
-  HelpText<"Override record layouts with those in the given file">;
-def pch_through_header_EQ : Joined<["-"], "pch-through-header=">,
-  HelpText<"Stop PCH generation after including this file.  When using a PCH, "
-           "skip tokens until after this file is included.">;
-def pch_through_hdrstop_create : Flag<["-"], "pch-through-hdrstop-create">,
-  HelpText<"When creating a PCH, stop PCH generation after #pragma hdrstop.">;
-def pch_through_hdrstop_use : Flag<["-"], "pch-through-hdrstop-use">,
-  HelpText<"When using a PCH, skip tokens until after a #pragma hdrstop.">;
-def fno_pch_timestamp : Flag<["-"], "fno-pch-timestamp">,
-  HelpText<"Disable inclusion of timestamp in precompiled headers">;
-def building_pch_with_obj : Flag<["-"], "building-pch-with-obj">,
-  HelpText<"This compilation is part of building a PCH with corresponding object file.">;
-
-def aligned_alloc_unavailable : Flag<["-"], "faligned-alloc-unavailable">,
-  HelpText<"Aligned allocation/deallocation functions are unavailable">;
-
-//===----------------------------------------------------------------------===//
-// Language Options
-//===----------------------------------------------------------------------===//
-
-let Flags = [CC1Option, CC1AsOption, NoDriverOption] in {
-
-def version : Flag<["-"], "version">,
-  HelpText<"Print the compiler version">;
-def main_file_name : Separate<["-"], "main-file-name">,
-  HelpText<"Main file name to use for debug info and source if missing">;
-def split_dwarf_output : Separate<["-"], "split-dwarf-output">,
-  HelpText<"File name to use for split dwarf debug info output">;
-
-}
-
-def fblocks_runtime_optional : Flag<["-"], "fblocks-runtime-optional">,
-  HelpText<"Weakly link in the blocks runtime">;
-def fexternc_nounwind : Flag<["-"], "fexternc-nounwind">,
-  HelpText<"Assume all functions with C linkage do not unwind">;
-def split_dwarf_file : Separate<["-"], "split-dwarf-file">,
-  HelpText<"Name of the split dwarf debug info file to encode in the object file">;
-def fno_wchar : Flag<["-"], "fno-wchar">,
-  HelpText<"Disable C++ builtin type wchar_t">;
-def fconstant_string_class : Separate<["-"], "fconstant-string-class">,
-  MetaVarName<"">,
-  HelpText<"Specify the class to use for constant Objective-C string objects.">;
-def fobjc_arc_cxxlib_EQ : Joined<["-"], "fobjc-arc-cxxlib=">,
-  HelpText<"Objective-C++ Automatic Reference Counting standard library kind">, Values<"libc++,libstdc++,none">;
-def fobjc_runtime_has_weak : Flag<["-"], "fobjc-runtime-has-weak">,
-  HelpText<"The target Objective-C runtime supports ARC weak operations">;
-def fobjc_dispatch_method_EQ : Joined<["-"], "fobjc-dispatch-method=">,
-  HelpText<"Objective-C dispatch method to use">, Values<"legacy,non-legacy,mixed">;
-def disable_objc_default_synthesize_properties : Flag<["-"], "disable-objc-default-synthesize-properties">,
-  HelpText<"disable the default synthesis of Objective-C properties">;
-def fencode_extended_block_signature : Flag<["-"], "fencode-extended-block-signature">,
-  HelpText<"enable extended encoding of block type signature">;
-def function_alignment : Separate<["-"], "function-alignment">,
-    HelpText<"default alignment for functions">;
-def pic_level : Separate<["-"], "pic-level">,
-  HelpText<"Value for __PIC__">;
-def pic_is_pie : Flag<["-"], "pic-is-pie">,
-  HelpText<"File is for a position independent executable">;
-def fno_validate_pch : Flag<["-"], "fno-validate-pch">,
-  HelpText<"Disable validation of precompiled headers">;
-def fallow_pch_with_errors : Flag<["-"], "fallow-pch-with-compiler-errors">,
-  HelpText<"Accept a PCH file that was created with compiler errors">;
-def dump_deserialized_pch_decls : Flag<["-"], "dump-deserialized-decls">,
-  HelpText<"Dump declarations that are deserialized from PCH, for testing">;
-def error_on_deserialized_pch_decl : Separate<["-"], "error-on-deserialized-decl">,
-  HelpText<"Emit error if a specific declaration is deserialized from PCH, for testing">;
-def error_on_deserialized_pch_decl_EQ : Joined<["-"], "error-on-deserialized-decl=">,
-  Alias;
-def static_define : Flag<["-"], "static-define">,
-  HelpText<"Should __STATIC__ be defined">;
-def stack_protector : Separate<["-"], "stack-protector">,
-  HelpText<"Enable stack protectors">;
-def stack_protector_buffer_size : Separate<["-"], "stack-protector-buffer-size">,
-  HelpText<"Lower bound for a buffer to be considered for stack protection">;
-def fvisibility : Separate<["-"], "fvisibility">,
-  HelpText<"Default type and symbol visibility">;
-def ftype_visibility : Separate<["-"], "ftype-visibility">,
-  HelpText<"Default type visibility">;
-def fapply_global_visibility_to_externs : Flag<["-"], "fapply-global-visibility-to-externs">,
-  HelpText<"Apply global symbol visibility to external declarations without an explicit visibility">;
-def ftemplate_depth : Separate<["-"], "ftemplate-depth">,
-  HelpText<"Maximum depth of recursive template instantiation">;
-def foperator_arrow_depth : Separate<["-"], "foperator-arrow-depth">,
-  HelpText<"Maximum number of 'operator->'s to call for a member access">;
-def fconstexpr_depth : Separate<["-"], "fconstexpr-depth">,
-  HelpText<"Maximum depth of recursive constexpr function calls">;
-def fconstexpr_steps : Separate<["-"], "fconstexpr-steps">,
-  HelpText<"Maximum number of steps in constexpr function evaluation">;
-def fbracket_depth : Separate<["-"], "fbracket-depth">,
-  HelpText<"Maximum nesting level for parentheses, brackets, and braces">;
-def fconst_strings : Flag<["-"], "fconst-strings">,
-  HelpText<"Use a const qualified type for string literals in C and ObjC">;
-def fno_const_strings : Flag<["-"], "fno-const-strings">,
-  HelpText<"Don't use a const qualified type for string literals in C and ObjC">;
-def fno_bitfield_type_align : Flag<["-"], "fno-bitfield-type-align">,
-  HelpText<"Ignore bit-field types when aligning structures">;
-def ffake_address_space_map : Flag<["-"], "ffake-address-space-map">,
-  HelpText<"Use a fake address space map; OpenCL testing purposes only">;
-def faddress_space_map_mangling_EQ : Joined<["-"], "faddress-space-map-mangling=">, MetaVarName<"">,
-  HelpText<"Set the mode for address space map based mangling; OpenCL testing purposes only">;
-def funknown_anytype : Flag<["-"], "funknown-anytype">,
-  HelpText<"Enable parser support for the __unknown_anytype type; for testing purposes only">;
-def fdebugger_support : Flag<["-"], "fdebugger-support">,
-  HelpText<"Enable special debugger support behavior">;
-def fdebugger_cast_result_to_id : Flag<["-"], "fdebugger-cast-result-to-id">,
-  HelpText<"Enable casting unknown expression results to id">;
-def fdebugger_objc_literal : Flag<["-"], "fdebugger-objc-literal">,
-  HelpText<"Enable special debugger support for Objective-C subscripting and literals">;
-def fdeprecated_macro : Flag<["-"], "fdeprecated-macro">,
-  HelpText<"Defines the __DEPRECATED macro">;
-def fno_deprecated_macro : Flag<["-"], "fno-deprecated-macro">,
-  HelpText<"Undefines the __DEPRECATED macro">;
-def fobjc_subscripting_legacy_runtime : Flag<["-"], "fobjc-subscripting-legacy-runtime">,
-  HelpText<"Allow Objective-C array and dictionary subscripting in legacy runtime">;
-def vtordisp_mode_EQ : Joined<["-"], "vtordisp-mode=">,
-  HelpText<"Control vtordisp placement on win32 targets">;
-def fnative_half_type: Flag<["-"], "fnative-half-type">,
-  HelpText<"Use the native half type for __fp16 instead of promoting to float">;
-def fnative_half_arguments_and_returns : Flag<["-"], "fnative-half-arguments-and-returns">,
-  HelpText<"Use the native __fp16 type for arguments and returns (and skip ABI-specific lowering)">;
-def fallow_half_arguments_and_returns : Flag<["-"], "fallow-half-arguments-and-returns">,
-  HelpText<"Allow function arguments and returns of type half">;
-def fdefault_calling_conv_EQ : Joined<["-"], "fdefault-calling-conv=">,
-  HelpText<"Set default calling convention">, Values<"cdecl,fastcall,stdcall,vectorcall,regcall">;
-def finclude_default_header : Flag<["-"], "finclude-default-header">,
-  HelpText<"Include default header file for OpenCL">;
-def fdeclare_opencl_builtins : Flag<["-"], "fdeclare-opencl-builtins">,
-  HelpText<"Add OpenCL builtin function declarations (experimental)">;
-def fpreserve_vec3_type : Flag<["-"], "fpreserve-vec3-type">,
-  HelpText<"Preserve 3-component vector type">;
-def fwchar_type_EQ : Joined<["-"], "fwchar-type=">,
-  HelpText<"Select underlying type for wchar_t">, Values<"char,short,int">;
-def fsigned_wchar : Flag<["-"], "fsigned-wchar">,
-  HelpText<"Use a signed type for wchar_t">;
-def fno_signed_wchar : Flag<["-"], "fno-signed-wchar">,
-  HelpText<"Use an unsigned type for wchar_t">;
-def fcompatibility_qualified_id_block_param_type_checking : Flag<["-"], "fcompatibility-qualified-id-block-type-checking">,
-  HelpText<"Allow using blocks with parameters of more specific type than "
-           "the type system guarantees when a parameter is qualified id">;
-
-// FIXME: Remove these entirely once functionality/tests have been excised.
-def fobjc_gc_only : Flag<["-"], "fobjc-gc-only">, Group,
-  HelpText<"Use GC exclusively for Objective-C related memory management">;
-def fobjc_gc : Flag<["-"], "fobjc-gc">, Group,
-  HelpText<"Enable Objective-C garbage collection">;
-
-//===----------------------------------------------------------------------===//
-// Header Search Options
-//===----------------------------------------------------------------------===//
-
-def nostdsysteminc : Flag<["-"], "nostdsysteminc">,
-  HelpText<"Disable standard system #include directories">;
-def fdisable_module_hash : Flag<["-"], "fdisable-module-hash">,
-  HelpText<"Disable the module hash">;
-def fmodules_hash_content : Flag<["-"], "fmodules-hash-content">,
-  HelpText<"Enable hashing the content of a module file">;
-def fmodules_strict_context_hash : Flag<["-"], "fmodules-strict-context-hash">,
-  HelpText<"Enable hashing of all compiler options that could impact the "
-           "semantics of a module in an implicit build">;
-def c_isystem : JoinedOrSeparate<["-"], "c-isystem">, MetaVarName<"">,
-  HelpText<"Add directory to the C SYSTEM include search path">;
-def objc_isystem : JoinedOrSeparate<["-"], "objc-isystem">,
-  MetaVarName<"">,
-  HelpText<"Add directory to the ObjC SYSTEM include search path">;
-def objcxx_isystem : JoinedOrSeparate<["-"], "objcxx-isystem">,
-  MetaVarName<"">,
-  HelpText<"Add directory to the ObjC++ SYSTEM include search path">;
-def internal_isystem : JoinedOrSeparate<["-"], "internal-isystem">,
-  MetaVarName<"">,
-  HelpText<"Add directory to the internal system include search path; these "
-           "are assumed to not be user-provided and are used to model system "
-           "and standard headers' paths.">;
-def internal_externc_isystem : JoinedOrSeparate<["-"], "internal-externc-isystem">,
-  MetaVarName<"">,
-  HelpText<"Add directory to the internal system include search path with "
-           "implicit extern \"C\" semantics; these are assumed to not be "
-           "user-provided and are used to model system and standard headers' "
-           "paths.">;
-
-//===----------------------------------------------------------------------===//
-// Preprocessor Options
-//===----------------------------------------------------------------------===//
-
-def chain_include : Separate<["-"], "chain-include">, MetaVarName<"">,
-  HelpText<"Include and chain a header file after turning it into PCH">;
-def preamble_bytes_EQ : Joined<["-"], "preamble-bytes=">,
-  HelpText<"Assume that the precompiled header is a precompiled preamble "
-           "covering the first N bytes of the main file">;
-def detailed_preprocessing_record : Flag<["-"], "detailed-preprocessing-record">,
-  HelpText<"include a detailed record of preprocessing actions">;
-def setup_static_analyzer : Flag<["-"], "setup-static-analyzer">,
-  HelpText<"Set up preprocessor for static analyzer (done automatically when static analyzer is run).">;
-def disable_pragma_debug_crash : Flag<["-"], "disable-pragma-debug-crash">,
-  HelpText<"Disable any #pragma clang __debug that can lead to crashing behavior. This is meant for testing.">;
-
-//===----------------------------------------------------------------------===//
-// OpenCL Options
-//===----------------------------------------------------------------------===//
-
-def cl_ext_EQ : CommaJoined<["-"], "cl-ext=">,
-  HelpText<"OpenCL only. Enable or disable OpenCL extensions. The argument is a comma-separated sequence of one or more extension names, each prefixed by '+' or '-'.">;
-
-//===----------------------------------------------------------------------===//
-// CUDA Options
-//===----------------------------------------------------------------------===//
-
-def fcuda_is_device : Flag<["-"], "fcuda-is-device">,
-  HelpText<"Generate code for CUDA device">;
-def fcuda_include_gpubinary : Separate<["-"], "fcuda-include-gpubinary">,
-  HelpText<"Incorporate CUDA device-side binary into host object file.">;
-def fcuda_allow_variadic_functions : Flag<["-"], "fcuda-allow-variadic-functions">,
-  HelpText<"Allow variadic functions in CUDA device code.">;
-def fno_cuda_host_device_constexpr : Flag<["-"], "fno-cuda-host-device-constexpr">,
-  HelpText<"Don't treat unattributed constexpr functions as __host__ __device__.">;
-
-//===----------------------------------------------------------------------===//
-// OpenMP Options
-//===----------------------------------------------------------------------===//
-
-def fopenmp_is_device : Flag<["-"], "fopenmp-is-device">,
-  HelpText<"Generate code only for an OpenMP target device.">;
-def fopenmp_host_ir_file_path : Separate<["-"], "fopenmp-host-ir-file-path">,
-  HelpText<"Path to the IR file produced by the frontend for the host.">;
-
-//===----------------------------------------------------------------------===//
-// SYCL Options
-//===----------------------------------------------------------------------===//
-
-def fsycl_is_device : Flag<["-"], "fsycl-is-device">,
-  HelpText<"Generate code for SYCL device.">;
-
-} // let Flags = [CC1Option]
-
-//===----------------------------------------------------------------------===//
-// cc1as-only Options
-//===----------------------------------------------------------------------===//
-
-let Flags = [CC1AsOption, NoDriverOption] in {
-
-// Language Options
-def n : Flag<["-"], "n">,
-  HelpText<"Don't automatically start assembly file with a text section">;
-
-// Frontend Options
-def filetype : Separate<["-"], "filetype">,
-    HelpText<"Specify the output file type ('asm', 'null', or 'obj')">;
-
-// Transliterate Options
-def output_asm_variant : Separate<["-"], "output-asm-variant">,
-    HelpText<"Select the asm variant index to use for output">;
-def show_encoding : Flag<["-"], "show-encoding">,
-    HelpText<"Show instruction encoding information in transliterate mode">;
-def show_inst : Flag<["-"], "show-inst">,
-    HelpText<"Show internal instruction representation in transliterate mode">;
-
-// Assemble Options
-def dwarf_debug_producer : Separate<["-"], "dwarf-debug-producer">,
-  HelpText<"The string to embed in the Dwarf debug AT_producer record.">;
-
-def defsym : Separate<["-"], "defsym">,
-  HelpText<"Define a value for a symbol">;
-} // let Flags = [CC1AsOption]
diff --git a/clang/include/clang/Driver/CLCompatOptions.td b/clang/include/clang/Driver/CLCompatOptions.td
deleted file mode 100644
index 17d248a3c5ad9..0000000000000
--- a/clang/include/clang/Driver/CLCompatOptions.td
+++ /dev/null
@@ -1,470 +0,0 @@
-//===--- CLCompatOptions.td - Options for clang-cl ------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file defines the options accepted by clang-cl.
-//
-//===----------------------------------------------------------------------===//
-
-def cl_Group : OptionGroup<"">, Flags<[CLOption]>,
-  HelpText<"CL.EXE COMPATIBILITY OPTIONS">;
-
-def cl_compile_Group : OptionGroup<"">,
-  Group;
-
-def cl_ignored_Group : OptionGroup<"">,
-  Group;
-
-class CLFlag : Option<["/", "-"], name, KIND_FLAG>,
-  Group, Flags<[CLOption, DriverOption]>;
-
-class CLCompileFlag : Option<["/", "-"], name, KIND_FLAG>,
-  Group, Flags<[CLOption, DriverOption]>;
-
-class CLIgnoredFlag : Option<["/", "-"], name, KIND_FLAG>,
-  Group, Flags<[CLOption, DriverOption]>;
-
-class CLJoined : Option<["/", "-"], name, KIND_JOINED>,
-  Group, Flags<[CLOption, DriverOption]>;
-
-class CLCompileJoined : Option<["/", "-"], name, KIND_JOINED>,
-  Group, Flags<[CLOption, DriverOption]>;
-
-class CLIgnoredJoined : Option<["/", "-"], name, KIND_JOINED>,
-  Group, Flags<[CLOption, DriverOption, HelpHidden]>;
-
-class CLJoinedOrSeparate : Option<["/", "-"], name,
-  KIND_JOINED_OR_SEPARATE>, Group, Flags<[CLOption, DriverOption]>;
-
-class CLCompileJoinedOrSeparate : Option<["/", "-"], name,
-  KIND_JOINED_OR_SEPARATE>, Group,
-  Flags<[CLOption, DriverOption]>;
-
-class CLRemainingArgsJoined : Option<["/", "-"], name,
-  KIND_REMAINING_ARGS_JOINED>, Group, Flags<[CLOption, DriverOption]>;
-
-// Aliases:
-// (We don't put any of these in cl_compile_Group as the options they alias are
-// already in the right group.)
-
-def _SLASH_Brepro : CLFlag<"Brepro">,
-  HelpText<"Do not write current time into COFF output (breaks link.exe /incremental)">,
-  Alias;
-def _SLASH_Brepro_ : CLFlag<"Brepro-">,
-  HelpText<"Write current time into COFF output (default)">,
-  Alias;
-def _SLASH_C : CLFlag<"C">,
-  HelpText<"Do not discard comments when preprocessing">, Alias;
-def _SLASH_c : CLFlag<"c">, HelpText<"Compile only">, Alias;
-def _SLASH_d1PP : CLFlag<"d1PP">,
-  HelpText<"Retain macro definitions in /E mode">, Alias
; -def _SLASH_d1reportAllClassLayout : CLFlag<"d1reportAllClassLayout">, - HelpText<"Dump record layout information">, - Alias, AliasArgs<["-fdump-record-layouts"]>; -def _SLASH_diagnostics_caret : CLFlag<"diagnostics:caret">, - HelpText<"Enable caret and column diagnostics (default)">; -def _SLASH_diagnostics_column : CLFlag<"diagnostics:column">, - HelpText<"Disable caret diagnostics but keep column info">; -def _SLASH_diagnostics_classic : CLFlag<"diagnostics:classic">, - HelpText<"Disable column and caret diagnostics">; -def _SLASH_D : CLJoinedOrSeparate<"D">, HelpText<"Define macro">, - MetaVarName<"">, Alias; -def _SLASH_E : CLFlag<"E">, HelpText<"Preprocess to stdout">, Alias; -def _SLASH_fp_except : CLFlag<"fp:except">, HelpText<"">, Alias; -def _SLASH_fp_except_ : CLFlag<"fp:except-">, - HelpText<"">, Alias; -def _SLASH_fp_fast : CLFlag<"fp:fast">, HelpText<"">, Alias; -def _SLASH_fp_precise : CLFlag<"fp:precise">, - HelpText<"">, Alias; -def _SLASH_fp_strict : CLFlag<"fp:strict">, HelpText<"">, Alias; -def _SLASH_GA : CLFlag<"GA">, Alias, AliasArgs<["local-exec"]>, - HelpText<"Assume thread-local variables are defined in the executable">; -def _SLASH_GR : CLFlag<"GR">, HelpText<"Emit RTTI data (default)">; -def _SLASH_GR_ : CLFlag<"GR-">, HelpText<"Do not emit RTTI data">; -def _SLASH_GF : CLIgnoredFlag<"GF">, - HelpText<"Enable string pooling (default)">; -def _SLASH_GF_ : CLFlag<"GF-">, HelpText<"Disable string pooling">, - Alias; -def _SLASH_GS : CLFlag<"GS">, - HelpText<"Enable buffer security check (default)">; -def _SLASH_GS_ : CLFlag<"GS-">, HelpText<"Disable buffer security check">; -def : CLFlag<"Gs">, HelpText<"Use stack probes (default)">, - Alias, AliasArgs<["4096"]>; -def _SLASH_Gs : CLJoined<"Gs">, - HelpText<"Set stack probe size (default 4096)">, Alias; -def _SLASH_Gy : CLFlag<"Gy">, HelpText<"Put each function in its own section">, - Alias; -def _SLASH_Gy_ : CLFlag<"Gy-">, - HelpText<"Do not put each function in its own section (default)">, - Alias; -def _SLASH_Gw : CLFlag<"Gw">, HelpText<"Put each data item in its own section">, - Alias; -def _SLASH_Gw_ : CLFlag<"Gw-">, - HelpText<"Do not put each data item in its own section (default)">, - Alias; -def _SLASH_help : CLFlag<"help">, Alias, - HelpText<"Display available options">; -def _SLASH_HELP : CLFlag<"HELP">, Alias; -def _SLASH_I : CLJoinedOrSeparate<"I">, - HelpText<"Add directory to include search path">, MetaVarName<"">, - Alias; -def _SLASH_J : CLFlag<"J">, HelpText<"Make char type unsigned">, - Alias; - -// The _SLASH_O option handles all the /O flags, but we also provide separate -// aliased options to provide separate help messages. -def _SLASH_O : CLJoined<"O">, - HelpText<"Set multiple /O flags at once; e.g. '/O2y-' for '/O2 /Oy-'">, - MetaVarName<"">; -def : CLFlag<"O1">, Alias<_SLASH_O>, AliasArgs<["1"]>, - HelpText<"Optimize for size (like /Og /Os /Oy /Ob2 /GF /Gy)">; -def : CLFlag<"O2">, Alias<_SLASH_O>, AliasArgs<["2"]>, - HelpText<"Optimize for speed (like /Og /Oi /Ot /Oy /Ob2 /GF /Gy)">; -def : CLFlag<"Ob0">, Alias<_SLASH_O>, AliasArgs<["b0"]>, - HelpText<"Disable function inlining">; -def : CLFlag<"Ob1">, Alias<_SLASH_O>, AliasArgs<["b1"]>, - HelpText<"Only inline functions explicitly or implicitly marked inline">; -def : CLFlag<"Ob2">, Alias<_SLASH_O>, AliasArgs<["b2"]>, - HelpText<"Inline functions as deemed beneficial by the compiler">; -def : CLFlag<"Od">, Alias<_SLASH_O>, AliasArgs<["d"]>, - HelpText<"Disable optimization">; -def : CLFlag<"Og">, Alias<_SLASH_O>, AliasArgs<["g"]>, - HelpText<"No effect">; -def : CLFlag<"Oi">, Alias<_SLASH_O>, AliasArgs<["i"]>, - HelpText<"Enable use of builtin functions">; -def : CLFlag<"Oi-">, Alias<_SLASH_O>, AliasArgs<["i-"]>, - HelpText<"Disable use of builtin functions">; -def : CLFlag<"Os">, Alias<_SLASH_O>, AliasArgs<["s"]>, - HelpText<"Optimize for size">; -def : CLFlag<"Ot">, Alias<_SLASH_O>, AliasArgs<["t"]>, - HelpText<"Optimize for speed">; -def : CLFlag<"Ox">, Alias<_SLASH_O>, AliasArgs<["x"]>, - HelpText<"Deprecated (like /Og /Oi /Ot /Oy /Ob2); use /O2">; -def : CLFlag<"Oy">, Alias<_SLASH_O>, AliasArgs<["y"]>, - HelpText<"Enable frame pointer omission (x86 only)">; -def : CLFlag<"Oy-">, Alias<_SLASH_O>, AliasArgs<["y-"]>, - HelpText<"Disable frame pointer omission (x86 only, default)">; - -def _SLASH_QUESTION : CLFlag<"?">, Alias, - HelpText<"Display available options">; -def _SLASH_Qvec : CLFlag<"Qvec">, - HelpText<"Enable the loop vectorization passes">, Alias; -def _SLASH_Qvec_ : CLFlag<"Qvec-">, - HelpText<"Disable the loop vectorization passes">, Alias; -def _SLASH_showIncludes : CLFlag<"showIncludes">, - HelpText<"Print info about included files to stderr">; -def _SLASH_showIncludes_user : CLFlag<"showIncludes:user">, - HelpText<"Like /showIncludes but omit system headers">; -def _SLASH_showFilenames : CLFlag<"showFilenames">, - HelpText<"Print the name of each compiled file">; -def _SLASH_showFilenames_ : CLFlag<"showFilenames-">, - HelpText<"Do not print the name of each compiled file (default)">; -def _SLASH_source_charset : CLCompileJoined<"source-charset:">, - HelpText<"Set source encoding, supports only UTF-8">, - Alias; -def _SLASH_execution_charset : CLCompileJoined<"execution-charset:">, - HelpText<"Set runtime encoding, supports only UTF-8">, - Alias; -def _SLASH_std : CLCompileJoined<"std:">, - HelpText<"Set C++ version (c++14,c++17,c++latest)">; -def _SLASH_U : CLJoinedOrSeparate<"U">, HelpText<"Undefine macro">, - MetaVarName<"">, Alias; -def _SLASH_validate_charset : CLFlag<"validate-charset">, - Alias, AliasArgs<["invalid-source-encoding"]>; -def _SLASH_validate_charset_ : CLFlag<"validate-charset-">, - Alias, AliasArgs<["no-invalid-source-encoding"]>; -def _SLASH_W0 : CLFlag<"W0">, HelpText<"Disable all warnings">, Alias; -def _SLASH_W1 : CLFlag<"W1">, HelpText<"Enable -Wall">, Alias; -def _SLASH_W2 : CLFlag<"W2">, HelpText<"Enable -Wall">, Alias; -def _SLASH_W3 : CLFlag<"W3">, HelpText<"Enable -Wall">, Alias; -def _SLASH_W4 : CLFlag<"W4">, HelpText<"Enable -Wall and -Wextra">, Alias; -def _SLASH_Wall : CLFlag<"Wall">, HelpText<"Enable -Weverything">, - Alias, AliasArgs<["everything"]>; -def _SLASH_WX : CLFlag<"WX">, HelpText<"Treat warnings as errors">, - Alias, AliasArgs<["error"]>; -def _SLASH_WX_ : CLFlag<"WX-">, - HelpText<"Do not treat warnings as errors (default)">, - Alias, AliasArgs<["no-error"]>; -def _SLASH_w_flag : CLFlag<"w">, HelpText<"Disable all warnings">, Alias; -def _SLASH_wd4005 : CLFlag<"wd4005">, Alias, - AliasArgs<["no-macro-redefined"]>; -def _SLASH_wd4018 : CLFlag<"wd4018">, Alias, - AliasArgs<["no-sign-compare"]>; -def _SLASH_wd4100 : CLFlag<"wd4100">, Alias, - AliasArgs<["no-unused-parameter"]>; -def _SLASH_wd4910 : CLFlag<"wd4910">, Alias, - AliasArgs<["no-dllexport-explicit-instantiation-decl"]>; -def _SLASH_wd4996 : CLFlag<"wd4996">, Alias, - AliasArgs<["no-deprecated-declarations"]>; -def _SLASH_vd : CLJoined<"vd">, HelpText<"Control vtordisp placement">, - Alias; -def _SLASH_X : CLFlag<"X">, - HelpText<"Do not add %INCLUDE% to include search path">, Alias; -def _SLASH_Zc_sizedDealloc : CLFlag<"Zc:sizedDealloc">, - HelpText<"Enable C++14 sized global deallocation functions">, - Alias; -def _SLASH_Zc_sizedDealloc_ : CLFlag<"Zc:sizedDealloc-">, - HelpText<"Disable C++14 sized global deallocation functions">, - Alias; -def _SLASH_Zc_alignedNew : CLFlag<"Zc:alignedNew">, - HelpText<"Enable C++17 aligned allocation functions">, - Alias; -def _SLASH_Zc_alignedNew_ : CLFlag<"Zc:alignedNew-">, - HelpText<"Disable C++17 aligned allocation functions">, - Alias; -def _SLASH_Zc_char8_t : CLFlag<"Zc:char8_t">, - HelpText<"Enable char8_t from C++2a">, - Alias; -def _SLASH_Zc_char8_t_ : CLFlag<"Zc:char8_t-">, - HelpText<"Disable char8_t from c++2a">, - Alias; -def _SLASH_Zc_strictStrings : CLFlag<"Zc:strictStrings">, - HelpText<"Treat string literals as const">, Alias, - AliasArgs<["error=c++11-compat-deprecated-writable-strings"]>; -def _SLASH_Zc_threadSafeInit : CLFlag<"Zc:threadSafeInit">, - HelpText<"Enable thread-safe initialization of static variables">, - Alias; -def _SLASH_Zc_threadSafeInit_ : CLFlag<"Zc:threadSafeInit-">, - HelpText<"Disable thread-safe initialization of static variables">, - Alias; -def _SLASH_Zc_trigraphs : CLFlag<"Zc:trigraphs">, - HelpText<"Enable trigraphs">, Alias; -def _SLASH_Zc_trigraphs_off : CLFlag<"Zc:trigraphs-">, - HelpText<"Disable trigraphs (default)">, Alias; -def _SLASH_Zc_twoPhase : CLFlag<"Zc:twoPhase">, - HelpText<"Enable two-phase name lookup in templates">, - Alias; -def _SLASH_Zc_twoPhase_ : CLFlag<"Zc:twoPhase-">, - HelpText<"Disable two-phase name lookup in templates (default)">, - Alias; -def _SLASH_Z7 : CLFlag<"Z7">, - HelpText<"Enable CodeView debug information in object files">; -def _SLASH_Zd : CLFlag<"Zd">, - HelpText<"Emit debug line number tables only">; -def _SLASH_Zi : CLFlag<"Zi">, Alias<_SLASH_Z7>, - HelpText<"Like /Z7">; -def _SLASH_Zp : CLJoined<"Zp">, - HelpText<"Set default maximum struct packing alignment">, - Alias; -def _SLASH_Zp_flag : CLFlag<"Zp">, - HelpText<"Set default maximum struct packing alignment to 1">, - Alias, AliasArgs<["1"]>; -def _SLASH_Zs : CLFlag<"Zs">, HelpText<"Syntax-check only">, - Alias; -def _SLASH_openmp_ : CLFlag<"openmp-">, - HelpText<"Disable OpenMP support">, Alias; -def _SLASH_openmp : CLFlag<"openmp">, HelpText<"Enable OpenMP support">, - Alias; -def _SLASH_openmp_experimental : CLFlag<"openmp:experimental">, - HelpText<"Enable OpenMP support with experimental SIMD support">, - Alias; - -// Non-aliases: - -def _SLASH_arch : CLCompileJoined<"arch:">, - HelpText<"Set architecture for code generation">; - -def _SLASH_M_Group : OptionGroup<"">, Group; -def _SLASH_volatile_Group : OptionGroup<"">, - Group; - -def _SLASH_EH : CLJoined<"EH">, HelpText<"Set exception handling model">; -def _SLASH_EP : CLFlag<"EP">, - HelpText<"Disable linemarker output and preprocess to stdout">; -def _SLASH_FA : CLFlag<"FA">, - HelpText<"Output assembly code file during compilation">; -def _SLASH_Fa : CLJoined<"Fa">, - HelpText<"Set assembly output file name (with /FA)">, - MetaVarName<"">; -def _SLASH_fallback : CLCompileFlag<"fallback">, - HelpText<"Fall back to cl.exe if clang-cl fails to compile">; -def _SLASH_FI : CLJoinedOrSeparate<"FI">, - HelpText<"Include file before parsing">, Alias; -def _SLASH_Fe : CLJoined<"Fe">, - HelpText<"Set output executable file name">, - MetaVarName<"">; -def _SLASH_Fi : CLCompileJoined<"Fi">, - HelpText<"Set preprocess output file name (with /P)">, - MetaVarName<"">; -def _SLASH_Fo : CLCompileJoined<"Fo">, - HelpText<"Set output object file (with /c)">, - MetaVarName<"">; -def _SLASH_guard : CLJoined<"guard:">, - HelpText<"Enable Control Flow Guard with /guard:cf, or only the table with /guard:cf,nochecks">; -def _SLASH_GX : CLFlag<"GX">, - HelpText<"Deprecated; use /EHsc">; -def _SLASH_GX_ : CLFlag<"GX-">, - HelpText<"Deprecated (like not passing /EH)">; -def _SLASH_imsvc : CLJoinedOrSeparate<"imsvc">, - HelpText<"Add to system include search path, as if in %INCLUDE%">, - MetaVarName<"">; -def _SLASH_LD : CLFlag<"LD">, HelpText<"Create DLL">; -def _SLASH_LDd : CLFlag<"LDd">, HelpText<"Create debug DLL">; -def _SLASH_link : CLRemainingArgsJoined<"link">, - HelpText<"Forward options to the linker">, MetaVarName<"">; -def _SLASH_MD : Option<["/", "-"], "MD", KIND_FLAG>, Group<_SLASH_M_Group>, - Flags<[CLOption, DriverOption]>, HelpText<"Use DLL run-time">; -def _SLASH_MDd : Option<["/", "-"], "MDd", KIND_FLAG>, Group<_SLASH_M_Group>, - Flags<[CLOption, DriverOption]>, HelpText<"Use DLL debug run-time">; -def _SLASH_MT : Option<["/", "-"], "MT", KIND_FLAG>, Group<_SLASH_M_Group>, - Flags<[CLOption, DriverOption]>, HelpText<"Use static run-time">; -def _SLASH_MTd : Option<["/", "-"], "MTd", KIND_FLAG>, Group<_SLASH_M_Group>, - Flags<[CLOption, DriverOption]>, HelpText<"Use static debug run-time">; -def _SLASH_o : CLJoinedOrSeparate<"o">, - HelpText<"Deprecated (set output file name); use /Fe or /Fe">, - MetaVarName<"">; -def _SLASH_P : CLFlag<"P">, HelpText<"Preprocess to file">; -def _SLASH_Tc : CLCompileJoinedOrSeparate<"Tc">, - HelpText<"Treat as C source file">, MetaVarName<"">; -def _SLASH_TC : CLCompileFlag<"TC">, HelpText<"Treat all source files as C">; -def _SLASH_Tp : CLCompileJoinedOrSeparate<"Tp">, - HelpText<"Treat as C++ source file">, MetaVarName<"">; -def _SLASH_TP : CLCompileFlag<"TP">, HelpText<"Treat all source files as C++">; -def _SLASH_volatile_iso : Option<["/", "-"], "volatile:iso", KIND_FLAG>, - Group<_SLASH_volatile_Group>, Flags<[CLOption, DriverOption]>, - HelpText<"Volatile loads and stores have standard semantics">; -def _SLASH_vmb : CLFlag<"vmb">, - HelpText<"Use a best-case representation method for member pointers">; -def _SLASH_vmg : CLFlag<"vmg">, - HelpText<"Use a most-general representation for member pointers">; -def _SLASH_vms : CLFlag<"vms">, - HelpText<"Set the default most-general representation to single inheritance">; -def _SLASH_vmm : CLFlag<"vmm">, - HelpText<"Set the default most-general representation to " - "multiple inheritance">; -def _SLASH_vmv : CLFlag<"vmv">, - HelpText<"Set the default most-general representation to " - "virtual inheritance">; -def _SLASH_volatile_ms : Option<["/", "-"], "volatile:ms", KIND_FLAG>, - Group<_SLASH_volatile_Group>, Flags<[CLOption, DriverOption]>, - HelpText<"Volatile loads and stores have acquire and release semantics">; -def _SLASH_clang : CLJoined<"clang:">, - HelpText<"Pass to the clang driver">, MetaVarName<"">; -def _SLASH_Zl : CLFlag<"Zl">, - HelpText<"Do not let object file auto-link default libraries">; - -def _SLASH_Yc : CLJoined<"Yc">, - HelpText<"Generate a pch file for all code up to and including ">, - MetaVarName<"">; -def _SLASH_Yu : CLJoined<"Yu">, - HelpText<"Load a pch file and use it instead of all code up to " - "and including ">, - MetaVarName<"">; -def _SLASH_Y_ : CLFlag<"Y-">, - HelpText<"Disable precompiled headers, overrides /Yc and /Yu">; -def _SLASH_Zc_dllexportInlines : CLFlag<"Zc:dllexportInlines">, - HelpText<"dllexport/dllimport inline member functions of dllexport/import classes (default)">; -def _SLASH_Zc_dllexportInlines_ : CLFlag<"Zc:dllexportInlines-">, - HelpText<"Do not dllexport/dllimport inline member functions of dllexport/import classes">; -def _SLASH_Fp : CLJoined<"Fp">, - HelpText<"Set pch file name (with /Yc and /Yu)">, MetaVarName<"">; - -def _SLASH_Gd : CLFlag<"Gd">, - HelpText<"Set __cdecl as a default calling convention">; -def _SLASH_Gr : CLFlag<"Gr">, - HelpText<"Set __fastcall as a default calling convention">; -def _SLASH_Gz : CLFlag<"Gz">, - HelpText<"Set __stdcall as a default calling convention">; -def _SLASH_Gv : CLFlag<"Gv">, - HelpText<"Set __vectorcall as a default calling convention">; -def _SLASH_Gregcall : CLFlag<"Gregcall">, - HelpText<"Set __regcall as a default calling convention">; - -// Ignored: - -def _SLASH_analyze_ : CLIgnoredFlag<"analyze-">; -def _SLASH_bigobj : CLIgnoredFlag<"bigobj">; -def _SLASH_cgthreads : CLIgnoredJoined<"cgthreads">; -def _SLASH_d2FastFail : CLIgnoredFlag<"d2FastFail">; -def _SLASH_d2Zi_PLUS : CLIgnoredFlag<"d2Zi+">; -def _SLASH_errorReport : CLIgnoredJoined<"errorReport">; -def _SLASH_FC : CLIgnoredFlag<"FC">; -def _SLASH_Fd : CLIgnoredJoined<"Fd">; -def _SLASH_FS : CLIgnoredFlag<"FS">; -def _SLASH_JMC : CLIgnoredFlag<"JMC">; -def _SLASH_kernel_ : CLIgnoredFlag<"kernel-">; -def _SLASH_nologo : CLIgnoredFlag<"nologo">; -def _SLASH_permissive_ : CLIgnoredFlag<"permissive-">; -def _SLASH_RTC : CLIgnoredJoined<"RTC">; -def _SLASH_sdl : CLIgnoredFlag<"sdl">; -def _SLASH_sdl_ : CLIgnoredFlag<"sdl-">; -def _SLASH_utf8 : CLIgnoredFlag<"utf-8">, - HelpText<"Set source and runtime encoding to UTF-8 (default)">; -def _SLASH_w : CLIgnoredJoined<"w">; -def _SLASH_Zc___cplusplus : CLIgnoredFlag<"Zc:__cplusplus">; -def _SLASH_Zc_auto : CLIgnoredFlag<"Zc:auto">; -def _SLASH_Zc_forScope : CLIgnoredFlag<"Zc:forScope">; -def _SLASH_Zc_inline : CLIgnoredFlag<"Zc:inline">; -def _SLASH_Zc_rvalueCast : CLIgnoredFlag<"Zc:rvalueCast">; -def _SLASH_Zc_ternary : CLIgnoredFlag<"Zc:ternary">; -def _SLASH_Zc_wchar_t : CLIgnoredFlag<"Zc:wchar_t">; -def _SLASH_ZH_MD5 : CLIgnoredFlag<"ZH:MD5">; -def _SLASH_ZH_SHA1 : CLIgnoredFlag<"ZH:SHA1">; -def _SLASH_ZH_SHA_256 : CLIgnoredFlag<"ZH:SHA_256">; -def _SLASH_Zm : CLIgnoredJoined<"Zm">; -def _SLASH_Zo : CLIgnoredFlag<"Zo">; -def _SLASH_Zo_ : CLIgnoredFlag<"Zo-">; - - -// Unsupported: - -def _SLASH_await : CLFlag<"await">; -def _SLASH_constexpr : CLJoined<"constexpr:">; -def _SLASH_AI : CLJoinedOrSeparate<"AI">; -def _SLASH_Bt : CLFlag<"Bt">; -def _SLASH_Bt_plus : CLFlag<"Bt+">; -def _SLASH_clr : CLJoined<"clr">; -def _SLASH_d2 : CLJoined<"d2">; -def _SLASH_doc : CLJoined<"doc">; -def _SLASH_FA_joined : CLJoined<"FA">; -def _SLASH_favor : CLJoined<"favor">; -def _SLASH_F : CLJoinedOrSeparate<"F">; -def _SLASH_Fm : CLJoined<"Fm">; -def _SLASH_Fr : CLJoined<"Fr">; -def _SLASH_FR : CLJoined<"FR">; -def _SLASH_FU : CLJoinedOrSeparate<"FU">; -def _SLASH_Fx : CLFlag<"Fx">; -def _SLASH_G1 : CLFlag<"G1">; -def _SLASH_G2 : CLFlag<"G2">; -def _SLASH_Ge : CLFlag<"Ge">; -def _SLASH_Gh : CLFlag<"Gh">; -def _SLASH_GH : CLFlag<"GH">; -def _SLASH_GL : CLFlag<"GL">; -def _SLASH_GL_ : CLFlag<"GL-">; -def _SLASH_Gm : CLFlag<"Gm">; -def _SLASH_Gm_ : CLFlag<"Gm-">; -def _SLASH_GT : CLFlag<"GT">; -def _SLASH_GZ : CLFlag<"GZ">; -def _SLASH_H : CLFlag<"H">; -def _SLASH_homeparams : CLFlag<"homeparams">; -def _SLASH_hotpatch : CLFlag<"hotpatch">; -def _SLASH_kernel : CLFlag<"kernel">; -def _SLASH_LN : CLFlag<"LN">; -def _SLASH_MP : CLJoined<"MP">; -def _SLASH_Qfast_transcendentals : CLFlag<"Qfast_transcendentals">; -def _SLASH_QIfist : CLFlag<"QIfist">; -def _SLASH_QIntel_jcc_erratum : CLFlag<"QIntel-jcc-erratum">; -def _SLASH_Qimprecise_fwaits : CLFlag<"Qimprecise_fwaits">; -def _SLASH_Qpar : CLFlag<"Qpar">; -def _SLASH_Qpar_report : CLJoined<"Qpar-report">; -def _SLASH_Qsafe_fp_loads : CLFlag<"Qsafe_fp_loads">; -def _SLASH_Qspectre : CLFlag<"Qspectre">; -def _SLASH_Qspectre_load : CLFlag<"Qspectre-load">; -def _SLASH_Qspectre_load_cf : CLFlag<"Qspectre-load-cf">; -def _SLASH_Qvec_report : CLJoined<"Qvec-report">; -def _SLASH_u : CLFlag<"u">; -def _SLASH_V : CLFlag<"V">; -def _SLASH_WL : CLFlag<"WL">; -def _SLASH_Wp64 : CLFlag<"Wp64">; -def _SLASH_Yd : CLFlag<"Yd">; -def _SLASH_Yl : CLJoined<"Yl">; -def _SLASH_Za : CLFlag<"Za">; -def _SLASH_Zc : CLJoined<"Zc:">; -def _SLASH_Ze : CLFlag<"Ze">; -def _SLASH_Zg : CLFlag<"Zg">; -def _SLASH_ZI : CLFlag<"ZI">; -def _SLASH_ZW : CLJoined<"ZW">; diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h index 90a0c871140a5..dc18f1314f81e 100644 --- a/clang/include/clang/Driver/Driver.h +++ b/clang/include/clang/Driver/Driver.h @@ -548,6 +548,9 @@ class Driver { /// handle this action. bool ShouldUseFlangCompiler(const JobAction &JA) const; + /// ShouldEmitStaticLibrary - Should the linker emit a static library. + bool ShouldEmitStaticLibrary(const llvm::opt::ArgList &Args) const; + /// Returns true if we are performing any kind of LTO. bool isUsingLTO() const { return LTOMode != LTOK_None; } @@ -618,7 +621,8 @@ class Driver { static bool GetReleaseVersion(StringRef Str, MutableArrayRef Digits); /// Compute the default -fmodule-cache-path. - static void getDefaultModuleCachePath(SmallVectorImpl &Result); + /// \return True if the system provides a default cache directory. + static bool getDefaultModuleCachePath(SmallVectorImpl &Result); }; /// \return True if the last defined optimization level is -Ofast. diff --git a/clang/include/clang/Driver/Job.h b/clang/include/clang/Driver/Job.h index 1c6ea6971919a..6173b9d314b4d 100644 --- a/clang/include/clang/Driver/Job.h +++ b/clang/include/clang/Driver/Job.h @@ -16,6 +16,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator.h" #include "llvm/Option/Option.h" +#include "llvm/Support/Program.h" #include #include #include @@ -36,6 +37,69 @@ struct CrashReportInfo { : Filename(Filename), VFSPath(VFSPath) {} }; +// Encodes the kind of response file supported for a command invocation. +// Response files are necessary if the command line gets too large, requiring +// the arguments to be transferred to a file. +struct ResponseFileSupport { + enum ResponseFileKind { + // Provides full support for response files, which means we can transfer + // all tool input arguments to a file. + RF_Full, + // Input file names can live in a file, but flags can't. This is a special + // case for old versions of Apple's ld64. + RF_FileList, + // Does not support response files: all arguments must be passed via + // command line. + RF_None + }; + /// The level of support for response files. + ResponseFileKind ResponseKind; + + /// The encoding to use when writing response files on Windows. Ignored on + /// other host OSes. + /// + /// Windows use cases: - GCC and Binutils on mingw only accept ANSI response + /// files encoded with the system current code page. + /// - MSVC's CL.exe and LINK.exe accept UTF16 on Windows. + /// - Clang accepts both UTF8 and UTF16. + /// + /// FIXME: When GNU tools learn how to parse UTF16 on Windows, we should + /// always use UTF16 for Windows, which is the Windows official encoding for + /// international characters. + llvm::sys::WindowsEncodingMethod ResponseEncoding; + + /// What prefix to use for the command-line argument when passing a response + /// file. + const char *ResponseFlag; + + /// Returns a ResponseFileSupport indicating that response files are not + /// supported. + static constexpr ResponseFileSupport None() { + return {RF_None, llvm::sys::WEM_UTF8, nullptr}; + } + + /// Returns a ResponseFileSupport indicating that response files are + /// supported, using the @file syntax. On windows, the file is written in the + /// UTF8 encoding. On other OSes, no re-encoding occurs. + static constexpr ResponseFileSupport AtFileUTF8() { + return {RF_Full, llvm::sys::WEM_UTF8, "@"}; + } + + /// Returns a ResponseFileSupport indicating that response files are + /// supported, using the @file syntax. On windows, the file is written in the + /// current ANSI code-page encoding. On other OSes, no re-encoding occurs. + static constexpr ResponseFileSupport AtFileCurCP() { + return {RF_Full, llvm::sys::WEM_CurrentCodePage, "@"}; + } + + /// Returns a ResponseFileSupport indicating that response files are + /// supported, using the @file syntax. On windows, the file is written in the + /// UTF-16 encoding. On other OSes, no re-encoding occurs. + static constexpr ResponseFileSupport AtFileUTF16() { + return {RF_Full, llvm::sys::WEM_UTF16, "@"}; + } +}; + /// Command - An executable path/name and argument vector to /// execute. class Command { @@ -45,6 +109,9 @@ class Command { /// Tool - The tool which caused the creation of this job. const Tool &Creator; + /// Whether and how to generate response files if the arguments are too long. + ResponseFileSupport ResponseSupport; + /// The executable to run. const char *Executable; @@ -89,7 +156,8 @@ class Command { /// Whether the command will be executed in this process or not. bool InProcess = false; - Command(const Action &Source, const Tool &Creator, const char *Executable, + Command(const Action &Source, const Tool &Creator, + ResponseFileSupport ResponseSupport, const char *Executable, const llvm::opt::ArgStringList &Arguments, ArrayRef Inputs); // FIXME: This really shouldn't be copyable, but is currently copied in some @@ -109,11 +177,16 @@ class Command { /// getCreator - Return the Tool which caused the creation of this job. const Tool &getCreator() const { return Creator; } + /// Returns the kind of response file supported by the current invocation. + const ResponseFileSupport &getResponseFileSupport() { + return ResponseSupport; + } + /// Set to pass arguments via a response file when launching the command void setResponseFile(const char *FileName); - /// Set an input file list, necessary if we need to use a response file but - /// the tool being called only supports input files lists. + /// Set an input file list, necessary if you specified an RF_FileList response + /// file support. void setInputFileList(llvm::opt::ArgStringList List) { InputFileList = std::move(List); } @@ -136,7 +209,8 @@ class Command { /// Use the CC1 tool callback when available, to avoid creating a new process class CC1Command : public Command { public: - CC1Command(const Action &Source, const Tool &Creator, const char *Executable, + CC1Command(const Action &Source, const Tool &Creator, + ResponseFileSupport ResponseSupport, const char *Executable, const llvm::opt::ArgStringList &Arguments, ArrayRef Inputs); @@ -154,7 +228,7 @@ class CC1Command : public Command { class FallbackCommand : public Command { public: FallbackCommand(const Action &Source_, const Tool &Creator_, - const char *Executable_, + ResponseFileSupport ResponseSupport, const char *Executable_, const llvm::opt::ArgStringList &Arguments_, ArrayRef Inputs, std::unique_ptr Fallback_); @@ -173,6 +247,7 @@ class FallbackCommand : public Command { class ForceSuccessCommand : public Command { public: ForceSuccessCommand(const Action &Source_, const Tool &Creator_, + ResponseFileSupport ResponseSupport, const char *Executable_, const llvm::opt::ArgStringList &Arguments_, ArrayRef Inputs); diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 8ad582c84c604..f4556c15d744c 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -483,6 +483,9 @@ def Wnonportable_cfstrings : Joined<["-"], "Wnonportable-cfstrings">, Group, HelpText<"Pass the comma separated arguments in to the preprocessor">, MetaVarName<"">, Group; +def Wundef_prefix_EQ : CommaJoined<["-"], "Wundef-prefix=">, Group, + Flags<[CC1Option, CoreOption, HelpHidden]>, MetaVarName<"">, + HelpText<"Enable warnings for undefined macros with a prefix in the comma separated list ">; def Wwrite_strings : Flag<["-"], "Wwrite-strings">, Group, Flags<[CC1Option, HelpHidden]>; def Wno_write_strings : Flag<["-"], "Wno-write-strings">, Group, Flags<[CC1Option, HelpHidden]>; def W_Joined : Joined<["-"], "W">, Group, Flags<[CC1Option, CoreOption]>, @@ -605,6 +608,8 @@ def hip_link : Flag<["--"], "hip-link">, def no_offload_arch_EQ : Joined<["--"], "no-offload-arch=">, Flags<[DriverOption]>, HelpText<"Remove CUDA/HIP offloading device architecture (e.g. sm_35, gfx906) from the list of devices to compile for. " "'all' resets the list to its default value.">; +def emit_static_lib : Flag<["--"], "emit-static-lib">, + HelpText<"Enable linker job to emit a static library.">; def no_cuda_gpu_arch_EQ : Joined<["--"], "no-cuda-gpu-arch=">, Flags<[DriverOption]>, Alias; def cuda_noopt_device_debug : Flag<["--"], "cuda-noopt-device-debug">, @@ -632,15 +637,19 @@ defm cuda_short_ptr : OptInFFlag<"cuda-short-ptr", "Use 32-bit pointers for accessing const/local/shared address spaces">; def rocm_path_EQ : Joined<["--"], "rocm-path=">, Group, HelpText<"ROCm installation path, used for finding and automatically linking required bitcode libraries.">; -def hip_device_lib_path_EQ : Joined<["--"], "hip-device-lib-path=">, Group, - HelpText<"HIP device library path. Alternative to rocm-path.">; +def rocm_device_lib_path_EQ : Joined<["--"], "rocm-device-lib-path=">, Group, + HelpText<"ROCm device library path. Alternative to rocm-path.">; +def : Joined<["--"], "hip-device-lib-path=">, Alias; def hip_device_lib_EQ : Joined<["--"], "hip-device-lib=">, Group, HelpText<"HIP device library">; +def hip_version_EQ : Joined<["--"], "hip-version=">, + HelpText<"HIP version in the format of major.minor.patch">; def fhip_dump_offload_linker_script : Flag<["-"], "fhip-dump-offload-linker-script">, Group, Flags<[NoArgumentUnused, HelpHidden]>; defm hip_new_launch_api : OptInFFlag<"hip-new-launch-api", - "Use new kernel launching API for HIP">; -defm gpu_allow_device_init : OptInFFlag<"gpu-allow-device-init", "Allow device side init function in HIP">; + "Use", "Don't use", " new kernel launching API for HIP">; +defm gpu_allow_device_init : OptInFFlag<"gpu-allow-device-init", + "Allow", "Don't allow", " device side init function in HIP">; def gpu_max_threads_per_block_EQ : Joined<["--"], "gpu-max-threads-per-block=">, Flags<[CC1Option]>, HelpText<"Default max threads per block for kernel launch bounds for HIP">; @@ -844,7 +853,8 @@ def fdiagnostics_color : Flag<["-"], "fdiagnostics-color">, Group, Flags<[CoreOption, DriverOption]>; def fdiagnostics_color_EQ : Joined<["-"], "fdiagnostics-color=">, Group; def fansi_escape_codes : Flag<["-"], "fansi-escape-codes">, Group, - Flags<[CoreOption, CC1Option]>, HelpText<"Use ANSI escape codes for diagnostics">; + Flags<[CoreOption, CC1Option]>, HelpText<"Use ANSI escape codes for diagnostics">, + MarshallingInfoFlag<"DiagnosticOpts->UseANSIEscapeCodes", "false">; def fcomment_block_commands : CommaJoined<["-"], "fcomment-block-commands=">, Group, Flags<[CC1Option]>, HelpText<"Treat each comma separated argument in as a documentation comment block command">, MetaVarName<"">; @@ -1237,6 +1247,9 @@ def fexperimental_isel : Flag<["-"], "fexperimental-isel">, Group def fexperimental_new_pass_manager : Flag<["-"], "fexperimental-new-pass-manager">, Group, Flags<[CC1Option]>, HelpText<"Enables an experimental new pass manager in LLVM.">; +def fexperimental_strict_floating_point : Flag<["-"], "fexperimental-strict-floating-point">, + Group, Flags<[CC1Option]>, + HelpText<"Enables experimental strict floating point in LLVM.">; def finput_charset_EQ : Joined<["-"], "finput-charset=">, Group; def fexec_charset_EQ : Joined<["-"], "fexec-charset=">, Group; def finstrument_functions : Flag<["-"], "finstrument-functions">, Group, Flags<[CC1Option]>, @@ -1584,7 +1597,6 @@ def fno_unwind_tables : Flag<["-"], "fno-unwind-tables">, Group; def fno_verbose_asm : Flag<["-"], "fno-verbose-asm">, Group, Flags<[CC1Option]>; def fno_working_directory : Flag<["-"], "fno-working-directory">, Group; def fno_wrapv : Flag<["-"], "fno-wrapv">, Group; -def fno_zero_initialized_in_bss : Flag<["-"], "fno-zero-initialized-in-bss">, Group; def fobjc_arc : Flag<["-"], "fobjc-arc">, Group, Flags<[CC1Option]>, HelpText<"Synthesize retain and release calls for Objective-C pointers">; def fno_objc_arc : Flag<["-"], "fno-objc-arc">, Group; @@ -1685,6 +1697,12 @@ def fopenmp_optimistic_collapse : Flag<["-"], "fopenmp-optimistic-collapse">, Gr Flags<[CC1Option, NoArgumentUnused, HelpHidden]>; def fno_openmp_optimistic_collapse : Flag<["-"], "fno-openmp-optimistic-collapse">, Group, Flags<[NoArgumentUnused, HelpHidden]>; +def fopenmp_cuda_parallel_target_regions : Flag<["-"], "fopenmp-cuda-parallel-target-regions">, Group, + Flags<[CC1Option, NoArgumentUnused, HelpHidden]>, + HelpText<"Support parallel execution of target regions on Cuda-based devices.">; +def fno_openmp_cuda_parallel_target_regions : Flag<["-"], "fno-openmp-cuda-parallel-target-regions">, Group, + Flags<[NoArgumentUnused, HelpHidden]>, + HelpText<"Support only serial execution of target regions on Cuda-based devices.">; def static_openmp: Flag<["-"], "static-openmp">, HelpText<"Use the static host OpenMP runtime while linking.">; def fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group; @@ -1915,7 +1933,7 @@ def fwrapv : Flag<["-"], "fwrapv">, Group, Flags<[CC1Option]>, HelpText<"Treat signed integer overflow as two's complement">; def fwritable_strings : Flag<["-"], "fwritable-strings">, Group, Flags<[CC1Option]>, HelpText<"Store string literals as writable data">; -def fzero_initialized_in_bss : Flag<["-"], "fzero-initialized-in-bss">, Group; +defm zero_initialized_in_bss : OptOutFFlag<"zero-initialized-in-bss", "", "Don't place zero initialized data in BSS">; defm function_sections : OptInFFlag<"function-sections", "Place each function in its own section">; def fbasic_block_sections_EQ : Joined<["-"], "fbasic-block-sections=">, Group, Flags<[CC1Option, CC1AsOption]>, @@ -2020,7 +2038,7 @@ def : Flag<["-"], "gno-record-gcc-switches">, Alias; def gstrict_dwarf : Flag<["-"], "gstrict-dwarf">, Group; def gno_strict_dwarf : Flag<["-"], "gno-strict-dwarf">, Group; def gcolumn_info : Flag<["-"], "gcolumn-info">, Group, Flags<[CoreOption]>; -def gno_column_info : Flag<["-"], "gno-column-info">, Group, Flags<[CoreOption]>; +def gno_column_info : Flag<["-"], "gno-column-info">, Group, Flags<[CoreOption, CC1Option]>; def gsplit_dwarf : Flag<["-"], "gsplit-dwarf">, Group; def gsplit_dwarf_EQ : Joined<["-"], "gsplit-dwarf=">, Group, HelpText<"Set DWARF fission mode to either 'split' or 'single'">, @@ -2254,6 +2272,11 @@ def mlvi_cfi : Flag<["-"], "mlvi-cfi">, Group, Flags<[CoreOption,Driver HelpText<"Enable only control-flow mitigations for Load Value Injection (LVI)">; def mno_lvi_cfi : Flag<["-"], "mno-lvi-cfi">, Group, Flags<[CoreOption,DriverOption]>, HelpText<"Disable control-flow mitigations for Load Value Injection (LVI)">; +def m_seses : Flag<["-"], "mseses">, Group, Flags<[CoreOption, DriverOption]>, + HelpText<"Enable speculative execution side effect suppression (SESES). " + "Includes LVI control flow integrity mitigations">; +def mno_seses : Flag<["-"], "mno-seses">, Group, Flags<[CoreOption, DriverOption]>, + HelpText<"Disable speculative execution side effect suppression (SESES)">; def mrelax : Flag<["-"], "mrelax">, Group, HelpText<"Enable linker relaxation">; @@ -3055,6 +3078,12 @@ def m3dnow : Flag<["-"], "m3dnow">, Group; def mno_3dnow : Flag<["-"], "mno-3dnow">, Group; def m3dnowa : Flag<["-"], "m3dnowa">, Group; def mno_3dnowa : Flag<["-"], "mno-3dnowa">, Group; +def mamx_bf16 : Flag<["-"], "mamx-bf16">, Group; +def mno_amx_bf16 : Flag<["-"], "mno-amx-bf16">, Group; +def mtamx_int8 : Flag<["-"], "mamx-int8">, Group; +def mno_amx_int8 : Flag<["-"], "mno-amx-int8">, Group; +def mamx_tile : Flag<["-"], "mamx-tile">, Group; +def mno_amx_tile : Flag<["-"], "mno-amx-tile">, Group; def msse : Flag<["-"], "msse">, Group; def mno_sse : Flag<["-"], "mno-sse">, Group; def msse2 : Flag<["-"], "msse2">, Group; @@ -3413,6 +3442,1405 @@ def fno_sycl : Flag<["-"], "fno-sycl">, Group, Flags<[CoreOption]>, def sycl_std_EQ : Joined<["-"], "sycl-std=">, Group, Flags<[CC1Option, NoArgumentUnused, CoreOption]>, HelpText<"SYCL language standard to compile for.">, Values<"2017, 121, 1.2.1, sycl-1.2.1">; -include "CC1Options.td" +//===----------------------------------------------------------------------===// +// CC1 Options +//===----------------------------------------------------------------------===// + +let Flags = [CC1Option, NoDriverOption] in { + +//===----------------------------------------------------------------------===// +// Target Options +//===----------------------------------------------------------------------===// + +let Flags = [CC1Option, CC1AsOption, NoDriverOption] in { + +def target_cpu : Separate<["-"], "target-cpu">, + HelpText<"Target a specific cpu type">; +def target_feature : Separate<["-"], "target-feature">, + HelpText<"Target specific attributes">; +def triple : Separate<["-"], "triple">, + HelpText<"Specify target triple (e.g. i686-apple-darwin9)">, + MarshallingInfoString<"TargetOpts->Triple", "llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple())", "std::string">, + AlwaysEmit, Normalizer<"normalizeTriple">, DenormalizeString; +def target_abi : Separate<["-"], "target-abi">, + HelpText<"Target a particular ABI type">; +def target_sdk_version_EQ : Joined<["-"], "target-sdk-version=">, + HelpText<"The version of target SDK used for compilation">; + +} + +def target_linker_version : Separate<["-"], "target-linker-version">, + HelpText<"Target linker version">; +def triple_EQ : Joined<["-"], "triple=">, Alias; +def mfpmath : Separate<["-"], "mfpmath">, + HelpText<"Which unit to use for fp math">; + +def fpadding_on_unsigned_fixed_point : Flag<["-"], "fpadding-on-unsigned-fixed-point">, + HelpText<"Force each unsigned fixed point type to have an extra bit of padding to align their scales with those of signed fixed point types">; +def fno_padding_on_unsigned_fixed_point : Flag<["-"], "fno-padding-on-unsigned-fixed-point">; + +//===----------------------------------------------------------------------===// +// Analyzer Options +//===----------------------------------------------------------------------===// + +def analysis_UnoptimizedCFG : Flag<["-"], "unoptimized-cfg">, + HelpText<"Generate unoptimized CFGs for all analyses">; +def analysis_CFGAddImplicitDtors : Flag<["-"], "cfg-add-implicit-dtors">, + HelpText<"Add C++ implicit destructors to CFGs for all analyses">; + +def analyzer_store : Separate<["-"], "analyzer-store">, + HelpText<"Source Code Analysis - Abstract Memory Store Models">; +def analyzer_store_EQ : Joined<["-"], "analyzer-store=">, Alias; + +def analyzer_constraints : Separate<["-"], "analyzer-constraints">, + HelpText<"Source Code Analysis - Symbolic Constraint Engines">; +def analyzer_constraints_EQ : Joined<["-"], "analyzer-constraints=">, + Alias; + +def analyzer_output : Separate<["-"], "analyzer-output">, + HelpText<"Source Code Analysis - Output Options">; +def analyzer_output_EQ : Joined<["-"], "analyzer-output=">, + Alias; + +def analyzer_purge : Separate<["-"], "analyzer-purge">, + HelpText<"Source Code Analysis - Dead Symbol Removal Frequency">; +def analyzer_purge_EQ : Joined<["-"], "analyzer-purge=">, Alias; + +def analyzer_opt_analyze_headers : Flag<["-"], "analyzer-opt-analyze-headers">, + HelpText<"Force the static analyzer to analyze functions defined in header files">; +def analyzer_opt_analyze_nested_blocks : Flag<["-"], "analyzer-opt-analyze-nested-blocks">, + HelpText<"Analyze the definitions of blocks in addition to functions">; +def analyzer_display_progress : Flag<["-"], "analyzer-display-progress">, + HelpText<"Emit verbose output about the analyzer's progress">; +def analyze_function : Separate<["-"], "analyze-function">, + HelpText<"Run analysis on specific function (for C++ include parameters in name)">; +def analyze_function_EQ : Joined<["-"], "analyze-function=">, Alias; +def trim_egraph : Flag<["-"], "trim-egraph">, + HelpText<"Only show error-related paths in the analysis graph">; +def analyzer_viz_egraph_graphviz : Flag<["-"], "analyzer-viz-egraph-graphviz">, + HelpText<"Display exploded graph using GraphViz">; +def analyzer_dump_egraph : Separate<["-"], "analyzer-dump-egraph">, + HelpText<"Dump exploded graph to the specified file">; +def analyzer_dump_egraph_EQ : Joined<["-"], "analyzer-dump-egraph=">, Alias; + +def analyzer_inline_max_stack_depth : Separate<["-"], "analyzer-inline-max-stack-depth">, + HelpText<"Bound on stack depth while inlining (4 by default)">; +def analyzer_inline_max_stack_depth_EQ : Joined<["-"], "analyzer-inline-max-stack-depth=">, + Alias; + +def analyzer_inlining_mode : Separate<["-"], "analyzer-inlining-mode">, + HelpText<"Specify the function selection heuristic used during inlining">; +def analyzer_inlining_mode_EQ : Joined<["-"], "analyzer-inlining-mode=">, Alias; + +def analyzer_disable_retry_exhausted : Flag<["-"], "analyzer-disable-retry-exhausted">, + HelpText<"Do not re-analyze paths leading to exhausted nodes with a different strategy (may decrease code coverage)">; + +def analyzer_max_loop : Separate<["-"], "analyzer-max-loop">, + HelpText<"The maximum number of times the analyzer will go through a loop">; +def analyzer_stats : Flag<["-"], "analyzer-stats">, + HelpText<"Print internal analyzer statistics.">; + +def analyzer_checker : Separate<["-"], "analyzer-checker">, + HelpText<"Choose analyzer checkers to enable">, + ValuesCode<[{ + const char *Values = + #define GET_CHECKERS + #define CHECKER(FULLNAME, CLASS, HT, DOC_URI, IS_HIDDEN) FULLNAME "," + #include "clang/StaticAnalyzer/Checkers/Checkers.inc" + #undef GET_CHECKERS + #define GET_PACKAGES + #define PACKAGE(FULLNAME) FULLNAME "," + #include "clang/StaticAnalyzer/Checkers/Checkers.inc" + #undef GET_PACKAGES + ; + }]>; +def analyzer_checker_EQ : Joined<["-"], "analyzer-checker=">, + Alias; + +def analyzer_disable_checker : Separate<["-"], "analyzer-disable-checker">, + HelpText<"Choose analyzer checkers to disable">; +def analyzer_disable_checker_EQ : Joined<["-"], "analyzer-disable-checker=">, + Alias; + +def analyzer_disable_all_checks : Flag<["-"], "analyzer-disable-all-checks">, + HelpText<"Disable all static analyzer checks">; + +def analyzer_checker_help : Flag<["-"], "analyzer-checker-help">, + HelpText<"Display the list of analyzer checkers that are available">; + +def analyzer_checker_help_alpha : Flag<["-"], "analyzer-checker-help-alpha">, + HelpText<"Display the list of in development analyzer checkers. These " + "are NOT considered safe, they are unstable and will emit incorrect " + "reports. Enable ONLY FOR DEVELOPMENT purposes">; + +def analyzer_checker_help_developer : Flag<["-"], "analyzer-checker-help-developer">, + HelpText<"Display the list of developer-only checkers such as modeling " + "and debug checkers">; + +def analyzer_config_help : Flag<["-"], "analyzer-config-help">, + HelpText<"Display the list of -analyzer-config options. These are meant for " + "development purposes only!">; + +def analyzer_list_enabled_checkers : Flag<["-"], "analyzer-list-enabled-checkers">, + HelpText<"Display the list of enabled analyzer checkers">; + +def analyzer_config : Separate<["-"], "analyzer-config">, + HelpText<"Choose analyzer options to enable">; + +def analyzer_checker_option_help : Flag<["-"], "analyzer-checker-option-help">, + HelpText<"Display the list of checker and package options">; + +def analyzer_checker_option_help_alpha : Flag<["-"], "analyzer-checker-option-help-alpha">, + HelpText<"Display the list of in development checker and package options. " + "These are NOT considered safe, they are unstable and will emit " + "incorrect reports. Enable ONLY FOR DEVELOPMENT purposes">; -include "CLCompatOptions.td" +def analyzer_checker_option_help_developer : Flag<["-"], "analyzer-checker-option-help-developer">, + HelpText<"Display the list of checker and package options meant for " + "development purposes only">; + +def analyzer_config_compatibility_mode : Separate<["-"], "analyzer-config-compatibility-mode">, + HelpText<"Don't emit errors on invalid analyzer-config inputs">; + +def analyzer_config_compatibility_mode_EQ : Joined<["-"], "analyzer-config-compatibility-mode=">, + Alias; + +def analyzer_werror : Flag<["-"], "analyzer-werror">, + HelpText<"Emit analyzer results as errors rather than warnings">; + +//===----------------------------------------------------------------------===// +// Migrator Options +//===----------------------------------------------------------------------===// +def migrator_no_nsalloc_error : Flag<["-"], "no-ns-alloc-error">, + HelpText<"Do not error on use of NSAllocateCollectable/NSReallocateCollectable">; + +def migrator_no_finalize_removal : Flag<["-"], "no-finalize-removal">, + HelpText<"Do not remove finalize method in gc mode">; + +//===----------------------------------------------------------------------===// +// CodeGen Options +//===----------------------------------------------------------------------===// + +let Flags = [CC1Option, CC1AsOption, NoDriverOption] in { +def debug_info_kind_EQ : Joined<["-"], "debug-info-kind=">; +def debug_info_macro : Flag<["-"], "debug-info-macro">, + HelpText<"Emit macro debug information">; +def default_function_attr : Separate<["-"], "default-function-attr">, + HelpText<"Apply given attribute to all functions">; +def dwarf_version_EQ : Joined<["-"], "dwarf-version=">; +def debugger_tuning_EQ : Joined<["-"], "debugger-tuning=">; +def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">, + HelpText<"The string to embed in the Dwarf debug flags record.">; +def record_command_line : Separate<["-"], "record-command-line">, + HelpText<"The string to embed in the .LLVM.command.line section.">; +def compress_debug_sections : Flag<["-", "--"], "compress-debug-sections">, + HelpText<"DWARF debug sections compression">; +def compress_debug_sections_EQ : Joined<["-", "--"], "compress-debug-sections=">, + HelpText<"DWARF debug sections compression type">; +def mno_exec_stack : Flag<["-"], "mnoexecstack">, + HelpText<"Mark the file as not needing an executable stack">; +def massembler_no_warn : Flag<["-"], "massembler-no-warn">, + HelpText<"Make assembler not emit warnings">; +def massembler_fatal_warnings : Flag<["-"], "massembler-fatal-warnings">, + HelpText<"Make assembler warnings fatal">; +def mrelax_relocations : Flag<["--"], "mrelax-relocations">, + HelpText<"Use relaxable elf relocations">; +def msave_temp_labels : Flag<["-"], "msave-temp-labels">, + HelpText<"Save temporary labels in the symbol table. " + "Note this may change .s semantics and shouldn't generally be used " + "on compiler-generated code.">; +def mrelocation_model : Separate<["-"], "mrelocation-model">, + HelpText<"The relocation model to use">, Values<"static,pic,ropi,rwpi,ropi-rwpi,dynamic-no-pic">, + NormalizedValuesScope<"llvm::Reloc">, + NormalizedValues<["Static", "PIC_", "ROPI", "RWPI", "ROPI_RWPI", "DynamicNoPIC"]>, + MarshallingInfoString<"CodeGenOpts.RelocationModel", "PIC_", "Model">, + AutoNormalizeEnum; +def fno_math_builtin : Flag<["-"], "fno-math-builtin">, + HelpText<"Disable implicit builtin knowledge of math functions">; +} + +def disable_llvm_verifier : Flag<["-"], "disable-llvm-verifier">, + HelpText<"Don't run the LLVM IR verifier pass">; +def disable_llvm_passes : Flag<["-"], "disable-llvm-passes">, + HelpText<"Use together with -emit-llvm to get pristine LLVM IR from the " + "frontend by not running any LLVM passes at all">; +def disable_llvm_optzns : Flag<["-"], "disable-llvm-optzns">, + Alias; +def disable_lifetimemarkers : Flag<["-"], "disable-lifetime-markers">, + HelpText<"Disable lifetime-markers emission even when optimizations are " + "enabled">; +def disable_O0_optnone : Flag<["-"], "disable-O0-optnone">, + HelpText<"Disable adding the optnone attribute to functions at O0">; +def disable_red_zone : Flag<["-"], "disable-red-zone">, + HelpText<"Do not emit code that uses the red zone.">; +def dwarf_ext_refs : Flag<["-"], "dwarf-ext-refs">, + HelpText<"Generate debug info with external references to clang modules" + " or precompiled headers">; +def dwarf_explicit_import : Flag<["-"], "dwarf-explicit-import">, + HelpText<"Generate explicit import from anonymous namespace to containing" + " scope">; +def debug_forward_template_params : Flag<["-"], "debug-forward-template-params">, + HelpText<"Emit complete descriptions of template parameters in forward" + " declarations">; +def fforbid_guard_variables : Flag<["-"], "fforbid-guard-variables">, + HelpText<"Emit an error if a C++ static local initializer would need a guard variable">; +def no_implicit_float : Flag<["-"], "no-implicit-float">, + HelpText<"Don't generate implicit floating point instructions">; +def fdump_vtable_layouts : Flag<["-"], "fdump-vtable-layouts">, + HelpText<"Dump the layouts of all vtables that will be emitted in a translation unit">; +def fmerge_functions : Flag<["-"], "fmerge-functions">, + HelpText<"Permit merging of identical functions when optimizing.">; +def femit_coverage_notes : Flag<["-"], "femit-coverage-notes">, + HelpText<"Emit a gcov coverage notes file when compiling.">; +def femit_coverage_data: Flag<["-"], "femit-coverage-data">, + HelpText<"Instrument the program to emit gcov coverage data when run.">; +def coverage_data_file : Separate<["-"], "coverage-data-file">, + HelpText<"Emit coverage data to this filename.">; +def coverage_data_file_EQ : Joined<["-"], "coverage-data-file=">, + Alias; +def coverage_notes_file : Separate<["-"], "coverage-notes-file">, + HelpText<"Emit coverage notes to this filename.">; +def coverage_notes_file_EQ : Joined<["-"], "coverage-notes-file=">, + Alias; +def coverage_version_EQ : Joined<["-"], "coverage-version=">, + HelpText<"Four-byte version string for gcov files.">; +def test_coverage : Flag<["-"], "test-coverage">, + HelpText<"Do not generate coverage files or remove coverage changes from IR">; +def dump_coverage_mapping : Flag<["-"], "dump-coverage-mapping">, + HelpText<"Dump the coverage mapping records, for testing">; +def fuse_register_sized_bitfield_access: Flag<["-"], "fuse-register-sized-bitfield-access">, + HelpText<"Use register sized accesses to bit-fields, when possible.">; +def relaxed_aliasing : Flag<["-"], "relaxed-aliasing">, + HelpText<"Turn off Type Based Alias Analysis">; +def no_struct_path_tbaa : Flag<["-"], "no-struct-path-tbaa">, + HelpText<"Turn off struct-path aware Type Based Alias Analysis">; +def new_struct_path_tbaa : Flag<["-"], "new-struct-path-tbaa">, + HelpText<"Enable enhanced struct-path aware Type Based Alias Analysis">; +def mdebug_pass : Separate<["-"], "mdebug-pass">, + HelpText<"Enable additional debug output">; +def mframe_pointer_EQ : Joined<["-"], "mframe-pointer=">, + HelpText<"Specify which frame pointers to retain (all, non-leaf, none).">, Values<"all,non-leaf,none">; +def mdisable_tail_calls : Flag<["-"], "mdisable-tail-calls">, + HelpText<"Disable tail call optimization, keeping the call stack accurate">; +def menable_no_infinities : Flag<["-"], "menable-no-infs">, + HelpText<"Allow optimization to assume there are no infinities.">; +def menable_no_nans : Flag<["-"], "menable-no-nans">, + HelpText<"Allow optimization to assume there are no NaNs.">; +def menable_unsafe_fp_math : Flag<["-"], "menable-unsafe-fp-math">, + HelpText<"Allow unsafe floating-point math optimizations which may decrease " + "precision">; +def mreassociate : Flag<["-"], "mreassociate">, + HelpText<"Allow reassociation transformations for floating-point instructions">; +def mabi_EQ_ieeelongdouble : Flag<["-"], "mabi=ieeelongdouble">, + HelpText<"Use IEEE 754 quadruple-precision for long double">; +def mfloat_abi : Separate<["-"], "mfloat-abi">, + HelpText<"The float ABI to use">; +def mtp : Separate<["-"], "mtp">, + HelpText<"Mode for reading thread pointer">; +def mlimit_float_precision : Separate<["-"], "mlimit-float-precision">, + HelpText<"Limit float precision to the given value">; +def split_stacks : Flag<["-"], "split-stacks">, + HelpText<"Try to use a split stack if possible.">; +def mregparm : Separate<["-"], "mregparm">, + HelpText<"Limit the number of registers available for integer arguments">; +def msmall_data_limit : Separate<["-"], "msmall-data-limit">, + HelpText<"Put global and static data smaller than the limit into a special section">; +def munwind_tables : Flag<["-"], "munwind-tables">, + HelpText<"Generate unwinding tables for all functions">; +def mconstructor_aliases : Flag<["-"], "mconstructor-aliases">, + HelpText<"Emit complete constructors and destructors as aliases when possible">; +def mlink_bitcode_file : Separate<["-"], "mlink-bitcode-file">, + HelpText<"Link the given bitcode file before performing optimizations.">; +def mlink_builtin_bitcode : Separate<["-"], "mlink-builtin-bitcode">, + HelpText<"Link and internalize needed symbols from the given bitcode file " + "before performing optimizations.">; +def mlink_cuda_bitcode : Separate<["-"], "mlink-cuda-bitcode">, + Alias; +def vectorize_loops : Flag<["-"], "vectorize-loops">, + HelpText<"Run the Loop vectorization passes">; +def vectorize_slp : Flag<["-"], "vectorize-slp">, + HelpText<"Run the SLP vectorization passes">; +def dependent_lib : Joined<["--"], "dependent-lib=">, + HelpText<"Add dependent library">; +def linker_option : Joined<["--"], "linker-option=">, + HelpText<"Add linker option">; +def fsanitize_coverage_type : Joined<["-"], "fsanitize-coverage-type=">, + HelpText<"Sanitizer coverage type">; +def fsanitize_coverage_indirect_calls + : Flag<["-"], "fsanitize-coverage-indirect-calls">, + HelpText<"Enable sanitizer coverage for indirect calls">; +def fsanitize_coverage_trace_bb + : Flag<["-"], "fsanitize-coverage-trace-bb">, + HelpText<"Enable basic block tracing in sanitizer coverage">; +def fsanitize_coverage_trace_cmp + : Flag<["-"], "fsanitize-coverage-trace-cmp">, + HelpText<"Enable cmp instruction tracing in sanitizer coverage">; +def fsanitize_coverage_trace_div + : Flag<["-"], "fsanitize-coverage-trace-div">, + HelpText<"Enable div instruction tracing in sanitizer coverage">; +def fsanitize_coverage_trace_gep + : Flag<["-"], "fsanitize-coverage-trace-gep">, + HelpText<"Enable gep instruction tracing in sanitizer coverage">; +def fsanitize_coverage_8bit_counters + : Flag<["-"], "fsanitize-coverage-8bit-counters">, + HelpText<"Enable frequency counters in sanitizer coverage">; +def fsanitize_coverage_inline_8bit_counters + : Flag<["-"], "fsanitize-coverage-inline-8bit-counters">, + HelpText<"Enable inline 8-bit counters in sanitizer coverage">; +def fsanitize_coverage_inline_bool_flag + : Flag<["-"], "fsanitize-coverage-inline-bool-flag">, + HelpText<"Enable inline bool flag in sanitizer coverage">; +def fsanitize_coverage_pc_table + : Flag<["-"], "fsanitize-coverage-pc-table">, + HelpText<"Create a table of coverage-instrumented PCs">; +def fsanitize_coverage_trace_pc + : Flag<["-"], "fsanitize-coverage-trace-pc">, + HelpText<"Enable PC tracing in sanitizer coverage">; +def fsanitize_coverage_trace_pc_guard + : Flag<["-"], "fsanitize-coverage-trace-pc-guard">, + HelpText<"Enable PC tracing with guard in sanitizer coverage">; +def fsanitize_coverage_no_prune + : Flag<["-"], "fsanitize-coverage-no-prune">, + HelpText<"Disable coverage pruning (i.e. instrument all blocks/edges)">; +def fsanitize_coverage_stack_depth + : Flag<["-"], "fsanitize-coverage-stack-depth">, + HelpText<"Enable max stack depth tracing">; +def fpatchable_function_entry_offset_EQ + : Joined<["-"], "fpatchable-function-entry-offset=">, MetaVarName<"">, + HelpText<"Generate M NOPs before function entry">; +def fprofile_instrument_EQ : Joined<["-"], "fprofile-instrument=">, + HelpText<"Enable PGO instrumentation. The accepted value is clang, llvm, " + "or none">, Values<"none,clang,llvm">; +def fprofile_instrument_path_EQ : Joined<["-"], "fprofile-instrument-path=">, + HelpText<"Generate instrumented code to collect execution counts into " + " (overridden by LLVM_PROFILE_FILE env var)">; +def fprofile_instrument_use_path_EQ : + Joined<["-"], "fprofile-instrument-use-path=">, + HelpText<"Specify the profile path in PGO use compilation">; +def flto_visibility_public_std: + Flag<["-"], "flto-visibility-public-std">, + HelpText<"Use public LTO visibility for classes in std and stdext namespaces">; +def flto_unit: Flag<["-"], "flto-unit">, + HelpText<"Emit IR to support LTO unit features (CFI, whole program vtable opt)">; +def fno_lto_unit: Flag<["-"], "fno-lto-unit">; +def fdebug_pass_manager : Flag<["-"], "fdebug-pass-manager">, + HelpText<"Prints debug information for the new pass manager">; +def fno_debug_pass_manager : Flag<["-"], "fno-debug-pass-manager">, + HelpText<"Disables debug printing for the new pass manager">; +// The driver option takes the key as a parameter to the -msign-return-address= +// and -mbranch-protection= options, but CC1 has a separate option so we +// don't have to parse the parameter twice. +def msign_return_address_key_EQ : Joined<["-"], "msign-return-address-key=">, + Values<"a_key,b_key">; +def mbranch_target_enforce : Flag<["-"], "mbranch-target-enforce">; +def fno_dllexport_inlines : Flag<["-"], "fno-dllexport-inlines">; +def cfguard_no_checks : Flag<["-"], "cfguard-no-checks">, + HelpText<"Emit Windows Control Flow Guard tables only (no checks)">; +def cfguard : Flag<["-"], "cfguard">, + HelpText<"Emit Windows Control Flow Guard tables and checks">; + +def fdenormal_fp_math_f32_EQ : Joined<["-"], "fdenormal-fp-math-f32=">, + Group; + +//===----------------------------------------------------------------------===// +// Dependency Output Options +//===----------------------------------------------------------------------===// + +def sys_header_deps : Flag<["-"], "sys-header-deps">, + HelpText<"Include system headers in dependency output">; +def module_file_deps : Flag<["-"], "module-file-deps">, + HelpText<"Include module files in dependency output">; +def header_include_file : Separate<["-"], "header-include-file">, + HelpText<"Filename (or -) to write header include output to">; +def show_includes : Flag<["--"], "show-includes">, + HelpText<"Print cl.exe style /showIncludes to stdout">; + +//===----------------------------------------------------------------------===// +// Diagnostic Options +//===----------------------------------------------------------------------===// + +def diagnostic_log_file : Separate<["-"], "diagnostic-log-file">, + HelpText<"Filename (or -) to log diagnostics to">; +def diagnostic_serialized_file : Separate<["-"], "serialize-diagnostic-file">, + MetaVarName<"">, + HelpText<"File for serializing diagnostics in a binary format">; + +def fdiagnostics_format : Separate<["-"], "fdiagnostics-format">, + HelpText<"Change diagnostic formatting to match IDE and command line tools">, Values<"clang,msvc,msvc-fallback,vi">; +def fdiagnostics_show_category : Separate<["-"], "fdiagnostics-show-category">, + HelpText<"Print diagnostic category">, Values<"none,id,name">; +def fno_diagnostics_use_presumed_location : Flag<["-"], "fno-diagnostics-use-presumed-location">, + HelpText<"Ignore #line directives when displaying diagnostic locations">; +def ftabstop : Separate<["-"], "ftabstop">, MetaVarName<"">, + HelpText<"Set the tab stop distance.">; +def ferror_limit : Separate<["-"], "ferror-limit">, MetaVarName<"">, + HelpText<"Set the maximum number of errors to emit before stopping (0 = no limit).">; +def fmacro_backtrace_limit : Separate<["-"], "fmacro-backtrace-limit">, MetaVarName<"">, + HelpText<"Set the maximum number of entries to print in a macro expansion backtrace (0 = no limit).">; +def ftemplate_backtrace_limit : Separate<["-"], "ftemplate-backtrace-limit">, MetaVarName<"">, + HelpText<"Set the maximum number of entries to print in a template instantiation backtrace (0 = no limit).">; +def fconstexpr_backtrace_limit : Separate<["-"], "fconstexpr-backtrace-limit">, MetaVarName<"">, + HelpText<"Set the maximum number of entries to print in a constexpr evaluation backtrace (0 = no limit).">; +def fspell_checking_limit : Separate<["-"], "fspell-checking-limit">, MetaVarName<"">, + HelpText<"Set the maximum number of times to perform spell checking on unrecognized identifiers (0 = no limit).">; +def fcaret_diagnostics_max_lines : + Separate<["-"], "fcaret-diagnostics-max-lines">, MetaVarName<"">, + HelpText<"Set the maximum number of source lines to show in a caret diagnostic">; +def verify_EQ : CommaJoined<["-"], "verify=">, + MetaVarName<"">, + HelpText<"Verify diagnostic output using comment directives that start with" + " prefixes in the comma-separated sequence ">; +def verify : Flag<["-"], "verify">, + HelpText<"Equivalent to -verify=expected">; +def verify_ignore_unexpected : Flag<["-"], "verify-ignore-unexpected">, + HelpText<"Ignore unexpected diagnostic messages">; +def verify_ignore_unexpected_EQ : CommaJoined<["-"], "verify-ignore-unexpected=">, + HelpText<"Ignore unexpected diagnostic messages">; +def Wno_rewrite_macros : Flag<["-"], "Wno-rewrite-macros">, + HelpText<"Silence ObjC rewriting warnings">; + +//===----------------------------------------------------------------------===// +// Frontend Options +//===----------------------------------------------------------------------===// + +// This isn't normally used, it is just here so we can parse a +// CompilerInvocation out of a driver-derived argument vector. +def cc1 : Flag<["-"], "cc1">; +def cc1as : Flag<["-"], "cc1as">; + +def ast_merge : Separate<["-"], "ast-merge">, + MetaVarName<"">, + HelpText<"Merge the given AST file into the translation unit being compiled.">; +def aux_target_cpu : Separate<["-"], "aux-target-cpu">, + HelpText<"Target a specific auxiliary cpu type">; +def aux_target_feature : Separate<["-"], "aux-target-feature">, + HelpText<"Target specific auxiliary attributes">; +def aux_triple : Separate<["-"], "aux-triple">, + HelpText<"Auxiliary target triple.">; +def code_completion_at : Separate<["-"], "code-completion-at">, + MetaVarName<"::">, + HelpText<"Dump code-completion information at a location">; +def remap_file : Separate<["-"], "remap-file">, + MetaVarName<";">, + HelpText<"Replace the contents of the file with the contents of the file">; +def code_completion_at_EQ : Joined<["-"], "code-completion-at=">, + Alias; +def code_completion_macros : Flag<["-"], "code-completion-macros">, + HelpText<"Include macros in code-completion results">; +def code_completion_patterns : Flag<["-"], "code-completion-patterns">, + HelpText<"Include code patterns in code-completion results">; +def no_code_completion_globals : Flag<["-"], "no-code-completion-globals">, + HelpText<"Do not include global declarations in code-completion results.">; +def no_code_completion_ns_level_decls : Flag<["-"], "no-code-completion-ns-level-decls">, + HelpText<"Do not include declarations inside namespaces (incl. global namespace) in the code-completion results.">; +def code_completion_brief_comments : Flag<["-"], "code-completion-brief-comments">, + HelpText<"Include brief documentation comments in code-completion results.">; +def code_completion_with_fixits : Flag<["-"], "code-completion-with-fixits">, + HelpText<"Include code completion results which require small fix-its.">; +def disable_free : Flag<["-"], "disable-free">, + HelpText<"Disable freeing of memory on exit">; +def discard_value_names : Flag<["-"], "discard-value-names">, + HelpText<"Discard value names in LLVM IR">; +def load : Separate<["-"], "load">, MetaVarName<"">, + HelpText<"Load the named plugin (dynamic shared object)">; +def plugin : Separate<["-"], "plugin">, MetaVarName<"">, + HelpText<"Use the named plugin action instead of the default action (use \"help\" to list available options)">; +def plugin_arg : JoinedAndSeparate<["-"], "plugin-arg-">, + MetaVarName<" ">, + HelpText<"Pass to plugin ">; +def add_plugin : Separate<["-"], "add-plugin">, MetaVarName<"">, + HelpText<"Use the named plugin action in addition to the default action">; +def ast_dump_filter : Separate<["-"], "ast-dump-filter">, + MetaVarName<"">, + HelpText<"Use with -ast-dump or -ast-print to dump/print only AST declaration" + " nodes having a certain substring in a qualified name. Use" + " -ast-list to list all filterable declaration node names.">; +def fno_modules_global_index : Flag<["-"], "fno-modules-global-index">, + HelpText<"Do not automatically generate or update the global module index">; +def fno_modules_error_recovery : Flag<["-"], "fno-modules-error-recovery">, + HelpText<"Do not automatically import modules for error recovery">; +def fmodule_map_file_home_is_cwd : Flag<["-"], "fmodule-map-file-home-is-cwd">, + HelpText<"Use the current working directory as the home directory of " + "module maps specified by -fmodule-map-file=">; +def fmodule_feature : Separate<["-"], "fmodule-feature">, + MetaVarName<"">, + HelpText<"Enable in module map requires declarations">; +def fmodules_embed_file_EQ : Joined<["-"], "fmodules-embed-file=">, + MetaVarName<"">, + HelpText<"Embed the contents of the specified file into the module file " + "being compiled.">; +def fmodules_embed_all_files : Joined<["-"], "fmodules-embed-all-files">, + HelpText<"Embed the contents of all files read by this compilation into " + "the produced module file.">; +def fmodules_local_submodule_visibility : + Flag<["-"], "fmodules-local-submodule-visibility">, + HelpText<"Enforce name visibility rules across submodules of the same " + "top-level module.">; +def fmodules_codegen : + Flag<["-"], "fmodules-codegen">, + HelpText<"Generate code for uses of this module that assumes an explicit " + "object file will be built for the module">; +def fmodules_debuginfo : + Flag<["-"], "fmodules-debuginfo">, + HelpText<"Generate debug info for types in an object file built from this " + "module and do not generate them elsewhere">; +def fmodule_format_EQ : Joined<["-"], "fmodule-format=">, + HelpText<"Select the container format for clang modules and PCH. " + "Supported options are 'raw' and 'obj'.">; +def ftest_module_file_extension_EQ : + Joined<["-"], "ftest-module-file-extension=">, + HelpText<"introduce a module file extension for testing purposes. " + "The argument is parsed as blockname:major:minor:hashed:user info">; +def fconcepts_ts : Flag<["-"], "fconcepts-ts">, + HelpText<"Enable C++ Extensions for Concepts. (deprecated - use -std=c++2a)">; +def fno_concept_satisfaction_caching : Flag<["-"], + "fno-concept-satisfaction-caching">, + HelpText<"Disable satisfaction caching for C++2a Concepts.">; + +def frecovery_ast : Flag<["-"], "frecovery-ast">, + HelpText<"Preserve expressions in AST rather than dropping them when " + "encountering semantic errors">; +def fno_recovery_ast : Flag<["-"], "fno-recovery-ast">; +def frecovery_ast_type : Flag<["-"], "frecovery-ast-type">, + HelpText<"Preserve the type for recovery expressions when possible " + "(experimental)">; +def fno_recovery_ast_type : Flag<["-"], "fno-recovery-ast-type">; + +let Group = Action_Group in { + +def Eonly : Flag<["-"], "Eonly">, + HelpText<"Just run preprocessor, no output (for timings)">; +def dump_raw_tokens : Flag<["-"], "dump-raw-tokens">, + HelpText<"Lex file in raw mode and dump raw tokens">; +def analyze : Flag<["-"], "analyze">, + HelpText<"Run static analysis engine">; +def dump_tokens : Flag<["-"], "dump-tokens">, + HelpText<"Run preprocessor, dump internal rep of tokens">; +def init_only : Flag<["-"], "init-only">, + HelpText<"Only execute frontend initialization">; +def fixit : Flag<["-"], "fixit">, + HelpText<"Apply fix-it advice to the input source">; +def fixit_EQ : Joined<["-"], "fixit=">, + HelpText<"Apply fix-it advice creating a file with the given suffix">; +def print_preamble : Flag<["-"], "print-preamble">, + HelpText<"Print the \"preamble\" of a file, which is a candidate for implicit" + " precompiled headers.">; +def emit_html : Flag<["-"], "emit-html">, + HelpText<"Output input source as HTML">; +def ast_print : Flag<["-"], "ast-print">, + HelpText<"Build ASTs and then pretty-print them">; +def ast_list : Flag<["-"], "ast-list">, + HelpText<"Build ASTs and print the list of declaration node qualified names">; +def ast_dump : Flag<["-"], "ast-dump">, + HelpText<"Build ASTs and then debug dump them">; +def ast_dump_EQ : Joined<["-"], "ast-dump=">, + HelpText<"Build ASTs and then debug dump them in the specified format. " + "Supported formats include: default, json">; +def ast_dump_all : Flag<["-"], "ast-dump-all">, + HelpText<"Build ASTs and then debug dump them, forcing deserialization">; +def ast_dump_all_EQ : Joined<["-"], "ast-dump-all=">, + HelpText<"Build ASTs and then debug dump them in the specified format, " + "forcing deserialization. Supported formats include: default, json">; +def ast_dump_decl_types : Flag<["-"], "ast-dump-decl-types">, + HelpText<"Include declaration types in AST dumps">; +def templight_dump : Flag<["-"], "templight-dump">, + HelpText<"Dump templight information to stdout">; +def ast_dump_lookups : Flag<["-"], "ast-dump-lookups">, + HelpText<"Build ASTs and then debug dump their name lookup tables">; +def ast_view : Flag<["-"], "ast-view">, + HelpText<"Build ASTs and view them with GraphViz">; +def emit_module : Flag<["-"], "emit-module">, + HelpText<"Generate pre-compiled module file from a module map">; +def emit_module_interface : Flag<["-"], "emit-module-interface">, + HelpText<"Generate pre-compiled module file from a C++ module interface">; +def emit_header_module : Flag<["-"], "emit-header-module">, + HelpText<"Generate pre-compiled module file from a set of header files">; +def emit_pch : Flag<["-"], "emit-pch">, + HelpText<"Generate pre-compiled header file">; +def emit_llvm_bc : Flag<["-"], "emit-llvm-bc">, + HelpText<"Build ASTs then convert to LLVM, emit .bc file">; +def emit_llvm_only : Flag<["-"], "emit-llvm-only">, + HelpText<"Build ASTs and convert to LLVM, discarding output">; +def emit_codegen_only : Flag<["-"], "emit-codegen-only">, + HelpText<"Generate machine code, but discard output">; +def emit_obj : Flag<["-"], "emit-obj">, + HelpText<"Emit native object files">; +def rewrite_test : Flag<["-"], "rewrite-test">, + HelpText<"Rewriter playground">; +def rewrite_macros : Flag<["-"], "rewrite-macros">, + HelpText<"Expand macros without full preprocessing">; +def migrate : Flag<["-"], "migrate">, + HelpText<"Migrate source code">; +def compiler_options_dump : Flag<["-"], "compiler-options-dump">, + HelpText<"Dump the compiler configuration options">; +def print_dependency_directives_minimized_source : Flag<["-"], + "print-dependency-directives-minimized-source">, + HelpText<"Print the output of the dependency directives source minimizer">; +} + +def emit_llvm_uselists : Flag<["-"], "emit-llvm-uselists">, + HelpText<"Preserve order of LLVM use-lists when serializing">; +def no_emit_llvm_uselists : Flag<["-"], "no-emit-llvm-uselists">, + HelpText<"Don't preserve order of LLVM use-lists when serializing">; + +def mt_migrate_directory : Separate<["-"], "mt-migrate-directory">, + HelpText<"Directory for temporary files produced during ARC or ObjC migration">; +def arcmt_check : Flag<["-"], "arcmt-check">, + HelpText<"Check for ARC migration issues that need manual handling">; +def arcmt_modify : Flag<["-"], "arcmt-modify">, + HelpText<"Apply modifications to files to conform to ARC">; +def arcmt_migrate : Flag<["-"], "arcmt-migrate">, + HelpText<"Apply modifications and produces temporary files that conform to ARC">; + +def opt_record_file : Separate<["-"], "opt-record-file">, + HelpText<"File name to use for YAML optimization record output">; +def opt_record_passes : Separate<["-"], "opt-record-passes">, + HelpText<"Only record remark information for passes whose names match the given regular expression">; +def opt_record_format : Separate<["-"], "opt-record-format">, + HelpText<"The format used for serializing remarks (default: YAML)">; + +def print_stats : Flag<["-"], "print-stats">, + HelpText<"Print performance metrics and statistics">; +def stats_file : Joined<["-"], "stats-file=">, + HelpText<"Filename to write statistics to">; +def fdump_record_layouts : Flag<["-"], "fdump-record-layouts">, + HelpText<"Dump record layout information">; +def fdump_record_layouts_simple : Flag<["-"], "fdump-record-layouts-simple">, + HelpText<"Dump record layout information in a simple form used for testing">; +def fix_what_you_can : Flag<["-"], "fix-what-you-can">, + HelpText<"Apply fix-it advice even in the presence of unfixable errors">; +def fix_only_warnings : Flag<["-"], "fix-only-warnings">, + HelpText<"Apply fix-it advice only for warnings, not errors">; +def fixit_recompile : Flag<["-"], "fixit-recompile">, + HelpText<"Apply fix-it changes and recompile">; +def fixit_to_temp : Flag<["-"], "fixit-to-temporary">, + HelpText<"Apply fix-it changes to temporary files">; + +def foverride_record_layout_EQ : Joined<["-"], "foverride-record-layout=">, + HelpText<"Override record layouts with those in the given file">; +def pch_through_header_EQ : Joined<["-"], "pch-through-header=">, + HelpText<"Stop PCH generation after including this file. When using a PCH, " + "skip tokens until after this file is included.">; +def pch_through_hdrstop_create : Flag<["-"], "pch-through-hdrstop-create">, + HelpText<"When creating a PCH, stop PCH generation after #pragma hdrstop.">; +def pch_through_hdrstop_use : Flag<["-"], "pch-through-hdrstop-use">, + HelpText<"When using a PCH, skip tokens until after a #pragma hdrstop.">; +def fno_pch_timestamp : Flag<["-"], "fno-pch-timestamp">, + HelpText<"Disable inclusion of timestamp in precompiled headers">; +def building_pch_with_obj : Flag<["-"], "building-pch-with-obj">, + HelpText<"This compilation is part of building a PCH with corresponding object file.">; + +def aligned_alloc_unavailable : Flag<["-"], "faligned-alloc-unavailable">, + HelpText<"Aligned allocation/deallocation functions are unavailable">; + +//===----------------------------------------------------------------------===// +// Language Options +//===----------------------------------------------------------------------===// + +let Flags = [CC1Option, CC1AsOption, NoDriverOption] in { + +def version : Flag<["-"], "version">, + HelpText<"Print the compiler version">; +def main_file_name : Separate<["-"], "main-file-name">, + HelpText<"Main file name to use for debug info and source if missing">; +def split_dwarf_output : Separate<["-"], "split-dwarf-output">, + HelpText<"File name to use for split dwarf debug info output">; + +} + +def fblocks_runtime_optional : Flag<["-"], "fblocks-runtime-optional">, + HelpText<"Weakly link in the blocks runtime">; +def fexternc_nounwind : Flag<["-"], "fexternc-nounwind">, + HelpText<"Assume all functions with C linkage do not unwind">; +def split_dwarf_file : Separate<["-"], "split-dwarf-file">, + HelpText<"Name of the split dwarf debug info file to encode in the object file">; +def fno_wchar : Flag<["-"], "fno-wchar">, + HelpText<"Disable C++ builtin type wchar_t">; +def fconstant_string_class : Separate<["-"], "fconstant-string-class">, + MetaVarName<"">, + HelpText<"Specify the class to use for constant Objective-C string objects.">; +def fobjc_arc_cxxlib_EQ : Joined<["-"], "fobjc-arc-cxxlib=">, + HelpText<"Objective-C++ Automatic Reference Counting standard library kind">, Values<"libc++,libstdc++,none">; +def fobjc_runtime_has_weak : Flag<["-"], "fobjc-runtime-has-weak">, + HelpText<"The target Objective-C runtime supports ARC weak operations">; +def fobjc_dispatch_method_EQ : Joined<["-"], "fobjc-dispatch-method=">, + HelpText<"Objective-C dispatch method to use">, Values<"legacy,non-legacy,mixed">; +def disable_objc_default_synthesize_properties : Flag<["-"], "disable-objc-default-synthesize-properties">, + HelpText<"disable the default synthesis of Objective-C properties">; +def fencode_extended_block_signature : Flag<["-"], "fencode-extended-block-signature">, + HelpText<"enable extended encoding of block type signature">; +def function_alignment : Separate<["-"], "function-alignment">, + HelpText<"default alignment for functions">; +def pic_level : Separate<["-"], "pic-level">, + HelpText<"Value for __PIC__">; +def pic_is_pie : Flag<["-"], "pic-is-pie">, + HelpText<"File is for a position independent executable">; +def fno_validate_pch : Flag<["-"], "fno-validate-pch">, + HelpText<"Disable validation of precompiled headers">; +def fallow_pch_with_errors : Flag<["-"], "fallow-pch-with-compiler-errors">, + HelpText<"Accept a PCH file that was created with compiler errors">; +def dump_deserialized_pch_decls : Flag<["-"], "dump-deserialized-decls">, + HelpText<"Dump declarations that are deserialized from PCH, for testing">; +def error_on_deserialized_pch_decl : Separate<["-"], "error-on-deserialized-decl">, + HelpText<"Emit error if a specific declaration is deserialized from PCH, for testing">; +def error_on_deserialized_pch_decl_EQ : Joined<["-"], "error-on-deserialized-decl=">, + Alias; +def static_define : Flag<["-"], "static-define">, + HelpText<"Should __STATIC__ be defined">; +def stack_protector : Separate<["-"], "stack-protector">, + HelpText<"Enable stack protectors">; +def stack_protector_buffer_size : Separate<["-"], "stack-protector-buffer-size">, + HelpText<"Lower bound for a buffer to be considered for stack protection">; +def fvisibility : Separate<["-"], "fvisibility">, + HelpText<"Default type and symbol visibility">; +def ftype_visibility : Separate<["-"], "ftype-visibility">, + HelpText<"Default type visibility">; +def fapply_global_visibility_to_externs : Flag<["-"], "fapply-global-visibility-to-externs">, + HelpText<"Apply global symbol visibility to external declarations without an explicit visibility">; +def ftemplate_depth : Separate<["-"], "ftemplate-depth">, + HelpText<"Maximum depth of recursive template instantiation">; +def foperator_arrow_depth : Separate<["-"], "foperator-arrow-depth">, + HelpText<"Maximum number of 'operator->'s to call for a member access">; +def fconstexpr_depth : Separate<["-"], "fconstexpr-depth">, + HelpText<"Maximum depth of recursive constexpr function calls">; +def fconstexpr_steps : Separate<["-"], "fconstexpr-steps">, + HelpText<"Maximum number of steps in constexpr function evaluation">; +def fbracket_depth : Separate<["-"], "fbracket-depth">, + HelpText<"Maximum nesting level for parentheses, brackets, and braces">; +def fconst_strings : Flag<["-"], "fconst-strings">, + HelpText<"Use a const qualified type for string literals in C and ObjC">; +def fno_const_strings : Flag<["-"], "fno-const-strings">, + HelpText<"Don't use a const qualified type for string literals in C and ObjC">; +def fno_bitfield_type_align : Flag<["-"], "fno-bitfield-type-align">, + HelpText<"Ignore bit-field types when aligning structures">; +def ffake_address_space_map : Flag<["-"], "ffake-address-space-map">, + HelpText<"Use a fake address space map; OpenCL testing purposes only">; +def faddress_space_map_mangling_EQ : Joined<["-"], "faddress-space-map-mangling=">, MetaVarName<"">, + HelpText<"Set the mode for address space map based mangling; OpenCL testing purposes only">; +def funknown_anytype : Flag<["-"], "funknown-anytype">, + HelpText<"Enable parser support for the __unknown_anytype type; for testing purposes only">; +def fdebugger_support : Flag<["-"], "fdebugger-support">, + HelpText<"Enable special debugger support behavior">; +def fdebugger_cast_result_to_id : Flag<["-"], "fdebugger-cast-result-to-id">, + HelpText<"Enable casting unknown expression results to id">; +def fdebugger_objc_literal : Flag<["-"], "fdebugger-objc-literal">, + HelpText<"Enable special debugger support for Objective-C subscripting and literals">; +def fdeprecated_macro : Flag<["-"], "fdeprecated-macro">, + HelpText<"Defines the __DEPRECATED macro">; +def fno_deprecated_macro : Flag<["-"], "fno-deprecated-macro">, + HelpText<"Undefines the __DEPRECATED macro">; +def fobjc_subscripting_legacy_runtime : Flag<["-"], "fobjc-subscripting-legacy-runtime">, + HelpText<"Allow Objective-C array and dictionary subscripting in legacy runtime">; +def vtordisp_mode_EQ : Joined<["-"], "vtordisp-mode=">, + HelpText<"Control vtordisp placement on win32 targets">; +def fnative_half_type: Flag<["-"], "fnative-half-type">, + HelpText<"Use the native half type for __fp16 instead of promoting to float">; +def fnative_half_arguments_and_returns : Flag<["-"], "fnative-half-arguments-and-returns">, + HelpText<"Use the native __fp16 type for arguments and returns (and skip ABI-specific lowering)">; +def fallow_half_arguments_and_returns : Flag<["-"], "fallow-half-arguments-and-returns">, + HelpText<"Allow function arguments and returns of type half">; +def fdefault_calling_conv_EQ : Joined<["-"], "fdefault-calling-conv=">, + HelpText<"Set default calling convention">, Values<"cdecl,fastcall,stdcall,vectorcall,regcall">; +def finclude_default_header : Flag<["-"], "finclude-default-header">, + HelpText<"Include default header file for OpenCL">; +def fdeclare_opencl_builtins : Flag<["-"], "fdeclare-opencl-builtins">, + HelpText<"Add OpenCL builtin function declarations (experimental)">; +def fpreserve_vec3_type : Flag<["-"], "fpreserve-vec3-type">, + HelpText<"Preserve 3-component vector type">; +def fwchar_type_EQ : Joined<["-"], "fwchar-type=">, + HelpText<"Select underlying type for wchar_t">, Values<"char,short,int">; +def fsigned_wchar : Flag<["-"], "fsigned-wchar">, + HelpText<"Use a signed type for wchar_t">; +def fno_signed_wchar : Flag<["-"], "fno-signed-wchar">, + HelpText<"Use an unsigned type for wchar_t">; +def fcompatibility_qualified_id_block_param_type_checking : Flag<["-"], "fcompatibility-qualified-id-block-type-checking">, + HelpText<"Allow using blocks with parameters of more specific type than " + "the type system guarantees when a parameter is qualified id">; + +// FIXME: Remove these entirely once functionality/tests have been excised. +def fobjc_gc_only : Flag<["-"], "fobjc-gc-only">, Group, + HelpText<"Use GC exclusively for Objective-C related memory management">; +def fobjc_gc : Flag<["-"], "fobjc-gc">, Group, + HelpText<"Enable Objective-C garbage collection">; + +//===----------------------------------------------------------------------===// +// Header Search Options +//===----------------------------------------------------------------------===// + +def nostdsysteminc : Flag<["-"], "nostdsysteminc">, + HelpText<"Disable standard system #include directories">; +def fdisable_module_hash : Flag<["-"], "fdisable-module-hash">, + HelpText<"Disable the module hash">; +def fmodules_hash_content : Flag<["-"], "fmodules-hash-content">, + HelpText<"Enable hashing the content of a module file">; +def fmodules_strict_context_hash : Flag<["-"], "fmodules-strict-context-hash">, + HelpText<"Enable hashing of all compiler options that could impact the " + "semantics of a module in an implicit build">, + MarshallingInfoFlag<"HeaderSearchOpts->ModulesStrictContextHash", "false">; +def c_isystem : JoinedOrSeparate<["-"], "c-isystem">, MetaVarName<"">, + HelpText<"Add directory to the C SYSTEM include search path">; +def objc_isystem : JoinedOrSeparate<["-"], "objc-isystem">, + MetaVarName<"">, + HelpText<"Add directory to the ObjC SYSTEM include search path">; +def objcxx_isystem : JoinedOrSeparate<["-"], "objcxx-isystem">, + MetaVarName<"">, + HelpText<"Add directory to the ObjC++ SYSTEM include search path">; +def internal_isystem : JoinedOrSeparate<["-"], "internal-isystem">, + MetaVarName<"">, + HelpText<"Add directory to the internal system include search path; these " + "are assumed to not be user-provided and are used to model system " + "and standard headers' paths.">; +def internal_externc_isystem : JoinedOrSeparate<["-"], "internal-externc-isystem">, + MetaVarName<"">, + HelpText<"Add directory to the internal system include search path with " + "implicit extern \"C\" semantics; these are assumed to not be " + "user-provided and are used to model system and standard headers' " + "paths.">; + +//===----------------------------------------------------------------------===// +// Preprocessor Options +//===----------------------------------------------------------------------===// + +def chain_include : Separate<["-"], "chain-include">, MetaVarName<"">, + HelpText<"Include and chain a header file after turning it into PCH">; +def preamble_bytes_EQ : Joined<["-"], "preamble-bytes=">, + HelpText<"Assume that the precompiled header is a precompiled preamble " + "covering the first N bytes of the main file">; +def detailed_preprocessing_record : Flag<["-"], "detailed-preprocessing-record">, + HelpText<"include a detailed record of preprocessing actions">; +def setup_static_analyzer : Flag<["-"], "setup-static-analyzer">, + HelpText<"Set up preprocessor for static analyzer (done automatically when static analyzer is run).">; +def disable_pragma_debug_crash : Flag<["-"], "disable-pragma-debug-crash">, + HelpText<"Disable any #pragma clang __debug that can lead to crashing behavior. This is meant for testing.">; + +//===----------------------------------------------------------------------===// +// OpenCL Options +//===----------------------------------------------------------------------===// + +def cl_ext_EQ : CommaJoined<["-"], "cl-ext=">, + HelpText<"OpenCL only. Enable or disable OpenCL extensions. The argument is a comma-separated sequence of one or more extension names, each prefixed by '+' or '-'.">; + +//===----------------------------------------------------------------------===// +// CUDA Options +//===----------------------------------------------------------------------===// + +def fcuda_is_device : Flag<["-"], "fcuda-is-device">, + HelpText<"Generate code for CUDA device">; +def fcuda_include_gpubinary : Separate<["-"], "fcuda-include-gpubinary">, + HelpText<"Incorporate CUDA device-side binary into host object file.">; +def fcuda_allow_variadic_functions : Flag<["-"], "fcuda-allow-variadic-functions">, + HelpText<"Allow variadic functions in CUDA device code.">; +def fno_cuda_host_device_constexpr : Flag<["-"], "fno-cuda-host-device-constexpr">, + HelpText<"Don't treat unattributed constexpr functions as __host__ __device__.">; + +//===----------------------------------------------------------------------===// +// OpenMP Options +//===----------------------------------------------------------------------===// + +def fopenmp_is_device : Flag<["-"], "fopenmp-is-device">, + HelpText<"Generate code only for an OpenMP target device.">; +def fopenmp_host_ir_file_path : Separate<["-"], "fopenmp-host-ir-file-path">, + HelpText<"Path to the IR file produced by the frontend for the host.">; + +//===----------------------------------------------------------------------===// +// SYCL Options +//===----------------------------------------------------------------------===// + +def fsycl_is_device : Flag<["-"], "fsycl-is-device">, + HelpText<"Generate code for SYCL device.">; + +} // let Flags = [CC1Option] + +//===----------------------------------------------------------------------===// +// cc1as-only Options +//===----------------------------------------------------------------------===// + +let Flags = [CC1AsOption, NoDriverOption] in { + +// Language Options +def n : Flag<["-"], "n">, + HelpText<"Don't automatically start assembly file with a text section">; + +// Frontend Options +def filetype : Separate<["-"], "filetype">, + HelpText<"Specify the output file type ('asm', 'null', or 'obj')">; + +// Transliterate Options +def output_asm_variant : Separate<["-"], "output-asm-variant">, + HelpText<"Select the asm variant index to use for output">; +def show_encoding : Flag<["-"], "show-encoding">, + HelpText<"Show instruction encoding information in transliterate mode">; +def show_inst : Flag<["-"], "show-inst">, + HelpText<"Show internal instruction representation in transliterate mode">; + +// Assemble Options +def dwarf_debug_producer : Separate<["-"], "dwarf-debug-producer">, + HelpText<"The string to embed in the Dwarf debug AT_producer record.">; + +def defsym : Separate<["-"], "defsym">, + HelpText<"Define a value for a symbol">; + +} // let Flags = [CC1AsOption] + +//===----------------------------------------------------------------------===// +// clang-cl Options +//===----------------------------------------------------------------------===// + +def cl_Group : OptionGroup<"">, Flags<[CLOption]>, + HelpText<"CL.EXE COMPATIBILITY OPTIONS">; + +def cl_compile_Group : OptionGroup<"">, + Group; + +def cl_ignored_Group : OptionGroup<"">, + Group; + +class CLFlag : Option<["/", "-"], name, KIND_FLAG>, + Group, Flags<[CLOption, DriverOption]>; + +class CLCompileFlag : Option<["/", "-"], name, KIND_FLAG>, + Group, Flags<[CLOption, DriverOption]>; + +class CLIgnoredFlag : Option<["/", "-"], name, KIND_FLAG>, + Group, Flags<[CLOption, DriverOption]>; + +class CLJoined : Option<["/", "-"], name, KIND_JOINED>, + Group, Flags<[CLOption, DriverOption]>; + +class CLCompileJoined : Option<["/", "-"], name, KIND_JOINED>, + Group, Flags<[CLOption, DriverOption]>; + +class CLIgnoredJoined : Option<["/", "-"], name, KIND_JOINED>, + Group, Flags<[CLOption, DriverOption, HelpHidden]>; + +class CLJoinedOrSeparate : Option<["/", "-"], name, + KIND_JOINED_OR_SEPARATE>, Group, Flags<[CLOption, DriverOption]>; + +class CLCompileJoinedOrSeparate : Option<["/", "-"], name, + KIND_JOINED_OR_SEPARATE>, Group, + Flags<[CLOption, DriverOption]>; + +class CLRemainingArgsJoined : Option<["/", "-"], name, + KIND_REMAINING_ARGS_JOINED>, Group, Flags<[CLOption, DriverOption]>; + +// Aliases: +// (We don't put any of these in cl_compile_Group as the options they alias are +// already in the right group.) + +def _SLASH_Brepro : CLFlag<"Brepro">, + HelpText<"Do not write current time into COFF output (breaks link.exe /incremental)">, + Alias; +def _SLASH_Brepro_ : CLFlag<"Brepro-">, + HelpText<"Write current time into COFF output (default)">, + Alias; +def _SLASH_C : CLFlag<"C">, + HelpText<"Do not discard comments when preprocessing">, Alias; +def _SLASH_c : CLFlag<"c">, HelpText<"Compile only">, Alias; +def _SLASH_d1PP : CLFlag<"d1PP">, + HelpText<"Retain macro definitions in /E mode">, Alias
; +def _SLASH_d1reportAllClassLayout : CLFlag<"d1reportAllClassLayout">, + HelpText<"Dump record layout information">, + Alias, AliasArgs<["-fdump-record-layouts"]>; +def _SLASH_diagnostics_caret : CLFlag<"diagnostics:caret">, + HelpText<"Enable caret and column diagnostics (default)">; +def _SLASH_diagnostics_column : CLFlag<"diagnostics:column">, + HelpText<"Disable caret diagnostics but keep column info">; +def _SLASH_diagnostics_classic : CLFlag<"diagnostics:classic">, + HelpText<"Disable column and caret diagnostics">; +def _SLASH_D : CLJoinedOrSeparate<"D">, HelpText<"Define macro">, + MetaVarName<"">, Alias; +def _SLASH_E : CLFlag<"E">, HelpText<"Preprocess to stdout">, Alias; +def _SLASH_fp_except : CLFlag<"fp:except">, HelpText<"">, Alias; +def _SLASH_fp_except_ : CLFlag<"fp:except-">, + HelpText<"">, Alias; +def _SLASH_fp_fast : CLFlag<"fp:fast">, HelpText<"">, Alias; +def _SLASH_fp_precise : CLFlag<"fp:precise">, + HelpText<"">, Alias; +def _SLASH_fp_strict : CLFlag<"fp:strict">, HelpText<"">, Alias; +def _SLASH_GA : CLFlag<"GA">, Alias, AliasArgs<["local-exec"]>, + HelpText<"Assume thread-local variables are defined in the executable">; +def _SLASH_GR : CLFlag<"GR">, HelpText<"Emit RTTI data (default)">; +def _SLASH_GR_ : CLFlag<"GR-">, HelpText<"Do not emit RTTI data">; +def _SLASH_GF : CLIgnoredFlag<"GF">, + HelpText<"Enable string pooling (default)">; +def _SLASH_GF_ : CLFlag<"GF-">, HelpText<"Disable string pooling">, + Alias; +def _SLASH_GS : CLFlag<"GS">, + HelpText<"Enable buffer security check (default)">; +def _SLASH_GS_ : CLFlag<"GS-">, HelpText<"Disable buffer security check">; +def : CLFlag<"Gs">, HelpText<"Use stack probes (default)">, + Alias, AliasArgs<["4096"]>; +def _SLASH_Gs : CLJoined<"Gs">, + HelpText<"Set stack probe size (default 4096)">, Alias; +def _SLASH_Gy : CLFlag<"Gy">, HelpText<"Put each function in its own section">, + Alias; +def _SLASH_Gy_ : CLFlag<"Gy-">, + HelpText<"Do not put each function in its own section (default)">, + Alias; +def _SLASH_Gw : CLFlag<"Gw">, HelpText<"Put each data item in its own section">, + Alias; +def _SLASH_Gw_ : CLFlag<"Gw-">, + HelpText<"Do not put each data item in its own section (default)">, + Alias; +def _SLASH_help : CLFlag<"help">, Alias, + HelpText<"Display available options">; +def _SLASH_HELP : CLFlag<"HELP">, Alias; +def _SLASH_I : CLJoinedOrSeparate<"I">, + HelpText<"Add directory to include search path">, MetaVarName<"">, + Alias; +def _SLASH_J : CLFlag<"J">, HelpText<"Make char type unsigned">, + Alias; + +// The _SLASH_O option handles all the /O flags, but we also provide separate +// aliased options to provide separate help messages. +def _SLASH_O : CLJoined<"O">, + HelpText<"Set multiple /O flags at once; e.g. '/O2y-' for '/O2 /Oy-'">, + MetaVarName<"">; +def : CLFlag<"O1">, Alias<_SLASH_O>, AliasArgs<["1"]>, + HelpText<"Optimize for size (like /Og /Os /Oy /Ob2 /GF /Gy)">; +def : CLFlag<"O2">, Alias<_SLASH_O>, AliasArgs<["2"]>, + HelpText<"Optimize for speed (like /Og /Oi /Ot /Oy /Ob2 /GF /Gy)">; +def : CLFlag<"Ob0">, Alias<_SLASH_O>, AliasArgs<["b0"]>, + HelpText<"Disable function inlining">; +def : CLFlag<"Ob1">, Alias<_SLASH_O>, AliasArgs<["b1"]>, + HelpText<"Only inline functions explicitly or implicitly marked inline">; +def : CLFlag<"Ob2">, Alias<_SLASH_O>, AliasArgs<["b2"]>, + HelpText<"Inline functions as deemed beneficial by the compiler">; +def : CLFlag<"Od">, Alias<_SLASH_O>, AliasArgs<["d"]>, + HelpText<"Disable optimization">; +def : CLFlag<"Og">, Alias<_SLASH_O>, AliasArgs<["g"]>, + HelpText<"No effect">; +def : CLFlag<"Oi">, Alias<_SLASH_O>, AliasArgs<["i"]>, + HelpText<"Enable use of builtin functions">; +def : CLFlag<"Oi-">, Alias<_SLASH_O>, AliasArgs<["i-"]>, + HelpText<"Disable use of builtin functions">; +def : CLFlag<"Os">, Alias<_SLASH_O>, AliasArgs<["s"]>, + HelpText<"Optimize for size">; +def : CLFlag<"Ot">, Alias<_SLASH_O>, AliasArgs<["t"]>, + HelpText<"Optimize for speed">; +def : CLFlag<"Ox">, Alias<_SLASH_O>, AliasArgs<["x"]>, + HelpText<"Deprecated (like /Og /Oi /Ot /Oy /Ob2); use /O2">; +def : CLFlag<"Oy">, Alias<_SLASH_O>, AliasArgs<["y"]>, + HelpText<"Enable frame pointer omission (x86 only)">; +def : CLFlag<"Oy-">, Alias<_SLASH_O>, AliasArgs<["y-"]>, + HelpText<"Disable frame pointer omission (x86 only, default)">; + +def _SLASH_QUESTION : CLFlag<"?">, Alias, + HelpText<"Display available options">; +def _SLASH_Qvec : CLFlag<"Qvec">, + HelpText<"Enable the loop vectorization passes">, Alias; +def _SLASH_Qvec_ : CLFlag<"Qvec-">, + HelpText<"Disable the loop vectorization passes">, Alias; +def _SLASH_showIncludes : CLFlag<"showIncludes">, + HelpText<"Print info about included files to stderr">; +def _SLASH_showIncludes_user : CLFlag<"showIncludes:user">, + HelpText<"Like /showIncludes but omit system headers">; +def _SLASH_showFilenames : CLFlag<"showFilenames">, + HelpText<"Print the name of each compiled file">; +def _SLASH_showFilenames_ : CLFlag<"showFilenames-">, + HelpText<"Do not print the name of each compiled file (default)">; +def _SLASH_source_charset : CLCompileJoined<"source-charset:">, + HelpText<"Set source encoding, supports only UTF-8">, + Alias; +def _SLASH_execution_charset : CLCompileJoined<"execution-charset:">, + HelpText<"Set runtime encoding, supports only UTF-8">, + Alias; +def _SLASH_std : CLCompileJoined<"std:">, + HelpText<"Set C++ version (c++14,c++17,c++latest)">; +def _SLASH_U : CLJoinedOrSeparate<"U">, HelpText<"Undefine macro">, + MetaVarName<"">, Alias; +def _SLASH_validate_charset : CLFlag<"validate-charset">, + Alias, AliasArgs<["invalid-source-encoding"]>; +def _SLASH_validate_charset_ : CLFlag<"validate-charset-">, + Alias, AliasArgs<["no-invalid-source-encoding"]>; +def _SLASH_W0 : CLFlag<"W0">, HelpText<"Disable all warnings">, Alias; +def _SLASH_W1 : CLFlag<"W1">, HelpText<"Enable -Wall">, Alias; +def _SLASH_W2 : CLFlag<"W2">, HelpText<"Enable -Wall">, Alias; +def _SLASH_W3 : CLFlag<"W3">, HelpText<"Enable -Wall">, Alias; +def _SLASH_W4 : CLFlag<"W4">, HelpText<"Enable -Wall and -Wextra">, Alias; +def _SLASH_Wall : CLFlag<"Wall">, HelpText<"Enable -Weverything">, + Alias, AliasArgs<["everything"]>; +def _SLASH_WX : CLFlag<"WX">, HelpText<"Treat warnings as errors">, + Alias, AliasArgs<["error"]>; +def _SLASH_WX_ : CLFlag<"WX-">, + HelpText<"Do not treat warnings as errors (default)">, + Alias, AliasArgs<["no-error"]>; +def _SLASH_w_flag : CLFlag<"w">, HelpText<"Disable all warnings">, Alias; +def _SLASH_wd4005 : CLFlag<"wd4005">, Alias, + AliasArgs<["no-macro-redefined"]>; +def _SLASH_wd4018 : CLFlag<"wd4018">, Alias, + AliasArgs<["no-sign-compare"]>; +def _SLASH_wd4100 : CLFlag<"wd4100">, Alias, + AliasArgs<["no-unused-parameter"]>; +def _SLASH_wd4910 : CLFlag<"wd4910">, Alias, + AliasArgs<["no-dllexport-explicit-instantiation-decl"]>; +def _SLASH_wd4996 : CLFlag<"wd4996">, Alias, + AliasArgs<["no-deprecated-declarations"]>; +def _SLASH_vd : CLJoined<"vd">, HelpText<"Control vtordisp placement">, + Alias; +def _SLASH_X : CLFlag<"X">, + HelpText<"Do not add %INCLUDE% to include search path">, Alias; +def _SLASH_Zc_sizedDealloc : CLFlag<"Zc:sizedDealloc">, + HelpText<"Enable C++14 sized global deallocation functions">, + Alias; +def _SLASH_Zc_sizedDealloc_ : CLFlag<"Zc:sizedDealloc-">, + HelpText<"Disable C++14 sized global deallocation functions">, + Alias; +def _SLASH_Zc_alignedNew : CLFlag<"Zc:alignedNew">, + HelpText<"Enable C++17 aligned allocation functions">, + Alias; +def _SLASH_Zc_alignedNew_ : CLFlag<"Zc:alignedNew-">, + HelpText<"Disable C++17 aligned allocation functions">, + Alias; +def _SLASH_Zc_char8_t : CLFlag<"Zc:char8_t">, + HelpText<"Enable char8_t from C++2a">, + Alias; +def _SLASH_Zc_char8_t_ : CLFlag<"Zc:char8_t-">, + HelpText<"Disable char8_t from c++2a">, + Alias; +def _SLASH_Zc_strictStrings : CLFlag<"Zc:strictStrings">, + HelpText<"Treat string literals as const">, Alias, + AliasArgs<["error=c++11-compat-deprecated-writable-strings"]>; +def _SLASH_Zc_threadSafeInit : CLFlag<"Zc:threadSafeInit">, + HelpText<"Enable thread-safe initialization of static variables">, + Alias; +def _SLASH_Zc_threadSafeInit_ : CLFlag<"Zc:threadSafeInit-">, + HelpText<"Disable thread-safe initialization of static variables">, + Alias; +def _SLASH_Zc_trigraphs : CLFlag<"Zc:trigraphs">, + HelpText<"Enable trigraphs">, Alias; +def _SLASH_Zc_trigraphs_off : CLFlag<"Zc:trigraphs-">, + HelpText<"Disable trigraphs (default)">, Alias; +def _SLASH_Zc_twoPhase : CLFlag<"Zc:twoPhase">, + HelpText<"Enable two-phase name lookup in templates">, + Alias; +def _SLASH_Zc_twoPhase_ : CLFlag<"Zc:twoPhase-">, + HelpText<"Disable two-phase name lookup in templates (default)">, + Alias; +def _SLASH_Z7 : CLFlag<"Z7">, + HelpText<"Enable CodeView debug information in object files">; +def _SLASH_Zd : CLFlag<"Zd">, + HelpText<"Emit debug line number tables only">; +def _SLASH_Zi : CLFlag<"Zi">, Alias<_SLASH_Z7>, + HelpText<"Like /Z7">; +def _SLASH_Zp : CLJoined<"Zp">, + HelpText<"Set default maximum struct packing alignment">, + Alias; +def _SLASH_Zp_flag : CLFlag<"Zp">, + HelpText<"Set default maximum struct packing alignment to 1">, + Alias, AliasArgs<["1"]>; +def _SLASH_Zs : CLFlag<"Zs">, HelpText<"Syntax-check only">, + Alias; +def _SLASH_openmp_ : CLFlag<"openmp-">, + HelpText<"Disable OpenMP support">, Alias; +def _SLASH_openmp : CLFlag<"openmp">, HelpText<"Enable OpenMP support">, + Alias; +def _SLASH_openmp_experimental : CLFlag<"openmp:experimental">, + HelpText<"Enable OpenMP support with experimental SIMD support">, + Alias; + +// Non-aliases: + +def _SLASH_arch : CLCompileJoined<"arch:">, + HelpText<"Set architecture for code generation">; + +def _SLASH_M_Group : OptionGroup<"">, Group; +def _SLASH_volatile_Group : OptionGroup<"">, + Group; + +def _SLASH_EH : CLJoined<"EH">, HelpText<"Set exception handling model">; +def _SLASH_EP : CLFlag<"EP">, + HelpText<"Disable linemarker output and preprocess to stdout">; +def _SLASH_FA : CLFlag<"FA">, + HelpText<"Output assembly code file during compilation">; +def _SLASH_Fa : CLJoined<"Fa">, + HelpText<"Set assembly output file name (with /FA)">, + MetaVarName<"">; +def _SLASH_fallback : CLCompileFlag<"fallback">, + HelpText<"Fall back to cl.exe if clang-cl fails to compile">; +def _SLASH_FI : CLJoinedOrSeparate<"FI">, + HelpText<"Include file before parsing">, Alias; +def _SLASH_Fe : CLJoined<"Fe">, + HelpText<"Set output executable file name">, + MetaVarName<"">; +def _SLASH_Fi : CLCompileJoined<"Fi">, + HelpText<"Set preprocess output file name (with /P)">, + MetaVarName<"">; +def _SLASH_Fo : CLCompileJoined<"Fo">, + HelpText<"Set output object file (with /c)">, + MetaVarName<"">; +def _SLASH_guard : CLJoined<"guard:">, + HelpText<"Enable Control Flow Guard with /guard:cf, or only the table with /guard:cf,nochecks">; +def _SLASH_GX : CLFlag<"GX">, + HelpText<"Deprecated; use /EHsc">; +def _SLASH_GX_ : CLFlag<"GX-">, + HelpText<"Deprecated (like not passing /EH)">; +def _SLASH_imsvc : CLJoinedOrSeparate<"imsvc">, + HelpText<"Add to system include search path, as if in %INCLUDE%">, + MetaVarName<"">; +def _SLASH_LD : CLFlag<"LD">, HelpText<"Create DLL">; +def _SLASH_LDd : CLFlag<"LDd">, HelpText<"Create debug DLL">; +def _SLASH_link : CLRemainingArgsJoined<"link">, + HelpText<"Forward options to the linker">, MetaVarName<"">; +def _SLASH_MD : Option<["/", "-"], "MD", KIND_FLAG>, Group<_SLASH_M_Group>, + Flags<[CLOption, DriverOption]>, HelpText<"Use DLL run-time">; +def _SLASH_MDd : Option<["/", "-"], "MDd", KIND_FLAG>, Group<_SLASH_M_Group>, + Flags<[CLOption, DriverOption]>, HelpText<"Use DLL debug run-time">; +def _SLASH_MT : Option<["/", "-"], "MT", KIND_FLAG>, Group<_SLASH_M_Group>, + Flags<[CLOption, DriverOption]>, HelpText<"Use static run-time">; +def _SLASH_MTd : Option<["/", "-"], "MTd", KIND_FLAG>, Group<_SLASH_M_Group>, + Flags<[CLOption, DriverOption]>, HelpText<"Use static debug run-time">; +def _SLASH_o : CLJoinedOrSeparate<"o">, + HelpText<"Deprecated (set output file name); use /Fe or /Fe">, + MetaVarName<"">; +def _SLASH_P : CLFlag<"P">, HelpText<"Preprocess to file">; +def _SLASH_Tc : CLCompileJoinedOrSeparate<"Tc">, + HelpText<"Treat as C source file">, MetaVarName<"">; +def _SLASH_TC : CLCompileFlag<"TC">, HelpText<"Treat all source files as C">; +def _SLASH_Tp : CLCompileJoinedOrSeparate<"Tp">, + HelpText<"Treat as C++ source file">, MetaVarName<"">; +def _SLASH_TP : CLCompileFlag<"TP">, HelpText<"Treat all source files as C++">; +def _SLASH_volatile_iso : Option<["/", "-"], "volatile:iso", KIND_FLAG>, + Group<_SLASH_volatile_Group>, Flags<[CLOption, DriverOption]>, + HelpText<"Volatile loads and stores have standard semantics">; +def _SLASH_vmb : CLFlag<"vmb">, + HelpText<"Use a best-case representation method for member pointers">; +def _SLASH_vmg : CLFlag<"vmg">, + HelpText<"Use a most-general representation for member pointers">; +def _SLASH_vms : CLFlag<"vms">, + HelpText<"Set the default most-general representation to single inheritance">; +def _SLASH_vmm : CLFlag<"vmm">, + HelpText<"Set the default most-general representation to " + "multiple inheritance">; +def _SLASH_vmv : CLFlag<"vmv">, + HelpText<"Set the default most-general representation to " + "virtual inheritance">; +def _SLASH_volatile_ms : Option<["/", "-"], "volatile:ms", KIND_FLAG>, + Group<_SLASH_volatile_Group>, Flags<[CLOption, DriverOption]>, + HelpText<"Volatile loads and stores have acquire and release semantics">; +def _SLASH_clang : CLJoined<"clang:">, + HelpText<"Pass to the clang driver">, MetaVarName<"">; +def _SLASH_Zl : CLFlag<"Zl">, + HelpText<"Do not let object file auto-link default libraries">; + +def _SLASH_Yc : CLJoined<"Yc">, + HelpText<"Generate a pch file for all code up to and including ">, + MetaVarName<"">; +def _SLASH_Yu : CLJoined<"Yu">, + HelpText<"Load a pch file and use it instead of all code up to " + "and including ">, + MetaVarName<"">; +def _SLASH_Y_ : CLFlag<"Y-">, + HelpText<"Disable precompiled headers, overrides /Yc and /Yu">; +def _SLASH_Zc_dllexportInlines : CLFlag<"Zc:dllexportInlines">, + HelpText<"dllexport/dllimport inline member functions of dllexport/import classes (default)">; +def _SLASH_Zc_dllexportInlines_ : CLFlag<"Zc:dllexportInlines-">, + HelpText<"Do not dllexport/dllimport inline member functions of dllexport/import classes">; +def _SLASH_Fp : CLJoined<"Fp">, + HelpText<"Set pch file name (with /Yc and /Yu)">, MetaVarName<"">; + +def _SLASH_Gd : CLFlag<"Gd">, + HelpText<"Set __cdecl as a default calling convention">; +def _SLASH_Gr : CLFlag<"Gr">, + HelpText<"Set __fastcall as a default calling convention">; +def _SLASH_Gz : CLFlag<"Gz">, + HelpText<"Set __stdcall as a default calling convention">; +def _SLASH_Gv : CLFlag<"Gv">, + HelpText<"Set __vectorcall as a default calling convention">; +def _SLASH_Gregcall : CLFlag<"Gregcall">, + HelpText<"Set __regcall as a default calling convention">; + +// Ignored: + +def _SLASH_analyze_ : CLIgnoredFlag<"analyze-">; +def _SLASH_bigobj : CLIgnoredFlag<"bigobj">; +def _SLASH_cgthreads : CLIgnoredJoined<"cgthreads">; +def _SLASH_d2FastFail : CLIgnoredFlag<"d2FastFail">; +def _SLASH_d2Zi_PLUS : CLIgnoredFlag<"d2Zi+">; +def _SLASH_errorReport : CLIgnoredJoined<"errorReport">; +def _SLASH_FC : CLIgnoredFlag<"FC">; +def _SLASH_Fd : CLIgnoredJoined<"Fd">; +def _SLASH_FS : CLIgnoredFlag<"FS">; +def _SLASH_JMC : CLIgnoredFlag<"JMC">; +def _SLASH_kernel_ : CLIgnoredFlag<"kernel-">; +def _SLASH_nologo : CLIgnoredFlag<"nologo">; +def _SLASH_permissive_ : CLIgnoredFlag<"permissive-">; +def _SLASH_RTC : CLIgnoredJoined<"RTC">; +def _SLASH_sdl : CLIgnoredFlag<"sdl">; +def _SLASH_sdl_ : CLIgnoredFlag<"sdl-">; +def _SLASH_utf8 : CLIgnoredFlag<"utf-8">, + HelpText<"Set source and runtime encoding to UTF-8 (default)">; +def _SLASH_w : CLIgnoredJoined<"w">; +def _SLASH_Zc___cplusplus : CLIgnoredFlag<"Zc:__cplusplus">; +def _SLASH_Zc_auto : CLIgnoredFlag<"Zc:auto">; +def _SLASH_Zc_forScope : CLIgnoredFlag<"Zc:forScope">; +def _SLASH_Zc_inline : CLIgnoredFlag<"Zc:inline">; +def _SLASH_Zc_rvalueCast : CLIgnoredFlag<"Zc:rvalueCast">; +def _SLASH_Zc_ternary : CLIgnoredFlag<"Zc:ternary">; +def _SLASH_Zc_wchar_t : CLIgnoredFlag<"Zc:wchar_t">; +def _SLASH_ZH_MD5 : CLIgnoredFlag<"ZH:MD5">; +def _SLASH_ZH_SHA1 : CLIgnoredFlag<"ZH:SHA1">; +def _SLASH_ZH_SHA_256 : CLIgnoredFlag<"ZH:SHA_256">; +def _SLASH_Zm : CLIgnoredJoined<"Zm">; +def _SLASH_Zo : CLIgnoredFlag<"Zo">; +def _SLASH_Zo_ : CLIgnoredFlag<"Zo-">; + + +// Unsupported: + +def _SLASH_await : CLFlag<"await">; +def _SLASH_constexpr : CLJoined<"constexpr:">; +def _SLASH_AI : CLJoinedOrSeparate<"AI">; +def _SLASH_Bt : CLFlag<"Bt">; +def _SLASH_Bt_plus : CLFlag<"Bt+">; +def _SLASH_clr : CLJoined<"clr">; +def _SLASH_d2 : CLJoined<"d2">; +def _SLASH_doc : CLJoined<"doc">; +def _SLASH_FA_joined : CLJoined<"FA">; +def _SLASH_favor : CLJoined<"favor">; +def _SLASH_F : CLJoinedOrSeparate<"F">; +def _SLASH_Fm : CLJoined<"Fm">; +def _SLASH_Fr : CLJoined<"Fr">; +def _SLASH_FR : CLJoined<"FR">; +def _SLASH_FU : CLJoinedOrSeparate<"FU">; +def _SLASH_Fx : CLFlag<"Fx">; +def _SLASH_G1 : CLFlag<"G1">; +def _SLASH_G2 : CLFlag<"G2">; +def _SLASH_Ge : CLFlag<"Ge">; +def _SLASH_Gh : CLFlag<"Gh">; +def _SLASH_GH : CLFlag<"GH">; +def _SLASH_GL : CLFlag<"GL">; +def _SLASH_GL_ : CLFlag<"GL-">; +def _SLASH_Gm : CLFlag<"Gm">; +def _SLASH_Gm_ : CLFlag<"Gm-">; +def _SLASH_GT : CLFlag<"GT">; +def _SLASH_GZ : CLFlag<"GZ">; +def _SLASH_H : CLFlag<"H">; +def _SLASH_homeparams : CLFlag<"homeparams">; +def _SLASH_hotpatch : CLFlag<"hotpatch">; +def _SLASH_kernel : CLFlag<"kernel">; +def _SLASH_LN : CLFlag<"LN">; +def _SLASH_MP : CLJoined<"MP">; +def _SLASH_Qfast_transcendentals : CLFlag<"Qfast_transcendentals">; +def _SLASH_QIfist : CLFlag<"QIfist">; +def _SLASH_QIntel_jcc_erratum : CLFlag<"QIntel-jcc-erratum">; +def _SLASH_Qimprecise_fwaits : CLFlag<"Qimprecise_fwaits">; +def _SLASH_Qpar : CLFlag<"Qpar">; +def _SLASH_Qpar_report : CLJoined<"Qpar-report">; +def _SLASH_Qsafe_fp_loads : CLFlag<"Qsafe_fp_loads">; +def _SLASH_Qspectre : CLFlag<"Qspectre">; +def _SLASH_Qspectre_load : CLFlag<"Qspectre-load">; +def _SLASH_Qspectre_load_cf : CLFlag<"Qspectre-load-cf">; +def _SLASH_Qvec_report : CLJoined<"Qvec-report">; +def _SLASH_u : CLFlag<"u">; +def _SLASH_V : CLFlag<"V">; +def _SLASH_WL : CLFlag<"WL">; +def _SLASH_Wp64 : CLFlag<"Wp64">; +def _SLASH_Yd : CLFlag<"Yd">; +def _SLASH_Yl : CLJoined<"Yl">; +def _SLASH_Za : CLFlag<"Za">; +def _SLASH_Zc : CLJoined<"Zc:">; +def _SLASH_Ze : CLFlag<"Ze">; +def _SLASH_Zg : CLFlag<"Zg">; +def _SLASH_ZI : CLFlag<"ZI">; +def _SLASH_ZW : CLJoined<"ZW">; diff --git a/clang/include/clang/Driver/Tool.h b/clang/include/clang/Driver/Tool.h index 8d04916069785..cc0a09fb27472 100644 --- a/clang/include/clang/Driver/Tool.h +++ b/clang/include/clang/Driver/Tool.h @@ -10,7 +10,6 @@ #define LLVM_CLANG_DRIVER_TOOL_H #include "clang/Basic/LLVM.h" -#include "llvm/Support/Program.h" namespace llvm { namespace opt { @@ -31,24 +30,6 @@ namespace driver { /// Tool - Information on a specific compilation tool. class Tool { -public: - // Documents the level of support for response files in this tool. - // Response files are necessary if the command line gets too large, - // requiring the arguments to be transferred to a file. - enum ResponseFileSupport { - // Provides full support for response files, which means we can transfer - // all tool input arguments to a file. E.g.: clang, gcc, binutils and MSVC - // tools. - RF_Full, - // Input file names can live in a file, but flags can't. E.g.: ld64 (Mac - // OS X linker). - RF_FileList, - // Does not support response files: all arguments must be passed via - // command line. - RF_None - }; - -private: /// The tool name (for debugging). const char *Name; @@ -58,20 +39,8 @@ class Tool { /// The tool chain this tool is a part of. const ToolChain &TheToolChain; - /// The level of support for response files seen in this tool - const ResponseFileSupport ResponseSupport; - - /// The encoding to use when writing response files for this tool on Windows - const llvm::sys::WindowsEncodingMethod ResponseEncoding; - - /// The flag used to pass a response file via command line to this tool - const char *const ResponseFlag; - public: - Tool(const char *Name, const char *ShortName, const ToolChain &TC, - ResponseFileSupport ResponseSupport = RF_None, - llvm::sys::WindowsEncodingMethod ResponseEncoding = llvm::sys::WEM_UTF8, - const char *ResponseFlag = "@"); + Tool(const char *Name, const char *ShortName, const ToolChain &TC); public: virtual ~Tool(); @@ -87,29 +56,6 @@ class Tool { virtual bool hasIntegratedCPP() const = 0; virtual bool isLinkJob() const { return false; } virtual bool isDsymutilJob() const { return false; } - /// Returns the level of support for response files of this tool, - /// whether it accepts arguments to be passed via a file on disk. - ResponseFileSupport getResponseFilesSupport() const { - return ResponseSupport; - } - /// Returns which encoding the response file should use. This is only - /// relevant on Windows platforms where there are different encodings being - /// accepted for different tools. On UNIX, UTF8 is universal. - /// - /// Windows use cases: - GCC and Binutils on mingw only accept ANSI response - /// files encoded with the system current code page. - /// - MSVC's CL.exe and LINK.exe accept UTF16 on Windows. - /// - Clang accepts both UTF8 and UTF16. - /// - /// FIXME: When GNU tools learn how to parse UTF16 on Windows, we should - /// always use UTF16 for Windows, which is the Windows official encoding for - /// international characters. - llvm::sys::WindowsEncodingMethod getResponseFileEncoding() const { - return ResponseEncoding; - } - /// Returns which prefix to use when passing the name of a response - /// file as a parameter to this tool. - const char *getResponseFileFlag() const { return ResponseFlag; } /// Does this tool have "good" standardized diagnostics, or should the /// driver add an additional "command failed" diagnostic on failures. diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index f33ed991f493d..7495e08fe6e64 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -139,6 +139,7 @@ class ToolChain { mutable std::unique_ptr Flang; mutable std::unique_ptr Assemble; mutable std::unique_ptr Link; + mutable std::unique_ptr StaticLibTool; mutable std::unique_ptr IfsMerge; mutable std::unique_ptr OffloadBundler; mutable std::unique_ptr OffloadWrapper; @@ -147,6 +148,7 @@ class ToolChain { Tool *getFlang() const; Tool *getAssemble() const; Tool *getLink() const; + Tool *getStaticLibTool() const; Tool *getIfsMerge() const; Tool *getClangAs() const; Tool *getOffloadBundler() const; @@ -174,6 +176,7 @@ class ToolChain { virtual Tool *buildAssembler() const; virtual Tool *buildLinker() const; + virtual Tool *buildStaticLibTool() const; virtual Tool *getTool(Action::ActionClass AC) const; /// \name Utilities for implementing subclasses. @@ -326,6 +329,9 @@ class ToolChain { /// the linker suffix or name. std::string GetLinkerPath() const; + /// Returns the linker path for emitting a static library. + std::string GetStaticLibToolPath() const; + /// Dispatch to the specific toolchain for verbose printing. /// /// This is used when handling the verbose option to print detailed, diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 96b73211d9fff..3549ec9eee0e5 100755 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -1425,6 +1425,17 @@ struct FormatStyle { /// For example: TESTSUITE std::vector NamespaceMacros; + /// A vector of macros which are whitespace-sensitive and shouldn't be + /// touched. + /// + /// These are expected to be macros of the form: + /// \code + /// STRINGIZE(...) + /// \endcode + /// + /// For example: STRINGIZE + std::vector WhitespaceSensitiveMacros; + tooling::IncludeStyle IncludeStyle; /// Indent case labels one level from the switch statement. diff --git a/clang/include/clang/Frontend/ASTConsumers.h b/clang/include/clang/Frontend/ASTConsumers.h index af8c4a517dcde..98cfc7cadc0dd 100644 --- a/clang/include/clang/Frontend/ASTConsumers.h +++ b/clang/include/clang/Frontend/ASTConsumers.h @@ -39,7 +39,7 @@ std::unique_ptr CreateASTPrinter(std::unique_ptr OS, std::unique_ptr CreateASTDumper(std::unique_ptr OS, StringRef FilterString, bool DumpDecls, bool Deserialize, bool DumpLookups, - ASTDumpOutputFormat Format); + bool DumpDeclTypes, ASTDumpOutputFormat Format); // AST Decl node lister: prints qualified names of all filterable AST Decl // nodes. diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h index ba9bd439c4a39..cb935becaef19 100644 --- a/clang/include/clang/Frontend/CompilerInstance.h +++ b/clang/include/clang/Frontend/CompilerInstance.h @@ -764,10 +764,7 @@ class CompilerInstance : public ModuleLoader { static bool InitializeSourceManager(const FrontendInputFile &Input, DiagnosticsEngine &Diags, FileManager &FileMgr, - SourceManager &SourceMgr, - HeaderSearch *HS, - DependencyOutputOptions &DepOpts, - const FrontendOptions &Opts); + SourceManager &SourceMgr); /// } diff --git a/clang/include/clang/Frontend/CompilerInvocation.h b/clang/include/clang/Frontend/CompilerInvocation.h index e63408da8f5ee..c723fc084c854 100644 --- a/clang/include/clang/Frontend/CompilerInvocation.h +++ b/clang/include/clang/Frontend/CompilerInvocation.h @@ -153,6 +153,8 @@ class CompilerInvocation : public CompilerInvocationBase { /// one of the vaild-to-access (albeit arbitrary) states. /// /// \param [out] Res - The resulting invocation. + /// \param [in] CommandLineArgs - Array of argument strings, this must not + /// contain "-cc1". static bool CreateFromArgs(CompilerInvocation &Res, ArrayRef CommandLineArgs, DiagnosticsEngine &Diags, @@ -184,6 +186,18 @@ class CompilerInvocation : public CompilerInvocationBase { /// identifying the conditions under which the module was built. std::string getModuleHash() const; + using StringAllocator = llvm::function_ref; + /// Generate a cc1-compatible command line arguments from this instance. + /// + /// \param [out] Args - The generated arguments. Note that the caller is + /// responsible for inserting the path to the clang executable and "-cc1" if + /// desired. + /// \param SA - A function that given a Twine can allocate storage for a given + /// command line argument and return a pointer to the newly allocated string. + /// The returned pointer is what gets appended to Args. + void generateCC1CommandLine(llvm::SmallVectorImpl &Args, + StringAllocator SA) const; + /// @} /// @name Option Subgroups /// @{ @@ -222,6 +236,16 @@ class CompilerInvocation : public CompilerInvocationBase { } /// @} + +private: + /// Parse options for flags that expose marshalling information in their + /// table-gen definition + /// + /// \param Args - The argument list containing the arguments to parse + /// \param Diags - The DiagnosticsEngine associated with CreateFromArgs + /// \returns - True if parsing was successful, false otherwise + bool parseSimpleArgs(const llvm::opt::ArgList &Args, + DiagnosticsEngine &Diags); }; IntrusiveRefCntPtr diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h index 6069b5eea2650..b2be33032c08d 100644 --- a/clang/include/clang/Frontend/FrontendOptions.h +++ b/clang/include/clang/Frontend/FrontendOptions.h @@ -285,6 +285,9 @@ class FrontendOptions { /// Whether we include lookup table dumps in AST dumps. unsigned ASTDumpLookups : 1; + /// Whether we include declaration type dumps in AST dumps. + unsigned ASTDumpDeclTypes : 1; + /// Whether we are performing an implicit module build. unsigned BuildingImplicitModule : 1; diff --git a/clang/include/clang/Lex/LiteralSupport.h b/clang/include/clang/Lex/LiteralSupport.h index 6829771b28308..0c4f0fe277b7c 100644 --- a/clang/include/clang/Lex/LiteralSupport.h +++ b/clang/include/clang/Lex/LiteralSupport.h @@ -40,7 +40,9 @@ void expandUCNs(SmallVectorImpl &Buf, StringRef Input); /// of a ppnumber, classifying it as either integer, floating, or erroneous, /// determines the radix of the value and can convert it to a useful value. class NumericLiteralParser { - Preprocessor &PP; // needed for diagnostics + const SourceManager &SM; + const LangOptions &LangOpts; + DiagnosticsEngine &Diags; const char *const ThisTokBegin; const char *const ThisTokEnd; @@ -54,9 +56,9 @@ class NumericLiteralParser { SmallString<32> UDSuffixBuf; public: - NumericLiteralParser(StringRef TokSpelling, - SourceLocation TokLoc, - Preprocessor &PP); + NumericLiteralParser(StringRef TokSpelling, SourceLocation TokLoc, + const SourceManager &SM, const LangOptions &LangOpts, + const TargetInfo &Target, DiagnosticsEngine &Diags); bool hadError : 1; bool isUnsigned : 1; bool isLong : 1; // This is *not* set for long long. diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 1ae219781c696..e809d87b59a0f 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -241,6 +241,9 @@ class Parser : public CodeCompletionHandler { /// The "depth" of the template parameters currently being parsed. unsigned TemplateParameterDepth; + /// Current kind of OpenMP clause + OpenMPClauseKind OMPClauseKind = llvm::omp::OMPC_unknown; + /// RAII class that manages the template parameter depth. class TemplateParameterDepthRAII { unsigned &Depth; @@ -1088,12 +1091,40 @@ class Parser : public CodeCompletionHandler { } }; + /// Introduces zero or more scopes for parsing. The scopes will all be exited + /// when the object is destroyed. + class MultiParseScope { + Parser &Self; + unsigned NumScopes = 0; + + MultiParseScope(const MultiParseScope&) = delete; + + public: + MultiParseScope(Parser &Self) : Self(Self) {} + void Enter(unsigned ScopeFlags) { + Self.EnterScope(ScopeFlags); + ++NumScopes; + } + void Exit() { + while (NumScopes) { + Self.ExitScope(); + --NumScopes; + } + } + ~MultiParseScope() { + Exit(); + } + }; + /// EnterScope - Start a new scope. void EnterScope(unsigned ScopeFlags); /// ExitScope - Pop a scope off the scope stack. void ExitScope(); + /// Re-enter the template scopes for a declaration that might be a template. + unsigned ReenterTemplateScopes(MultiParseScope &S, Decl *D); + private: /// RAII object used to modify the scope flags for the current scope. class ParseScopeFlags { @@ -1278,13 +1309,7 @@ class Parser : public CodeCompletionHandler { Decl *D; CachedTokens Toks; - /// Whether this member function had an associated template - /// scope. When true, D is a template declaration. - /// otherwise, it is a member function declaration. - bool TemplateScope; - - explicit LexedMethod(Parser* P, Decl *MD) - : Self(P), D(MD), TemplateScope(false) {} + explicit LexedMethod(Parser *P, Decl *MD) : Self(P), D(MD) {} void ParseLexedMethodDefs() override; }; @@ -1314,8 +1339,7 @@ class Parser : public CodeCompletionHandler { /// argument (C++ [class.mem]p2). struct LateParsedMethodDeclaration : public LateParsedDeclaration { explicit LateParsedMethodDeclaration(Parser *P, Decl *M) - : Self(P), Method(M), TemplateScope(false), - ExceptionSpecTokens(nullptr) {} + : Self(P), Method(M), ExceptionSpecTokens(nullptr) {} void ParseLexedMethodDeclarations() override; @@ -1324,11 +1348,6 @@ class Parser : public CodeCompletionHandler { /// Method - The method declaration. Decl *Method; - /// Whether this member function had an associated template - /// scope. When true, D is a template declaration. - /// otherwise, it is a member function declaration. - bool TemplateScope; - /// DefaultArgs - Contains the parameters of the function and /// their default arguments. At least one of the parameters will /// have a default argument, but all of the parameters of the @@ -1373,18 +1392,13 @@ class Parser : public CodeCompletionHandler { /// parsed after the corresponding top-level class is complete. struct ParsingClass { ParsingClass(Decl *TagOrTemplate, bool TopLevelClass, bool IsInterface) - : TopLevelClass(TopLevelClass), TemplateScope(false), - IsInterface(IsInterface), TagOrTemplate(TagOrTemplate) { } + : TopLevelClass(TopLevelClass), IsInterface(IsInterface), + TagOrTemplate(TagOrTemplate) {} /// Whether this is a "top-level" class, meaning that it is /// not nested within another class. bool TopLevelClass : 1; - /// Whether this class had an associated template - /// scope. When true, TagOrTemplate is a template declaration; - /// otherwise, it is a tag declaration. - bool TemplateScope : 1; - /// Whether this class is an __interface. bool IsInterface : 1; @@ -1483,6 +1497,10 @@ class Parser : public CodeCompletionHandler { SourceRange getSourceRange() const LLVM_READONLY; }; + // In ParseCXXInlineMethods.cpp. + struct ReenterTemplateScopeRAII; + struct ReenterClassScopeRAII; + void LexTemplateFunctionForLateParsing(CachedTokens &Toks); void ParseLateTemplatedFuncDef(LateParsedTemplate &LPT); @@ -2053,8 +2071,9 @@ class Parser : public CodeCompletionHandler { StmtResult ParseCompoundStatementBody(bool isStmtExpr = false); bool ParseParenExprOrCondition(StmtResult *InitStmt, Sema::ConditionResult &CondResult, - SourceLocation Loc, - Sema::ConditionKind CK); + SourceLocation Loc, Sema::ConditionKind CK, + SourceLocation *LParenLoc = nullptr, + SourceLocation *RParenLoc = nullptr); StmtResult ParseIfStatement(SourceLocation *TrailingElseLoc); StmtResult ParseSwitchStatement(SourceLocation *TrailingElseLoc); StmtResult ParseWhileStatement(SourceLocation *TrailingElseLoc); @@ -3240,7 +3259,7 @@ class Parser : public CodeCompletionHandler { DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo, ParsingDeclRAIIObject &DiagsFromParams, SourceLocation &DeclEnd, ParsedAttributes &AccessAttrs, AccessSpecifier AS = AS_none); - bool ParseTemplateParameters(unsigned Depth, + bool ParseTemplateParameters(MultiParseScope &TemplateScopes, unsigned Depth, SmallVectorImpl &TemplateParams, SourceLocation &LAngleLoc, SourceLocation &RAngleLoc); diff --git a/clang/include/clang/Sema/Scope.h b/clang/include/clang/Sema/Scope.h index 9b8f1415a1e37..b7260f15fe1b9 100644 --- a/clang/include/clang/Sema/Scope.h +++ b/clang/include/clang/Sema/Scope.h @@ -322,8 +322,21 @@ class Scope { /// declared in. bool isDeclScope(const Decl *D) const { return DeclsInScope.count(D) != 0; } - DeclContext *getEntity() const { return Entity; } - void setEntity(DeclContext *E) { Entity = E; } + /// Get the entity corresponding to this scope. + DeclContext *getEntity() const { + return isTemplateParamScope() ? nullptr : Entity; + } + + /// Get the DeclContext in which to continue unqualified lookup after a + /// lookup in this scope. + DeclContext *getLookupEntity() const { return Entity; } + + void setEntity(DeclContext *E) { + assert(!isTemplateParamScope() && + "entity associated with template param scope"); + Entity = E; + } + void setLookupEntity(DeclContext *E) { Entity = E; } /// Determine whether any unrecoverable errors have occurred within this /// scope. Note that this may return false even if the scope contains invalid diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 8c8e981e60652..6f7ad8076718d 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -490,10 +490,41 @@ class Sema final { PragmaLocation(PragmaLocation), PragmaPushLocation(PragmaPushLocation) {} }; - void Act(SourceLocation PragmaLocation, - PragmaMsStackAction Action, - llvm::StringRef StackSlotLabel, - ValueType Value); + + void Act(SourceLocation PragmaLocation, PragmaMsStackAction Action, + llvm::StringRef StackSlotLabel, ValueType Value) { + if (Action == PSK_Reset) { + CurrentValue = DefaultValue; + CurrentPragmaLocation = PragmaLocation; + return; + } + if (Action & PSK_Push) + Stack.emplace_back(StackSlotLabel, CurrentValue, CurrentPragmaLocation, + PragmaLocation); + else if (Action & PSK_Pop) { + if (!StackSlotLabel.empty()) { + // If we've got a label, try to find it and jump there. + auto I = llvm::find_if(llvm::reverse(Stack), [&](const Slot &x) { + return x.StackSlotLabel == StackSlotLabel; + }); + // If we found the label so pop from there. + if (I != Stack.rend()) { + CurrentValue = I->Value; + CurrentPragmaLocation = I->PragmaLocation; + Stack.erase(std::prev(I.base()), Stack.end()); + } + } else if (!Stack.empty()) { + // We do not have a label, just pop the last entry. + CurrentValue = Stack.back().Value; + CurrentPragmaLocation = Stack.back().PragmaLocation; + Stack.pop_back(); + } + } + if (Action & PSK_Set) { + CurrentValue = Value; + CurrentPragmaLocation = PragmaLocation; + } + } // MSVC seems to add artificial slots to #pragma stacks on entering a C++ // method body to restore the stacks on exit, so it works like this: @@ -557,6 +588,15 @@ class Sema final { // This stack tracks the current state of Sema.CurFPFeatures. PragmaStack FpPragmaStack; + FPOptionsOverride CurFPFeatureOverrides() { + FPOptionsOverride result; + if (!FpPragmaStack.hasValue()) { + result = FPOptionsOverride(); + } else { + result = FPOptionsOverride(FpPragmaStack.CurrentValue); + } + return result; + } // RAII object to push / pop sentinel slots for all MS #pragma stacks. // Actions should be performed only if we enter / exit a C++ method body. @@ -1358,12 +1398,19 @@ class Sema final { /// statements. class FPFeaturesStateRAII { public: - FPFeaturesStateRAII(Sema &S) : S(S), OldFPFeaturesState(S.CurFPFeatures) {} - ~FPFeaturesStateRAII() { S.CurFPFeatures = OldFPFeaturesState; } + FPFeaturesStateRAII(Sema &S) : S(S), OldFPFeaturesState(S.CurFPFeatures) { + OldOverrides = S.FpPragmaStack.CurrentValue; + } + ~FPFeaturesStateRAII() { + S.CurFPFeatures = OldFPFeaturesState; + S.FpPragmaStack.CurrentValue = OldOverrides; + } + unsigned getOverrides() { return OldOverrides; } private: Sema& S; FPOptions OldFPFeaturesState; + unsigned OldOverrides; }; void addImplicitTypedef(StringRef Name, QualType T); @@ -1697,6 +1744,10 @@ class Sema final { static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo = nullptr); CanThrowResult canThrow(const Stmt *E); + /// Determine whether the callee of a particular function call can throw. + /// E, D and Loc are all optional. + static CanThrowResult canCalleeThrow(Sema &S, const Expr *E, const Decl *D, + SourceLocation Loc = SourceLocation()); const FunctionProtoType *ResolveExceptionSpec(SourceLocation Loc, const FunctionProtoType *FPT); void UpdateExceptionSpec(FunctionDecl *FD, @@ -2862,8 +2913,6 @@ class Sema final { Decl *EnumDecl, ArrayRef Elements, Scope *S, const ParsedAttributesView &Attr); - DeclContext *getContainingDC(DeclContext *DC); - /// Set the current declaration context until it gets popped. void PushDeclContext(Scope *S, DeclContext *DC); void PopDeclContext(); @@ -2873,6 +2922,11 @@ class Sema final { void EnterDeclaratorContext(Scope *S, DeclContext *DC); void ExitDeclaratorContext(Scope *S); + /// Enter a template parameter scope, after it's been associated with a particular + /// DeclContext. Causes lookup within the scope to chain through enclosing contexts + /// in the correct order. + void EnterTemplatedContext(Scope *S, DeclContext *DC); + /// Push the parameters of D, which must be a function, into scope. void ActOnReenterFunctionContext(Scope* S, Decl* D); void ActOnExitFunctionContext(); @@ -4323,7 +4377,8 @@ class Sema final { ConditionResult Cond); StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, Stmt *Body); - StmtResult ActOnWhileStmt(SourceLocation WhileLoc, ConditionResult Cond, + StmtResult ActOnWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc, + ConditionResult Cond, SourceLocation RParenLoc, Stmt *Body); StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body, SourceLocation WhileLoc, SourceLocation CondLParen, @@ -4917,8 +4972,11 @@ class Sema final { SourceLocation RBLoc); ExprResult ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, - Expr *LowerBound, SourceLocation ColonLoc, - Expr *Length, SourceLocation RBLoc); + Expr *LowerBound, + SourceLocation ColonLocFirst, + SourceLocation ColonLocSecond, + Expr *Length, Expr *Stride, + SourceLocation RBLoc); ExprResult ActOnOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc, SourceLocation RParenLoc, ArrayRef Dims, @@ -6785,7 +6843,8 @@ class Sema final { void ActOnFinishCXXNonNestedClass(); void ActOnReenterCXXMethodParameter(Scope *S, ParmVarDecl *Param); - unsigned ActOnReenterTemplateScope(Scope *S, Decl *Template); + unsigned ActOnReenterTemplateScope(Decl *Template, + llvm::function_ref EnterScope); void ActOnStartDelayedMemberDeclarations(Scope *S, Decl *Record); void ActOnStartDelayedCXXMethodDeclaration(Scope *S, Decl *Method); void ActOnDelayedCXXMethodParameter(Scope *S, Decl *Param); @@ -6906,7 +6965,7 @@ class Sema final { /// DiagnoseAbsenceOfOverrideControl - Diagnose if 'override' keyword was /// not used in the declaration of an overriding method. - void DiagnoseAbsenceOfOverrideControl(NamedDecl *D); + void DiagnoseAbsenceOfOverrideControl(NamedDecl *D, bool Inconsistent); /// CheckForFunctionMarkedFinal - Checks whether a virtual member function /// overrides a virtual member function marked 'final', according to @@ -9043,6 +9102,8 @@ class Sema final { TemplateArgumentListInfo &Result, const MultiLevelTemplateArgumentList &TemplateArgs); + bool InstantiateDefaultArgument(SourceLocation CallLoc, FunctionDecl *FD, + ParmVarDecl *Param); void InstantiateExceptionSpec(SourceLocation PointOfInstantiation, FunctionDecl *Function); bool CheckInstantiatedFunctionTemplateConstraints( @@ -9598,10 +9659,10 @@ class Sema final { /// Are precise floating point semantics currently enabled? bool isPreciseFPEnabled() { - return !CurFPFeatures.allowAssociativeMath() && - !CurFPFeatures.noSignedZeros() && - !CurFPFeatures.allowReciprocalMath() && - !CurFPFeatures.allowApproximateFunctions(); + return !CurFPFeatures.getAllowFPReassociate() && + !CurFPFeatures.getNoSignedZero() && + !CurFPFeatures.getAllowReciprocal() && + !CurFPFeatures.getAllowApproxFunc(); } /// ActOnPragmaFloatControl - Call on well-formed \#pragma float_control @@ -9644,21 +9705,21 @@ class Sema final { /// ActOnPragmaFPContract - Called on well formed /// \#pragma {STDC,OPENCL} FP_CONTRACT and /// \#pragma clang fp contract - void ActOnPragmaFPContract(LangOptions::FPModeKind FPC); + void ActOnPragmaFPContract(SourceLocation Loc, LangOptions::FPModeKind FPC); /// Called on well formed /// \#pragma clang fp reassociate - void ActOnPragmaFPReassociate(bool IsEnabled); + void ActOnPragmaFPReassociate(SourceLocation Loc, bool IsEnabled); /// ActOnPragmaFenvAccess - Called on well formed /// \#pragma STDC FENV_ACCESS void ActOnPragmaFEnvAccess(SourceLocation Loc, bool IsEnabled); /// Called to set rounding mode for floating point operations. - void setRoundingMode(llvm::RoundingMode); + void setRoundingMode(SourceLocation Loc, llvm::RoundingMode); /// Called to set exception behavior for floating point operations. - void setExceptionMode(LangOptions::FPExceptionModeKind); + void setExceptionMode(SourceLocation Loc, LangOptions::FPExceptionModeKind); /// AddAlignmentAttributesForRecord - Adds any needed alignment attributes to /// a the record decl, to handle '\#pragma pack' and '\#pragma options align'. @@ -9796,6 +9857,9 @@ class Sema final { void CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body); ClassTemplateDecl *lookupCoroutineTraits(SourceLocation KwLoc, SourceLocation FuncLoc); + /// Check that the expression co_await promise.final_suspend() shall not be + /// potentially-throwing. + bool checkFinalSuspendNoThrow(const Stmt *FinalSuspend); //===--------------------------------------------------------------------===// // OpenCL extensions. @@ -11770,12 +11834,13 @@ class Sema final { /// - Otherwise, returns true without emitting any diagnostics. bool CheckCUDACall(SourceLocation Loc, FunctionDecl *Callee); + void CUDACheckLambdaCapture(CXXMethodDecl *D, const sema::Capture &Capture); + /// Set __device__ or __host__ __device__ attributes on the given lambda /// operator() method. /// - /// CUDA lambdas declared inside __device__ or __global__ functions inherit - /// the __device__ attribute. Similarly, lambdas inside __host__ __device__ - /// functions become __host__ __device__ themselves. + /// CUDA lambdas by default is host device function unless it has explicit + /// host or device attribute. void CUDASetLambdaAttrs(CXXMethodDecl *Method); /// Finds a function in \p Matches with highest calling priority @@ -11922,7 +11987,7 @@ class Sema final { void CodeCompleteDesignator(const QualType BaseType, llvm::ArrayRef InitExprs, const Designation &D); - void CodeCompleteAfterIf(Scope *S); + void CodeCompleteAfterIf(Scope *S, bool IsBracedThen); void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, bool EnteringContext, bool IsUsingDeclaration, QualType BaseType, @@ -11938,6 +12003,7 @@ class Sema final { void CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro, bool AfterAmpersand); + void CodeCompleteAfterFunctionEquals(Declarator &D); void CodeCompleteObjCAtDirective(Scope *S); void CodeCompleteObjCAtVisibility(Scope *S); @@ -12083,6 +12149,13 @@ class Sema final { bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckX86BuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall); bool CheckX86BuiltinGatherScatterScale(unsigned BuiltinID, CallExpr *TheCall); + bool CheckX86BuiltinTileArguments(unsigned BuiltinID, CallExpr *TheCall); + bool CheckX86BuiltinTileArgumentsRange(CallExpr *TheCall, + ArrayRef ArgNums); + bool CheckX86BuiltinTileArgumentsRange(CallExpr *TheCall, int ArgNum); + bool CheckX86BuiltinTileDuplicate(CallExpr *TheCall, ArrayRef ArgNums); + bool CheckX86BuiltinTileRangeAndDuplicate(CallExpr *TheCall, + ArrayRef ArgNums); bool CheckX86BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, diff --git a/clang/include/clang/Sema/Template.h b/clang/include/clang/Sema/Template.h index 8166b6cf9b6f0..91d175fdd0506 100644 --- a/clang/include/clang/Sema/Template.h +++ b/clang/include/clang/Sema/Template.h @@ -42,6 +42,17 @@ class TypedefNameDecl; class TypeSourceInfo; class VarDecl; +/// The kind of template substitution being performed. +enum class TemplateSubstitutionKind : char { + /// We are substituting template parameters for template arguments in order + /// to form a template specialization. + Specialization, + /// We are substituting template parameters for (typically) other template + /// parameters in order to rewrite a declaration as a different declaration + /// (for example, when forming a deduction guide from a constructor). + Rewrite, +}; + /// Data structure that captures multiple levels of template argument /// lists for use in template instantiation. /// @@ -73,6 +84,9 @@ class VarDecl; /// being substituted. unsigned NumRetainedOuterLevels = 0; + /// The kind of substitution described by this argument list. + TemplateSubstitutionKind Kind = TemplateSubstitutionKind::Specialization; + public: /// Construct an empty set of template argument lists. MultiLevelTemplateArgumentList() = default; @@ -83,6 +97,18 @@ class VarDecl; addOuterTemplateArguments(&TemplateArgs); } + void setKind(TemplateSubstitutionKind K) { Kind = K; } + + /// Determine the kind of template substitution being performed. + TemplateSubstitutionKind getKind() const { return Kind; } + + /// Determine whether we are rewriting template parameters rather than + /// substituting for them. If so, we should not leave references to the + /// original template parameters behind. + bool isRewrite() const { + return Kind == TemplateSubstitutionKind::Rewrite; + } + /// Determine the number of levels in this template argument /// list. unsigned getNumLevels() const { @@ -95,6 +121,10 @@ class VarDecl; return TemplateArgumentLists.size(); } + unsigned getNumRetainedOuterLevels() const { + return NumRetainedOuterLevels; + } + /// Determine how many of the \p OldDepth outermost template parameter /// lists would be removed by substituting these arguments. unsigned getNewDepth(unsigned OldDepth) const { @@ -159,6 +189,9 @@ class VarDecl; void addOuterRetainedLevel() { ++NumRetainedOuterLevels; } + void addOuterRetainedLevels(unsigned Num) { + NumRetainedOuterLevels += Num; + } /// Retrieve the innermost template argument list. const ArgList &getInnermost() const { diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h index 35f73e1dfd7ca..7a6664af65d89 100644 --- a/clang/include/clang/Serialization/ASTWriter.h +++ b/clang/include/clang/Serialization/ASTWriter.h @@ -62,6 +62,7 @@ class CXXRecordDecl; class CXXTemporary; class FileEntry; class FPOptions; +class FPOptionsOverride; class FunctionDecl; class HeaderSearch; class HeaderSearchOptions; @@ -506,7 +507,7 @@ class ASTWriter : public ASTDeserializationListener, bool IsModule); void WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord); void WriteDeclContextVisibleUpdate(const DeclContext *DC); - void WriteFPPragmaOptions(const FPOptions &Opts); + void WriteFPPragmaOptions(const FPOptionsOverride &Opts); void WriteOpenCLExtensions(Sema &SemaRef); void WriteOpenCLExtensionTypes(Sema &SemaRef); void WriteOpenCLExtensionDecls(Sema &SemaRef); diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index 9de324506bf66..cbd9254003282 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -130,7 +130,8 @@ def CallAndMessageModeling : Checker<"CallAndMessageModeling">, "function/method call. For instance, if we can't reason about the " "nullability of the implicit this parameter after a method call, " "this checker conservatively assumes it to be non-null">, - Documentation; + Documentation, + Hidden; def CallAndMessageChecker : Checker<"CallAndMessage">, HelpText<"Check for logical errors for function calls and Objective-C " @@ -220,7 +221,8 @@ def StackAddrEscapeChecker : Checker<"StackAddressEscape">, def DynamicTypePropagation : Checker<"DynamicTypePropagation">, HelpText<"Generate dynamic type information">, - Documentation; + Documentation, + Hidden; def NonnullGlobalConstantsChecker: Checker<"NonnilStringConstants">, HelpText<"Assume that const string-like globals are non-null">, @@ -354,9 +356,17 @@ def StdCLibraryFunctionsChecker : Checker<"StdCLibraryFunctions">, "If set to true, the checker displays the found summaries " "for the given translation unit.", "false", - Released> + Released, + Hide>, + CmdLineOption ]>, - Documentation; + Documentation, + Hidden; def TrustNonnullChecker : Checker<"TrustNonnull">, HelpText<"Trust that returns from framework methods annotated with _Nonnull " @@ -365,18 +375,6 @@ def TrustNonnullChecker : Checker<"TrustNonnull">, } // end "apiModeling" -let ParentPackage = APIModelingAlpha in { - -def StdCLibraryFunctionArgsChecker : Checker<"StdCLibraryFunctionArgs">, - HelpText<"Check constraints of arguments of C standard library functions, " - "such as whether the parameter of isalpha is in the range [0, 255] " - "or is EOF.">, - Dependencies<[StdCLibraryFunctionsChecker]>, - WeakDependencies<[NonNullParamChecker]>, - Documentation; - -} // end "alpha.apiModeling" - //===----------------------------------------------------------------------===// // Evaluate "builtin" functions. //===----------------------------------------------------------------------===// @@ -535,6 +533,14 @@ def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">, HelpText<"Check for calls to blocking functions inside a critical section">, Documentation; +def StdCLibraryFunctionArgsChecker : Checker<"StdCLibraryFunctionArgs">, + HelpText<"Check constraints of arguments of C standard library functions, " + "such as whether the parameter of isalpha is in the range [0, 255] " + "or is EOF.">, + Dependencies<[StdCLibraryFunctionsChecker]>, + WeakDependencies<[NonNullParamChecker]>, + Documentation; + } // end "alpha.unix" //===----------------------------------------------------------------------===// @@ -571,9 +577,17 @@ def CXXSelfAssignmentChecker : Checker<"SelfAssignment">, Documentation, Hidden; -def SmartPtrModeling: Checker<"SmartPtr">, +def SmartPtrModeling: Checker<"SmartPtrModeling">, HelpText<"Model behavior of C++ smart pointers">, Documentation, + CheckerOptions<[ + CmdLineOption, + ]>, Hidden; def MoveChecker: Checker<"Move">, @@ -730,6 +744,11 @@ def MismatchedIteratorChecker : Checker<"MismatchedIterator">, Dependencies<[IteratorModeling]>, Documentation; +def SmartPtrChecker: Checker<"SmartPtr">, + HelpText<"Find the dereference of null SmrtPtr">, + Dependencies<[SmartPtrModeling]>, + Documentation; + } // end: "alpha.cplusplus" @@ -1372,6 +1391,12 @@ def AnalysisOrderChecker : Checker<"AnalysisOrder">, "false", Released, Hide>, + CmdLineOption, CmdLineOption Fixits; BugReport(Kind kind, const BugType &bt, StringRef desc) - : K(kind), BT(bt), Description(desc) {} + : BugReport(kind, bt, "", desc) {} BugReport(Kind K, const BugType &BT, StringRef ShortDescription, StringRef Description) @@ -369,16 +370,13 @@ class PathSensitiveBugReport : public BugReport { public: PathSensitiveBugReport(const BugType &bt, StringRef desc, const ExplodedNode *errorNode) - : BugReport(Kind::PathSensitive, bt, desc), ErrorNode(errorNode), - ErrorNodeRange(getStmt() ? getStmt()->getSourceRange() - : SourceRange()) {} + : PathSensitiveBugReport(bt, desc, desc, errorNode) {} PathSensitiveBugReport(const BugType &bt, StringRef shortDesc, StringRef desc, const ExplodedNode *errorNode) - : BugReport(Kind::PathSensitive, bt, shortDesc, desc), - ErrorNode(errorNode), - ErrorNodeRange(getStmt() ? getStmt()->getSourceRange() - : SourceRange()) {} + : PathSensitiveBugReport(bt, shortDesc, desc, errorNode, + /*LocationToUnique*/ {}, + /*DeclToUnique*/ nullptr) {} /// Create a PathSensitiveBugReport with a custom uniqueing location. /// @@ -391,11 +389,13 @@ class PathSensitiveBugReport : public BugReport { const ExplodedNode *errorNode, PathDiagnosticLocation LocationToUnique, const Decl *DeclToUnique) - : BugReport(Kind::PathSensitive, bt, desc), ErrorNode(errorNode), - ErrorNodeRange(getStmt() ? getStmt()->getSourceRange() : SourceRange()), - UniqueingLocation(LocationToUnique), UniqueingDecl(DeclToUnique) { - assert(errorNode); - } + : PathSensitiveBugReport(bt, desc, desc, errorNode, LocationToUnique, + DeclToUnique) {} + + PathSensitiveBugReport(const BugType &bt, StringRef shortDesc, StringRef desc, + const ExplodedNode *errorNode, + PathDiagnosticLocation LocationToUnique, + const Decl *DeclToUnique); static bool classof(const BugReport *R) { return R->getKind() == Kind::PathSensitive; diff --git a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h index de0ee5de81b53..365b1ff1bfe3e 100644 --- a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h +++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h @@ -386,6 +386,8 @@ class FalsePositiveRefutationBRVisitor final : public BugReporterVisitor { void finalizeVisitor(BugReporterContext &BRC, const ExplodedNode *EndPathNode, PathSensitiveBugReport &BR) override; + void addConstraints(const ExplodedNode *N, + bool OverwriteConstraintsOnExistingSyms); }; diff --git a/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h b/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h index 820ccfceecf6a..d2f71baa56a46 100644 --- a/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ b/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -43,10 +43,12 @@ class CallEvent; class CheckerBase; class CheckerContext; class CheckerRegistry; +struct CheckerRegistryData; class ExplodedGraph; class ExplodedNode; class ExplodedNodeSet; class ExprEngine; +struct EvalCallOptions; class MemRegion; struct NodeBuilderContext; class ObjCMethodCall; @@ -129,7 +131,7 @@ class CheckerManager { const Preprocessor *PP = nullptr; CheckerNameRef CurrentCheckerName; DiagnosticsEngine &Diags; - std::unique_ptr Registry; + std::unique_ptr RegistryData; public: // These constructors are defined in the Frontend library, because @@ -151,8 +153,8 @@ class CheckerManager { : CheckerManager(Context, AOptions, PP, {}, {}) {} /// Constructs a CheckerManager without requiring an AST. No checker - /// registration will take place. Only useful for retrieving the - /// CheckerRegistry and print for help flags where the AST is unavalaible. + /// registration will take place. Only useful when one needs to print the + /// help flags through CheckerRegistryData, and the AST is unavalaible. CheckerManager(AnalyzerOptions &AOptions, const LangOptions &LangOpts, DiagnosticsEngine &Diags, ArrayRef plugins); @@ -171,7 +173,9 @@ class CheckerManager { assert(PP); return *PP; } - const CheckerRegistry &getCheckerRegistry() const { return *Registry; } + const CheckerRegistryData &getCheckerRegistryData() const { + return *RegistryData; + } DiagnosticsEngine &getDiagnostics() const { return Diags; } ASTContext &getASTContext() const { assert(Context); @@ -433,9 +437,9 @@ class CheckerManager { /// Run checkers for evaluating a call. /// /// Warning: Currently, the CallEvent MUST come from a CallExpr! - void runCheckersForEvalCall(ExplodedNodeSet &Dst, - const ExplodedNodeSet &Src, - const CallEvent &CE, ExprEngine &Eng); + void runCheckersForEvalCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, + const CallEvent &CE, ExprEngine &Eng, + const EvalCallOptions &CallOpts); /// Run checkers for the entire Translation Unit. void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU, diff --git a/clang/include/clang/StaticAnalyzer/Core/CheckerRegistryData.h b/clang/include/clang/StaticAnalyzer/Core/CheckerRegistryData.h new file mode 100644 index 0000000000000..43248d8e6bb8d --- /dev/null +++ b/clang/include/clang/StaticAnalyzer/Core/CheckerRegistryData.h @@ -0,0 +1,226 @@ +//===- CheckerRegistryData.h ------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the data structures to which the TableGen file Checkers.td +// maps to, as well as what was parsed from the the specific invocation (whether +// a checker/package is enabled, their options values, etc). +// +// The parsing of the invocation is done by CheckerRegistry, which is found in +// the Frontend library. This allows the Core and Checkers libraries to utilize +// this information, such as enforcing rules on checker dependency bug emission, +// ensuring all checker options were queried, etc. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRYDATA_H +#define LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRYDATA_H + +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/SetVector.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/raw_ostream.h" + +namespace clang { + +class AnalyzerOptions; + +namespace ento { + +class CheckerManager; + +/// Initialization functions perform any necessary setup for a checker. +/// They should include a call to CheckerManager::registerChecker. +using RegisterCheckerFn = void (*)(CheckerManager &); +using ShouldRegisterFunction = bool (*)(const CheckerManager &); + +/// Specifies a command line option. It may either belong to a checker or a +/// package. +struct CmdLineOption { + StringRef OptionType; + StringRef OptionName; + StringRef DefaultValStr; + StringRef Description; + StringRef DevelopmentStatus; + bool IsHidden; + + CmdLineOption(StringRef OptionType, StringRef OptionName, + StringRef DefaultValStr, StringRef Description, + StringRef DevelopmentStatus, bool IsHidden) + : OptionType(OptionType), OptionName(OptionName), + DefaultValStr(DefaultValStr), Description(Description), + DevelopmentStatus(DevelopmentStatus), IsHidden(IsHidden) { + + assert((OptionType == "bool" || OptionType == "string" || + OptionType == "int") && + "Unknown command line option type!"); + + assert((OptionType != "bool" || + (DefaultValStr == "true" || DefaultValStr == "false")) && + "Invalid value for boolean command line option! Maybe incorrect " + "parameters to the addCheckerOption or addPackageOption method?"); + + int Tmp; + assert((OptionType != "int" || !DefaultValStr.getAsInteger(0, Tmp)) && + "Invalid value for integer command line option! Maybe incorrect " + "parameters to the addCheckerOption or addPackageOption method?"); + (void)Tmp; + + assert((DevelopmentStatus == "alpha" || DevelopmentStatus == "beta" || + DevelopmentStatus == "released") && + "Invalid development status!"); + } + + LLVM_DUMP_METHOD void dump() const; + LLVM_DUMP_METHOD void dumpToStream(llvm::raw_ostream &Out) const; +}; + +using CmdLineOptionList = llvm::SmallVector; + +struct CheckerInfo; + +using CheckerInfoList = std::vector; +using CheckerInfoListRange = llvm::iterator_range; +using ConstCheckerInfoList = llvm::SmallVector; +using CheckerInfoSet = llvm::SetVector; + +/// Specifies a checker. Note that this isn't what we call a checker object, +/// it merely contains everything required to create one. +struct CheckerInfo { + enum class StateFromCmdLine { + // This checker wasn't explicitly enabled or disabled. + State_Unspecified, + // This checker was explicitly disabled. + State_Disabled, + // This checker was explicitly enabled. + State_Enabled + }; + + RegisterCheckerFn Initialize = nullptr; + ShouldRegisterFunction ShouldRegister = nullptr; + StringRef FullName; + StringRef Desc; + StringRef DocumentationUri; + CmdLineOptionList CmdLineOptions; + bool IsHidden = false; + StateFromCmdLine State = StateFromCmdLine::State_Unspecified; + + ConstCheckerInfoList Dependencies; + ConstCheckerInfoList WeakDependencies; + + bool isEnabled(const CheckerManager &mgr) const { + return State == StateFromCmdLine::State_Enabled && ShouldRegister(mgr); + } + + bool isDisabled(const CheckerManager &mgr) const { + return State == StateFromCmdLine::State_Disabled || !ShouldRegister(mgr); + } + + // Since each checker must have a different full name, we can identify + // CheckerInfo objects by them. + bool operator==(const CheckerInfo &Rhs) const { + return FullName == Rhs.FullName; + } + + CheckerInfo(RegisterCheckerFn Fn, ShouldRegisterFunction sfn, StringRef Name, + StringRef Desc, StringRef DocsUri, bool IsHidden) + : Initialize(Fn), ShouldRegister(sfn), FullName(Name), Desc(Desc), + DocumentationUri(DocsUri), IsHidden(IsHidden) {} + + // Used for lower_bound. + explicit CheckerInfo(StringRef FullName) : FullName(FullName) {} + + LLVM_DUMP_METHOD void dump() const; + LLVM_DUMP_METHOD void dumpToStream(llvm::raw_ostream &Out) const; +}; + +using StateFromCmdLine = CheckerInfo::StateFromCmdLine; + +/// Specifies a package. Each package option is implicitly an option for all +/// checkers within the package. +struct PackageInfo { + StringRef FullName; + CmdLineOptionList CmdLineOptions; + + // Since each package must have a different full name, we can identify + // CheckerInfo objects by them. + bool operator==(const PackageInfo &Rhs) const { + return FullName == Rhs.FullName; + } + + explicit PackageInfo(StringRef FullName) : FullName(FullName) {} + + LLVM_DUMP_METHOD void dump() const; + LLVM_DUMP_METHOD void dumpToStream(llvm::raw_ostream &Out) const; +}; + +using PackageInfoList = llvm::SmallVector; + +namespace checker_registry { + +template struct FullNameLT { + bool operator()(const T &Lhs, const T &Rhs) { + return Lhs.FullName < Rhs.FullName; + } +}; + +using PackageNameLT = FullNameLT; +using CheckerNameLT = FullNameLT; + +template +std::conditional_t::value, + typename CheckerOrPackageInfoList::const_iterator, + typename CheckerOrPackageInfoList::iterator> +binaryFind(CheckerOrPackageInfoList &Collection, StringRef FullName) { + + using CheckerOrPackage = typename CheckerOrPackageInfoList::value_type; + using CheckerOrPackageFullNameLT = FullNameLT; + + assert(llvm::is_sorted(Collection, CheckerOrPackageFullNameLT{}) && + "In order to efficiently gather checkers/packages, this function " + "expects them to be already sorted!"); + + return llvm::lower_bound(Collection, CheckerOrPackage(FullName), + CheckerOrPackageFullNameLT{}); +} +} // namespace checker_registry + +struct CheckerRegistryData { +public: + CheckerInfoSet EnabledCheckers; + + CheckerInfoList Checkers; + PackageInfoList Packages; + /// Used for counting how many checkers belong to a certain package in the + /// \c Checkers field. For convenience purposes. + llvm::StringMap PackageSizes; + + /// Contains all (FullName, CmdLineOption) pairs. Similarly to dependencies, + /// we only modify the actual CheckerInfo and PackageInfo objects once all + /// of them have been added. + llvm::SmallVector, 0> PackageOptions; + llvm::SmallVector, 0> CheckerOptions; + + llvm::SmallVector, 0> Dependencies; + llvm::SmallVector, 0> WeakDependencies; + + CheckerInfoListRange getMutableCheckersForCmdLineArg(StringRef CmdLineArg); + + /// Prints the name and description of all checkers in this registry. + /// This output is not intended to be machine-parseable. + void printCheckerWithDescList(const AnalyzerOptions &AnOpts, raw_ostream &Out, + size_t MaxNameChars = 30) const; + void printEnabledCheckerList(raw_ostream &Out) const; + void printCheckerOptionList(const AnalyzerOptions &AnOpts, + raw_ostream &Out) const; +}; + +} // namespace ento +} // namespace clang + +#endif // LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRYDATA_H diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h index a71469e90ea25..d75f9f63286db 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h @@ -788,6 +788,10 @@ class CXXMemberOperatorCall : public CXXInstanceCall { // to implicit this-parameter on the declaration. return CallArgumentIndex + 1; } + + OverloadedOperatorKind getOverloadedOperator() const { + return getOriginExpr()->getOperator(); + } }; /// Represents an implicit call to a C++ destructor. diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h index baa3a94adb640..cdfe986355c56 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h @@ -96,8 +96,37 @@ class RegionAndSymbolInvalidationTraits; class SymbolManager; class SwitchNodeBuilder; +/// Hints for figuring out of a call should be inlined during evalCall(). +struct EvalCallOptions { + /// This call is a constructor or a destructor for which we do not currently + /// compute the this-region correctly. + bool IsCtorOrDtorWithImproperlyModeledTargetRegion = false; + + /// This call is a constructor or a destructor for a single element within + /// an array, a part of array construction or destruction. + bool IsArrayCtorOrDtor = false; + + /// This call is a constructor or a destructor of a temporary value. + bool IsTemporaryCtorOrDtor = false; + + /// This call is a constructor for a temporary that is lifetime-extended + /// by binding it to a reference-type field within an aggregate, + /// for example 'A { const C &c; }; A a = { C() };' + bool IsTemporaryLifetimeExtendedViaAggregate = false; + + /// This call is a pre-C++17 elidable constructor that we failed to elide + /// because we failed to compute the target region into which + /// this constructor would have been ultimately elided. Analysis that + /// we perform in this case is still correct but it behaves differently, + /// as if copy elision is disabled. + bool IsElidableCtorThatHasNotBeenElided = false; + + EvalCallOptions() {} +}; + class ExprEngine { void anchor(); + public: /// The modes of inlining, which override the default analysis-wide settings. enum InliningModes { @@ -108,34 +137,6 @@ class ExprEngine { Inline_Minimal = 0x1 }; - /// Hints for figuring out of a call should be inlined during evalCall(). - struct EvalCallOptions { - /// This call is a constructor or a destructor for which we do not currently - /// compute the this-region correctly. - bool IsCtorOrDtorWithImproperlyModeledTargetRegion = false; - - /// This call is a constructor or a destructor for a single element within - /// an array, a part of array construction or destruction. - bool IsArrayCtorOrDtor = false; - - /// This call is a constructor or a destructor of a temporary value. - bool IsTemporaryCtorOrDtor = false; - - /// This call is a constructor for a temporary that is lifetime-extended - /// by binding it to a reference-type field within an aggregate, - /// for example 'A { const C &c; }; A a = { C() };' - bool IsTemporaryLifetimeExtendedViaAggregate = false; - - /// This call is a pre-C++17 elidable constructor that we failed to elide - /// because we failed to compute the target region into which - /// this constructor would have been ultimately elided. Analysis that - /// we perform in this case is still correct but it behaves differently, - /// as if copy elision is disabled. - bool IsElidableCtorThatHasNotBeenElided = false; - - EvalCallOptions() {} - }; - private: cross_tu::CrossTranslationUnitContext &CTU; diff --git a/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h b/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h index 7b72fae0fefed..43dbfb1585151 100644 --- a/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h +++ b/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h @@ -5,17 +5,22 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// +// +// Contains the logic for parsing the TableGen file Checkers.td, and parsing the +// specific invocation of the analyzer (which checker/package is enabled, values +// of their options, etc). This is in the frontend library because checker +// registry functions are called from here but are defined in the dependent +// library libStaticAnalyzerCheckers, but the actual data structure that holds +// the parsed information is in the Core library. +// +//===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H -#define LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H +#ifndef LLVM_CLANG_STATICANALYZER_FRONTEND_CHECKERREGISTRY_H +#define LLVM_CLANG_STATICANALYZER_FRONTEND_CHECKERREGISTRY_H #include "clang/Basic/LLVM.h" -#include "llvm/ADT/SetVector.h" -#include "llvm/ADT/StringMap.h" +#include "clang/StaticAnalyzer/Core/CheckerRegistryData.h" #include "llvm/ADT/StringRef.h" -#include "llvm/Support/raw_ostream.h" -#include -#include // FIXME: move this information to an HTML file in docs/. // At the very least, a checker plugin is a dynamic library that exports @@ -83,143 +88,16 @@ class CheckerManager; /// "core.builtin", or the full name "core.builtin.NoReturnFunctionChecker". class CheckerRegistry { public: - CheckerRegistry(ArrayRef plugins, DiagnosticsEngine &diags, - AnalyzerOptions &AnOpts, + CheckerRegistry(CheckerRegistryData &Data, ArrayRef Plugins, + DiagnosticsEngine &Diags, AnalyzerOptions &AnOpts, ArrayRef> - checkerRegistrationFns = {}); + CheckerRegistrationFns = {}); /// Collects all enabled checkers in the field EnabledCheckers. It preserves /// the order of insertion, as dependencies have to be enabled before the /// checkers that depend on them. void initializeRegistry(const CheckerManager &Mgr); - /// Initialization functions perform any necessary setup for a checker. - /// They should include a call to CheckerManager::registerChecker. - using InitializationFunction = void (*)(CheckerManager &); - using ShouldRegisterFunction = bool (*)(const CheckerManager &); - - /// Specifies a command line option. It may either belong to a checker or a - /// package. - struct CmdLineOption { - StringRef OptionType; - StringRef OptionName; - StringRef DefaultValStr; - StringRef Description; - StringRef DevelopmentStatus; - bool IsHidden; - - CmdLineOption(StringRef OptionType, StringRef OptionName, - StringRef DefaultValStr, StringRef Description, - StringRef DevelopmentStatus, bool IsHidden) - : OptionType(OptionType), OptionName(OptionName), - DefaultValStr(DefaultValStr), Description(Description), - DevelopmentStatus(DevelopmentStatus), IsHidden(IsHidden) { - - assert((OptionType == "bool" || OptionType == "string" || - OptionType == "int") && - "Unknown command line option type!"); - - assert((OptionType != "bool" || - (DefaultValStr == "true" || DefaultValStr == "false")) && - "Invalid value for boolean command line option! Maybe incorrect " - "parameters to the addCheckerOption or addPackageOption method?"); - - int Tmp; - assert((OptionType != "int" || !DefaultValStr.getAsInteger(0, Tmp)) && - "Invalid value for integer command line option! Maybe incorrect " - "parameters to the addCheckerOption or addPackageOption method?"); - (void)Tmp; - - assert((DevelopmentStatus == "alpha" || DevelopmentStatus == "beta" || - DevelopmentStatus == "released") && - "Invalid development status!"); - } - - LLVM_DUMP_METHOD void dump() const { dumpToStream(llvm::errs()); } - LLVM_DUMP_METHOD void dumpToStream(llvm::raw_ostream &Out) const; - }; - - using CmdLineOptionList = llvm::SmallVector; - - struct CheckerInfo; - - using CheckerInfoList = std::vector; - using CheckerInfoListRange = llvm::iterator_range; - using ConstCheckerInfoList = llvm::SmallVector; - using CheckerInfoSet = llvm::SetVector; - - /// Specifies a checker. Note that this isn't what we call a checker object, - /// it merely contains everything required to create one. - struct CheckerInfo { - enum class StateFromCmdLine { - // This checker wasn't explicitly enabled or disabled. - State_Unspecified, - // This checker was explicitly disabled. - State_Disabled, - // This checker was explicitly enabled. - State_Enabled - }; - - InitializationFunction Initialize = nullptr; - ShouldRegisterFunction ShouldRegister = nullptr; - StringRef FullName; - StringRef Desc; - StringRef DocumentationUri; - CmdLineOptionList CmdLineOptions; - bool IsHidden = false; - StateFromCmdLine State = StateFromCmdLine::State_Unspecified; - - ConstCheckerInfoList Dependencies; - ConstCheckerInfoList WeakDependencies; - - bool isEnabled(const CheckerManager &mgr) const { - return State == StateFromCmdLine::State_Enabled && ShouldRegister(mgr); - } - - bool isDisabled(const CheckerManager &mgr) const { - return State == StateFromCmdLine::State_Disabled || !ShouldRegister(mgr); - } - - // Since each checker must have a different full name, we can identify - // CheckerInfo objects by them. - bool operator==(const CheckerInfo &Rhs) const { - return FullName == Rhs.FullName; - } - - CheckerInfo(InitializationFunction Fn, ShouldRegisterFunction sfn, - StringRef Name, StringRef Desc, StringRef DocsUri, - bool IsHidden) - : Initialize(Fn), ShouldRegister(sfn), FullName(Name), Desc(Desc), - DocumentationUri(DocsUri), IsHidden(IsHidden) {} - - // Used for lower_bound. - explicit CheckerInfo(StringRef FullName) : FullName(FullName) {} - - LLVM_DUMP_METHOD void dump() const { dumpToStream(llvm::errs()); } - LLVM_DUMP_METHOD void dumpToStream(llvm::raw_ostream &Out) const; - }; - - using StateFromCmdLine = CheckerInfo::StateFromCmdLine; - - /// Specifies a package. Each package option is implicitly an option for all - /// checkers within the package. - struct PackageInfo { - StringRef FullName; - CmdLineOptionList CmdLineOptions; - - // Since each package must have a different full name, we can identify - // CheckerInfo objects by them. - bool operator==(const PackageInfo &Rhs) const { - return FullName == Rhs.FullName; - } - - explicit PackageInfo(StringRef FullName) : FullName(FullName) {} - - LLVM_DUMP_METHOD void dump() const { dumpToStream(llvm::errs()); } - LLVM_DUMP_METHOD void dumpToStream(llvm::raw_ostream &Out) const; - }; - - using PackageInfoList = llvm::SmallVector; private: /// Default initialization function for checkers -- since CheckerManager @@ -237,7 +115,7 @@ class CheckerRegistry { public: /// Adds a checker to the registry. Use this non-templated overload when your /// checker requires custom initialization. - void addChecker(InitializationFunction Fn, ShouldRegisterFunction sfn, + void addChecker(RegisterCheckerFn Fn, ShouldRegisterFunction sfn, StringRef FullName, StringRef Desc, StringRef DocsUri, bool IsHidden); @@ -305,46 +183,17 @@ class CheckerRegistry { /// Check if every option corresponds to a specific checker or package. void validateCheckerOptions() const; - /// Prints the name and description of all checkers in this registry. - /// This output is not intended to be machine-parseable. - void printCheckerWithDescList(raw_ostream &Out, - size_t MaxNameChars = 30) const; - void printEnabledCheckerList(raw_ostream &Out) const; - void printCheckerOptionList(raw_ostream &Out) const; - private: - /// Return an iterator range of mutable CheckerInfos \p CmdLineArg applies to. - /// For example, it'll return the checkers for the core package, if - /// \p CmdLineArg is "core". - CheckerInfoListRange getMutableCheckersForCmdLineArg(StringRef CmdLineArg); - - CheckerInfoList Checkers; - PackageInfoList Packages; - /// Used for couting how many checkers belong to a certain package in the - /// \c Checkers field. For convenience purposes. - llvm::StringMap PackageSizes; - - /// Contains all (Dependendent checker, Dependency) pairs. We need this, as - /// we'll resolve dependencies after all checkers were added first. - llvm::SmallVector, 0> Dependencies; - llvm::SmallVector, 0> WeakDependencies; - template void resolveDependencies(); - - /// Contains all (FullName, CmdLineOption) pairs. Similarly to dependencies, - /// we only modify the actual CheckerInfo and PackageInfo objects once all - /// of them have been added. - llvm::SmallVector, 0> PackageOptions; - llvm::SmallVector, 0> CheckerOptions; - void resolveCheckerAndPackageOptions(); + CheckerRegistryData &Data; + DiagnosticsEngine &Diags; AnalyzerOptions &AnOpts; - CheckerInfoSet EnabledCheckers; }; } // namespace ento } // namespace clang -#endif // LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H +#endif // LLVM_CLANG_STATICANALYZER_FRONTEND_CHECKERREGISTRY_H diff --git a/clang/include/clang/Testing/TestClangConfig.h b/clang/include/clang/Testing/TestClangConfig.h new file mode 100644 index 0000000000000..eefa36dc2ebb9 --- /dev/null +++ b/clang/include/clang/Testing/TestClangConfig.h @@ -0,0 +1,85 @@ +//===--- TestClangConfig.h ------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TESTING_TESTCLANGCONFIG_H +#define LLVM_CLANG_TESTING_TESTCLANGCONFIG_H + +#include "clang/Testing/CommandLineArgs.h" +#include "llvm/Support/raw_ostream.h" +#include +#include + +namespace clang { + +/// A Clang configuration for end-to-end tests that can be converted to +/// command line arguments for the driver. +/// +/// The configuration is represented as typed, named values, making it easier +/// and safer to work with compared to an array of string command line flags. +struct TestClangConfig { + TestLanguage Language; + + /// The argument of the `-target` command line flag. + std::string Target; + + bool isC() const { return Language == Lang_C89 || Language == Lang_C99; } + + bool isC99OrLater() const { return Language == Lang_C99; } + + bool isCXX() const { + return Language == Lang_CXX03 || Language == Lang_CXX11 || + Language == Lang_CXX14 || Language == Lang_CXX17 || + Language == Lang_CXX20; + } + + bool isCXX11OrLater() const { + return Language == Lang_CXX11 || Language == Lang_CXX14 || + Language == Lang_CXX17 || Language == Lang_CXX20; + } + + bool isCXX14OrLater() const { + return Language == Lang_CXX14 || Language == Lang_CXX17 || + Language == Lang_CXX20; + } + + bool isCXX17OrLater() const { + return Language == Lang_CXX17 || Language == Lang_CXX20; + } + + bool supportsCXXDynamicExceptionSpecification() const { + return Language == Lang_CXX03 || Language == Lang_CXX11 || + Language == Lang_CXX14; + } + + bool hasDelayedTemplateParsing() const { + return Target == "x86_64-pc-win32-msvc"; + } + + std::vector getCommandLineArgs() const { + std::vector Result = getCommandLineArgsForTesting(Language); + Result.push_back("-target"); + Result.push_back(Target); + return Result; + } + + std::string toString() const { + std::string Result; + llvm::raw_string_ostream OS(Result); + OS << "{ Language=" << Language << ", Target=" << Target << " }"; + return OS.str(); + } + + friend std::ostream &operator<<(std::ostream &OS, + const TestClangConfig &ClangConfig) { + return OS << ClangConfig.toString(); + } +}; + +} // end namespace clang + +#endif diff --git a/clang/include/clang/Tooling/Refactoring/AtomicChange.h b/clang/include/clang/Tooling/Refactoring/AtomicChange.h index 7cb9987e80c7b..f1034a3d05794 100644 --- a/clang/include/clang/Tooling/Refactoring/AtomicChange.h +++ b/clang/include/clang/Tooling/Refactoring/AtomicChange.h @@ -17,6 +17,7 @@ #include "clang/Basic/SourceManager.h" #include "clang/Format/Format.h" #include "clang/Tooling/Core/Replacement.h" +#include "llvm/ADT/Any.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" @@ -41,6 +42,9 @@ class AtomicChange { /// is being changed, e.g. the call to a refactored method. AtomicChange(const SourceManager &SM, SourceLocation KeyPosition); + AtomicChange(const SourceManager &SM, SourceLocation KeyPosition, + llvm::Any Metadata); + /// Creates an atomic change for \p FilePath with a customized key. AtomicChange(llvm::StringRef FilePath, llvm::StringRef Key) : Key(Key), FilePath(FilePath) {} @@ -120,6 +124,8 @@ class AtomicChange { return RemovedHeaders; } + const llvm::Any &getMetadata() const { return Metadata; } + private: AtomicChange() {} @@ -135,6 +141,12 @@ class AtomicChange { std::vector InsertedHeaders; std::vector RemovedHeaders; tooling::Replacements Replaces; + + // This field stores metadata which is ignored for the purposes of applying + // edits to source, but may be useful for other consumers of AtomicChanges. In + // particular, consumers can use this to direct how they want to consume each + // edit. + llvm::Any Metadata; }; using AtomicChanges = std::vector; diff --git a/clang/include/clang/Tooling/ReplacementsYaml.h b/clang/include/clang/Tooling/ReplacementsYaml.h index 2e3e401652e22..83e35d6232555 100644 --- a/clang/include/clang/Tooling/ReplacementsYaml.h +++ b/clang/include/clang/Tooling/ReplacementsYaml.h @@ -35,13 +35,7 @@ template <> struct MappingTraits { NormalizedReplacement(const IO &, const clang::tooling::Replacement &R) : FilePath(R.getFilePath()), Offset(R.getOffset()), - Length(R.getLength()), ReplacementText(R.getReplacementText()) { - size_t lineBreakPos = ReplacementText.find('\n'); - while (lineBreakPos != std::string::npos) { - ReplacementText.replace(lineBreakPos, 1, "\n\n"); - lineBreakPos = ReplacementText.find('\n', lineBreakPos + 2); - } - } + Length(R.getLength()), ReplacementText(R.getReplacementText()) {} clang::tooling::Replacement denormalize(const IO &) { return clang::tooling::Replacement(FilePath, Offset, Length, diff --git a/clang/include/clang/Tooling/Syntax/Nodes.h b/clang/include/clang/Tooling/Syntax/Nodes.h index 139ac9aa8eca2..d97b127638bba 100644 --- a/clang/include/clang/Tooling/Syntax/Nodes.h +++ b/clang/include/clang/Tooling/Syntax/Nodes.h @@ -43,8 +43,17 @@ enum class NodeKind : uint16_t { PrefixUnaryOperatorExpression, PostfixUnaryOperatorExpression, BinaryOperatorExpression, - CxxNullPtrExpression, + ParenExpression, IntegerLiteralExpression, + CharacterLiteralExpression, + FloatingLiteralExpression, + StringLiteralExpression, + BoolLiteralExpression, + CxxNullPtrExpression, + IntegerUserDefinedLiteralExpression, + FloatUserDefinedLiteralExpression, + CharUserDefinedLiteralExpression, + StringUserDefinedLiteralExpression, IdExpression, // Statements. @@ -157,7 +166,8 @@ enum class NodeRole : uint8_t { ParametersAndQualifiers_trailingReturn, IdExpression_id, IdExpression_qualifier, - NestedNameSpecifier_specifier + NestedNameSpecifier_specifier, + ParenExpression_subExpression }; /// For debugging purposes. llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, NodeRole R); @@ -244,7 +254,72 @@ class UnknownExpression final : public Expression { } }; -/// C++11 'nullptr' expression. +/// Models a parenthesized expression `(E)`. C++ [expr.prim.paren] +/// e.g. `(3 + 2)` in `a = 1 + (3 + 2);` +class ParenExpression final : public Expression { +public: + ParenExpression() : Expression(NodeKind::ParenExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::ParenExpression; + } + syntax::Leaf *openParen(); + syntax::Expression *subExpression(); + syntax::Leaf *closeParen(); +}; + +/// Expression for integer literals. C++ [lex.icon] +class IntegerLiteralExpression final : public Expression { +public: + IntegerLiteralExpression() : Expression(NodeKind::IntegerLiteralExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::IntegerLiteralExpression; + } + syntax::Leaf *literalToken(); +}; + +/// Expression for character literals. C++ [lex.ccon] +class CharacterLiteralExpression final : public Expression { +public: + CharacterLiteralExpression() + : Expression(NodeKind::CharacterLiteralExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::CharacterLiteralExpression; + } + syntax::Leaf *literalToken(); +}; + +/// Expression for floating-point literals. C++ [lex.fcon] +class FloatingLiteralExpression final : public Expression { +public: + FloatingLiteralExpression() + : Expression(NodeKind::FloatingLiteralExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::FloatingLiteralExpression; + } + syntax::Leaf *literalToken(); +}; + +/// Expression for string-literals. C++ [lex.string] +class StringLiteralExpression final : public Expression { +public: + StringLiteralExpression() : Expression(NodeKind::StringLiteralExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::StringLiteralExpression; + } + syntax::Leaf *literalToken(); +}; + +/// Expression for boolean literals. C++ [lex.bool] +class BoolLiteralExpression final : public Expression { +public: + BoolLiteralExpression() : Expression(NodeKind::BoolLiteralExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::BoolLiteralExpression; + } + syntax::Leaf *literalToken(); +}; + +/// Expression for the `nullptr` literal. C++ [lex.nullptr] class CxxNullPtrExpression final : public Expression { public: CxxNullPtrExpression() : Expression(NodeKind::CxxNullPtrExpression) {} @@ -254,16 +329,72 @@ class CxxNullPtrExpression final : public Expression { syntax::Leaf *nullPtrKeyword(); }; -/// Expression for integer literals. -class IntegerLiteralExpression final : public Expression { +/// Expression for user-defined literal. C++ [lex.ext] +/// user-defined-literal: +/// user-defined-integer-literal +/// user-defined-floating-point-literal +/// user-defined-string-literal +/// user-defined-character-literal +class UserDefinedLiteralExpression : public Expression { public: - IntegerLiteralExpression() : Expression(NodeKind::IntegerLiteralExpression) {} + UserDefinedLiteralExpression(NodeKind K) : Expression(K) {} static bool classof(const Node *N) { - return N->kind() == NodeKind::IntegerLiteralExpression; + return N->kind() == NodeKind::IntegerUserDefinedLiteralExpression || + N->kind() == NodeKind::FloatUserDefinedLiteralExpression || + N->kind() == NodeKind::CharUserDefinedLiteralExpression || + N->kind() == NodeKind::StringUserDefinedLiteralExpression; } syntax::Leaf *literalToken(); }; +/// Expression for user-defined-integer-literal. C++ [lex.ext] +class IntegerUserDefinedLiteralExpression final + : public UserDefinedLiteralExpression { +public: + IntegerUserDefinedLiteralExpression() + : UserDefinedLiteralExpression( + NodeKind::IntegerUserDefinedLiteralExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::IntegerUserDefinedLiteralExpression; + } +}; + +/// Expression for user-defined-floating-point-literal. C++ [lex.ext] +class FloatUserDefinedLiteralExpression final + : public UserDefinedLiteralExpression { +public: + FloatUserDefinedLiteralExpression() + : UserDefinedLiteralExpression( + NodeKind::FloatUserDefinedLiteralExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::FloatUserDefinedLiteralExpression; + } +}; + +/// Expression for user-defined-character-literal. C++ [lex.ext] +class CharUserDefinedLiteralExpression final + : public UserDefinedLiteralExpression { +public: + CharUserDefinedLiteralExpression() + : UserDefinedLiteralExpression( + NodeKind::CharUserDefinedLiteralExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::CharUserDefinedLiteralExpression; + } +}; + +/// Expression for user-defined-string-literal. C++ [lex.ext] +class StringUserDefinedLiteralExpression final + : public UserDefinedLiteralExpression { +public: + StringUserDefinedLiteralExpression() + : UserDefinedLiteralExpression( + NodeKind::StringUserDefinedLiteralExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::StringUserDefinedLiteralExpression; + } +}; + /// An abstract class for prefix and postfix unary operators. class UnaryOperatorExpression : public Expression { public: diff --git a/clang/include/clang/Tooling/Transformer/RangeSelector.h b/clang/include/clang/Tooling/Transformer/RangeSelector.h index eaab3fc4c0c78..2807037bc208f 100644 --- a/clang/include/clang/Tooling/Transformer/RangeSelector.h +++ b/clang/include/clang/Tooling/Transformer/RangeSelector.h @@ -32,10 +32,20 @@ inline RangeSelector charRange(CharSourceRange R) { } /// Selects from the start of \p Begin and to the end of \p End. -RangeSelector range(RangeSelector Begin, RangeSelector End); +RangeSelector enclose(RangeSelector Begin, RangeSelector End); /// Convenience version of \c range where end-points are bound nodes. -RangeSelector range(std::string BeginID, std::string EndID); +RangeSelector encloseNodes(std::string BeginID, std::string EndID); + +/// DEPRECATED. Use `enclose`. +inline RangeSelector range(RangeSelector Begin, RangeSelector End) { + return enclose(std::move(Begin), std::move(End)); +} + +/// DEPRECATED. Use `encloseNodes`. +inline RangeSelector range(std::string BeginID, std::string EndID) { + return encloseNodes(std::move(BeginID), std::move(EndID)); +} /// Selects the (empty) range [B,B) when \p Selector selects the range [B,E). RangeSelector before(RangeSelector Selector); diff --git a/clang/include/clang/Tooling/Transformer/RewriteRule.h b/clang/include/clang/Tooling/Transformer/RewriteRule.h index 0a961ccc475df..d9e68717d5c8f 100644 --- a/clang/include/clang/Tooling/Transformer/RewriteRule.h +++ b/clang/include/clang/Tooling/Transformer/RewriteRule.h @@ -21,6 +21,7 @@ #include "clang/Tooling/Refactoring/AtomicChange.h" #include "clang/Tooling/Transformer/MatchConsumer.h" #include "clang/Tooling/Transformer/RangeSelector.h" +#include "llvm/ADT/Any.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Error.h" @@ -35,6 +36,7 @@ namespace transformer { struct Edit { CharSourceRange Range; std::string Replacement; + llvm::Any Metadata; }; /// Maps a match result to a list of concrete edits (with possible @@ -85,6 +87,7 @@ struct ASTEdit { RangeSelector TargetRange; TextGenerator Replacement; TextGenerator Note; + llvm::Any Metadata; }; /// Lifts a list of `ASTEdit`s into an `EditGenerator`. @@ -258,6 +261,11 @@ inline ASTEdit insertAfter(RangeSelector S, TextGenerator Replacement) { /// Removes the source selected by \p S. ASTEdit remove(RangeSelector S); +inline ASTEdit withMetadata(ASTEdit edit, llvm::Any Metadata) { + edit.Metadata = std::move(Metadata); + return edit; +} + /// The following three functions are a low-level part of the RewriteRule /// API. We expose them for use in implementing the fixtures that interpret /// RewriteRule, like Transformer and TransfomerTidy, or for more advanced diff --git a/clang/include/clang/Tooling/Transformer/Stencil.h b/clang/include/clang/Tooling/Transformer/Stencil.h index 0363b689dc5b7..1b50a670f70b6 100644 --- a/clang/include/clang/Tooling/Transformer/Stencil.h +++ b/clang/include/clang/Tooling/Transformer/Stencil.h @@ -69,14 +69,6 @@ template Stencil cat(Ts &&... Parts) { // Functions for conveniently building stencils. // -/// DEPRECATED: Use `cat` instead. -/// \returns exactly the text provided. -Stencil text(llvm::StringRef Text); - -/// DEPRECATED: Use `cat` instead. -/// \returns the source corresponding to the selected range. -Stencil selection(RangeSelector Selector); - /// Generates the source of the expression bound to \p Id, wrapping it in /// parentheses if it may parse differently depending on context. For example, a /// binary operation is always wrapped, while a variable reference is never @@ -112,7 +104,7 @@ Stencil maybeAddressOf(llvm::StringRef ExprId); /// Additionally, `e` is wrapped in parentheses, if needed. Stencil access(llvm::StringRef BaseId, Stencil Member); inline Stencil access(llvm::StringRef BaseId, llvm::StringRef Member) { - return access(BaseId, text(Member)); + return access(BaseId, detail::makeStencil(Member)); } /// Chooses between the two stencil parts, based on whether \p ID is bound in @@ -123,7 +115,8 @@ Stencil ifBound(llvm::StringRef Id, Stencil TrueStencil, Stencil FalseStencil); /// match. inline Stencil ifBound(llvm::StringRef Id, llvm::StringRef TrueText, llvm::StringRef FalseText) { - return ifBound(Id, text(TrueText), text(FalseText)); + return ifBound(Id, detail::makeStencil(TrueText), + detail::makeStencil(FalseText)); } /// Wraps a \c MatchConsumer in a \c Stencil, so that it can be used in a \c diff --git a/clang/include/clang/module.modulemap b/clang/include/clang/module.modulemap index 7549ff2e3bcd6..13d4dbf9dc2e8 100644 --- a/clang/include/clang/module.modulemap +++ b/clang/include/clang/module.modulemap @@ -54,6 +54,7 @@ module Clang_Basic { textual header "Basic/CodeGenOptions.def" textual header "Basic/DiagnosticOptions.def" textual header "Basic/Features.def" + textual header "Basic/FPOptions.def" textual header "Basic/MSP430Target.def" textual header "Basic/LangOptions.def" textual header "Basic/OpenCLExtensions.def" diff --git a/clang/lib/ARCMigrate/CMakeLists.txt b/clang/lib/ARCMigrate/CMakeLists.txt index 619328ca5ca76..6f19bea476daa 100644 --- a/clang/lib/ARCMigrate/CMakeLists.txt +++ b/clang/lib/ARCMigrate/CMakeLists.txt @@ -34,4 +34,7 @@ add_clang_library(clangARCMigrate clangRewrite clangSema clangSerialization + + DEPENDS + omp_gen ) diff --git a/clang/lib/ARCMigrate/TransProperties.cpp b/clang/lib/ARCMigrate/TransProperties.cpp index adfb4bd77ac60..cba2256ef97b0 100644 --- a/clang/lib/ARCMigrate/TransProperties.cpp +++ b/clang/lib/ARCMigrate/TransProperties.cpp @@ -287,7 +287,10 @@ class PropertiesRewriter { public: PlusOneAssign(ObjCIvarDecl *D) : Ivar(D) {} - bool VisitBinAssign(BinaryOperator *E) { + bool VisitBinaryOperator(BinaryOperator *E) { + if (E->getOpcode() != BO_Assign) + return true; + Expr *lhs = E->getLHS()->IgnoreParenImpCasts(); if (ObjCIvarRefExpr *RE = dyn_cast(lhs)) { if (RE->getDecl() != Ivar) diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp index 50f8d05dacb4f..f3828bb54c1d3 100644 --- a/clang/lib/AST/APValue.cpp +++ b/clang/lib/AST/APValue.cpp @@ -378,11 +378,6 @@ void APValue::swap(APValue &RHS) { memcpy(RHS.Data.buffer, TmpData, DataSize); } -LLVM_DUMP_METHOD void APValue::dump() const { - dump(llvm::errs()); - llvm::errs() << '\n'; -} - static double GetApproxValue(const llvm::APFloat &F) { llvm::APFloat V = F; bool ignored; @@ -391,85 +386,6 @@ static double GetApproxValue(const llvm::APFloat &F) { return V.convertToDouble(); } -void APValue::dump(raw_ostream &OS) const { - switch (getKind()) { - case None: - OS << "None"; - return; - case Indeterminate: - OS << "Indeterminate"; - return; - case Int: - OS << "Int: " << getInt(); - return; - case Float: - OS << "Float: " << GetApproxValue(getFloat()); - return; - case FixedPoint: - OS << "FixedPoint : " << getFixedPoint(); - return; - case Vector: - OS << "Vector: "; - getVectorElt(0).dump(OS); - for (unsigned i = 1; i != getVectorLength(); ++i) { - OS << ", "; - getVectorElt(i).dump(OS); - } - return; - case ComplexInt: - OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag(); - return; - case ComplexFloat: - OS << "ComplexFloat: " << GetApproxValue(getComplexFloatReal()) - << ", " << GetApproxValue(getComplexFloatImag()); - return; - case LValue: - OS << "LValue: "; - return; - case Array: - OS << "Array: "; - for (unsigned I = 0, N = getArrayInitializedElts(); I != N; ++I) { - getArrayInitializedElt(I).dump(OS); - if (I != getArraySize() - 1) OS << ", "; - } - if (hasArrayFiller()) { - OS << getArraySize() - getArrayInitializedElts() << " x "; - getArrayFiller().dump(OS); - } - return; - case Struct: - OS << "Struct "; - if (unsigned N = getStructNumBases()) { - OS << " bases: "; - getStructBase(0).dump(OS); - for (unsigned I = 1; I != N; ++I) { - OS << ", "; - getStructBase(I).dump(OS); - } - } - if (unsigned N = getStructNumFields()) { - OS << " fields: "; - getStructField(0).dump(OS); - for (unsigned I = 1; I != N; ++I) { - OS << ", "; - getStructField(I).dump(OS); - } - } - return; - case Union: - OS << "Union: "; - getUnionValue().dump(OS); - return; - case MemberPointer: - OS << "MemberPointer: "; - return; - case AddrLabelDiff: - OS << "AddrLabelDiff: "; - return; - } - llvm_unreachable("Unknown APValue kind!"); -} - void APValue::printPretty(raw_ostream &Out, const ASTContext &Ctx, QualType Ty) const { switch (getKind()) { diff --git a/clang/lib/AST/ASTDumper.cpp b/clang/lib/AST/ASTDumper.cpp index d7a25cc827aa4..284e5bdbc6b0f 100644 --- a/clang/lib/AST/ASTDumper.cpp +++ b/clang/lib/AST/ASTDumper.cpp @@ -159,17 +159,22 @@ void QualType::dump(const char *msg) const { dump(); } -LLVM_DUMP_METHOD void QualType::dump() const { dump(llvm::errs()); } +LLVM_DUMP_METHOD void QualType::dump() const { + ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false); + Dumper.Visit(*this); +} -LLVM_DUMP_METHOD void QualType::dump(llvm::raw_ostream &OS) const { - ASTDumper Dumper(OS, nullptr, nullptr); +LLVM_DUMP_METHOD void QualType::dump(llvm::raw_ostream &OS, + const ASTContext &Context) const { + ASTDumper Dumper(OS, Context, Context.getDiagnostics().getShowColors()); Dumper.Visit(*this); } -LLVM_DUMP_METHOD void Type::dump() const { dump(llvm::errs()); } +LLVM_DUMP_METHOD void Type::dump() const { QualType(this, 0).dump(); } -LLVM_DUMP_METHOD void Type::dump(llvm::raw_ostream &OS) const { - QualType(this, 0).dump(OS); +LLVM_DUMP_METHOD void Type::dump(llvm::raw_ostream &OS, + const ASTContext &Context) const { + QualType(this, 0).dump(OS, Context); } //===----------------------------------------------------------------------===// @@ -189,8 +194,7 @@ LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS, bool Deserialize, (void)Deserialize; // FIXME? P.Visit(this); } else { - ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &SM, - SM.getDiagnostics().getShowColors(), Ctx.getPrintingPolicy()); + ASTDumper P(OS, Ctx, Ctx.getDiagnostics().getShowColors()); P.setDeserialize(Deserialize); P.Visit(this); } @@ -198,9 +202,7 @@ LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS, bool Deserialize, LLVM_DUMP_METHOD void Decl::dumpColor() const { const ASTContext &Ctx = getASTContext(); - ASTDumper P(llvm::errs(), &Ctx.getCommentCommandTraits(), - &Ctx.getSourceManager(), /*ShowColors*/ true, - Ctx.getPrintingPolicy()); + ASTDumper P(llvm::errs(), Ctx, /*ShowColors=*/true); P.Visit(this); } @@ -214,10 +216,8 @@ LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS, const DeclContext *DC = this; while (!DC->isTranslationUnit()) DC = DC->getParent(); - ASTContext &Ctx = cast(DC)->getASTContext(); - const SourceManager &SM = Ctx.getSourceManager(); - ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager(), - SM.getDiagnostics().getShowColors(), Ctx.getPrintingPolicy()); + const ASTContext &Ctx = cast(DC)->getASTContext(); + ASTDumper P(OS, Ctx, Ctx.getDiagnostics().getShowColors()); P.setDeserialize(Deserialize); P.dumpLookups(this, DumpDecls); } @@ -226,27 +226,19 @@ LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS, // Stmt method implementations //===----------------------------------------------------------------------===// -LLVM_DUMP_METHOD void Stmt::dump(SourceManager &SM) const { - dump(llvm::errs(), SM); -} - -LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS, SourceManager &SM) const { - ASTDumper P(OS, nullptr, &SM); - P.Visit(this); -} - -LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS) const { - ASTDumper P(OS, nullptr, nullptr); +LLVM_DUMP_METHOD void Stmt::dump() const { + ASTDumper P(llvm::errs(), /*ShowColors=*/false); P.Visit(this); } -LLVM_DUMP_METHOD void Stmt::dump() const { - ASTDumper P(llvm::errs(), nullptr, nullptr); +LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS, + const ASTContext &Context) const { + ASTDumper P(OS, Context, Context.getDiagnostics().getShowColors()); P.Visit(this); } LLVM_DUMP_METHOD void Stmt::dumpColor() const { - ASTDumper P(llvm::errs(), nullptr, nullptr, /*ShowColors*/true); + ASTDumper P(llvm::errs(), /*ShowColors=*/true); P.Visit(this); } @@ -255,27 +247,42 @@ LLVM_DUMP_METHOD void Stmt::dumpColor() const { //===----------------------------------------------------------------------===// LLVM_DUMP_METHOD void Comment::dump() const { - dump(llvm::errs(), nullptr, nullptr); -} - -LLVM_DUMP_METHOD void Comment::dump(const ASTContext &Context) const { - dump(llvm::errs(), &Context.getCommentCommandTraits(), - &Context.getSourceManager()); + const auto *FC = dyn_cast(this); + if (!FC) + return; + ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false); + Dumper.Visit(FC, FC); } -void Comment::dump(raw_ostream &OS, const CommandTraits *Traits, - const SourceManager *SM) const { - const FullComment *FC = dyn_cast(this); +LLVM_DUMP_METHOD void Comment::dump(raw_ostream &OS, + const ASTContext &Context) const { + const auto *FC = dyn_cast(this); if (!FC) return; - ASTDumper D(OS, Traits, SM); - D.Visit(FC, FC); + ASTDumper Dumper(OS, Context, Context.getDiagnostics().getShowColors()); + Dumper.Visit(FC, FC); } LLVM_DUMP_METHOD void Comment::dumpColor() const { - const FullComment *FC = dyn_cast(this); + const auto *FC = dyn_cast(this); if (!FC) return; - ASTDumper D(llvm::errs(), nullptr, nullptr, /*ShowColors*/true); - D.Visit(FC, FC); + ASTDumper Dumper(llvm::errs(), /*ShowColors=*/true); + Dumper.Visit(FC, FC); +} + +//===----------------------------------------------------------------------===// +// APValue method implementations +//===----------------------------------------------------------------------===// + +LLVM_DUMP_METHOD void APValue::dump() const { + ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false); + Dumper.Visit(*this, /*Ty=*/QualType()); +} + +LLVM_DUMP_METHOD void APValue::dump(raw_ostream &OS, + const ASTContext &Context) const { + ASTDumper Dumper(llvm::errs(), Context, + Context.getDiagnostics().getShowColors()); + Dumper.Visit(*this, /*Ty=*/Context.getPointerType(Context.CharTy)); } diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 8b96e20e374d3..3779e0cb872b5 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -3646,6 +3646,54 @@ ExpectedDecl ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) { return ToIndirectField; } +/// Used as return type of getFriendCountAndPosition. +struct FriendCountAndPosition { + /// Number of similar looking friends. + unsigned int TotalCount; + /// Index of the specific FriendDecl. + unsigned int IndexOfDecl; +}; + +template +static FriendCountAndPosition getFriendCountAndPosition( + const FriendDecl *FD, + llvm::function_ref GetCanTypeOrDecl) { + unsigned int FriendCount = 0; + llvm::Optional FriendPosition; + const auto *RD = cast(FD->getLexicalDeclContext()); + + T TypeOrDecl = GetCanTypeOrDecl(FD); + + for (const FriendDecl *FoundFriend : RD->friends()) { + if (FoundFriend == FD) { + FriendPosition = FriendCount; + ++FriendCount; + } else if (!FoundFriend->getFriendDecl() == !FD->getFriendDecl() && + GetCanTypeOrDecl(FoundFriend) == TypeOrDecl) { + ++FriendCount; + } + } + + assert(FriendPosition && "Friend decl not found in own parent."); + + return {FriendCount, *FriendPosition}; +} + +static FriendCountAndPosition getFriendCountAndPosition(const FriendDecl *FD) { + if (FD->getFriendType()) + return getFriendCountAndPosition(FD, [](const FriendDecl *F) { + if (TypeSourceInfo *TSI = F->getFriendType()) + return TSI->getType().getCanonicalType(); + llvm_unreachable("Wrong friend object type."); + }); + else + return getFriendCountAndPosition(FD, [](const FriendDecl *F) { + if (Decl *D = F->getFriendDecl()) + return D->getCanonicalDecl(); + llvm_unreachable("Wrong friend object type."); + }); +} + ExpectedDecl ASTNodeImporter::VisitFriendDecl(FriendDecl *D) { // Import the major distinguishing characteristics of a declaration. DeclContext *DC, *LexicalDC; @@ -3654,25 +3702,37 @@ ExpectedDecl ASTNodeImporter::VisitFriendDecl(FriendDecl *D) { // Determine whether we've already imported this decl. // FriendDecl is not a NamedDecl so we cannot use lookup. - auto *RD = cast(DC); + // We try to maintain order and count of redundant friend declarations. + const auto *RD = cast(DC); FriendDecl *ImportedFriend = RD->getFirstFriend(); + SmallVector ImportedEquivalentFriends; while (ImportedFriend) { + bool Match = false; if (D->getFriendDecl() && ImportedFriend->getFriendDecl()) { - if (IsStructuralMatch(D->getFriendDecl(), ImportedFriend->getFriendDecl(), - /*Complain=*/false)) - return Importer.MapImported(D, ImportedFriend); - + Match = + IsStructuralMatch(D->getFriendDecl(), ImportedFriend->getFriendDecl(), + /*Complain=*/false); } else if (D->getFriendType() && ImportedFriend->getFriendType()) { - if (Importer.IsStructurallyEquivalent( - D->getFriendType()->getType(), - ImportedFriend->getFriendType()->getType(), true)) - return Importer.MapImported(D, ImportedFriend); + Match = Importer.IsStructurallyEquivalent( + D->getFriendType()->getType(), + ImportedFriend->getFriendType()->getType(), /*Complain=*/false); } + if (Match) + ImportedEquivalentFriends.push_back(ImportedFriend); + ImportedFriend = ImportedFriend->getNextFriend(); } + FriendCountAndPosition CountAndPosition = getFriendCountAndPosition(D); + + assert(ImportedEquivalentFriends.size() <= CountAndPosition.TotalCount && + "Class with non-matching friends is imported, ODR check wrong?"); + if (ImportedEquivalentFriends.size() == CountAndPosition.TotalCount) + return Importer.MapImported( + D, ImportedEquivalentFriends[CountAndPosition.IndexOfDecl]); // Not found. Create it. + // The declarations will be put into order later by ImportDeclContext. FriendDecl::FriendUnion ToFU; if (NamedDecl *FriendD = D->getFriendDecl()) { NamedDecl *ToFriendD; @@ -6057,11 +6117,13 @@ ExpectedStmt ASTNodeImporter::VisitWhileStmt(WhileStmt *S) { auto ToCond = importChecked(Err, S->getCond()); auto ToBody = importChecked(Err, S->getBody()); auto ToWhileLoc = importChecked(Err, S->getWhileLoc()); + auto ToLParenLoc = importChecked(Err, S->getLParenLoc()); + auto ToRParenLoc = importChecked(Err, S->getRParenLoc()); if (Err) return std::move(Err); return WhileStmt::Create(Importer.getToContext(), ToConditionVariable, ToCond, - ToBody, ToWhileLoc); + ToBody, ToWhileLoc, ToLParenLoc, ToRParenLoc); } ExpectedStmt ASTNodeImporter::VisitDoStmt(DoStmt *S) { @@ -6676,7 +6738,7 @@ ExpectedStmt ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) { return UnaryOperator::Create( Importer.getToContext(), ToSubExpr, E->getOpcode(), ToType, E->getValueKind(), E->getObjectKind(), ToOperatorLoc, E->canOverflow(), - E->getFPFeatures(Importer.getFromContext().getLangOpts())); + E->getFPOptionsOverride()); } ExpectedStmt diff --git a/clang/lib/AST/ASTImporterLookupTable.cpp b/clang/lib/AST/ASTImporterLookupTable.cpp index 7390329d4ed8d..4d6fff8f34191 100644 --- a/clang/lib/AST/ASTImporterLookupTable.cpp +++ b/clang/lib/AST/ASTImporterLookupTable.cpp @@ -45,7 +45,11 @@ struct Builder : RecursiveASTVisitor { LT.add(RTy->getAsCXXRecordDecl()); else if (const auto *SpecTy = dyn_cast(Ty)) LT.add(SpecTy->getAsCXXRecordDecl()); - else if (isa(Ty)) { + else if (const auto *SubstTy = + dyn_cast(Ty)) { + if (SubstTy->getAsCXXRecordDecl()) + LT.add(SubstTy->getAsCXXRecordDecl()); + } else if (isa(Ty)) { // We do not put friend typedefs to the lookup table because // ASTImporter does not organize typedefs into redecl chains. } else { diff --git a/clang/lib/AST/ASTTypeTraits.cpp b/clang/lib/AST/ASTTypeTraits.cpp index 37e81e5813eca..34fc587694be9 100644 --- a/clang/lib/AST/ASTTypeTraits.cpp +++ b/clang/lib/AST/ASTTypeTraits.cpp @@ -118,6 +118,8 @@ ASTNodeKind ASTNodeKind::getFromNode(const OMPClause &C) { #define OMP_CLAUSE_NO_CLASS(Enum, Str) \ case llvm::omp::Clause::Enum: \ llvm_unreachable("unexpected OpenMP clause kind"); + default: + break; #include "llvm/Frontend/OpenMP/OMPKinds.def" } llvm_unreachable("invalid stmt kind"); @@ -150,13 +152,14 @@ void DynTypedNode::print(llvm::raw_ostream &OS, OS << "Unable to print values of type " << NodeKind.asStringRef() << "\n"; } -void DynTypedNode::dump(llvm::raw_ostream &OS, SourceManager &SM) const { +void DynTypedNode::dump(llvm::raw_ostream &OS, + const ASTContext &Context) const { if (const Decl *D = get()) D->dump(OS); else if (const Stmt *S = get()) - S->dump(OS, SM); + S->dump(OS, Context); else if (const Type *T = get()) - T->dump(OS); + T->dump(OS, Context); else OS << "Unable to dump values of type " << NodeKind.asStringRef() << "\n"; } diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt index 6018d32af8f8f..35099fd0dacf8 100644 --- a/clang/lib/AST/CMakeLists.txt +++ b/clang/lib/AST/CMakeLists.txt @@ -119,4 +119,5 @@ add_clang_library(clangAST DEPENDS Opcodes + omp_gen ) diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 1676f319394dd..5c0a98815dd79 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -3623,7 +3623,8 @@ bool FunctionDecl::isTemplateInstantiation() const { return clang::isTemplateInstantiation(getTemplateSpecializationKind()); } -FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const { +FunctionDecl * +FunctionDecl::getTemplateInstantiationPattern(bool ForDefinition) const { // If this is a generic lambda call operator specialization, its // instantiation pattern is always its primary template's pattern // even if its primary template was instantiated from another @@ -3640,18 +3641,20 @@ FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const { } if (MemberSpecializationInfo *Info = getMemberSpecializationInfo()) { - if (!clang::isTemplateInstantiation(Info->getTemplateSpecializationKind())) + if (ForDefinition && + !clang::isTemplateInstantiation(Info->getTemplateSpecializationKind())) return nullptr; return getDefinitionOrSelf(cast(Info->getInstantiatedFrom())); } - if (!clang::isTemplateInstantiation(getTemplateSpecializationKind())) + if (ForDefinition && + !clang::isTemplateInstantiation(getTemplateSpecializationKind())) return nullptr; if (FunctionTemplateDecl *Primary = getPrimaryTemplate()) { // If we hit a point where the user provided a specialization of this // template, we're done looking. - while (!Primary->isMemberSpecialization()) { + while (!ForDefinition || !Primary->isMemberSpecialization()) { auto *NewPrimary = Primary->getInstantiatedFromMemberTemplate(); if (!NewPrimary) break; diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 2aab53f4fa908..da1eadd9d931d 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -240,15 +240,47 @@ TemplateDecl *Decl::getDescribedTemplate() const { return nullptr; } +const TemplateParameterList *Decl::getDescribedTemplateParams() const { + if (auto *TD = getDescribedTemplate()) + return TD->getTemplateParameters(); + if (auto *CTPSD = dyn_cast(this)) + return CTPSD->getTemplateParameters(); + if (auto *VTPSD = dyn_cast(this)) + return VTPSD->getTemplateParameters(); + return nullptr; +} + bool Decl::isTemplated() const { - // A declaration is dependent if it is a template or a template pattern, or + // A declaration is templated if it is a template or a template pattern, or // is within (lexcially for a friend, semantically otherwise) a dependent // context. // FIXME: Should local extern declarations be treated like friends? if (auto *AsDC = dyn_cast(this)) return AsDC->isDependentContext(); auto *DC = getFriendObjectKind() ? getLexicalDeclContext() : getDeclContext(); - return DC->isDependentContext() || isTemplateDecl() || getDescribedTemplate(); + return DC->isDependentContext() || isTemplateDecl() || + getDescribedTemplateParams(); +} + +unsigned Decl::getTemplateDepth() const { + if (auto *DC = dyn_cast(this)) + if (DC->isFileContext()) + return 0; + + if (auto *TPL = getDescribedTemplateParams()) + return TPL->getDepth() + 1; + + // If this is a dependent lambda, there might be an enclosing variable + // template. In this case, the next step is not the parent DeclContext (or + // even a DeclContext at all). + auto *RD = dyn_cast(this); + if (RD && RD->isDependentLambda()) + if (Decl *Context = RD->getLambdaContextDecl()) + return Context->getTemplateDepth(); + + const DeclContext *DC = + getFriendObjectKind() ? getLexicalDeclContext() : getDeclContext(); + return cast(DC)->getTemplateDepth(); } const DeclContext *Decl::getParentFunctionOrMethod() const { @@ -332,8 +364,10 @@ void Decl::setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC, } } -bool Decl::isInLocalScope() const { +bool Decl::isInLocalScopeForInstantiation() const { const DeclContext *LDC = getLexicalDeclContext(); + if (!LDC->isDependentContext()) + return false; while (true) { if (LDC->isFunctionOrMethod()) return true; diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index 4df6512e6c76c..2e48b2b46c4da 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -1374,7 +1374,12 @@ void DeclPrinter::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) { } void DeclPrinter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *PID) { - Out << "@implementation " << *PID->getClassInterface() << '(' << *PID <<")\n"; + Out << "@implementation "; + if (const auto *CID = PID->getClassInterface()) + Out << *CID; + else + Out << "<>"; + Out << '(' << *PID << ")\n"; VisitDeclContext(PID, false); Out << "@end"; @@ -1382,7 +1387,11 @@ void DeclPrinter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *PID) { } void DeclPrinter::VisitObjCCategoryDecl(ObjCCategoryDecl *PID) { - Out << "@interface " << *PID->getClassInterface(); + Out << "@interface "; + if (const auto *CID = PID->getClassInterface()) + Out << *CID; + else + Out << "<>"; if (auto TypeParams = PID->getTypeParamList()) { PrintObjCTypeParams(TypeParams); } diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 5cbd66f11601c..343a271c33944 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -3812,6 +3812,11 @@ Expr::isNullPointerConstant(ASTContext &Ctx, return Source->isNullPointerConstant(Ctx, NPC); } + // If the expression has no type information, it cannot be a null pointer + // constant. + if (getType().isNull()) + return NPCK_NotNull; + // C++11 nullptr_t is always a null pointer constant. if (getType()->isNullPtrType()) return NPCK_CXX11_nullptr; @@ -4463,7 +4468,7 @@ ParenListExpr *ParenListExpr::CreateEmpty(const ASTContext &Ctx, BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, - FPOptions FPFeatures) + FPOptionsOverride FPFeatures) : Expr(BinaryOperatorClass, ResTy, VK, OK) { BinaryOperatorBits.Opc = opc; assert(!isCompoundAssignmentOp() && @@ -4471,8 +4476,7 @@ BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, BinaryOperatorBits.OpLoc = opLoc; SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; - BinaryOperatorBits.HasFPFeatures = - FPFeatures.requiresTrailingStorage(Ctx.getLangOpts()); + BinaryOperatorBits.HasFPFeatures = FPFeatures.requiresTrailingStorage(); if (BinaryOperatorBits.HasFPFeatures) *getTrailingFPFeatures() = FPFeatures; setDependence(computeDependence(this)); @@ -4481,7 +4485,7 @@ BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, - FPOptions FPFeatures, bool dead2) + FPOptionsOverride FPFeatures, bool dead2) : Expr(CompoundAssignOperatorClass, ResTy, VK, OK) { BinaryOperatorBits.Opc = opc; assert(isCompoundAssignmentOp() && @@ -4489,8 +4493,7 @@ BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, BinaryOperatorBits.OpLoc = opLoc; SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; - BinaryOperatorBits.HasFPFeatures = - FPFeatures.requiresTrailingStorage(Ctx.getLangOpts()); + BinaryOperatorBits.HasFPFeatures = FPFeatures.requiresTrailingStorage(); if (BinaryOperatorBits.HasFPFeatures) *getTrailingFPFeatures() = FPFeatures; setDependence(computeDependence(this)); @@ -4508,8 +4511,8 @@ BinaryOperator *BinaryOperator::Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, - FPOptions FPFeatures) { - bool HasFPFeatures = FPFeatures.requiresTrailingStorage(C.getLangOpts()); + FPOptionsOverride FPFeatures) { + bool HasFPFeatures = FPFeatures.requiresTrailingStorage(); unsigned Extra = sizeOfTrailingObjects(HasFPFeatures); void *Mem = C.Allocate(sizeof(BinaryOperator) + Extra, alignof(BinaryOperator)); @@ -4525,11 +4528,13 @@ CompoundAssignOperator::CreateEmpty(const ASTContext &C, bool HasFPFeatures) { return new (Mem) CompoundAssignOperator(C, EmptyShell(), HasFPFeatures); } -CompoundAssignOperator *CompoundAssignOperator::Create( - const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, - ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, - FPOptions FPFeatures, QualType CompLHSType, QualType CompResultType) { - bool HasFPFeatures = FPFeatures.requiresTrailingStorage(C.getLangOpts()); +CompoundAssignOperator * +CompoundAssignOperator::Create(const ASTContext &C, Expr *lhs, Expr *rhs, + Opcode opc, QualType ResTy, ExprValueKind VK, + ExprObjectKind OK, SourceLocation opLoc, + FPOptionsOverride FPFeatures, + QualType CompLHSType, QualType CompResultType) { + bool HasFPFeatures = FPFeatures.requiresTrailingStorage(); unsigned Extra = sizeOfTrailingObjects(HasFPFeatures); void *Mem = C.Allocate(sizeof(CompoundAssignOperator) + Extra, alignof(CompoundAssignOperator)); @@ -4540,7 +4545,7 @@ CompoundAssignOperator *CompoundAssignOperator::Create( UnaryOperator *UnaryOperator::CreateEmpty(const ASTContext &C, bool hasFPFeatures) { - void *Mem = C.Allocate(totalSizeToAlloc(hasFPFeatures), + void *Mem = C.Allocate(totalSizeToAlloc(hasFPFeatures), alignof(UnaryOperator)); return new (Mem) UnaryOperator(hasFPFeatures, EmptyShell()); } @@ -4548,13 +4553,12 @@ UnaryOperator *UnaryOperator::CreateEmpty(const ASTContext &C, UnaryOperator::UnaryOperator(const ASTContext &Ctx, Expr *input, Opcode opc, QualType type, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, bool CanOverflow, - FPOptions FPFeatures) + FPOptionsOverride FPFeatures) : Expr(UnaryOperatorClass, type, VK, OK), Val(input) { UnaryOperatorBits.Opc = opc; UnaryOperatorBits.CanOverflow = CanOverflow; UnaryOperatorBits.Loc = l; - UnaryOperatorBits.HasFPFeatures = - FPFeatures.requiresTrailingStorage(Ctx.getLangOpts()); + UnaryOperatorBits.HasFPFeatures = FPFeatures.requiresTrailingStorage(); setDependence(computeDependence(this)); } @@ -4562,9 +4566,9 @@ UnaryOperator *UnaryOperator::Create(const ASTContext &C, Expr *input, Opcode opc, QualType type, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, bool CanOverflow, - FPOptions FPFeatures) { - bool HasFPFeatures = FPFeatures.requiresTrailingStorage(C.getLangOpts()); - unsigned Size = totalSizeToAlloc(HasFPFeatures); + FPOptionsOverride FPFeatures) { + bool HasFPFeatures = FPFeatures.requiresTrailingStorage(); + unsigned Size = totalSizeToAlloc(HasFPFeatures); void *Mem = C.Allocate(Size, alignof(UnaryOperator)); return new (Mem) UnaryOperator(C, input, opc, type, VK, OK, l, CanOverflow, FPFeatures); @@ -4775,8 +4779,10 @@ QualType OMPArraySectionExpr::getBaseOriginalType(const Expr *Base) { RecoveryExpr::RecoveryExpr(ASTContext &Ctx, QualType T, SourceLocation BeginLoc, SourceLocation EndLoc, ArrayRef SubExprs) - : Expr(RecoveryExprClass, T, VK_LValue, OK_Ordinary), BeginLoc(BeginLoc), - EndLoc(EndLoc), NumExprs(SubExprs.size()) { + : Expr(RecoveryExprClass, T.getNonReferenceType(), + T->isDependentType() ? VK_LValue : getValueKindForType(T), + OK_Ordinary), + BeginLoc(BeginLoc), EndLoc(EndLoc), NumExprs(SubExprs.size()) { assert(!T.isNull()); assert(llvm::all_of(SubExprs, [](Expr* E) { return E != nullptr; })); diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index f9f825b29ed07..5d99f61c579ff 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -525,27 +525,27 @@ CXXOperatorCallExpr::CXXOperatorCallExpr(OverloadedOperatorKind OpKind, Expr *Fn, ArrayRef Args, QualType Ty, ExprValueKind VK, SourceLocation OperatorLoc, - FPOptions FPFeatures, + FPOptionsOverride FPFeatures, ADLCallKind UsesADL) : CallExpr(CXXOperatorCallExprClass, Fn, /*PreArgs=*/{}, Args, Ty, VK, OperatorLoc, /*MinNumArgs=*/0, UsesADL) { CXXOperatorCallExprBits.OperatorKind = OpKind; - CXXOperatorCallExprBits.FPFeatures = FPFeatures.getAsOpaqueInt(); assert( (CXXOperatorCallExprBits.OperatorKind == static_cast(OpKind)) && "OperatorKind overflow!"); - assert((CXXOperatorCallExprBits.FPFeatures == FPFeatures.getAsOpaqueInt()) && - "FPFeatures overflow!"); Range = getSourceRangeImpl(); + Overrides = FPFeatures; } CXXOperatorCallExpr::CXXOperatorCallExpr(unsigned NumArgs, EmptyShell Empty) : CallExpr(CXXOperatorCallExprClass, /*NumPreArgs=*/0, NumArgs, Empty) {} -CXXOperatorCallExpr *CXXOperatorCallExpr::Create( - const ASTContext &Ctx, OverloadedOperatorKind OpKind, Expr *Fn, - ArrayRef Args, QualType Ty, ExprValueKind VK, - SourceLocation OperatorLoc, FPOptions FPFeatures, ADLCallKind UsesADL) { +CXXOperatorCallExpr * +CXXOperatorCallExpr::Create(const ASTContext &Ctx, + OverloadedOperatorKind OpKind, Expr *Fn, + ArrayRef Args, QualType Ty, + ExprValueKind VK, SourceLocation OperatorLoc, + FPOptionsOverride FPFeatures, ADLCallKind UsesADL) { // Allocate storage for the trailing objects of CallExpr. unsigned NumArgs = Args.size(); unsigned SizeOfTrailingObjects = @@ -1118,6 +1118,10 @@ LambdaExpr::LambdaExpr(QualType T, SourceRange IntroducerRange, LambdaExpr::LambdaExpr(EmptyShell Empty, unsigned NumCaptures) : Expr(LambdaExprClass, Empty) { LambdaExprBits.NumCaptures = NumCaptures; + + // Initially don't initialize the body of the LambdaExpr. The body will + // be lazily deserialized when needed. + getStoredStmts()[NumCaptures] = nullptr; // Not one past the end. } LambdaExpr *LambdaExpr::Create(const ASTContext &Context, CXXRecordDecl *Class, @@ -1147,6 +1151,25 @@ LambdaExpr *LambdaExpr::CreateDeserialized(const ASTContext &C, return new (Mem) LambdaExpr(EmptyShell(), NumCaptures); } +void LambdaExpr::initBodyIfNeeded() const { + if (!getStoredStmts()[capture_size()]) { + auto *This = const_cast(this); + This->getStoredStmts()[capture_size()] = getCallOperator()->getBody(); + } +} + +Stmt *LambdaExpr::getBody() const { + initBodyIfNeeded(); + return getStoredStmts()[capture_size()]; +} + +const CompoundStmt *LambdaExpr::getCompoundStmtBody() const { + Stmt *Body = getBody(); + if (const auto *CoroBody = dyn_cast(Body)) + return cast(CoroBody->getBody()); + return cast(Body); +} + bool LambdaExpr::isInitCapture(const LambdaCapture *C) const { return (C->capturesVariable() && C->getCapturedVar()->isInitCapture() && (getCallOperator() == C->getCapturedVar()->getDeclContext())); @@ -1216,6 +1239,17 @@ ArrayRef LambdaExpr::getExplicitTemplateParameters() const { bool LambdaExpr::isMutable() const { return !getCallOperator()->isConst(); } +LambdaExpr::child_range LambdaExpr::children() { + initBodyIfNeeded(); + return child_range(getStoredStmts(), getStoredStmts() + capture_size() + 1); +} + +LambdaExpr::const_child_range LambdaExpr::children() const { + initBodyIfNeeded(); + return const_child_range(getStoredStmts(), + getStoredStmts() + capture_size() + 1); +} + ExprWithCleanups::ExprWithCleanups(Expr *subexpr, bool CleanupsHaveSideEffects, ArrayRef objects) diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp index 42873d090ffa6..31aa734ffedba 100644 --- a/clang/lib/AST/ExprClassification.cpp +++ b/clang/lib/AST/ExprClassification.cpp @@ -130,7 +130,6 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { case Expr::UnresolvedLookupExprClass: case Expr::UnresolvedMemberExprClass: case Expr::TypoExprClass: - case Expr::RecoveryExprClass: case Expr::DependentCoawaitExprClass: case Expr::CXXDependentScopeMemberExprClass: case Expr::DependentScopeDeclRefExprClass: @@ -276,6 +275,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { return Cl::CL_PRValue; } + case Expr::RecoveryExprClass: case Expr::OpaqueValueExprClass: return ClassifyExprValueKind(Lang, E, E->getValueKind()); diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 640bdd0d45e53..a4dc0ccad1e0f 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -2664,6 +2664,155 @@ static bool handleFloatFloatBinOp(EvalInfo &Info, const Expr *E, return true; } +static bool handleLogicalOpForVector(const APInt &LHSValue, + BinaryOperatorKind Opcode, + const APInt &RHSValue, APInt &Result) { + bool LHS = (LHSValue != 0); + bool RHS = (RHSValue != 0); + + if (Opcode == BO_LAnd) + Result = LHS && RHS; + else + Result = LHS || RHS; + return true; +} +static bool handleLogicalOpForVector(const APFloat &LHSValue, + BinaryOperatorKind Opcode, + const APFloat &RHSValue, APInt &Result) { + bool LHS = !LHSValue.isZero(); + bool RHS = !RHSValue.isZero(); + + if (Opcode == BO_LAnd) + Result = LHS && RHS; + else + Result = LHS || RHS; + return true; +} + +static bool handleLogicalOpForVector(const APValue &LHSValue, + BinaryOperatorKind Opcode, + const APValue &RHSValue, APInt &Result) { + // The result is always an int type, however operands match the first. + if (LHSValue.getKind() == APValue::Int) + return handleLogicalOpForVector(LHSValue.getInt(), Opcode, + RHSValue.getInt(), Result); + assert(LHSValue.getKind() == APValue::Float && "Should be no other options"); + return handleLogicalOpForVector(LHSValue.getFloat(), Opcode, + RHSValue.getFloat(), Result); +} + +template +static bool +handleCompareOpForVectorHelper(const APTy &LHSValue, BinaryOperatorKind Opcode, + const APTy &RHSValue, APInt &Result) { + switch (Opcode) { + default: + llvm_unreachable("unsupported binary operator"); + case BO_EQ: + Result = (LHSValue == RHSValue); + break; + case BO_NE: + Result = (LHSValue != RHSValue); + break; + case BO_LT: + Result = (LHSValue < RHSValue); + break; + case BO_GT: + Result = (LHSValue > RHSValue); + break; + case BO_LE: + Result = (LHSValue <= RHSValue); + break; + case BO_GE: + Result = (LHSValue >= RHSValue); + break; + } + + return true; +} + +static bool handleCompareOpForVector(const APValue &LHSValue, + BinaryOperatorKind Opcode, + const APValue &RHSValue, APInt &Result) { + // The result is always an int type, however operands match the first. + if (LHSValue.getKind() == APValue::Int) + return handleCompareOpForVectorHelper(LHSValue.getInt(), Opcode, + RHSValue.getInt(), Result); + assert(LHSValue.getKind() == APValue::Float && "Should be no other options"); + return handleCompareOpForVectorHelper(LHSValue.getFloat(), Opcode, + RHSValue.getFloat(), Result); +} + +// Perform binary operations for vector types, in place on the LHS. +static bool handleVectorVectorBinOp(EvalInfo &Info, const Expr *E, + BinaryOperatorKind Opcode, + APValue &LHSValue, + const APValue &RHSValue) { + assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI && + "Operation not supported on vector types"); + + const auto *VT = E->getType()->castAs(); + unsigned NumElements = VT->getNumElements(); + QualType EltTy = VT->getElementType(); + + // In the cases (typically C as I've observed) where we aren't evaluating + // constexpr but are checking for cases where the LHS isn't yet evaluatable, + // just give up. + if (!LHSValue.isVector()) { + assert(LHSValue.isLValue() && + "A vector result that isn't a vector OR uncalculated LValue"); + Info.FFDiag(E); + return false; + } + + assert(LHSValue.getVectorLength() == NumElements && + RHSValue.getVectorLength() == NumElements && "Different vector sizes"); + + SmallVector ResultElements; + + for (unsigned EltNum = 0; EltNum < NumElements; ++EltNum) { + APValue LHSElt = LHSValue.getVectorElt(EltNum); + APValue RHSElt = RHSValue.getVectorElt(EltNum); + + if (EltTy->isIntegerType()) { + APSInt EltResult{Info.Ctx.getIntWidth(EltTy), + EltTy->isUnsignedIntegerType()}; + bool Success = true; + + if (BinaryOperator::isLogicalOp(Opcode)) + Success = handleLogicalOpForVector(LHSElt, Opcode, RHSElt, EltResult); + else if (BinaryOperator::isComparisonOp(Opcode)) + Success = handleCompareOpForVector(LHSElt, Opcode, RHSElt, EltResult); + else + Success = handleIntIntBinOp(Info, E, LHSElt.getInt(), Opcode, + RHSElt.getInt(), EltResult); + + if (!Success) { + Info.FFDiag(E); + return false; + } + ResultElements.emplace_back(EltResult); + + } else if (EltTy->isFloatingType()) { + assert(LHSElt.getKind() == APValue::Float && + RHSElt.getKind() == APValue::Float && + "Mismatched LHS/RHS/Result Type"); + APFloat LHSFloat = LHSElt.getFloat(); + + if (!handleFloatFloatBinOp(Info, E, LHSFloat, Opcode, + RHSElt.getFloat())) { + Info.FFDiag(E); + return false; + } + + ResultElements.emplace_back(LHSFloat); + } + } + + LHSValue = APValue(ResultElements.data(), ResultElements.size()); + return true; +} + /// Cast an lvalue referring to a base subobject to a derived class, by /// truncating the lvalue's path to the given length. static bool CastToDerivedClass(EvalInfo &Info, const Expr *E, LValue &Result, @@ -2876,7 +3025,7 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, if (Info.checkingPotentialConstantExpression()) return false; if (!Frame || !Frame->Arguments) { - Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); + Info.FFDiag(E, diag::note_constexpr_function_param_value_unknown) << VD; return false; } Result = &Frame->Arguments[PVD->getFunctionScopeIndex()]; @@ -2907,12 +3056,34 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, } // Dig out the initializer, and use the declaration which it's attached to. + // FIXME: We should eventually check whether the variable has a reachable + // initializing declaration. const Expr *Init = VD->getAnyInitializer(VD); - if (!Init || Init->isValueDependent()) { - // If we're checking a potential constant expression, the variable could be - // initialized later. - if (!Info.checkingPotentialConstantExpression()) - Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); + if (!Init) { + // Don't diagnose during potential constant expression checking; an + // initializer might be added later. + if (!Info.checkingPotentialConstantExpression()) { + Info.FFDiag(E, diag::note_constexpr_var_init_unknown, 1) + << VD; + Info.Note(VD->getLocation(), diag::note_declared_at); + } + return false; + } + + if (Init->isValueDependent()) { + // The DeclRefExpr is not value-dependent, but the variable it refers to + // has a value-dependent initializer. This should only happen in + // constant-folding cases, where the variable is not actually of a suitable + // type for use in a constant expression (otherwise the DeclRefExpr would + // have been value-dependent too), so diagnose that. + assert(!VD->mightBeUsableInConstantExpressions(Info.Ctx)); + if (!Info.checkingPotentialConstantExpression()) { + Info.FFDiag(E, Info.getLangOpts().CPlusPlus11 + ? diag::note_constexpr_ltor_non_constexpr + : diag::note_constexpr_ltor_non_integral, 1) + << VD << VD->getType(); + Info.Note(VD->getLocation(), diag::note_declared_at); + } return false; } @@ -2923,13 +3094,6 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, return true; } - // Never evaluate the initializer of a weak variable. We can't be sure that - // this is the definition which will be used. - if (VD->isWeak()) { - Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); - return false; - } - // Check that we can fold the initializer. In C++, we will have already done // this in the cases where it matters for conformance. SmallVector Notes; @@ -2939,13 +3103,24 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, Info.Note(VD->getLocation(), diag::note_declared_at); Info.addNotes(Notes); return false; - } else if (!VD->checkInitIsICE()) { + } + + // Check that the variable is actually usable in constant expressions. + if (!VD->checkInitIsICE()) { Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant, Notes.size() + 1) << VD; Info.Note(VD->getLocation(), diag::note_declared_at); Info.addNotes(Notes); } + // Never use the initializer of a weak variable, not even for constant + // folding. We can't be sure that this is the definition that will be used. + if (VD->isWeak()) { + Info.FFDiag(E, diag::note_constexpr_var_init_weak) << VD; + Info.Note(VD->getLocation(), diag::note_declared_at); + return false; + } + Result = VD->getEvaluatedValue(); return true; } @@ -3648,6 +3823,11 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, return CompleteObject(); } + // In OpenCL if a variable is in constant address space it is a const value. + bool IsConstant = BaseType.isConstQualified() || + (Info.getLangOpts().OpenCL && + BaseType.getAddressSpace() == LangAS::opencl_constant); + // Unless we're looking at a local variable or argument in a constexpr call, // the variable we're reading must be const. if (!Frame) { @@ -3665,9 +3845,7 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, } else if (BaseType->isIntegralOrEnumerationType()) { // In OpenCL if a variable is in constant address space it is a const // value. - if (!(BaseType.isConstQualified() || - (Info.getLangOpts().OpenCL && - BaseType.getAddressSpace() == LangAS::opencl_constant))) { + if (!IsConstant) { if (!IsAccess) return CompleteObject(LVal.getLValueBase(), nullptr, BaseType); if (Info.getLangOpts().CPlusPlus) { @@ -3680,27 +3858,29 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, } } else if (!IsAccess) { return CompleteObject(LVal.getLValueBase(), nullptr, BaseType); - } else if (BaseType->isFloatingType() && BaseType.isConstQualified()) { - // We support folding of const floating-point types, in order to make - // static const data members of such types (supported as an extension) - // more useful. - if (Info.getLangOpts().CPlusPlus11) { - Info.CCEDiag(E, diag::note_constexpr_ltor_non_constexpr, 1) << VD; + } else if (IsConstant && Info.checkingPotentialConstantExpression() && + BaseType->isLiteralType(Info.Ctx) && !VD->hasDefinition()) { + // This variable might end up being constexpr. Don't diagnose it yet. + } else if (IsConstant) { + // Keep evaluating to see what we can do. In particular, we support + // folding of const floating-point types, in order to make static const + // data members of such types (supported as an extension) more useful. + if (Info.getLangOpts().CPlusPlus) { + Info.CCEDiag(E, Info.getLangOpts().CPlusPlus11 + ? diag::note_constexpr_ltor_non_constexpr + : diag::note_constexpr_ltor_non_integral, 1) + << VD << BaseType; Info.Note(VD->getLocation(), diag::note_declared_at); } else { Info.CCEDiag(E); } - } else if (BaseType.isConstQualified() && VD->hasDefinition(Info.Ctx)) { - Info.CCEDiag(E, diag::note_constexpr_ltor_non_constexpr) << VD; - // Keep evaluating to see what we can do. } else { - // FIXME: Allow folding of values of any literal type in all languages. - if (Info.checkingPotentialConstantExpression() && - VD->getType().isConstQualified() && !VD->hasDefinition(Info.Ctx)) { - // The definition of this variable could be constexpr. We can't - // access it right now, but may be able to in future. - } else if (Info.getLangOpts().CPlusPlus11) { - Info.FFDiag(E, diag::note_constexpr_ltor_non_constexpr, 1) << VD; + // Never allow reading a non-const value. + if (Info.getLangOpts().CPlusPlus) { + Info.FFDiag(E, Info.getLangOpts().CPlusPlus11 + ? diag::note_constexpr_ltor_non_constexpr + : diag::note_constexpr_ltor_non_integral, 1) + << VD << BaseType; Info.Note(VD->getLocation(), diag::note_declared_at); } else { Info.FFDiag(E); @@ -3910,12 +4090,26 @@ struct CompoundAssignSubobjectHandler { return false; case APValue::LValue: return foundPointer(Subobj, SubobjType); + case APValue::Vector: + return foundVector(Subobj, SubobjType); default: // FIXME: can this happen? Info.FFDiag(E); return false; } } + + bool foundVector(APValue &Value, QualType SubobjType) { + if (!checkConst(SubobjType)) + return false; + + if (!SubobjType->isVectorType()) { + Info.FFDiag(E); + return false; + } + return handleVectorVectorBinOp(Info, E, Opcode, Value, RHS); + } + bool found(APSInt &Value, QualType SubobjType) { if (!checkConst(SubobjType)) return false; @@ -4312,37 +4506,48 @@ static bool HandleBaseToDerivedCast(EvalInfo &Info, const CastExpr *E, } /// Get the value to use for a default-initialized object of type T. -static APValue getDefaultInitValue(QualType T) { +/// Return false if it encounters something invalid. +static bool getDefaultInitValue(QualType T, APValue &Result) { + bool Success = true; if (auto *RD = T->getAsCXXRecordDecl()) { - if (RD->isUnion()) - return APValue((const FieldDecl*)nullptr); - - APValue Struct(APValue::UninitStruct(), RD->getNumBases(), - std::distance(RD->field_begin(), RD->field_end())); + if (RD->isInvalidDecl()) { + Result = APValue(); + return false; + } + if (RD->isUnion()) { + Result = APValue((const FieldDecl *)nullptr); + return true; + } + Result = APValue(APValue::UninitStruct(), RD->getNumBases(), + std::distance(RD->field_begin(), RD->field_end())); unsigned Index = 0; for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), - End = RD->bases_end(); I != End; ++I, ++Index) - Struct.getStructBase(Index) = getDefaultInitValue(I->getType()); + End = RD->bases_end(); + I != End; ++I, ++Index) + Success &= getDefaultInitValue(I->getType(), Result.getStructBase(Index)); for (const auto *I : RD->fields()) { if (I->isUnnamedBitfield()) continue; - Struct.getStructField(I->getFieldIndex()) = - getDefaultInitValue(I->getType()); + Success &= getDefaultInitValue(I->getType(), + Result.getStructField(I->getFieldIndex())); } - return Struct; + return Success; } if (auto *AT = dyn_cast_or_null(T->getAsArrayTypeUnsafe())) { - APValue Array(APValue::UninitArray(), 0, AT->getSize().getZExtValue()); - if (Array.hasArrayFiller()) - Array.getArrayFiller() = getDefaultInitValue(AT->getElementType()); - return Array; + Result = APValue(APValue::UninitArray(), 0, AT->getSize().getZExtValue()); + if (Result.hasArrayFiller()) + Success &= + getDefaultInitValue(AT->getElementType(), Result.getArrayFiller()); + + return Success; } - return APValue::IndeterminateValue(); + Result = APValue::IndeterminateValue(); + return true; } namespace { @@ -4372,10 +4577,8 @@ static bool EvaluateVarDecl(EvalInfo &Info, const VarDecl *VD) { Info.CurrentCall->createTemporary(VD, VD->getType(), true, Result); const Expr *InitE = VD->getInit(); - if (!InitE) { - Val = getDefaultInitValue(VD->getType()); - return true; - } + if (!InitE) + return getDefaultInitValue(VD->getType(), Val); if (InitE->isValueDependent()) return false; @@ -5372,11 +5575,11 @@ struct StartLifetimeOfUnionMemberHandler { const Expr *LHSExpr; const FieldDecl *Field; bool DuringInit; - + bool Failed = false; static const AccessKinds AccessKind = AK_Assign; typedef bool result_type; - bool failed() { return false; } + bool failed() { return Failed; } bool found(APValue &Subobj, QualType SubobjType) { // We are supposed to perform no initialization but begin the lifetime of // the object. We interpret that as meaning to do what default @@ -5400,8 +5603,9 @@ struct StartLifetimeOfUnionMemberHandler { diag::note_constexpr_union_member_change_during_init); return false; } - - Subobj.setUnion(Field, getDefaultInitValue(Field->getType())); + APValue Result; + Failed = !getDefaultInitValue(Field->getType(), Result); + Subobj.setUnion(Field, Result); return true; } bool found(APSInt &Value, QualType SubobjType) { @@ -5717,8 +5921,9 @@ static bool HandleConstructorCall(const Expr *E, const LValue &This, for (; !declaresSameEntity(*FieldIt, FD); ++FieldIt) { assert(FieldIt != RD->field_end() && "missing field?"); if (!FieldIt->isUnnamedBitfield()) - Result.getStructField(FieldIt->getFieldIndex()) = - getDefaultInitValue(FieldIt->getType()); + Success &= getDefaultInitValue( + FieldIt->getType(), + Result.getStructField(FieldIt->getFieldIndex())); } ++FieldIt; }; @@ -5770,10 +5975,10 @@ static bool HandleConstructorCall(const Expr *E, const LValue &This, if (CD->isUnion()) *Value = APValue(FD); else - // FIXME: This immediately starts the lifetime of all members of an - // anonymous struct. It would be preferable to strictly start member - // lifetime in initialization order. - *Value = getDefaultInitValue(Info.Ctx.getRecordType(CD)); + // FIXME: This immediately starts the lifetime of all members of + // an anonymous struct. It would be preferable to strictly start + // member lifetime in initialization order. + Success &= getDefaultInitValue(Info.Ctx.getRecordType(CD), *Value); } // Store Subobject as its parent before updating it for the last element // in the chain. @@ -5820,8 +6025,9 @@ static bool HandleConstructorCall(const Expr *E, const LValue &This, if (!RD->isUnion()) { for (; FieldIt != RD->field_end(); ++FieldIt) { if (!FieldIt->isUnnamedBitfield()) - Result.getStructField(FieldIt->getFieldIndex()) = - getDefaultInitValue(FieldIt->getType()); + Success &= getDefaultInitValue( + FieldIt->getType(), + Result.getStructField(FieldIt->getFieldIndex())); } } @@ -8907,8 +9113,8 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) { } else if (Init) { if (!EvaluateInPlace(*Val, Info, Result, Init)) return false; - } else { - *Val = getDefaultInitValue(AllocType); + } else if (!getDefaultInitValue(AllocType, *Val)) { + return false; } // Array new returns a pointer to the first element, not a pointer to the @@ -9279,8 +9485,7 @@ bool RecordExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E, if (ZeroInit) return ZeroInitialization(E, T); - Result = getDefaultInitValue(T); - return true; + return getDefaultInitValue(T, Result); } const FunctionDecl *Definition = nullptr; @@ -9516,10 +9721,9 @@ namespace { bool VisitCastExpr(const CastExpr* E); bool VisitInitListExpr(const InitListExpr *E); bool VisitUnaryImag(const UnaryOperator *E); - // FIXME: Missing: unary -, unary ~, binary add/sub/mul/div, - // binary comparisons, binary and/or/xor, - // conditional operator (for GNU conditional select), - // shufflevector, ExtVectorElementExpr + bool VisitBinaryOperator(const BinaryOperator *E); + // FIXME: Missing: unary -, unary ~, conditional operator (for GNU + // conditional select), shufflevector, ExtVectorElementExpr }; } // end anonymous namespace @@ -9667,6 +9871,41 @@ bool VectorExprEvaluator::VisitUnaryImag(const UnaryOperator *E) { return ZeroInitialization(E); } +bool VectorExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { + BinaryOperatorKind Op = E->getOpcode(); + assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp && + "Operation not supported on vector types"); + + if (Op == BO_Comma) + return ExprEvaluatorBaseTy::VisitBinaryOperator(E); + + Expr *LHS = E->getLHS(); + Expr *RHS = E->getRHS(); + + assert(LHS->getType()->isVectorType() && RHS->getType()->isVectorType() && + "Must both be vector types"); + // Checking JUST the types are the same would be fine, except shifts don't + // need to have their types be the same (since you always shift by an int). + assert(LHS->getType()->getAs()->getNumElements() == + E->getType()->getAs()->getNumElements() && + RHS->getType()->getAs()->getNumElements() == + E->getType()->getAs()->getNumElements() && + "All operands must be the same size."); + + APValue LHSValue; + APValue RHSValue; + bool LHSOK = Evaluate(LHSValue, Info, LHS); + if (!LHSOK && !Info.noteFailure()) + return false; + if (!Evaluate(RHSValue, Info, RHS) || !LHSOK) + return false; + + if (!handleVectorVectorBinOp(Info, E, Op, LHSValue, RHSValue)) + return false; + + return Success(LHSValue, E); +} + //===----------------------------------------------------------------------===// // Array Evaluation //===----------------------------------------------------------------------===// @@ -10992,6 +11231,7 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, } case Builtin::BI__builtin_expect: + case Builtin::BI__builtin_expect_with_probability: return Visit(E->getArg(0)); case Builtin::BI__builtin_ffs: @@ -12673,8 +12913,14 @@ bool FixedPointExprEvaluator::VisitCastExpr(const CastExpr *E) { return false; bool Overflowed; APFixedPoint Result = Src.convert(DestFXSema, &Overflowed); - if (Overflowed && !HandleOverflow(Info, E, Result, DestType)) - return false; + if (Overflowed) { + if (Info.checkingForUndefinedBehavior()) + Info.Ctx.getDiagnostics().Report(E->getExprLoc(), + diag::warn_fixedpoint_constant_overflow) + << Result.toString() << E->getType(); + else if (!HandleOverflow(Info, E, Result, E->getType())) + return false; + } return Success(Result, E); } case CK_IntegralToFixedPoint: { @@ -12686,8 +12932,14 @@ bool FixedPointExprEvaluator::VisitCastExpr(const CastExpr *E) { APFixedPoint IntResult = APFixedPoint::getFromIntValue( Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed); - if (Overflowed && !HandleOverflow(Info, E, IntResult, DestType)) - return false; + if (Overflowed) { + if (Info.checkingForUndefinedBehavior()) + Info.Ctx.getDiagnostics().Report(E->getExprLoc(), + diag::warn_fixedpoint_constant_overflow) + << IntResult.toString() << E->getType(); + else if (!HandleOverflow(Info, E, IntResult, E->getType())) + return false; + } return Success(IntResult, E); } @@ -12700,6 +12952,9 @@ bool FixedPointExprEvaluator::VisitCastExpr(const CastExpr *E) { } bool FixedPointExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { + if (E->isPtrMemOp() || E->isAssignmentOp() || E->getOpcode() == BO_Comma) + return ExprEvaluatorBaseTy::VisitBinaryOperator(E); + const Expr *LHS = E->getLHS(); const Expr *RHS = E->getRHS(); FixedPointSemantics ResultFXSema = @@ -12712,20 +12967,45 @@ bool FixedPointExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { if (!EvaluateFixedPointOrInteger(RHS, RHSFX, Info)) return false; + bool OpOverflow = false, ConversionOverflow = false; + APFixedPoint Result(LHSFX.getSemantics()); switch (E->getOpcode()) { case BO_Add: { - bool AddOverflow, ConversionOverflow; - APFixedPoint Result = LHSFX.add(RHSFX, &AddOverflow) - .convert(ResultFXSema, &ConversionOverflow); - if ((AddOverflow || ConversionOverflow) && - !HandleOverflow(Info, E, Result, E->getType())) + Result = LHSFX.add(RHSFX, &OpOverflow) + .convert(ResultFXSema, &ConversionOverflow); + break; + } + case BO_Sub: { + Result = LHSFX.sub(RHSFX, &OpOverflow) + .convert(ResultFXSema, &ConversionOverflow); + break; + } + case BO_Mul: { + Result = LHSFX.mul(RHSFX, &OpOverflow) + .convert(ResultFXSema, &ConversionOverflow); + break; + } + case BO_Div: { + if (RHSFX.getValue() == 0) { + Info.FFDiag(E, diag::note_expr_divide_by_zero); return false; - return Success(Result, E); + } + Result = LHSFX.div(RHSFX, &OpOverflow) + .convert(ResultFXSema, &ConversionOverflow); + break; } default: return false; } - llvm_unreachable("Should've exited before this"); + if (OpOverflow || ConversionOverflow) { + if (Info.checkingForUndefinedBehavior()) + Info.Ctx.getDiagnostics().Report(E->getExprLoc(), + diag::warn_fixedpoint_constant_overflow) + << Result.toString() << E->getType(); + else if (!HandleOverflow(Info, E, Result, E->getType())) + return false; + } + return Success(Result, E); } //===----------------------------------------------------------------------===// @@ -14012,10 +14292,11 @@ bool VarDecl::evaluateDestruction( // Make a copy of the value for the destructor to mutate, if we know it. // Otherwise, treat the value as default-initialized; if the destructor works // anyway, then the destruction is constant (and must be essentially empty). - APValue DestroyedValue = - (getEvaluatedValue() && !getEvaluatedValue()->isAbsent()) - ? *getEvaluatedValue() - : getDefaultInitValue(getType()); + APValue DestroyedValue; + if (getEvaluatedValue() && !getEvaluatedValue()->isAbsent()) + DestroyedValue = *getEvaluatedValue(); + else if (!getDefaultInitValue(getType(), DestroyedValue)) + return false; EvalInfo Info(getASTContext(), EStatus, EvalInfo::EM_ConstantExpression); Info.setEvaluatingDecl(this, DestroyedValue, diff --git a/clang/lib/AST/FormatString.cpp b/clang/lib/AST/FormatString.cpp index e9f6b88631af5..83b952116a5e0 100644 --- a/clang/lib/AST/FormatString.cpp +++ b/clang/lib/AST/FormatString.cpp @@ -419,7 +419,6 @@ ArgType::matchesType(ASTContext &C, QualType argTy) const { QualType pointeeTy = PT->getPointeeType(); if (const BuiltinType *BT = pointeeTy->getAs()) switch (BT->getKind()) { - case BuiltinType::Void: case BuiltinType::Char_U: case BuiltinType::UChar: case BuiltinType::Char_S: diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp index c9a84a2b7d57d..4bd00ece86ab8 100644 --- a/clang/lib/AST/JSONNodeDumper.cpp +++ b/clang/lib/AST/JSONNodeDumper.cpp @@ -183,6 +183,13 @@ void JSONNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) { attributeOnlyIfTrue("selected", A.isSelected()); } +void JSONNodeDumper::Visit(const APValue &Value, QualType Ty) { + std::string Str; + llvm::raw_string_ostream OS(Str); + Value.printPretty(OS, Ctx, Ty); + JOS.attribute("value", OS.str()); +} + void JSONNodeDumper::writeIncludeStack(PresumedLoc Loc, bool JustFirst) { if (Loc.isInvalid()) return; @@ -1272,12 +1279,8 @@ void JSONNodeDumper::VisitCXXTypeidExpr(const CXXTypeidExpr *CTE) { } void JSONNodeDumper::VisitConstantExpr(const ConstantExpr *CE) { - if (CE->getResultAPValueKind() != APValue::None) { - std::string Str; - llvm::raw_string_ostream OS(Str); - CE->getAPValueResult().printPretty(OS, Ctx, CE->getType()); - JOS.attribute("value", OS.str()); - } + if (CE->getResultAPValueKind() != APValue::None) + Visit(CE->getAPValueResult(), CE->getType()); } void JSONNodeDumper::VisitInitListExpr(const InitListExpr *ILE) { diff --git a/clang/lib/AST/Mangle.cpp b/clang/lib/AST/Mangle.cpp index 53f1a48d69a5e..a732325006c66 100644 --- a/clang/lib/AST/Mangle.cpp +++ b/clang/lib/AST/Mangle.cpp @@ -25,6 +25,7 @@ #include "llvm/IR/DataLayout.h" #include "llvm/IR/Mangler.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" using namespace clang; diff --git a/clang/lib/AST/NestedNameSpecifier.cpp b/clang/lib/AST/NestedNameSpecifier.cpp index 87bf4e122ec84..08e8819a4d69d 100644 --- a/clang/lib/AST/NestedNameSpecifier.cpp +++ b/clang/lib/AST/NestedNameSpecifier.cpp @@ -243,6 +243,10 @@ bool NestedNameSpecifier::containsUnexpandedParameterPack() const { return getDependence() & NestedNameSpecifierDependence::UnexpandedPack; } +bool NestedNameSpecifier::containsErrors() const { + return getDependence() & NestedNameSpecifierDependence::Error; +} + /// Print this nested name specifier to the given output /// stream. void NestedNameSpecifier::print(raw_ostream &OS, const PrintingPolicy &Policy, diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index 6a8b3ce231f2f..a0b0dca553907 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -51,6 +51,8 @@ OMPClause::child_range OMPClause::used_children() { case OMPC_match: case OMPC_unknown: break; + default: + break; } llvm_unreachable("unknown OMPClause"); } @@ -154,6 +156,8 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) { case OMPC_uses_allocators: case OMPC_affinity: break; + default: + break; } return nullptr; @@ -246,6 +250,8 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C) case OMPC_uses_allocators: case OMPC_affinity: break; + default: + break; } return nullptr; diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index 028e82a5df4d7..d56c7e2ab8c0e 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -15,6 +15,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" +#include "clang/AST/VTableBuilder.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/SmallSet.h" #include "llvm/Support/Format.h" @@ -1186,11 +1187,10 @@ ItaniumRecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) { // Query the external layout to see if it provides an offset. bool HasExternalLayout = false; if (UseExternalLayout) { - // FIXME: This appears to be reversed. if (Base->IsVirtual) - HasExternalLayout = External.getExternalNVBaseOffset(Base->Class, Offset); - else HasExternalLayout = External.getExternalVBaseOffset(Base->Class, Offset); + else + HasExternalLayout = External.getExternalNVBaseOffset(Base->Class, Offset); } // Clang <= 6 incorrectly applied the 'packed' attribute to base classes. @@ -2107,7 +2107,7 @@ static const CXXMethodDecl *computeKeyFunction(ASTContext &Context, if (MD->isImplicit()) continue; - if (MD->isInlineSpecified()) + if (MD->isInlineSpecified() || MD->isConstexpr()) continue; if (MD->hasInlineBody()) @@ -2568,9 +2568,11 @@ MicrosoftRecordLayoutBuilder::layoutNonVirtualBases(const CXXRecordDecl *RD) { // information about the bases, such as required alignment and the presence of // zero sized members. const ASTRecordLayout *PreviousBaseLayout = nullptr; + bool HasPolymorphicBaseClass = false; // Iterate through the bases and lay out the non-virtual ones. for (const CXXBaseSpecifier &Base : RD->bases()) { const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl(); + HasPolymorphicBaseClass |= BaseDecl->isPolymorphic(); const ASTRecordLayout &BaseLayout = Context.getASTRecordLayout(BaseDecl); // Mark and skip virtual bases. if (Base.isVirtual()) { @@ -2594,11 +2596,23 @@ MicrosoftRecordLayoutBuilder::layoutNonVirtualBases(const CXXRecordDecl *RD) { layoutNonVirtualBase(RD, BaseDecl, BaseLayout, PreviousBaseLayout); } // Figure out if we need a fresh VFPtr for this class. - if (!PrimaryBase && RD->isDynamicClass()) - for (CXXRecordDecl::method_iterator i = RD->method_begin(), - e = RD->method_end(); - !HasOwnVFPtr && i != e; ++i) - HasOwnVFPtr = i->isVirtual() && i->size_overridden_methods() == 0; + if (RD->isPolymorphic()) { + if (!HasPolymorphicBaseClass) + // This class introduces polymorphism, so we need a vftable to store the + // RTTI information. + HasOwnVFPtr = true; + else if (!PrimaryBase) { + // We have a polymorphic base class but can't extend its vftable. Add a + // new vfptr if we would use any vftable slots. + for (CXXMethodDecl *M : RD->methods()) { + if (MicrosoftVTableContext::hasVtableSlot(M) && + M->size_overridden_methods() == 0) { + HasOwnVFPtr = true; + break; + } + } + } + } // If we don't have a primary base then we have a leading object that could // itself lead with a zero-sized object, something we track. bool CheckLeadingLayout = !PrimaryBase; @@ -2993,7 +3007,8 @@ void MicrosoftRecordLayoutBuilder::computeVtorDispSet( llvm::SmallPtrSet BasesWithOverriddenMethods; // Seed the working set with our non-destructor, non-pure virtual methods. for (const CXXMethodDecl *MD : RD->methods()) - if (MD->isVirtual() && !isa(MD) && !MD->isPure()) + if (MicrosoftVTableContext::hasVtableSlot(MD) && + !isa(MD) && !MD->isPure()) Work.insert(MD); while (!Work.empty()) { const CXXMethodDecl *MD = *Work.begin(); diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp index ce76d4941b32b..25e685be3e9b1 100644 --- a/clang/lib/AST/Stmt.cpp +++ b/clang/lib/AST/Stmt.cpp @@ -1012,7 +1012,8 @@ void SwitchStmt::setConditionVariable(const ASTContext &Ctx, VarDecl *V) { } WhileStmt::WhileStmt(const ASTContext &Ctx, VarDecl *Var, Expr *Cond, - Stmt *Body, SourceLocation WL) + Stmt *Body, SourceLocation WL, SourceLocation LParenLoc, + SourceLocation RParenLoc) : Stmt(WhileStmtClass) { bool HasVar = Var != nullptr; WhileStmtBits.HasVar = HasVar; @@ -1023,6 +1024,8 @@ WhileStmt::WhileStmt(const ASTContext &Ctx, VarDecl *Var, Expr *Cond, setConditionVariable(Ctx, Var); setWhileLoc(WL); + setLParenLoc(LParenLoc); + setRParenLoc(RParenLoc); } WhileStmt::WhileStmt(EmptyShell Empty, bool HasVar) @@ -1031,12 +1034,14 @@ WhileStmt::WhileStmt(EmptyShell Empty, bool HasVar) } WhileStmt *WhileStmt::Create(const ASTContext &Ctx, VarDecl *Var, Expr *Cond, - Stmt *Body, SourceLocation WL) { + Stmt *Body, SourceLocation WL, + SourceLocation LParenLoc, + SourceLocation RParenLoc) { bool HasVar = Var != nullptr; void *Mem = Ctx.Allocate(totalSizeToAlloc(NumMandatoryStmtPtr + HasVar), alignof(WhileStmt)); - return new (Mem) WhileStmt(Ctx, Var, Cond, Body, WL); + return new (Mem) WhileStmt(Ctx, Var, Cond, Body, WL, LParenLoc, RParenLoc); } WhileStmt *WhileStmt::CreateEmpty(const ASTContext &Ctx, bool HasVar) { diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 11e222f95176d..f797f5fe8e6d1 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -1343,11 +1343,16 @@ void StmtPrinter::VisitOMPArraySectionExpr(OMPArraySectionExpr *Node) { OS << "["; if (Node->getLowerBound()) PrintExpr(Node->getLowerBound()); - if (Node->getColonLoc().isValid()) { + if (Node->getColonLocFirst().isValid()) { OS << ":"; if (Node->getLength()) PrintExpr(Node->getLength()); } + if (Node->getColonLocSecond().isValid()) { + OS << ":"; + if (Node->getStride()) + PrintExpr(Node->getStride()); + } OS << "]"; } diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index 0d49c443e03e2..5b0a0ac392c00 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -11,15 +11,20 @@ //===----------------------------------------------------------------------===// #include "clang/AST/TextNodeDumper.h" +#include "clang/AST/APValue.h" #include "clang/AST/DeclFriend.h" #include "clang/AST/DeclOpenMP.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/LocInfoType.h" +#include "clang/AST/Type.h" #include "clang/Basic/Module.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/Specifiers.h" #include "clang/Basic/TypeTraits.h" +#include +#include + using namespace clang; static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {} @@ -51,12 +56,15 @@ static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) { llvm_unreachable("Decl that isn't part of DeclNodes.inc!"); } -TextNodeDumper::TextNodeDumper(raw_ostream &OS, bool ShowColors, - const SourceManager *SM, - const PrintingPolicy &PrintPolicy, - const comments::CommandTraits *Traits) - : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors), SM(SM), - PrintPolicy(PrintPolicy), Traits(Traits) {} +TextNodeDumper::TextNodeDumper(raw_ostream &OS, const ASTContext &Context, + bool ShowColors) + : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors), + Context(&Context), SM(&Context.getSourceManager()), + PrintPolicy(Context.getPrintingPolicy()), + Traits(&Context.getCommentCommandTraits()) {} + +TextNodeDumper::TextNodeDumper(raw_ostream &OS, bool ShowColors) + : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors) {} void TextNodeDumper::Visit(const comments::Comment *C, const comments::FullComment *FC) { @@ -347,6 +355,218 @@ void TextNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) { OS << " selected"; } +static double GetApproxValue(const llvm::APFloat &F) { + llvm::APFloat V = F; + bool ignored; + V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven, + &ignored); + return V.convertToDouble(); +} + +/// True if the \p APValue \p Value can be folded onto the current line. +static bool isSimpleAPValue(const APValue &Value) { + switch (Value.getKind()) { + case APValue::None: + case APValue::Indeterminate: + case APValue::Int: + case APValue::Float: + case APValue::FixedPoint: + case APValue::ComplexInt: + case APValue::ComplexFloat: + case APValue::LValue: + case APValue::MemberPointer: + case APValue::AddrLabelDiff: + return true; + case APValue::Vector: + case APValue::Array: + case APValue::Struct: + return false; + case APValue::Union: + return isSimpleAPValue(Value.getUnionValue()); + } + llvm_unreachable("unexpected APValue kind!"); +} + +/// Dump the children of the \p APValue \p Value. +/// +/// \param[in] Value The \p APValue to visit +/// \param[in] Ty The \p QualType passed to \p Visit +/// +/// \param[in] IdxToChildFun A function mapping an \p APValue and an index +/// to one of the child of the \p APValue +/// +/// \param[in] NumChildren \p IdxToChildFun will be called on \p Value with +/// the indices in the range \p [0,NumChildren( +/// +/// \param[in] LabelSingular The label to use on a line with a single child +/// \param[in] LabelPlurial The label to use on a line with multiple children +void TextNodeDumper::dumpAPValueChildren( + const APValue &Value, QualType Ty, + const APValue &(*IdxToChildFun)(const APValue &, unsigned), + unsigned NumChildren, StringRef LabelSingular, StringRef LabelPlurial) { + // To save some vertical space we print up to MaxChildrenPerLine APValues + // considered to be simple (by isSimpleAPValue) on a single line. + constexpr unsigned MaxChildrenPerLine = 4; + unsigned I = 0; + while (I < NumChildren) { + unsigned J = I; + while (J < NumChildren) { + if (isSimpleAPValue(IdxToChildFun(Value, J)) && + (J - I < MaxChildrenPerLine)) { + ++J; + continue; + } + break; + } + + J = std::max(I + 1, J); + + // Print [I,J) on a single line. + AddChild(J - I > 1 ? LabelPlurial : LabelSingular, [=]() { + for (unsigned X = I; X < J; ++X) { + Visit(IdxToChildFun(Value, X), Ty); + if (X + 1 != J) + OS << ", "; + } + }); + I = J; + } +} + +void TextNodeDumper::Visit(const APValue &Value, QualType Ty) { + ColorScope Color(OS, ShowColors, ValueKindColor); + switch (Value.getKind()) { + case APValue::None: + OS << "None"; + return; + case APValue::Indeterminate: + OS << "Indeterminate"; + return; + case APValue::Int: + OS << "Int "; + { + ColorScope Color(OS, ShowColors, ValueColor); + OS << Value.getInt(); + } + return; + case APValue::Float: + OS << "Float "; + { + ColorScope Color(OS, ShowColors, ValueColor); + OS << GetApproxValue(Value.getFloat()); + } + return; + case APValue::FixedPoint: + OS << "FixedPoint "; + { + ColorScope Color(OS, ShowColors, ValueColor); + OS << Value.getFixedPoint(); + } + return; + case APValue::Vector: { + unsigned VectorLength = Value.getVectorLength(); + OS << "Vector length=" << VectorLength; + + dumpAPValueChildren( + Value, Ty, + [](const APValue &Value, unsigned Index) -> const APValue & { + return Value.getVectorElt(Index); + }, + VectorLength, "element", "elements"); + return; + } + case APValue::ComplexInt: + OS << "ComplexInt "; + { + ColorScope Color(OS, ShowColors, ValueColor); + OS << Value.getComplexIntReal() << " + " << Value.getComplexIntImag() + << 'i'; + } + return; + case APValue::ComplexFloat: + OS << "ComplexFloat "; + { + ColorScope Color(OS, ShowColors, ValueColor); + OS << GetApproxValue(Value.getComplexFloatReal()) << " + " + << GetApproxValue(Value.getComplexFloatImag()) << 'i'; + } + return; + case APValue::LValue: + (void)Context; + OS << "LValue "; + return; + case APValue::Array: { + unsigned ArraySize = Value.getArraySize(); + unsigned NumInitializedElements = Value.getArrayInitializedElts(); + OS << "Array size=" << ArraySize; + + dumpAPValueChildren( + Value, Ty, + [](const APValue &Value, unsigned Index) -> const APValue & { + return Value.getArrayInitializedElt(Index); + }, + NumInitializedElements, "element", "elements"); + + if (Value.hasArrayFiller()) { + AddChild("filler", [=] { + { + ColorScope Color(OS, ShowColors, ValueColor); + OS << ArraySize - NumInitializedElements << " x "; + } + Visit(Value.getArrayFiller(), Ty); + }); + } + + return; + } + case APValue::Struct: { + OS << "Struct"; + + dumpAPValueChildren( + Value, Ty, + [](const APValue &Value, unsigned Index) -> const APValue & { + return Value.getStructBase(Index); + }, + Value.getStructNumBases(), "base", "bases"); + + dumpAPValueChildren( + Value, Ty, + [](const APValue &Value, unsigned Index) -> const APValue & { + return Value.getStructField(Index); + }, + Value.getStructNumFields(), "field", "fields"); + + return; + } + case APValue::Union: { + OS << "Union"; + { + ColorScope Color(OS, ShowColors, ValueColor); + if (const FieldDecl *FD = Value.getUnionField()) + OS << " ." << *cast(FD); + } + // If the union value is considered to be simple, fold it into the + // current line to save some vertical space. + const APValue &UnionValue = Value.getUnionValue(); + if (isSimpleAPValue(UnionValue)) { + OS << ' '; + Visit(UnionValue, Ty); + } else { + AddChild([=] { Visit(UnionValue, Ty); }); + } + + return; + } + case APValue::MemberPointer: + OS << "MemberPointer "; + return; + case APValue::AddrLabelDiff: + OS << "AddrLabelDiff "; + return; + } + llvm_unreachable("Unknown APValue kind!"); +} + void TextNodeDumper::dumpPointer(const void *Ptr) { ColorScope Color(OS, ShowColors, AddressColor); OS << ' ' << Ptr; @@ -709,11 +929,9 @@ void TextNodeDumper::VisitCaseStmt(const CaseStmt *Node) { } void TextNodeDumper::VisitConstantExpr(const ConstantExpr *Node) { - if (Node->getResultAPValueKind() != APValue::None) { - ColorScope Color(OS, ShowColors, ValueColor); - OS << " "; - Node->getAPValueResult().dump(OS); - } + if (Node->hasAPValueResult()) + AddChild("value", + [=] { Visit(Node->getAPValueResult(), Node->getType()); }); } void TextNodeDumper::VisitCallExpr(const CallExpr *Node) { @@ -1451,6 +1669,16 @@ void TextNodeDumper::VisitVarDecl(const VarDecl *D) { OS << " destroyed"; if (D->isParameterPack()) OS << " pack"; + + if (D->hasInit()) { + const Expr *E = D->getInit(); + // Only dump the value of constexpr VarDecls for now. + if (E && !E->isValueDependent() && D->isConstexpr()) { + const APValue *Value = D->evaluateValue(); + if (Value) + AddChild("value", [=] { Visit(*Value, E->getType()); }); + } + } } void TextNodeDumper::VisitBindingDecl(const BindingDecl *D) { diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index ba0d86befe1b9..10a6a26101302 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -347,15 +347,7 @@ ExtIntType::ExtIntType(bool IsUnsigned, unsigned NumBits) DependentExtIntType::DependentExtIntType(const ASTContext &Context, bool IsUnsigned, Expr *NumBitsExpr) : Type(DependentExtInt, QualType{}, - ((NumBitsExpr->isValueDependent() || NumBitsExpr->isTypeDependent()) - ? TypeDependence::Dependent - : TypeDependence::None) | - (NumBitsExpr->isInstantiationDependent() - ? TypeDependence::Instantiation - : TypeDependence::None) | - (NumBitsExpr->containsUnexpandedParameterPack() - ? TypeDependence::VariablyModified - : TypeDependence::None)), + toTypeDependence(NumBitsExpr->getDependence())), Context(Context), ExprAndUnsigned(NumBitsExpr, IsUnsigned) {} bool DependentExtIntType::isUnsigned() const { @@ -3591,7 +3583,7 @@ TemplateSpecializationType::TemplateSpecializationType( auto *TemplateArgs = reinterpret_cast(this + 1); for (const TemplateArgument &Arg : Args) { - // Update instantiation-dependent and variably-modified bits. + // Update instantiation-dependent, variably-modified, and error bits. // If the canonical type exists and is non-dependent, the template // specialization type can be non-dependent even if one of the type // arguments is. Given: diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp index 013ebe23ec918..f5865ce96b647 100644 --- a/clang/lib/AST/VTableBuilder.cpp +++ b/clang/lib/AST/VTableBuilder.cpp @@ -408,7 +408,7 @@ void FinalOverriders::dump(raw_ostream &Out, BaseSubobject Base, // Now dump the overriders for this base subobject. for (const auto *MD : RD->methods()) { - if (!MD->isVirtual()) + if (!VTableContextBase::hasVtableSlot(MD)) continue; MD = MD->getCanonicalDecl(); @@ -486,8 +486,8 @@ static bool HasSameVirtualSignature(const CXXMethodDecl *LHS, bool VCallOffsetMap::MethodsCanShareVCallOffset(const CXXMethodDecl *LHS, const CXXMethodDecl *RHS) { - assert(LHS->isVirtual() && "LHS must be virtual!"); - assert(RHS->isVirtual() && "LHS must be virtual!"); + assert(VTableContextBase::hasVtableSlot(LHS) && "LHS must be virtual!"); + assert(VTableContextBase::hasVtableSlot(RHS) && "LHS must be virtual!"); // A destructor can share a vcall offset with another destructor. if (isa(LHS)) @@ -697,7 +697,7 @@ void VCallAndVBaseOffsetBuilder::AddVCallOffsets(BaseSubobject Base, // Add the vcall offsets. for (const auto *MD : RD->methods()) { - if (!MD->isVirtual()) + if (!VTableContextBase::hasVtableSlot(MD)) continue; MD = MD->getCanonicalDecl(); @@ -1085,7 +1085,7 @@ typedef llvm::SmallPtrSet OverriddenMethodsSetTy; template static void visitAllOverriddenMethods(const CXXMethodDecl *MD, VisitorTy &Visitor) { - assert(MD->isVirtual() && "Method is not virtual!"); + assert(VTableContextBase::hasVtableSlot(MD) && "Method is not virtual!"); for (const CXXMethodDecl *OverriddenMD : MD->overridden_methods()) { if (!Visitor(OverriddenMD)) @@ -1489,7 +1489,7 @@ void ItaniumVTableBuilder::AddMethods( // Now go through all virtual member functions and add them. for (const auto *MD : RD->methods()) { - if (!MD->isVirtual()) + if (!ItaniumVTableContext::hasVtableSlot(MD)) continue; MD = MD->getCanonicalDecl(); @@ -2169,7 +2169,7 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) { for (const auto *MD : MostDerivedClass->methods()) { // We only want virtual member functions. - if (!MD->isVirtual()) + if (!ItaniumVTableContext::hasVtableSlot(MD)) continue; MD = MD->getCanonicalDecl(); @@ -2257,6 +2257,10 @@ VTableLayout::VTableLayout(ArrayRef VTableIndices, VTableLayout::~VTableLayout() { } +bool VTableContextBase::hasVtableSlot(const CXXMethodDecl *MD) { + return MD->isVirtual() && !MD->isConsteval(); +} + ItaniumVTableContext::ItaniumVTableContext( ASTContext &Context, VTableComponentLayout ComponentLayout) : VTableContextBase(/*MS=*/false), ComponentLayout(ComponentLayout) {} @@ -2537,8 +2541,9 @@ class VFTableBuilder { BasesSetVectorTy VisitedBases; AddMethods(BaseSubobject(MostDerivedClass, CharUnits::Zero()), 0, nullptr, VisitedBases); - assert((HasRTTIComponent ? Components.size() - 1 : Components.size()) && - "vftable can't be empty"); + // Note that it is possible for the vftable to contain only an RTTI + // pointer, if all virtual functions are constewval. + assert(!Components.empty() && "vftable can't be empty"); assert(MethodVFTableLocations.empty()); for (const auto &I : MethodInfoMap) { @@ -2917,7 +2922,7 @@ static void GroupNewVirtualOverloads( if (Inserted) Groups.push_back(MethodGroup()); if (const auto *MD = dyn_cast(ND)) - if (MD->isVirtual()) + if (MicrosoftVTableContext::hasVtableSlot(MD)) Groups[J->second].push_back(MD->getCanonicalDecl()); } @@ -3513,7 +3518,7 @@ static const FullPathTy *selectBestPath(ASTContext &Context, getOffsetOfFullPath(Context, TopLevelRD, SpecificPath); FinalOverriders Overriders(TopLevelRD, CharUnits::Zero(), TopLevelRD); for (const CXXMethodDecl *MD : Info.IntroducingObject->methods()) { - if (!MD->isVirtual()) + if (!MicrosoftVTableContext::hasVtableSlot(MD)) continue; FinalOverriders::OverriderInfo OI = Overriders.getOverrider(MD->getCanonicalDecl(), BaseOffset); @@ -3652,7 +3657,7 @@ void MicrosoftVTableContext::dumpMethodLocations( for (const auto &I : NewMethods) { const CXXMethodDecl *MD = cast(I.first.getDecl()); - assert(MD->isVirtual()); + assert(hasVtableSlot(MD)); std::string MethodName = PredefinedExpr::ComputeName( PredefinedExpr::PrettyFunctionNoVirtual, MD); @@ -3772,7 +3777,7 @@ MicrosoftVTableContext::getVFTableLayout(const CXXRecordDecl *RD, MethodVFTableLocation MicrosoftVTableContext::getMethodVFTableLocation(GlobalDecl GD) { - assert(cast(GD.getDecl())->isVirtual() && + assert(hasVtableSlot(cast(GD.getDecl())) && "Only use this method for virtual methods or dtors"); if (isa(GD.getDecl())) assert(GD.getDtorType() == Dtor_Deleting); diff --git a/clang/lib/ASTMatchers/ASTMatchFinder.cpp b/clang/lib/ASTMatchers/ASTMatchFinder.cpp index 1b49067f0f9d7..e88da16dd3d40 100644 --- a/clang/lib/ASTMatchers/ASTMatchFinder.cpp +++ b/clang/lib/ASTMatchers/ASTMatchFinder.cpp @@ -43,6 +43,13 @@ typedef MatchFinder::MatchCallback MatchCallback; // optimize this on. static const unsigned MaxMemoizationEntries = 10000; +enum class MatchType { + Ancestors, + + Descendants, + Child, +}; + // We use memoization to avoid running the same matcher on the same // AST node twice. This struct is the key for looking up match // result. It consists of an ID of the MatcherInterface (for @@ -60,10 +67,11 @@ struct MatchKey { DynTypedNode Node; BoundNodesTreeBuilder BoundNodes; TraversalKind Traversal = TK_AsIs; + MatchType Type; bool operator<(const MatchKey &Other) const { - return std::tie(Traversal, MatcherID, Node, BoundNodes) < - std::tie(Other.Traversal, Other.MatcherID, Other.Node, + return std::tie(Traversal, Type, MatcherID, Node, BoundNodes) < + std::tie(Other.Traversal, Other.Type, Other.MatcherID, Other.Node, Other.BoundNodes); } }; @@ -456,7 +464,8 @@ class MatchASTVisitor : public RecursiveASTVisitor, // Note that we key on the bindings *before* the match. Key.BoundNodes = *Builder; Key.Traversal = Ctx.getParentMapContext().getTraversalKind(); - + // Memoize result even doing a single-level match, it might be expensive. + Key.Type = MaxDepth == 1 ? MatchType::Child : MatchType::Descendants; MemoizationMap::iterator I = ResultCache.find(Key); if (I != ResultCache.end()) { *Builder = I->second.Nodes; @@ -693,7 +702,10 @@ class MatchASTVisitor : public RecursiveASTVisitor, BoundNodesTreeBuilder *Builder, AncestorMatchMode MatchMode) { // For AST-nodes that don't have an identity, we can't memoize. - if (!Builder->isComparable()) + // When doing a single-level match, we don't need to memoize because + // ParentMap (in ASTContext) already memoizes the result. + if (!Builder->isComparable() || + MatchMode == AncestorMatchMode::AMM_ParentOnly) return matchesAncestorOfRecursively(Node, Ctx, Matcher, Builder, MatchMode); @@ -702,6 +714,7 @@ class MatchASTVisitor : public RecursiveASTVisitor, Key.Node = Node; Key.BoundNodes = *Builder; Key.Traversal = Ctx.getParentMapContext().getTraversalKind(); + Key.Type = MatchType::Ancestors; // Note that we cannot use insert and reuse the iterator, as recursive // calls to match might invalidate the result cache iterators. @@ -742,7 +755,7 @@ class MatchASTVisitor : public RecursiveASTVisitor, return D->getKind() == Decl::TranslationUnit; })) { llvm::errs() << "Tried to match orphan node:\n"; - Node.dump(llvm::errs(), ActiveASTContext->getSourceManager()); + Node.dump(llvm::errs(), *ActiveASTContext); llvm_unreachable("Parent map should be complete!"); } #endif diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp index 9b69734d075d3..4b9baf7a0e751 100644 --- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp +++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp @@ -29,6 +29,8 @@ #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/Regex.h" +#include "llvm/Support/WithColor.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -682,6 +684,19 @@ getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc, return llvm::None; } +std::shared_ptr createAndVerifyRegex(StringRef Regex, + llvm::Regex::RegexFlags Flags, + StringRef MatcherID) { + assert(!Regex.empty() && "Empty regex string"); + auto SharedRegex = std::make_shared(Regex, Flags); + std::string Error; + if (!SharedRegex->isValid(Error)) { + llvm::WithColor::error() + << "building matcher '" << MatcherID << "': " << Error << "\n"; + llvm::WithColor::note() << " input was '" << Regex << "'\n"; + } + return SharedRegex; +} } // end namespace internal const internal::VariadicDynCastAllOfMatcher diff --git a/clang/lib/ASTMatchers/CMakeLists.txt b/clang/lib/ASTMatchers/CMakeLists.txt index cde871cd31cac..68f214b778401 100644 --- a/clang/lib/ASTMatchers/CMakeLists.txt +++ b/clang/lib/ASTMatchers/CMakeLists.txt @@ -14,4 +14,7 @@ add_clang_library(clangASTMatchers clangAST clangBasic clangLex + + DEPENDS + omp_gen ) diff --git a/clang/lib/ASTMatchers/Dynamic/CMakeLists.txt b/clang/lib/ASTMatchers/Dynamic/CMakeLists.txt index 1c6c1e68ce1e4..adb891575b308 100644 --- a/clang/lib/ASTMatchers/Dynamic/CMakeLists.txt +++ b/clang/lib/ASTMatchers/Dynamic/CMakeLists.txt @@ -23,4 +23,7 @@ add_clang_library(clangDynamicASTMatchers clangAST clangASTMatchers clangBasic + + DEPENDS + omp_gen ) diff --git a/clang/lib/ASTMatchers/Dynamic/Marshallers.cpp b/clang/lib/ASTMatchers/Dynamic/Marshallers.cpp index 78b6ca1aa227f..989ee0fa75cdd 100644 --- a/clang/lib/ASTMatchers/Dynamic/Marshallers.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Marshallers.cpp @@ -10,6 +10,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Regex.h" #include static llvm::Optional @@ -110,3 +111,62 @@ clang::ast_matchers::dynamic::internal::ArgTypeTraits< "UETT_"); return llvm::None; } + +static constexpr std::pair + RegexMap[] = { + {"NoFlags", llvm::Regex::RegexFlags::NoFlags}, + {"IgnoreCase", llvm::Regex::RegexFlags::IgnoreCase}, + {"Newline", llvm::Regex::RegexFlags::Newline}, + {"BasicRegex", llvm::Regex::RegexFlags::BasicRegex}, +}; + +llvm::Optional getRegexFlag(llvm::StringRef Flag) { + for (const auto &StringFlag : RegexMap) { + if (Flag == StringFlag.first) + return StringFlag.second; + } + return llvm::None; +} + +llvm::Optional getCloseRegexMatch(llvm::StringRef Flag) { + for (const auto &StringFlag : RegexMap) { + if (Flag.edit_distance(StringFlag.first) < 3) + return StringFlag.first; + } + return llvm::None; +} + +llvm::Optional +clang::ast_matchers::dynamic::internal::ArgTypeTraits< + llvm::Regex::RegexFlags>::getFlags(llvm::StringRef Flags) { + llvm::Optional Flag; + SmallVector Split; + Flags.split(Split, '|', -1, false); + for (StringRef OrFlag : Split) { + if (llvm::Optional NextFlag = + getRegexFlag(OrFlag.trim())) + Flag = Flag.getValueOr(llvm::Regex::NoFlags) | *NextFlag; + else + return None; + } + return Flag; +} + +llvm::Optional +clang::ast_matchers::dynamic::internal::ArgTypeTraits< + llvm::Regex::RegexFlags>::getBestGuess(const VariantValue &Value) { + if (!Value.isString()) + return llvm::None; + SmallVector Split; + llvm::StringRef(Value.getString()).split(Split, '|', -1, false); + for (llvm::StringRef &Flag : Split) { + if (llvm::Optional BestGuess = + getCloseRegexMatch(Flag.trim())) + Flag = *BestGuess; + else + return None; + } + if (Split.empty()) + return None; + return llvm::join(Split, " | "); +} diff --git a/clang/lib/ASTMatchers/Dynamic/Marshallers.h b/clang/lib/ASTMatchers/Dynamic/Marshallers.h index e07db59433b71..33f6d1e4155cb 100644 --- a/clang/lib/ASTMatchers/Dynamic/Marshallers.h +++ b/clang/lib/ASTMatchers/Dynamic/Marshallers.h @@ -35,6 +35,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Twine.h" +#include "llvm/Support/Regex.h" #include #include #include @@ -192,6 +193,24 @@ template <> struct ArgTypeTraits { static llvm::Optional getBestGuess(const VariantValue &Value); }; +template <> struct ArgTypeTraits { +private: + static Optional getFlags(llvm::StringRef Flags); + +public: + static bool is(const VariantValue &Value) { + return Value.isString() && getFlags(Value.getString()); + } + + static llvm::Regex::RegexFlags get(const VariantValue &Value) { + return *getFlags(Value.getString()); + } + + static ArgKind getKind() { return ArgKind(ArgKind::AK_String); } + + static llvm::Optional getBestGuess(const VariantValue &Value); +}; + template <> struct ArgTypeTraits { private: static Optional getClauseKind(llvm::StringRef ClauseKind) { @@ -711,6 +730,71 @@ class OverloadedMatcherDescriptor : public MatcherDescriptor { std::vector> Overloads; }; +template +class RegexMatcherDescriptor : public MatcherDescriptor { +public: + RegexMatcherDescriptor(ReturnType (*WithFlags)(StringRef, + llvm::Regex::RegexFlags), + ReturnType (*NoFlags)(StringRef), + ArrayRef RetKinds) + : WithFlags(WithFlags), NoFlags(NoFlags), + RetKinds(RetKinds.begin(), RetKinds.end()) {} + bool isVariadic() const override { return true; } + unsigned getNumArgs() const override { return 0; } + + void getArgKinds(ASTNodeKind ThisKind, unsigned ArgNo, + std::vector &Kinds) const override { + assert(ArgNo < 2); + Kinds.push_back(ArgKind::AK_String); + } + + bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity, + ASTNodeKind *LeastDerivedKind) const override { + return isRetKindConvertibleTo(RetKinds, Kind, Specificity, + LeastDerivedKind); + } + + VariantMatcher create(SourceRange NameRange, ArrayRef Args, + Diagnostics *Error) const override { + if (Args.size() < 1 || Args.size() > 2) { + Error->addError(NameRange, Diagnostics::ET_RegistryWrongArgCount) + << "1 or 2" << Args.size(); + return VariantMatcher(); + } + if (!ArgTypeTraits::is(Args[0].Value)) { + Error->addError(Args[0].Range, Error->ET_RegistryWrongArgType) + << 1 << ArgTypeTraits::getKind().asString() + << Args[0].Value.getTypeAsString(); + return VariantMatcher(); + } + if (Args.size() == 1) { + return outvalueToVariantMatcher( + NoFlags(ArgTypeTraits::get(Args[0].Value))); + } + if (!ArgTypeTraits::is(Args[1].Value)) { + if (llvm::Optional BestGuess = + ArgTypeTraits::getBestGuess( + Args[1].Value)) { + Error->addError(Args[1].Range, Error->ET_RegistryUnknownEnumWithReplace) + << 2 << Args[1].Value.getString() << *BestGuess; + } else { + Error->addError(Args[1].Range, Error->ET_RegistryWrongArgType) + << 2 << ArgTypeTraits::getKind().asString() + << Args[1].Value.getTypeAsString(); + } + return VariantMatcher(); + } + return outvalueToVariantMatcher( + WithFlags(ArgTypeTraits::get(Args[0].Value), + ArgTypeTraits::get(Args[1].Value))); + } + +private: + ReturnType (*const WithFlags)(StringRef, llvm::Regex::RegexFlags); + ReturnType (*const NoFlags)(StringRef); + const std::vector RetKinds; +}; + /// Variadic operator marshaller function. class VariadicOperatorMatcherDescriptor : public MatcherDescriptor { public: @@ -814,6 +898,16 @@ makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1, ArgType2), reinterpret_cast(Func), MatcherName, RetTypes, AKs); } +template +std::unique_ptr makeMatcherRegexMarshall( + ReturnType (*FuncFlags)(llvm::StringRef, llvm::Regex::RegexFlags), + ReturnType (*Func)(llvm::StringRef)) { + std::vector RetTypes; + BuildReturnTypeVector::build(RetTypes); + return std::make_unique>(FuncFlags, Func, + RetTypes); +} + /// Variadic overload. template )> diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp index 950a56f795516..ec2215804c098 100644 --- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -90,6 +90,9 @@ void RegistryMaps::registerMatcher( REGISTER_MATCHER_OVERLOAD(name); \ } while (false) +#define REGISTER_REGEX_MATCHER(name) \ + registerMatcher(#name, internal::makeMatcherRegexMarshall(name, name)) + /// Generate a registry map with all the known matchers. /// Please keep sorted alphabetically! RegistryMaps::RegistryMaps() { @@ -121,6 +124,10 @@ RegistryMaps::RegistryMaps() { }; REGISTER_MATCHER_OVERLOAD(equals); + REGISTER_REGEX_MATCHER(isExpansionInFileMatching); + REGISTER_REGEX_MATCHER(matchesName); + REGISTER_REGEX_MATCHER(matchesSelector); + REGISTER_MATCHER(accessSpecDecl); REGISTER_MATCHER(addrLabelExpr); REGISTER_MATCHER(alignOfExpr); @@ -151,6 +158,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(characterLiteral); REGISTER_MATCHER(chooseExpr); REGISTER_MATCHER(classTemplateDecl); + REGISTER_MATCHER(classTemplatePartialSpecializationDecl); REGISTER_MATCHER(classTemplateSpecializationDecl); REGISTER_MATCHER(complexType); REGISTER_MATCHER(compoundLiteralExpr); @@ -219,7 +227,6 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(floatLiteral); REGISTER_MATCHER(forEach); REGISTER_MATCHER(forEachArgumentWithParam); - REGISTER_MATCHER(isAtPosition); REGISTER_MATCHER(forEachConstructorInitializer); REGISTER_MATCHER(forEachDescendant); REGISTER_MATCHER(forEachOverridden); @@ -271,6 +278,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(hasDefinition); REGISTER_MATCHER(hasDescendant); REGISTER_MATCHER(hasDestinationType); + REGISTER_MATCHER(hasDirectBase); REGISTER_MATCHER(hasDynamicExceptionSpec); REGISTER_MATCHER(hasEitherOperand); REGISTER_MATCHER(hasElementType); @@ -353,6 +361,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(isArray); REGISTER_MATCHER(isArrow); REGISTER_MATCHER(isAssignmentOperator); + REGISTER_MATCHER(isAtPosition); REGISTER_MATCHER(isBaseInitializer); REGISTER_MATCHER(isBitField); REGISTER_MATCHER(isCatchAll); @@ -370,8 +379,9 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(isDefinition); REGISTER_MATCHER(isDelegatingConstructor); REGISTER_MATCHER(isDeleted); + REGISTER_MATCHER(isEnum); REGISTER_MATCHER(isExceptionVariable); - REGISTER_MATCHER(isExpansionInFileMatching); + REGISTER_MATCHER(isExpandedFromMacro); REGISTER_MATCHER(isExpansionInMainFile); REGISTER_MATCHER(isExpansionInSystemHeader); REGISTER_MATCHER(isExplicit); @@ -379,6 +389,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(isExpr); REGISTER_MATCHER(isExternC); REGISTER_MATCHER(isFinal); + REGISTER_MATCHER(isFirstPrivateKind); REGISTER_MATCHER(isImplicit); REGISTER_MATCHER(isInStdNamespace); REGISTER_MATCHER(isInTemplateInstantiation); @@ -426,8 +437,6 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(labelStmt); REGISTER_MATCHER(lambdaExpr); REGISTER_MATCHER(linkageSpecDecl); - REGISTER_MATCHER(matchesName); - REGISTER_MATCHER(matchesSelector); REGISTER_MATCHER(materializeTemporaryExpr); REGISTER_MATCHER(member); REGISTER_MATCHER(memberExpr); diff --git a/clang/lib/Analysis/BodyFarm.cpp b/clang/lib/Analysis/BodyFarm.cpp index e10fbce711465..f9f0553d28f05 100644 --- a/clang/lib/Analysis/BodyFarm.cpp +++ b/clang/lib/Analysis/BodyFarm.cpp @@ -116,18 +116,17 @@ BinaryOperator *ASTMaker::makeAssignment(const Expr *LHS, const Expr *RHS, QualType Ty) { return BinaryOperator::Create( C, const_cast(LHS), const_cast(RHS), BO_Assign, Ty, - VK_RValue, OK_Ordinary, SourceLocation(), FPOptions(C.getLangOpts())); + VK_RValue, OK_Ordinary, SourceLocation(), FPOptionsOverride()); } BinaryOperator *ASTMaker::makeComparison(const Expr *LHS, const Expr *RHS, BinaryOperator::Opcode Op) { assert(BinaryOperator::isLogicalOp(Op) || BinaryOperator::isComparisonOp(Op)); - return BinaryOperator::Create(C, const_cast(LHS), - const_cast(RHS), Op, - C.getLogicalOperationType(), VK_RValue, - OK_Ordinary, SourceLocation(), - FPOptions(C.getLangOpts())); + return BinaryOperator::Create( + C, const_cast(LHS), const_cast(RHS), Op, + C.getLogicalOperationType(), VK_RValue, OK_Ordinary, SourceLocation(), + FPOptionsOverride()); } CompoundStmt *ASTMaker::makeCompound(ArrayRef Stmts) { @@ -148,8 +147,7 @@ DeclRefExpr *ASTMaker::makeDeclRefExpr( UnaryOperator *ASTMaker::makeDereference(const Expr *Arg, QualType Ty) { return UnaryOperator::Create(C, const_cast(Arg), UO_Deref, Ty, VK_LValue, OK_Ordinary, SourceLocation(), - /*CanOverflow*/ false, - FPOptions(C.getLangOpts())); + /*CanOverflow*/ false, FPOptionsOverride()); } ImplicitCastExpr *ASTMaker::makeLvalueToRvalue(const Expr *Arg, QualType Ty) { @@ -297,7 +295,7 @@ static CallExpr *create_call_once_lambda_call(ASTContext &C, ASTMaker M, /*QualType=*/C.VoidTy, /*ExprValueType=*/VK_RValue, /*SourceLocation=*/SourceLocation(), - /*FPFeatures=*/FPOptions(C.getLangOpts())); + /*FPFeatures=*/FPOptionsOverride()); } /// Create a fake body for std::call_once. @@ -457,7 +455,7 @@ static Stmt *create_call_once(ASTContext &C, const FunctionDecl *D) { /* QualType=*/C.IntTy, /* ExprValueKind=*/VK_RValue, /* ExprObjectKind=*/OK_Ordinary, SourceLocation(), - /* CanOverflow*/ false, FPOptions(C.getLangOpts())); + /* CanOverflow*/ false, FPOptionsOverride()); // Create assignment. BinaryOperator *FlagAssignment = M.makeAssignment( @@ -522,7 +520,7 @@ static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) { Expr *DoneValue = UnaryOperator::Create(C, M.makeIntegerLiteral(0, C.LongTy), UO_Not, C.LongTy, VK_RValue, OK_Ordinary, SourceLocation(), - /*CanOverflow*/ false, FPOptions(C.getLangOpts())); + /*CanOverflow*/ false, FPOptionsOverride()); BinaryOperator *B = M.makeAssignment( diff --git a/clang/lib/Analysis/CMakeLists.txt b/clang/lib/Analysis/CMakeLists.txt index 3333eab3b96d1..82cb00a8c3e0e 100644 --- a/clang/lib/Analysis/CMakeLists.txt +++ b/clang/lib/Analysis/CMakeLists.txt @@ -35,6 +35,9 @@ add_clang_library(clangAnalysis clangASTMatchers clangBasic clangLex + + DEPENDS + omp_gen ) add_subdirectory(plugins) diff --git a/clang/lib/Analysis/ReachableCode.cpp b/clang/lib/Analysis/ReachableCode.cpp index 369879ad65f50..221d137dadb87 100644 --- a/clang/lib/Analysis/ReachableCode.cpp +++ b/clang/lib/Analysis/ReachableCode.cpp @@ -138,10 +138,10 @@ static bool isDeadReturn(const CFGBlock *B, const Stmt *S) { static SourceLocation getTopMostMacro(SourceLocation Loc, SourceManager &SM) { assert(Loc.isMacroID()); SourceLocation Last; - while (Loc.isMacroID()) { + do { Last = Loc; Loc = SM.getImmediateMacroCallerLoc(Loc); - } + } while (Loc.isMacroID()); return Last; } diff --git a/clang/lib/Analysis/UninitializedValues.cpp b/clang/lib/Analysis/UninitializedValues.cpp index 3d44d1c070fea..67cd39728c350 100644 --- a/clang/lib/Analysis/UninitializedValues.cpp +++ b/clang/lib/Analysis/UninitializedValues.cpp @@ -405,6 +405,15 @@ static bool isPointerToConst(const QualType &QT) { return QT->isAnyPointerType() && QT->getPointeeType().isConstQualified(); } +static bool hasTrivialBody(CallExpr *CE) { + if (FunctionDecl *FD = CE->getDirectCallee()) { + if (FunctionTemplateDecl *FTD = FD->getPrimaryTemplate()) + return FTD->getTemplatedDecl()->hasTrivialBody(); + return FD->hasTrivialBody(); + } + return false; +} + void ClassifyRefs::VisitCallExpr(CallExpr *CE) { // Classify arguments to std::move as used. if (CE->isCallToStdMove()) { @@ -413,7 +422,7 @@ void ClassifyRefs::VisitCallExpr(CallExpr *CE) { classify(CE->getArg(0), Use); return; } - + bool isTrivialBody = hasTrivialBody(CE); // If a value is passed by const pointer to a function, // we should not assume that it is initialized by the call, and we // conservatively do not assume that it is used. @@ -423,7 +432,7 @@ void ClassifyRefs::VisitCallExpr(CallExpr *CE) { I != E; ++I) { if ((*I)->isGLValue()) { if ((*I)->getType().isConstQualified()) - classify((*I), ConstRefUse); + classify((*I), isTrivialBody ? Ignore : ConstRefUse); } else if (isPointerToConst((*I)->getType())) { const Expr *Ex = stripCasts(DC->getParentASTContext(), *I); const auto *UO = dyn_cast(Ex); diff --git a/clang/lib/Basic/CMakeLists.txt b/clang/lib/Basic/CMakeLists.txt index 65cb9c505dd02..1b55d84173771 100644 --- a/clang/lib/Basic/CMakeLists.txt +++ b/clang/lib/Basic/CMakeLists.txt @@ -84,6 +84,7 @@ add_clang_library(clangBasic Targets/Sparc.cpp Targets/SystemZ.cpp Targets/TCE.cpp + Targets/VE.cpp Targets/WebAssembly.cpp Targets/X86.cpp Targets/XCore.cpp @@ -94,5 +95,8 @@ add_clang_library(clangBasic XRayInstr.cpp XRayLists.cpp ${version_inc} + + DEPENDS + omp_gen ) diff --git a/clang/lib/Basic/DiagnosticIDs.cpp b/clang/lib/Basic/DiagnosticIDs.cpp index 6f8b5440a4f3e..8c7e63e063019 100644 --- a/clang/lib/Basic/DiagnosticIDs.cpp +++ b/clang/lib/Basic/DiagnosticIDs.cpp @@ -85,6 +85,7 @@ VALIDATE_DIAG_SIZE(LEX) VALIDATE_DIAG_SIZE(PARSE) VALIDATE_DIAG_SIZE(AST) VALIDATE_DIAG_SIZE(COMMENT) +VALIDATE_DIAG_SIZE(CROSSTU) VALIDATE_DIAG_SIZE(SEMA) VALIDATE_DIAG_SIZE(ANALYSIS) VALIDATE_DIAG_SIZE(REFACTORING) diff --git a/clang/lib/Basic/FixedPoint.cpp b/clang/lib/Basic/FixedPoint.cpp index 05600dfc6d212..ed8b92c98fdbb 100644 --- a/clang/lib/Basic/FixedPoint.cpp +++ b/clang/lib/Basic/FixedPoint.cpp @@ -173,6 +173,142 @@ APFixedPoint APFixedPoint::add(const APFixedPoint &Other, return APFixedPoint(Result, CommonFXSema); } +APFixedPoint APFixedPoint::sub(const APFixedPoint &Other, + bool *Overflow) const { + auto CommonFXSema = Sema.getCommonSemantics(Other.getSemantics()); + APFixedPoint ConvertedThis = convert(CommonFXSema); + APFixedPoint ConvertedOther = Other.convert(CommonFXSema); + llvm::APSInt ThisVal = ConvertedThis.getValue(); + llvm::APSInt OtherVal = ConvertedOther.getValue(); + bool Overflowed = false; + + llvm::APSInt Result; + if (CommonFXSema.isSaturated()) { + Result = CommonFXSema.isSigned() ? ThisVal.ssub_sat(OtherVal) + : ThisVal.usub_sat(OtherVal); + } else { + Result = ThisVal.isSigned() ? ThisVal.ssub_ov(OtherVal, Overflowed) + : ThisVal.usub_ov(OtherVal, Overflowed); + } + + if (Overflow) + *Overflow = Overflowed; + + return APFixedPoint(Result, CommonFXSema); +} + +APFixedPoint APFixedPoint::mul(const APFixedPoint &Other, + bool *Overflow) const { + auto CommonFXSema = Sema.getCommonSemantics(Other.getSemantics()); + APFixedPoint ConvertedThis = convert(CommonFXSema); + APFixedPoint ConvertedOther = Other.convert(CommonFXSema); + llvm::APSInt ThisVal = ConvertedThis.getValue(); + llvm::APSInt OtherVal = ConvertedOther.getValue(); + bool Overflowed = false; + + // Widen the LHS and RHS so we can perform a full multiplication. + unsigned Wide = CommonFXSema.getWidth() * 2; + if (CommonFXSema.isSigned()) { + ThisVal = ThisVal.sextOrSelf(Wide); + OtherVal = OtherVal.sextOrSelf(Wide); + } else { + ThisVal = ThisVal.zextOrSelf(Wide); + OtherVal = OtherVal.zextOrSelf(Wide); + } + + // Perform the full multiplication and downscale to get the same scale. + // + // Note that the right shifts here perform an implicit downwards rounding. + // This rounding could discard bits that would technically place the result + // outside the representable range. We interpret the spec as allowing us to + // perform the rounding step first, avoiding the overflow case that would + // arise. + llvm::APSInt Result; + if (CommonFXSema.isSigned()) + Result = ThisVal.smul_ov(OtherVal, Overflowed) + .ashr(CommonFXSema.getScale()); + else + Result = ThisVal.umul_ov(OtherVal, Overflowed) + .lshr(CommonFXSema.getScale()); + assert(!Overflowed && "Full multiplication cannot overflow!"); + Result.setIsSigned(CommonFXSema.isSigned()); + + // If our result lies outside of the representative range of the common + // semantic, we either have overflow or saturation. + llvm::APSInt Max = APFixedPoint::getMax(CommonFXSema).getValue() + .extOrTrunc(Wide); + llvm::APSInt Min = APFixedPoint::getMin(CommonFXSema).getValue() + .extOrTrunc(Wide); + if (CommonFXSema.isSaturated()) { + if (Result < Min) + Result = Min; + else if (Result > Max) + Result = Max; + } else + Overflowed = Result < Min || Result > Max; + + if (Overflow) + *Overflow = Overflowed; + + return APFixedPoint(Result.sextOrTrunc(CommonFXSema.getWidth()), + CommonFXSema); +} + +APFixedPoint APFixedPoint::div(const APFixedPoint &Other, + bool *Overflow) const { + auto CommonFXSema = Sema.getCommonSemantics(Other.getSemantics()); + APFixedPoint ConvertedThis = convert(CommonFXSema); + APFixedPoint ConvertedOther = Other.convert(CommonFXSema); + llvm::APSInt ThisVal = ConvertedThis.getValue(); + llvm::APSInt OtherVal = ConvertedOther.getValue(); + bool Overflowed = false; + + // Widen the LHS and RHS so we can perform a full division. + unsigned Wide = CommonFXSema.getWidth() * 2; + if (CommonFXSema.isSigned()) { + ThisVal = ThisVal.sextOrSelf(Wide); + OtherVal = OtherVal.sextOrSelf(Wide); + } else { + ThisVal = ThisVal.zextOrSelf(Wide); + OtherVal = OtherVal.zextOrSelf(Wide); + } + + // Upscale to compensate for the loss of precision from division, and + // perform the full division. + ThisVal = ThisVal.shl(CommonFXSema.getScale()); + llvm::APSInt Result; + if (CommonFXSema.isSigned()) { + llvm::APInt Rem; + llvm::APInt::sdivrem(ThisVal, OtherVal, Result, Rem); + // If the quotient is negative and the remainder is nonzero, round + // towards negative infinity by subtracting epsilon from the result. + if (ThisVal.isNegative() != OtherVal.isNegative() && !Rem.isNullValue()) + Result = Result - 1; + } else + Result = ThisVal.udiv(OtherVal); + Result.setIsSigned(CommonFXSema.isSigned()); + + // If our result lies outside of the representative range of the common + // semantic, we either have overflow or saturation. + llvm::APSInt Max = APFixedPoint::getMax(CommonFXSema).getValue() + .extOrTrunc(Wide); + llvm::APSInt Min = APFixedPoint::getMin(CommonFXSema).getValue() + .extOrTrunc(Wide); + if (CommonFXSema.isSaturated()) { + if (Result < Min) + Result = Min; + else if (Result > Max) + Result = Max; + } else + Overflowed = Result < Min || Result > Max; + + if (Overflow) + *Overflow = Overflowed; + + return APFixedPoint(Result.sextOrTrunc(CommonFXSema.getWidth()), + CommonFXSema); +} + void APFixedPoint::toString(llvm::SmallVectorImpl &Str) const { llvm::APSInt Val = getValue(); unsigned Scale = getScale(); diff --git a/clang/lib/Basic/LangOptions.cpp b/clang/lib/Basic/LangOptions.cpp index a74efdc460bf7..c08670c87fb69 100644 --- a/clang/lib/Basic/LangOptions.cpp +++ b/clang/lib/Basic/LangOptions.cpp @@ -24,7 +24,7 @@ void LangOptions::resetNonModularOptions() { #define LANGOPT(Name, Bits, Default, Description) #define BENIGN_LANGOPT(Name, Bits, Default, Description) Name = Default; #define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ - Name = Default; + Name = static_cast(Default); #include "clang/Basic/LangOptions.def" // These options do not affect AST generation. @@ -53,6 +53,17 @@ FPOptions FPOptions::defaultWithoutTrailingStorage(const LangOptions &LO) { return result; } -bool FPOptions::requiresTrailingStorage(const LangOptions &LO) { - return getAsOpaqueInt() != defaultWithoutTrailingStorage(LO).getAsOpaqueInt(); +LLVM_DUMP_METHOD void FPOptions::dump() { +#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ + llvm::errs() << "\n " #NAME " " << get##NAME(); +#include "clang/Basic/FPOptions.def" + llvm::errs() << "\n"; +} + +LLVM_DUMP_METHOD void FPOptionsOverride::dump() { +#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ + if (has##NAME##Override()) \ + llvm::errs() << "\n " #NAME " Override is " << get##NAME##Override(); +#include "clang/Basic/FPOptions.def" + llvm::errs() << "\n"; } diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index a000e4dee3b85..cae61ad4f2e3a 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -178,6 +178,8 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, case OMPC_uses_allocators: case OMPC_affinity: break; + default: + break; } llvm_unreachable("Invalid OpenMP simple clause kind"); } @@ -427,6 +429,8 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, case OMPC_uses_allocators: case OMPC_affinity: break; + default: + break; } llvm_unreachable("Invalid OpenMP simple clause kind"); } @@ -580,7 +584,7 @@ bool clang::isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind) { void clang::getOpenMPCaptureRegions( SmallVectorImpl &CaptureRegions, OpenMPDirectiveKind DKind) { - assert(DKind <= OMPD_unknown); + assert(unsigned(DKind) < llvm::omp::Directive_enumSize); switch (DKind) { case OMPD_parallel: case OMPD_parallel_for: @@ -681,6 +685,7 @@ void clang::getOpenMPCaptureRegions( case OMPD_end_declare_variant: llvm_unreachable("OpenMP Directive is not allowed"); case OMPD_unknown: + default: llvm_unreachable("Unknown OpenMP directive"); } } diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp index 6e4c8e8052bdc..0a76c78cd44fb 100644 --- a/clang/lib/Basic/SourceManager.cpp +++ b/clang/lib/Basic/SourceManager.cpp @@ -861,11 +861,8 @@ FileID SourceManager::getFileIDLocal(unsigned SLocOffset) const { --I; if (I->getOffset() <= SLocOffset) { FileID Res = FileID::get(int(I - LocalSLocEntryTable.begin())); - - // If this isn't an expansion, remember it. We have good locality across - // FileID lookups. - if (!I->isExpansion()) - LastFileIDLookup = Res; + // Remember it. We have good locality across FileID lookups. + LastFileIDLookup = Res; NumLinearScans += NumProbes+1; return Res; } @@ -882,11 +879,8 @@ FileID SourceManager::getFileIDLocal(unsigned SLocOffset) const { unsigned LessIndex = 0; NumProbes = 0; while (true) { - bool Invalid = false; unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex; - unsigned MidOffset = getLocalSLocEntry(MiddleIndex, &Invalid).getOffset(); - if (Invalid) - return FileID::get(0); + unsigned MidOffset = getLocalSLocEntry(MiddleIndex).getOffset(); ++NumProbes; @@ -898,15 +892,12 @@ FileID SourceManager::getFileIDLocal(unsigned SLocOffset) const { } // If the middle index contains the value, succeed and return. - // FIXME: This could be made faster by using a function that's aware of - // being in the local area. - if (isOffsetInFileID(FileID::get(MiddleIndex), SLocOffset)) { + if (MiddleIndex + 1 == LocalSLocEntryTable.size() || + SLocOffset < getLocalSLocEntry(MiddleIndex + 1).getOffset()) { FileID Res = FileID::get(MiddleIndex); - // If this isn't a macro expansion, remember it. We have good locality - // across FileID lookups. - if (!LocalSLocEntryTable[MiddleIndex].isExpansion()) - LastFileIDLookup = Res; + // Remember it. We have good locality across FileID lookups. + LastFileIDLookup = Res; NumBinaryProbes += NumProbes; return Res; } @@ -944,9 +935,7 @@ FileID SourceManager::getFileIDLoaded(unsigned SLocOffset) const { const SrcMgr::SLocEntry &E = getLoadedSLocEntry(I); if (E.getOffset() <= SLocOffset) { FileID Res = FileID::get(-int(I) - 2); - - if (!E.isExpansion()) - LastFileIDLookup = Res; + LastFileIDLookup = Res; NumLinearScans += NumProbes + 1; return Res; } @@ -979,8 +968,7 @@ FileID SourceManager::getFileIDLoaded(unsigned SLocOffset) const { if (isOffsetInFileID(FileID::get(-int(MiddleIndex) - 2), SLocOffset)) { FileID Res = FileID::get(-int(MiddleIndex) - 2); - if (!E.isExpansion()) - LastFileIDLookup = Res; + LastFileIDLookup = Res; NumBinaryProbes += NumProbes; return Res; } @@ -1695,11 +1683,7 @@ FileID SourceManager::translateFile(const FileEntry *SourceFile) const { // The location we're looking for isn't in the main file; look // through all of the local source locations. for (unsigned I = 0, N = local_sloc_entry_size(); I != N; ++I) { - bool Invalid = false; - const SLocEntry &SLoc = getLocalSLocEntry(I, &Invalid); - if (Invalid) - return FileID(); - + const SLocEntry &SLoc = getLocalSLocEntry(I); if (SLoc.isFile() && SLoc.getFile().getContentCache() && SLoc.getFile().getContentCache()->OrigEntry == SourceFile) return FileID::get(I); diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 7f360b715da90..eccdc21d724a1 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -37,6 +37,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { HasFloat128 = false; HasFloat16 = false; HasBFloat16 = false; + HasStrictFP = false; PointerWidth = PointerAlign = 32; BoolWidth = BoolAlign = 8; IntWidth = IntAlign = 32; diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 69133ca31fec4..6bbcafa27dfe6 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -33,6 +33,7 @@ #include "Targets/Sparc.h" #include "Targets/SystemZ.h" #include "Targets/TCE.h" +#include "Targets/VE.h" #include "Targets/WebAssembly.h" #include "Targets/X86.h" #include "Targets/XCore.h" @@ -613,6 +614,9 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, return new LinuxTargetInfo(Triple, Opts); case llvm::Triple::renderscript64: return new LinuxTargetInfo(Triple, Opts); + + case llvm::Triple::ve: + return new LinuxTargetInfo(Triple, Opts); } } } // namespace targets diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index b474d1203deed..25c02cb888c1b 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -260,6 +260,24 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__ARM_NEON_FP", "0xE"); } + if (FPU & SveMode) + Builder.defineMacro("__ARM_FEATURE_SVE", "1"); + + if (HasSVE2) + Builder.defineMacro("__ARM_FEATURE_SVE2", "1"); + + if (HasSVE2 && HasSVE2AES) + Builder.defineMacro("__ARM_FEATURE_SVE2_AES", "1"); + + if (HasSVE2 && HasSVE2BitPerm) + Builder.defineMacro("__ARM_FEATURE_SVE2_BITPERM", "1"); + + if (HasSVE2 && HasSVE2SHA3) + Builder.defineMacro("__ARM_FEATURE_SVE2_SHA3", "1"); + + if (HasSVE2 && HasSVE2SM4) + Builder.defineMacro("__ARM_FEATURE_SVE2_SM4", "1"); + if (HasCRC) Builder.defineMacro("__ARM_FEATURE_CRC32", "1"); @@ -290,8 +308,22 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__ARM_FEATURE_BF16", "1"); Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1"); Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1"); + Builder.defineMacro("__ARM_FEATURE_BF16_SCALAR_ARITHMETIC", "1"); + } + + if ((FPU & SveMode) && HasBFloat16) { + Builder.defineMacro("__ARM_FEATURE_SVE_BF16", "1"); } + if ((FPU & SveMode) && HasMatmulFP64) + Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP64", "1"); + + if ((FPU & SveMode) && HasMatmulFP32) + Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP32", "1"); + + if ((FPU & SveMode) && HasMatMul) + Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_INT8", "1"); + if ((FPU & NeonMode) && HasFP16FML) Builder.defineMacro("__ARM_FEATURE_FP16FML", "1"); @@ -354,7 +386,11 @@ ArrayRef AArch64TargetInfo::getTargetBuiltins() const { bool AArch64TargetInfo::hasFeature(StringRef Feature) const { return Feature == "aarch64" || Feature == "arm64" || Feature == "arm" || (Feature == "neon" && (FPU & NeonMode)) || - (Feature == "sve" && (FPU & SveMode)); + ((Feature == "sve" || Feature == "sve2" || Feature == "sve2-bitperm" || + Feature == "sve2-aes" || Feature == "sve2-sha3" || + Feature == "sve2-sm4" || Feature == "f64mm" || Feature == "f32mm" || + Feature == "i8mm" || Feature == "bf16") && + (FPU & SveMode)); } bool AArch64TargetInfo::handleTargetFeatures(std::vector &Features, @@ -370,13 +406,60 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector &Features, HasTME = false; HasMatMul = false; HasBFloat16 = false; + HasSVE2 = false; + HasSVE2AES = false; + HasSVE2SHA3 = false; + HasSVE2SM4 = false; + HasSVE2BitPerm = false; + HasMatmulFP64 = false; + HasMatmulFP32 = false; + ArchKind = llvm::AArch64::ArchKind::ARMV8A; for (const auto &Feature : Features) { if (Feature == "+neon") FPU |= NeonMode; - if (Feature == "+sve") + if (Feature == "+sve") { + FPU |= SveMode; + HasFullFP16 = 1; + } + if (Feature == "+sve2") { FPU |= SveMode; + HasFullFP16 = 1; + HasSVE2 = 1; + } + if (Feature == "+sve2-aes") { + FPU |= SveMode; + HasFullFP16 = 1; + HasSVE2 = 1; + HasSVE2AES = 1; + } + if (Feature == "+sve2-sha3") { + FPU |= SveMode; + HasFullFP16 = 1; + HasSVE2 = 1; + HasSVE2SHA3 = 1; + } + if (Feature == "+sve2-sm4") { + FPU |= SveMode; + HasFullFP16 = 1; + HasSVE2 = 1; + HasSVE2SM4 = 1; + } + if (Feature == "+sve2-bitperm") { + FPU |= SveMode; + HasFullFP16 = 1; + HasSVE2 = 1; + HasSVE2BitPerm = 1; + } + if (Feature == "+f32mm") { + FPU |= SveMode; + HasMatmulFP32 = true; + } + if (Feature == "+f64mm") { + FPU |= SveMode; + HasMatmulFP64 = true; + } if (Feature == "+crc") HasCRC = true; if (Feature == "+crypto") diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h index 4a58c6671f4e2..d1982897d84e2 100644 --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -37,6 +37,13 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo { bool HasMTE; bool HasTME; bool HasMatMul; + bool HasSVE2; + bool HasSVE2AES; + bool HasSVE2SHA3; + bool HasSVE2SM4; + bool HasSVE2BitPerm; + bool HasMatmulFP64; + bool HasMatmulFP32; llvm::AArch64::ArchKind ArchKind; diff --git a/clang/lib/Basic/Targets/AMDGPU.h b/clang/lib/Basic/Targets/AMDGPU.h index 387b91abb537d..d0394492cad6d 100644 --- a/clang/lib/Basic/Targets/AMDGPU.h +++ b/clang/lib/Basic/Targets/AMDGPU.h @@ -130,8 +130,26 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo { "exec_hi", "tma_lo", "tma_hi", "tba_lo", "tba_hi", }); + switch (*Name) { + case 'I': + Info.setRequiresImmediate(-16, 64); + return true; + case 'J': + Info.setRequiresImmediate(-32768, 32767); + return true; + case 'A': + case 'B': + case 'C': + Info.setRequiresImmediate(); + return true; + default: + break; + } + StringRef S(Name); - if (S == "A") { + + if (S == "DA" || S == "DB") { + Name++; Info.setRequiresImmediate(); return true; } @@ -203,6 +221,12 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo { // the constraint. In practice, it won't be changed unless the // constraint is longer than one character. std::string convertConstraint(const char *&Constraint) const override { + + StringRef S(Constraint); + if (S == "DA" || S == "DB") { + return std::string("^") + std::string(Constraint++, 2); + } + const char *Begin = Constraint; TargetInfo::ConstraintInfo Info("", ""); if (validateAsmConstraint(Constraint, Info)) diff --git a/clang/lib/Basic/Targets/MSP430.h b/clang/lib/Basic/Targets/MSP430.h index 620f12d2b8e3a..9d42e4d4bb183 100644 --- a/clang/lib/Basic/Targets/MSP430.h +++ b/clang/lib/Basic/Targets/MSP430.h @@ -64,8 +64,14 @@ class LLVM_LIBRARY_VISIBILITY MSP430TargetInfo : public TargetInfo { ArrayRef getGCCRegNames() const override; ArrayRef getGCCRegAliases() const override { - // No aliases. - return None; + // Make r0 - r3 be recognized by llc (f.e., in clobber list) + static const TargetInfo::GCCRegAlias GCCRegAliases[] = { + {{"r0"}, "pc"}, + {{"r1"}, "sp"}, + {{"r2"}, "sr"}, + {{"r3"}, "cg"}, + }; + return llvm::makeArrayRef(GCCRegAliases); } bool validateAsmConstraint(const char *&Name, diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index 22a367a5ad42f..858059bacb86b 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -343,13 +343,20 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { const char *getFloat128Mangling() const override { return "u9__ieee128"; } bool hasExtIntType() const override { return true; } + + bool isSPRegName(StringRef RegName) const override { + return RegName.equals("r1") || RegName.equals("x1"); + } }; class LLVM_LIBRARY_VISIBILITY PPC32TargetInfo : public PPCTargetInfo { public: PPC32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : PPCTargetInfo(Triple, Opts) { - resetDataLayout("E-m:e-p:32:32-i64:64-n32"); + if (Triple.isOSAIX()) + resetDataLayout("E-m:a-p:32:32-i64:64-n32"); + else + resetDataLayout("E-m:e-p:32:32-i64:64-n32"); switch (getTriple().getOS()) { case llvm::Triple::Linux: @@ -395,7 +402,11 @@ class LLVM_LIBRARY_VISIBILITY PPC64TargetInfo : public PPCTargetInfo { IntMaxType = SignedLong; Int64Type = SignedLong; - if ((Triple.getArch() == llvm::Triple::ppc64le)) { + if (Triple.isOSAIX()) { + // TODO: Set appropriate ABI for AIX platform. + resetDataLayout("E-m:a-i64:64-n32:64"); + SuitableAlign = 64; + } else if ((Triple.getArch() == llvm::Triple::ppc64le)) { resetDataLayout("e-m:e-i64:64-n32:64"); ABI = "elfv2"; } else { @@ -403,9 +414,6 @@ class LLVM_LIBRARY_VISIBILITY PPC64TargetInfo : public PPCTargetInfo { ABI = "elfv1"; } - if (Triple.getOS() == llvm::Triple::AIX) - SuitableAlign = 64; - if (Triple.isOSFreeBSD() || Triple.getOS() == llvm::Triple::AIX || Triple.isMusl()) { LongDoubleWidth = LongDoubleAlign = 64; diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h index 134b0313b86ab..d7869e3754a82 100644 --- a/clang/lib/Basic/Targets/SystemZ.h +++ b/clang/lib/Basic/Targets/SystemZ.h @@ -48,6 +48,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo { MinGlobalAlign = 16; resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64"); MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; + HasStrictFP = true; } void getTargetDefines(const LangOptions &Opts, diff --git a/clang/lib/Basic/Targets/VE.cpp b/clang/lib/Basic/Targets/VE.cpp new file mode 100644 index 0000000000000..22223654e8adc --- /dev/null +++ b/clang/lib/Basic/Targets/VE.cpp @@ -0,0 +1,39 @@ +//===--- VE.cpp - Implement VE target feature support ---------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements VE TargetInfo objects. +// +//===----------------------------------------------------------------------===// + +#include "VE.h" +#include "clang/Basic/Builtins.h" +#include "clang/Basic/MacroBuilder.h" +#include "clang/Basic/TargetBuiltins.h" + +using namespace clang; +using namespace clang::targets; + +void VETargetInfo::getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + Builder.defineMacro("_LP64", "1"); + Builder.defineMacro("unix", "1"); + Builder.defineMacro("__unix__", "1"); + Builder.defineMacro("__linux__", "1"); + Builder.defineMacro("__ve", "1"); + Builder.defineMacro("__ve__", "1"); + Builder.defineMacro("__STDC_HOSTED__", "1"); + Builder.defineMacro("__STDC__", "1"); + Builder.defineMacro("__NEC__", "1"); + // FIXME: define __FAST_MATH__ 1 if -ffast-math is enabled + // FIXME: define __OPTIMIZE__ n if -On is enabled + // FIXME: define __VECTOR__ n 1 if automatic vectorization is enabled +} + +ArrayRef VETargetInfo::getTargetBuiltins() const { + return ArrayRef(); +} diff --git a/clang/lib/Basic/Targets/VE.h b/clang/lib/Basic/Targets/VE.h new file mode 100644 index 0000000000000..f863a0af0acb6 --- /dev/null +++ b/clang/lib/Basic/Targets/VE.h @@ -0,0 +1,170 @@ +//===--- VE.h - Declare VE target feature support ---------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares VE TargetInfo objects. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_VE_H +#define LLVM_CLANG_LIB_BASIC_TARGETS_VE_H + +#include "clang/Basic/TargetInfo.h" +#include "clang/Basic/TargetOptions.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Support/Compiler.h" + +namespace clang { +namespace targets { + +class LLVM_LIBRARY_VISIBILITY VETargetInfo : public TargetInfo { + static const Builtin::Info BuiltinInfo[]; + +public: + VETargetInfo(const llvm::Triple &Triple, const TargetOptions &) + : TargetInfo(Triple) { + NoAsmVariants = true; + LongDoubleWidth = 128; + LongDoubleAlign = 128; + LongDoubleFormat = &llvm::APFloat::IEEEquad(); + DoubleAlign = LongLongAlign = 64; + SuitableAlign = 64; + LongWidth = LongAlign = PointerWidth = PointerAlign = 64; + SizeType = UnsignedLong; + PtrDiffType = SignedLong; + IntPtrType = SignedLong; + IntMaxType = SignedLong; + Int64Type = SignedLong; + RegParmMax = 8; + MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; + + WCharType = UnsignedInt; + WIntType = UnsignedInt; + UseZeroLengthBitfieldAlignment = true; + resetDataLayout("e-m:e-i64:64-n32:64-S128"); + } + + void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const override; + + bool hasSjLjLowering() const override { + // TODO + return false; + } + + ArrayRef getTargetBuiltins() const override; + + BuiltinVaListKind getBuiltinVaListKind() const override { + return TargetInfo::VoidPtrBuiltinVaList; + } + + CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { + switch (CC) { + default: + return CCCR_Warning; + case CC_C: + return CCCR_OK; + } + } + + const char *getClobbers() const override { return ""; } + + ArrayRef getGCCRegNames() const override { + static const char *const GCCRegNames[] = { + // Regular registers + "sx0", "sx1", "sx2", "sx3", "sx4", "sx5", "sx6", "sx7", + "sx8", "sx9", "sx10", "sx11", "sx12", "sx13", "sx14", "sx15", + "sx16", "sx17", "sx18", "sx19", "sx20", "sx21", "sx22", "sx23", + "sx24", "sx25", "sx26", "sx27", "sx28", "sx29", "sx30", "sx31", + "sx32", "sx33", "sx34", "sx35", "sx36", "sx37", "sx38", "sx39", + "sx40", "sx41", "sx42", "sx43", "sx44", "sx45", "sx46", "sx47", + "sx48", "sx49", "sx50", "sx51", "sx52", "sx53", "sx54", "sx55", + "sx56", "sx57", "sx58", "sx59", "sx60", "sx61", "sx62", "sx63", + }; + return llvm::makeArrayRef(GCCRegNames); + } + + ArrayRef getGCCRegAliases() const override { + static const TargetInfo::GCCRegAlias GCCRegAliases[] = { + {{"s0"}, "sx0"}, + {{"s1"}, "sx1"}, + {{"s2"}, "sx2"}, + {{"s3"}, "sx3"}, + {{"s4"}, "sx4"}, + {{"s5"}, "sx5"}, + {{"s6"}, "sx6"}, + {{"s7"}, "sx7"}, + {{"s8", "sl"}, "sx8"}, + {{"s9", "fp"}, "sx9"}, + {{"s10", "lr"}, "sx10"}, + {{"s11", "sp"}, "sx11"}, + {{"s12", "outer"}, "sx12"}, + {{"s13"}, "sx13"}, + {{"s14", "tp"}, "sx14"}, + {{"s15", "got"}, "sx15"}, + {{"s16", "plt"}, "sx16"}, + {{"s17", "info"}, "sx17"}, + {{"s18"}, "sx18"}, + {{"s19"}, "sx19"}, + {{"s20"}, "sx20"}, + {{"s21"}, "sx21"}, + {{"s22"}, "sx22"}, + {{"s23"}, "sx23"}, + {{"s24"}, "sx24"}, + {{"s25"}, "sx25"}, + {{"s26"}, "sx26"}, + {{"s27"}, "sx27"}, + {{"s28"}, "sx28"}, + {{"s29"}, "sx29"}, + {{"s30"}, "sx30"}, + {{"s31"}, "sx31"}, + {{"s32"}, "sx32"}, + {{"s33"}, "sx33"}, + {{"s34"}, "sx34"}, + {{"s35"}, "sx35"}, + {{"s36"}, "sx36"}, + {{"s37"}, "sx37"}, + {{"s38"}, "sx38"}, + {{"s39"}, "sx39"}, + {{"s40"}, "sx40"}, + {{"s41"}, "sx41"}, + {{"s42"}, "sx42"}, + {{"s43"}, "sx43"}, + {{"s44"}, "sx44"}, + {{"s45"}, "sx45"}, + {{"s46"}, "sx46"}, + {{"s47"}, "sx47"}, + {{"s48"}, "sx48"}, + {{"s49"}, "sx49"}, + {{"s50"}, "sx50"}, + {{"s51"}, "sx51"}, + {{"s52"}, "sx52"}, + {{"s53"}, "sx53"}, + {{"s54"}, "sx54"}, + {{"s55"}, "sx55"}, + {{"s56"}, "sx56"}, + {{"s57"}, "sx57"}, + {{"s58"}, "sx58"}, + {{"s59"}, "sx59"}, + {{"s60"}, "sx60"}, + {{"s61"}, "sx61"}, + {{"s62"}, "sx62"}, + {{"s63"}, "sx63"}, + }; + return llvm::makeArrayRef(GCCRegAliases); + } + + bool validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &Info) const override { + return false; + } + + bool allowsLargerPreferedTypeAlignment() const override { return false; } +}; +} // namespace targets +} // namespace clang +#endif // LLVM_CLANG_LIB_BASIC_TARGETS_VE_H diff --git a/clang/lib/Basic/Targets/WebAssembly.h b/clang/lib/Basic/Targets/WebAssembly.h index e09e21d908022..77a2fe9ae1173 100644 --- a/clang/lib/Basic/Targets/WebAssembly.h +++ b/clang/lib/Basic/Targets/WebAssembly.h @@ -133,11 +133,7 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo { bool hasExtIntType() const override { return true; } - bool hasProtectedVisibility() const override { - // TODO: For now, continue to advertise "protected" support for - // Emscripten targets. - return getTriple().isOSEmscripten(); - } + bool hasProtectedVisibility() const override { return false; } }; class LLVM_LIBRARY_VISIBILITY WebAssembly32TargetInfo diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp index 0092c52b2b231..543f232d24591 100644 --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -62,6 +62,7 @@ static const char *const GCCRegNames[] = { "cr0", "cr2", "cr3", "cr4", "cr8", "dr0", "dr1", "dr2", "dr3", "dr6", "dr7", "bnd0", "bnd1", "bnd2", "bnd3", + "tmm0", "tmm1", "tmm2", "tmm3", "tmm4", "tmm5", "tmm6", "tmm7", }; const TargetInfo::AddlRegName AddlRegNames[] = { @@ -107,337 +108,15 @@ bool X86TargetInfo::initFeatureMap( // FIXME: This *really* should not be here. // X86_64 always has SSE2. if (getTriple().getArch() == llvm::Triple::x86_64) - setFeatureEnabledImpl(Features, "sse2", true); + setFeatureEnabled(Features, "sse2", true); using namespace llvm::X86; - const enum CPUKind Kind = parseArchX86(CPU); - // Enable X87 for all X86 processors but Lakemont. - if (Kind != CK_Lakemont) - setFeatureEnabledImpl(Features, "x87", true); + SmallVector CPUFeatures; + getFeaturesForCPU(CPU, CPUFeatures); + for (auto &F : CPUFeatures) + setFeatureEnabled(Features, F, true); - // Enable cmpxchg8 for i586 and greater CPUs. Include generic for backwards - // compatibility. - if (Kind >= CK_i586 || Kind == CK_None) - setFeatureEnabledImpl(Features, "cx8", true); - - switch (Kind) { - case CK_None: - case CK_i386: - case CK_i486: - case CK_i586: - case CK_Pentium: - case CK_PentiumPro: - case CK_i686: - case CK_Lakemont: - break; - - case CK_Cooperlake: - // CPX inherits all CLX features plus AVX512BF16 - setFeatureEnabledImpl(Features, "avx512bf16", true); - LLVM_FALLTHROUGH; - case CK_Cascadelake: - // CLX inherits all SKX features plus AVX512VNNI - setFeatureEnabledImpl(Features, "avx512vnni", true); - LLVM_FALLTHROUGH; - case CK_SkylakeServer: - setFeatureEnabledImpl(Features, "avx512f", true); - setFeatureEnabledImpl(Features, "avx512cd", true); - setFeatureEnabledImpl(Features, "avx512dq", true); - setFeatureEnabledImpl(Features, "avx512bw", true); - setFeatureEnabledImpl(Features, "avx512vl", true); - setFeatureEnabledImpl(Features, "clwb", true); - setFeatureEnabledImpl(Features, "pku", true); - // SkylakeServer cores inherits all SKL features, except SGX - goto SkylakeCommon; - - case CK_Tigerlake: - setFeatureEnabledImpl(Features, "avx512vp2intersect", true); - setFeatureEnabledImpl(Features, "movdiri", true); - setFeatureEnabledImpl(Features, "movdir64b", true); - setFeatureEnabledImpl(Features, "shstk", true); - // Tigerlake cores inherits IcelakeClient, except pconfig and wbnoinvd - goto IcelakeCommon; - - case CK_IcelakeServer: - setFeatureEnabledImpl(Features, "pconfig", true); - setFeatureEnabledImpl(Features, "wbnoinvd", true); - LLVM_FALLTHROUGH; - case CK_IcelakeClient: -IcelakeCommon: - setFeatureEnabledImpl(Features, "vaes", true); - setFeatureEnabledImpl(Features, "gfni", true); - setFeatureEnabledImpl(Features, "vpclmulqdq", true); - setFeatureEnabledImpl(Features, "avx512bitalg", true); - setFeatureEnabledImpl(Features, "avx512vbmi2", true); - setFeatureEnabledImpl(Features, "avx512vnni", true); - setFeatureEnabledImpl(Features, "avx512vpopcntdq", true); - setFeatureEnabledImpl(Features, "rdpid", true); - setFeatureEnabledImpl(Features, "clwb", true); - LLVM_FALLTHROUGH; - case CK_Cannonlake: - setFeatureEnabledImpl(Features, "avx512f", true); - setFeatureEnabledImpl(Features, "avx512cd", true); - setFeatureEnabledImpl(Features, "avx512dq", true); - setFeatureEnabledImpl(Features, "avx512bw", true); - setFeatureEnabledImpl(Features, "avx512vl", true); - setFeatureEnabledImpl(Features, "avx512ifma", true); - setFeatureEnabledImpl(Features, "avx512vbmi", true); - setFeatureEnabledImpl(Features, "pku", true); - setFeatureEnabledImpl(Features, "sha", true); - LLVM_FALLTHROUGH; - case CK_SkylakeClient: - setFeatureEnabledImpl(Features, "sgx", true); - // SkylakeServer cores inherits all SKL features, except SGX -SkylakeCommon: - setFeatureEnabledImpl(Features, "xsavec", true); - setFeatureEnabledImpl(Features, "xsaves", true); - setFeatureEnabledImpl(Features, "clflushopt", true); - setFeatureEnabledImpl(Features, "aes", true); - LLVM_FALLTHROUGH; - case CK_Broadwell: - setFeatureEnabledImpl(Features, "rdseed", true); - setFeatureEnabledImpl(Features, "adx", true); - setFeatureEnabledImpl(Features, "prfchw", true); - LLVM_FALLTHROUGH; - case CK_Haswell: - setFeatureEnabledImpl(Features, "avx2", true); - setFeatureEnabledImpl(Features, "lzcnt", true); - setFeatureEnabledImpl(Features, "bmi", true); - setFeatureEnabledImpl(Features, "bmi2", true); - setFeatureEnabledImpl(Features, "fma", true); - setFeatureEnabledImpl(Features, "invpcid", true); - setFeatureEnabledImpl(Features, "movbe", true); - LLVM_FALLTHROUGH; - case CK_IvyBridge: - setFeatureEnabledImpl(Features, "rdrnd", true); - setFeatureEnabledImpl(Features, "f16c", true); - setFeatureEnabledImpl(Features, "fsgsbase", true); - LLVM_FALLTHROUGH; - case CK_SandyBridge: - setFeatureEnabledImpl(Features, "avx", true); - setFeatureEnabledImpl(Features, "xsave", true); - setFeatureEnabledImpl(Features, "xsaveopt", true); - LLVM_FALLTHROUGH; - case CK_Westmere: - setFeatureEnabledImpl(Features, "pclmul", true); - LLVM_FALLTHROUGH; - case CK_Nehalem: - setFeatureEnabledImpl(Features, "sse4.2", true); - LLVM_FALLTHROUGH; - case CK_Penryn: - setFeatureEnabledImpl(Features, "sse4.1", true); - LLVM_FALLTHROUGH; - case CK_Core2: - setFeatureEnabledImpl(Features, "ssse3", true); - setFeatureEnabledImpl(Features, "sahf", true); - LLVM_FALLTHROUGH; - case CK_Nocona: - setFeatureEnabledImpl(Features, "cx16", true); - LLVM_FALLTHROUGH; - case CK_Yonah: - case CK_Prescott: - setFeatureEnabledImpl(Features, "sse3", true); - LLVM_FALLTHROUGH; - case CK_PentiumM: - case CK_Pentium4: - case CK_x86_64: - setFeatureEnabledImpl(Features, "sse2", true); - LLVM_FALLTHROUGH; - case CK_Pentium3: - case CK_C3_2: - setFeatureEnabledImpl(Features, "sse", true); - LLVM_FALLTHROUGH; - case CK_Pentium2: - setFeatureEnabledImpl(Features, "fxsr", true); - LLVM_FALLTHROUGH; - case CK_PentiumMMX: - case CK_K6: - case CK_WinChipC6: - setFeatureEnabledImpl(Features, "mmx", true); - break; - - case CK_Tremont: - setFeatureEnabledImpl(Features, "clwb", true); - setFeatureEnabledImpl(Features, "gfni", true); - LLVM_FALLTHROUGH; - case CK_GoldmontPlus: - setFeatureEnabledImpl(Features, "ptwrite", true); - setFeatureEnabledImpl(Features, "rdpid", true); - setFeatureEnabledImpl(Features, "sgx", true); - LLVM_FALLTHROUGH; - case CK_Goldmont: - setFeatureEnabledImpl(Features, "sha", true); - setFeatureEnabledImpl(Features, "rdseed", true); - setFeatureEnabledImpl(Features, "xsave", true); - setFeatureEnabledImpl(Features, "xsaveopt", true); - setFeatureEnabledImpl(Features, "xsavec", true); - setFeatureEnabledImpl(Features, "xsaves", true); - setFeatureEnabledImpl(Features, "clflushopt", true); - setFeatureEnabledImpl(Features, "fsgsbase", true); - setFeatureEnabledImpl(Features, "aes", true); - LLVM_FALLTHROUGH; - case CK_Silvermont: - setFeatureEnabledImpl(Features, "rdrnd", true); - setFeatureEnabledImpl(Features, "pclmul", true); - setFeatureEnabledImpl(Features, "sse4.2", true); - setFeatureEnabledImpl(Features, "prfchw", true); - LLVM_FALLTHROUGH; - case CK_Bonnell: - setFeatureEnabledImpl(Features, "movbe", true); - setFeatureEnabledImpl(Features, "ssse3", true); - setFeatureEnabledImpl(Features, "fxsr", true); - setFeatureEnabledImpl(Features, "cx16", true); - setFeatureEnabledImpl(Features, "sahf", true); - setFeatureEnabledImpl(Features, "mmx", true); - break; - - case CK_KNM: - // TODO: Add avx5124fmaps/avx5124vnniw. - setFeatureEnabledImpl(Features, "avx512vpopcntdq", true); - LLVM_FALLTHROUGH; - case CK_KNL: - setFeatureEnabledImpl(Features, "avx512f", true); - setFeatureEnabledImpl(Features, "avx512cd", true); - setFeatureEnabledImpl(Features, "avx512er", true); - setFeatureEnabledImpl(Features, "avx512pf", true); - setFeatureEnabledImpl(Features, "prfchw", true); - setFeatureEnabledImpl(Features, "prefetchwt1", true); - setFeatureEnabledImpl(Features, "fxsr", true); - setFeatureEnabledImpl(Features, "rdseed", true); - setFeatureEnabledImpl(Features, "adx", true); - setFeatureEnabledImpl(Features, "lzcnt", true); - setFeatureEnabledImpl(Features, "bmi", true); - setFeatureEnabledImpl(Features, "bmi2", true); - setFeatureEnabledImpl(Features, "fma", true); - setFeatureEnabledImpl(Features, "rdrnd", true); - setFeatureEnabledImpl(Features, "f16c", true); - setFeatureEnabledImpl(Features, "fsgsbase", true); - setFeatureEnabledImpl(Features, "aes", true); - setFeatureEnabledImpl(Features, "pclmul", true); - setFeatureEnabledImpl(Features, "cx16", true); - setFeatureEnabledImpl(Features, "xsaveopt", true); - setFeatureEnabledImpl(Features, "xsave", true); - setFeatureEnabledImpl(Features, "movbe", true); - setFeatureEnabledImpl(Features, "sahf", true); - setFeatureEnabledImpl(Features, "mmx", true); - break; - - case CK_K6_2: - case CK_K6_3: - case CK_WinChip2: - case CK_C3: - setFeatureEnabledImpl(Features, "3dnow", true); - break; - - case CK_AMDFAM10: - setFeatureEnabledImpl(Features, "sse4a", true); - setFeatureEnabledImpl(Features, "lzcnt", true); - setFeatureEnabledImpl(Features, "popcnt", true); - setFeatureEnabledImpl(Features, "sahf", true); - LLVM_FALLTHROUGH; - case CK_K8SSE3: - setFeatureEnabledImpl(Features, "sse3", true); - LLVM_FALLTHROUGH; - case CK_K8: - setFeatureEnabledImpl(Features, "sse2", true); - LLVM_FALLTHROUGH; - case CK_AthlonXP: - setFeatureEnabledImpl(Features, "sse", true); - setFeatureEnabledImpl(Features, "fxsr", true); - LLVM_FALLTHROUGH; - case CK_Athlon: - case CK_Geode: - setFeatureEnabledImpl(Features, "3dnowa", true); - break; - - case CK_BTVER2: - setFeatureEnabledImpl(Features, "avx", true); - setFeatureEnabledImpl(Features, "aes", true); - setFeatureEnabledImpl(Features, "pclmul", true); - setFeatureEnabledImpl(Features, "bmi", true); - setFeatureEnabledImpl(Features, "f16c", true); - setFeatureEnabledImpl(Features, "xsaveopt", true); - setFeatureEnabledImpl(Features, "movbe", true); - LLVM_FALLTHROUGH; - case CK_BTVER1: - setFeatureEnabledImpl(Features, "ssse3", true); - setFeatureEnabledImpl(Features, "sse4a", true); - setFeatureEnabledImpl(Features, "lzcnt", true); - setFeatureEnabledImpl(Features, "popcnt", true); - setFeatureEnabledImpl(Features, "prfchw", true); - setFeatureEnabledImpl(Features, "cx16", true); - setFeatureEnabledImpl(Features, "fxsr", true); - setFeatureEnabledImpl(Features, "sahf", true); - setFeatureEnabledImpl(Features, "mmx", true); - break; - - case CK_ZNVER2: - setFeatureEnabledImpl(Features, "clwb", true); - setFeatureEnabledImpl(Features, "rdpid", true); - setFeatureEnabledImpl(Features, "wbnoinvd", true); - LLVM_FALLTHROUGH; - case CK_ZNVER1: - setFeatureEnabledImpl(Features, "adx", true); - setFeatureEnabledImpl(Features, "aes", true); - setFeatureEnabledImpl(Features, "avx2", true); - setFeatureEnabledImpl(Features, "bmi", true); - setFeatureEnabledImpl(Features, "bmi2", true); - setFeatureEnabledImpl(Features, "clflushopt", true); - setFeatureEnabledImpl(Features, "clzero", true); - setFeatureEnabledImpl(Features, "cx16", true); - setFeatureEnabledImpl(Features, "f16c", true); - setFeatureEnabledImpl(Features, "fma", true); - setFeatureEnabledImpl(Features, "fsgsbase", true); - setFeatureEnabledImpl(Features, "fxsr", true); - setFeatureEnabledImpl(Features, "lzcnt", true); - setFeatureEnabledImpl(Features, "mmx", true); - setFeatureEnabledImpl(Features, "mwaitx", true); - setFeatureEnabledImpl(Features, "movbe", true); - setFeatureEnabledImpl(Features, "pclmul", true); - setFeatureEnabledImpl(Features, "popcnt", true); - setFeatureEnabledImpl(Features, "prfchw", true); - setFeatureEnabledImpl(Features, "rdrnd", true); - setFeatureEnabledImpl(Features, "rdseed", true); - setFeatureEnabledImpl(Features, "sahf", true); - setFeatureEnabledImpl(Features, "sha", true); - setFeatureEnabledImpl(Features, "sse4a", true); - setFeatureEnabledImpl(Features, "xsave", true); - setFeatureEnabledImpl(Features, "xsavec", true); - setFeatureEnabledImpl(Features, "xsaveopt", true); - setFeatureEnabledImpl(Features, "xsaves", true); - break; - - case CK_BDVER4: - setFeatureEnabledImpl(Features, "avx2", true); - setFeatureEnabledImpl(Features, "bmi2", true); - setFeatureEnabledImpl(Features, "mwaitx", true); - LLVM_FALLTHROUGH; - case CK_BDVER3: - setFeatureEnabledImpl(Features, "fsgsbase", true); - setFeatureEnabledImpl(Features, "xsaveopt", true); - LLVM_FALLTHROUGH; - case CK_BDVER2: - setFeatureEnabledImpl(Features, "bmi", true); - setFeatureEnabledImpl(Features, "fma", true); - setFeatureEnabledImpl(Features, "f16c", true); - setFeatureEnabledImpl(Features, "tbm", true); - LLVM_FALLTHROUGH; - case CK_BDVER1: - // xop implies avx, sse4a and fma4. - setFeatureEnabledImpl(Features, "xop", true); - setFeatureEnabledImpl(Features, "lwp", true); - setFeatureEnabledImpl(Features, "lzcnt", true); - setFeatureEnabledImpl(Features, "aes", true); - setFeatureEnabledImpl(Features, "pclmul", true); - setFeatureEnabledImpl(Features, "prfchw", true); - setFeatureEnabledImpl(Features, "cx16", true); - setFeatureEnabledImpl(Features, "fxsr", true); - setFeatureEnabledImpl(Features, "xsave", true); - setFeatureEnabledImpl(Features, "sahf", true); - setFeatureEnabledImpl(Features, "mmx", true); - break; - } if (!TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec)) return false; @@ -450,12 +129,6 @@ bool X86TargetInfo::initFeatureMap( llvm::find(FeaturesVec, "-popcnt") == FeaturesVec.end()) Features["popcnt"] = true; - // Enable prfchw if 3DNow! is enabled and prfchw is not explicitly disabled. - I = Features.find("3dnow"); - if (I != Features.end() && I->getValue() && - llvm::find(FeaturesVec, "-prfchw") == FeaturesVec.end()) - Features["prfchw"] = true; - // Additionally, if SSE is enabled and mmx is not explicitly disabled, // then enable MMX. I = Features.find("sse"); @@ -463,264 +136,34 @@ bool X86TargetInfo::initFeatureMap( llvm::find(FeaturesVec, "-mmx") == FeaturesVec.end()) Features["mmx"] = true; - return true; -} - -void X86TargetInfo::setSSELevel(llvm::StringMap &Features, - X86SSEEnum Level, bool Enabled) { - if (Enabled) { - switch (Level) { - case AVX512F: - Features["avx512f"] = true; - Features["fma"] = true; - Features["f16c"] = true; - LLVM_FALLTHROUGH; - case AVX2: - Features["avx2"] = true; - LLVM_FALLTHROUGH; - case AVX: - Features["avx"] = true; - Features["xsave"] = true; - LLVM_FALLTHROUGH; - case SSE42: - Features["sse4.2"] = true; - LLVM_FALLTHROUGH; - case SSE41: - Features["sse4.1"] = true; - LLVM_FALLTHROUGH; - case SSSE3: - Features["ssse3"] = true; - LLVM_FALLTHROUGH; - case SSE3: - Features["sse3"] = true; - LLVM_FALLTHROUGH; - case SSE2: - Features["sse2"] = true; - LLVM_FALLTHROUGH; - case SSE1: - Features["sse"] = true; - LLVM_FALLTHROUGH; - case NoSSE: - break; - } - return; - } - - switch (Level) { - case NoSSE: - case SSE1: - Features["sse"] = false; - LLVM_FALLTHROUGH; - case SSE2: - Features["sse2"] = Features["pclmul"] = Features["aes"] = false; - Features["sha"] = Features["gfni"] = false; - LLVM_FALLTHROUGH; - case SSE3: - Features["sse3"] = false; - setXOPLevel(Features, NoXOP, false); - LLVM_FALLTHROUGH; - case SSSE3: - Features["ssse3"] = false; - LLVM_FALLTHROUGH; - case SSE41: - Features["sse4.1"] = false; - LLVM_FALLTHROUGH; - case SSE42: - Features["sse4.2"] = false; - LLVM_FALLTHROUGH; - case AVX: - Features["fma"] = Features["avx"] = Features["f16c"] = false; - Features["xsave"] = Features["xsaveopt"] = Features["vaes"] = false; - Features["vpclmulqdq"] = false; - setXOPLevel(Features, FMA4, false); - LLVM_FALLTHROUGH; - case AVX2: - Features["avx2"] = false; - LLVM_FALLTHROUGH; - case AVX512F: - Features["avx512f"] = Features["avx512cd"] = Features["avx512er"] = false; - Features["avx512pf"] = Features["avx512dq"] = Features["avx512bw"] = false; - Features["avx512vl"] = Features["avx512vbmi"] = false; - Features["avx512ifma"] = Features["avx512vpopcntdq"] = false; - Features["avx512bitalg"] = Features["avx512vnni"] = false; - Features["avx512vbmi2"] = Features["avx512bf16"] = false; - Features["avx512vp2intersect"] = false; - break; - } -} - -void X86TargetInfo::setMMXLevel(llvm::StringMap &Features, - MMX3DNowEnum Level, bool Enabled) { - if (Enabled) { - switch (Level) { - case AMD3DNowAthlon: - Features["3dnowa"] = true; - LLVM_FALLTHROUGH; - case AMD3DNow: - Features["3dnow"] = true; - LLVM_FALLTHROUGH; - case MMX: - Features["mmx"] = true; - LLVM_FALLTHROUGH; - case NoMMX3DNow: - break; - } - return; - } - - switch (Level) { - case NoMMX3DNow: - case MMX: - Features["mmx"] = false; - LLVM_FALLTHROUGH; - case AMD3DNow: - Features["3dnow"] = false; - LLVM_FALLTHROUGH; - case AMD3DNowAthlon: - Features["3dnowa"] = false; - break; - } -} - -void X86TargetInfo::setXOPLevel(llvm::StringMap &Features, XOPEnum Level, - bool Enabled) { - if (Enabled) { - switch (Level) { - case XOP: - Features["xop"] = true; - LLVM_FALLTHROUGH; - case FMA4: - Features["fma4"] = true; - setSSELevel(Features, AVX, true); - LLVM_FALLTHROUGH; - case SSE4A: - Features["sse4a"] = true; - setSSELevel(Features, SSE3, true); - LLVM_FALLTHROUGH; - case NoXOP: - break; - } - return; - } + // Enable xsave if avx is enabled and xsave is not explicitly disabled. + I = Features.find("avx"); + if (I != Features.end() && I->getValue() && + llvm::find(FeaturesVec, "-xsave") == FeaturesVec.end()) + Features["xsave"] = true; - switch (Level) { - case NoXOP: - case SSE4A: - Features["sse4a"] = false; - LLVM_FALLTHROUGH; - case FMA4: - Features["fma4"] = false; - LLVM_FALLTHROUGH; - case XOP: - Features["xop"] = false; - break; - } + return true; } -void X86TargetInfo::setFeatureEnabledImpl(llvm::StringMap &Features, - StringRef Name, bool Enabled) { - // This is a bit of a hack to deal with the sse4 target feature when used - // as part of the target attribute. We handle sse4 correctly everywhere - // else. See below for more information on how we handle the sse4 options. - if (Name != "sse4") - Features[Name] = Enabled; - - if (Name == "mmx") { - setMMXLevel(Features, MMX, Enabled); - } else if (Name == "sse") { - setSSELevel(Features, SSE1, Enabled); - } else if (Name == "sse2") { - setSSELevel(Features, SSE2, Enabled); - } else if (Name == "sse3") { - setSSELevel(Features, SSE3, Enabled); - } else if (Name == "ssse3") { - setSSELevel(Features, SSSE3, Enabled); - } else if (Name == "sse4.2") { - setSSELevel(Features, SSE42, Enabled); - } else if (Name == "sse4.1") { - setSSELevel(Features, SSE41, Enabled); - } else if (Name == "3dnow") { - setMMXLevel(Features, AMD3DNow, Enabled); - } else if (Name == "3dnowa") { - setMMXLevel(Features, AMD3DNowAthlon, Enabled); - } else if (Name == "aes") { - if (Enabled) - setSSELevel(Features, SSE2, Enabled); - else - Features["vaes"] = false; - } else if (Name == "vaes") { - if (Enabled) { - setSSELevel(Features, AVX, Enabled); - Features["aes"] = true; - } - } else if (Name == "pclmul") { - if (Enabled) - setSSELevel(Features, SSE2, Enabled); - else - Features["vpclmulqdq"] = false; - } else if (Name == "vpclmulqdq") { - if (Enabled) { - setSSELevel(Features, AVX, Enabled); - Features["pclmul"] = true; - } - } else if (Name == "gfni") { - if (Enabled) - setSSELevel(Features, SSE2, Enabled); - } else if (Name == "avx") { - setSSELevel(Features, AVX, Enabled); - } else if (Name == "avx2") { - setSSELevel(Features, AVX2, Enabled); - } else if (Name == "avx512f") { - setSSELevel(Features, AVX512F, Enabled); - } else if (Name.startswith("avx512")) { - if (Enabled) - setSSELevel(Features, AVX512F, Enabled); - // Enable BWI instruction if certain features are being enabled. - if ((Name == "avx512vbmi" || Name == "avx512vbmi2" || - Name == "avx512bitalg" || Name == "avx512bf16") && Enabled) - Features["avx512bw"] = true; - // Also disable some features if BWI is being disabled. - if (Name == "avx512bw" && !Enabled) { - Features["avx512vbmi"] = false; - Features["avx512vbmi2"] = false; - Features["avx512bitalg"] = false; - Features["avx512bf16"] = false; - } - } else if (Name == "fma") { - if (Enabled) - setSSELevel(Features, AVX, Enabled); - else - setSSELevel(Features, AVX512F, Enabled); - } else if (Name == "fma4") { - setXOPLevel(Features, FMA4, Enabled); - } else if (Name == "xop") { - setXOPLevel(Features, XOP, Enabled); - } else if (Name == "sse4a") { - setXOPLevel(Features, SSE4A, Enabled); - } else if (Name == "f16c") { - if (Enabled) - setSSELevel(Features, AVX, Enabled); - else - setSSELevel(Features, AVX512F, Enabled); - } else if (Name == "sha") { - if (Enabled) - setSSELevel(Features, SSE2, Enabled); - } else if (Name == "sse4") { +void X86TargetInfo::setFeatureEnabled(llvm::StringMap &Features, + StringRef Name, bool Enabled) const { + if (Name == "sse4") { // We can get here via the __target__ attribute since that's not controlled // via the -msse4/-mno-sse4 command line alias. Handle this the same way // here - turn on the sse4.2 if enabled, turn off the sse4.1 level if // disabled. if (Enabled) - setSSELevel(Features, SSE42, Enabled); + Name = "sse4.2"; else - setSSELevel(Features, SSE41, Enabled); - } else if (Name == "xsave") { - if (!Enabled) - Features["xsaveopt"] = false; - } else if (Name == "xsaveopt" || Name == "xsavec" || Name == "xsaves") { - if (Enabled) - Features["xsave"] = true; + Name = "sse4.1"; } + + Features[Name] = Enabled; + + SmallVector ImpliedFeatures; + llvm::X86::getImpliedFeatures(Name, Enabled, ImpliedFeatures); + for (const auto &F : ImpliedFeatures) + Features[F] = Enabled; } /// handleTargetFeatures - Perform initialization based on the user @@ -855,6 +298,12 @@ bool X86TargetInfo::handleTargetFeatures(std::vector &Features, HasINVPCID = true; } else if (Feature == "+enqcmd") { HasENQCMD = true; + } else if (Feature == "+amx-bf16") { + HasAMXBF16 = true; + } else if (Feature == "+amx-int8") { + HasAMXINT8 = true; + } else if (Feature == "+amx-tile") { + HasAMXTILE = true; } else if (Feature == "+serialize") { HasSERIALIZE = true; } else if (Feature == "+tsxldtrk") { @@ -1250,6 +699,12 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__INVPCID__"); if (HasENQCMD) Builder.defineMacro("__ENQCMD__"); + if (HasAMXTILE) + Builder.defineMacro("__AMXTILE__"); + if (HasAMXINT8) + Builder.defineMacro("__AMXINT8__"); + if (HasAMXBF16) + Builder.defineMacro("__AMXBF16__"); if (HasSERIALIZE) Builder.defineMacro("__SERIALIZE__"); if (HasTSXLDTRK) @@ -1346,6 +801,9 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("3dnowa", true) .Case("adx", true) .Case("aes", true) + .Case("amx-bf16", true) + .Case("amx-int8", true) + .Case("amx-tile", true) .Case("avx", true) .Case("avx2", true) .Case("avx512f", true) @@ -1428,6 +886,9 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { return llvm::StringSwitch(Feature) .Case("adx", HasADX) .Case("aes", HasAES) + .Case("amx-bf16", HasAMXBF16) + .Case("amx-int8", HasAMXINT8) + .Case("amx-tile", HasAMXTILE) .Case("avx", SSELevel >= AVX) .Case("avx2", SSELevel >= AVX2) .Case("avx512f", SSELevel >= AVX512F) @@ -1518,14 +979,14 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { // X86TargetInfo::hasFeature for a somewhat comprehensive list). bool X86TargetInfo::validateCpuSupports(StringRef FeatureStr) const { return llvm::StringSwitch(FeatureStr) -#define X86_FEATURE_COMPAT(VAL, ENUM, STR) .Case(STR, true) +#define X86_FEATURE_COMPAT(ENUM, STR) .Case(STR, true) #include "llvm/Support/X86TargetParser.def" .Default(false); } static llvm::X86::ProcessorFeatures getFeature(StringRef Name) { return llvm::StringSwitch(Name) -#define X86_FEATURE_COMPAT(VAL, ENUM, STR) .Case(STR, llvm::X86::ENUM) +#define X86_FEATURE_COMPAT(ENUM, STR) .Case(STR, llvm::X86::FEATURE_##ENUM) #include "llvm/Support/X86TargetParser.def" ; // Note, this function should only be used after ensuring the value is @@ -1553,15 +1014,8 @@ unsigned X86TargetInfo::multiVersionSortPriority(StringRef Name) const { using namespace llvm::X86; CPUKind Kind = parseArchX86(Name); if (Kind != CK_None) { - switch (Kind) { - default: - llvm_unreachable( - "CPU Type without a key feature used in 'target' attribute"); -#define PROC_WITH_FEAT(ENUM, STR, IS64, KEY_FEAT) \ - case CK_##ENUM: \ - return (getFeaturePriority(llvm::X86::KEY_FEAT) << 1) + 1; -#include "llvm/Support/X86TargetParser.def" - } + ProcessorFeatures KeyFeature = getKeyFeature(Kind); + return (getFeaturePriority(KeyFeature) << 1) + 1; } // Now we know we have a feature, so get its priority and shift it a few so @@ -1608,9 +1062,9 @@ void X86TargetInfo::getCPUSpecificCPUDispatchFeatures( bool X86TargetInfo::validateCpuIs(StringRef FeatureStr) const { return llvm::StringSwitch(FeatureStr) #define X86_VENDOR(ENUM, STRING) .Case(STRING, true) -#define X86_CPU_TYPE_COMPAT_ALIAS(ENUM, ALIAS) .Case(ALIAS, true) -#define X86_CPU_TYPE_COMPAT(ARCHNAME, ENUM, STR) .Case(STR, true) -#define X86_CPU_SUBTYPE_COMPAT(ARCHNAME, ENUM, STR) .Case(STR, true) +#define X86_CPU_TYPE_ALIAS(ENUM, ALIAS) .Case(ALIAS, true) +#define X86_CPU_TYPE(ENUM, STR) .Case(STR, true) +#define X86_CPU_SUBTYPE(ENUM, STR) .Case(STR, true) #include "llvm/Support/X86TargetParser.def" .Default(false); } diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h index c33c608e27c84..72a01d2514c23 100644 --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -125,6 +125,9 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo { bool HasPTWRITE = false; bool HasINVPCID = false; bool HasENQCMD = false; + bool HasAMXTILE = false; + bool HasAMXINT8 = false; + bool HasAMXBF16 = false; bool HasSERIALIZE = false; bool HasTSXLDTRK = false; @@ -138,6 +141,7 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo { : TargetInfo(Triple) { LongDoubleFormat = &llvm::APFloat::x87DoubleExtended(); AddrSpaceMap = &X86AddrSpaceMap; + HasStrictFP = true; } const char *getLongDoubleMangling() const override { @@ -259,24 +263,8 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - static void setSSELevel(llvm::StringMap &Features, X86SSEEnum Level, - bool Enabled); - - static void setMMXLevel(llvm::StringMap &Features, MMX3DNowEnum Level, - bool Enabled); - - static void setXOPLevel(llvm::StringMap &Features, XOPEnum Level, - bool Enabled); - void setFeatureEnabled(llvm::StringMap &Features, StringRef Name, - bool Enabled) const override { - setFeatureEnabledImpl(Features, Name, Enabled); - } - - // This exists purely to cut down on the number of virtual calls in - // initFeatureMap which calls this repeatedly. - static void setFeatureEnabledImpl(llvm::StringMap &Features, - StringRef Name, bool Enabled); + bool Enabled) const final; bool initFeatureMap(llvm::StringMap &Features, DiagnosticsEngine &Diags, @@ -285,7 +273,7 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo { bool isValidFeatureName(StringRef Name) const override; - bool hasFeature(StringRef Feature) const override; + bool hasFeature(StringRef Feature) const final; bool handleTargetFeatures(std::vector &Features, DiagnosticsEngine &Diags) override; diff --git a/clang/lib/Basic/Version.cpp b/clang/lib/Basic/Version.cpp index c4b7d34ed1686..286107cab9d7b 100644 --- a/clang/lib/Basic/Version.cpp +++ b/clang/lib/Basic/Version.cpp @@ -97,8 +97,12 @@ std::string getClangToolFullVersion(StringRef ToolName) { #ifdef CLANG_VENDOR OS << CLANG_VENDOR; #endif - OS << ToolName << " version " CLANG_VERSION_STRING " " - << getClangFullRepositoryVersion(); + OS << ToolName << " version " CLANG_VERSION_STRING; + + std::string repo = getClangFullRepositoryVersion(); + if (!repo.empty()) { + OS << " " << repo; + } return OS.str(); } @@ -111,7 +115,13 @@ std::string getClangFullCPPVersion() { #ifdef CLANG_VENDOR OS << CLANG_VENDOR; #endif - OS << "Clang " CLANG_VERSION_STRING " " << getClangFullRepositoryVersion(); + OS << "Clang " CLANG_VERSION_STRING; + + std::string repo = getClangFullRepositoryVersion(); + if (!repo.empty()) { + OS << " " << repo; + } + return OS.str(); } diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 9e6d5e4593d3d..dce0940670a24 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -620,6 +620,9 @@ void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM, PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize; PMBuilder.SLPVectorize = CodeGenOpts.VectorizeSLP; PMBuilder.LoopVectorize = CodeGenOpts.VectorizeLoop; + // Only enable CGProfilePass when using integrated assembler, since + // non-integrated assemblers don't recognize .cgprofile section. + PMBuilder.CallGraphProfile = !CodeGenOpts.DisableIntegratedAS; PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops; // Loop interleaving in the loop vectorizer has historically been set to be @@ -1144,7 +1147,9 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager( PTO.LoopInterleaving = CodeGenOpts.UnrollLoops; PTO.LoopVectorization = CodeGenOpts.VectorizeLoop; PTO.SLPVectorization = CodeGenOpts.VectorizeSLP; - PTO.CallGraphProfile = CodeGenOpts.CallGraphProfile; + // Only enable CGProfilePass when using integrated assembler, since + // non-integrated assemblers don't recognize .cgprofile section. + PTO.CallGraphProfile = !CodeGenOpts.DisableIntegratedAS; PTO.Coroutines = LangOpts.Coroutines; PassInstrumentationCallbacks PIC; @@ -1562,7 +1567,9 @@ static void runThinLTOBackend( Conf.PTO.LoopInterleaving = CGOpts.UnrollLoops; Conf.PTO.LoopVectorization = CGOpts.VectorizeLoop; Conf.PTO.SLPVectorization = CGOpts.VectorizeSLP; - Conf.PTO.CallGraphProfile = CGOpts.CallGraphProfile; + // Only enable CGProfilePass when using integrated assembler, since + // non-integrated assemblers don't recognize .cgprofile section. + Conf.PTO.CallGraphProfile = !CGOpts.DisableIntegratedAS; // Context sensitive profile. if (CGOpts.hasProfileCSIRInstr()) { diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 7943c3f34504f..35a93a7889f40 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -219,8 +219,9 @@ static RValue EmitBinaryAtomicPost(CodeGenFunction &CGF, Kind, Args[0], Args[1], llvm::AtomicOrdering::SequentiallyConsistent); Result = CGF.Builder.CreateBinOp(Op, Result, Args[1]); if (Invert) - Result = CGF.Builder.CreateBinOp(llvm::Instruction::Xor, Result, - llvm::ConstantInt::get(IntType, -1)); + Result = + CGF.Builder.CreateBinOp(llvm::Instruction::Xor, Result, + llvm::ConstantInt::getAllOnesValue(IntType)); Result = EmitFromInt(CGF, Result, T, ValueType); return RValue::get(Result); } @@ -2194,6 +2195,33 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, Builder.CreateCall(FnExpect, {ArgValue, ExpectedValue}, "expval"); return RValue::get(Result); } + case Builtin::BI__builtin_expect_with_probability: { + Value *ArgValue = EmitScalarExpr(E->getArg(0)); + llvm::Type *ArgType = ArgValue->getType(); + + Value *ExpectedValue = EmitScalarExpr(E->getArg(1)); + llvm::APFloat Probability(0.0); + const Expr *ProbArg = E->getArg(2); + bool EvalSucceed = ProbArg->EvaluateAsFloat(Probability, CGM.getContext()); + assert(EvalSucceed && "probability should be able to evaluate as float"); + (void)EvalSucceed; + bool LoseInfo = false; + Probability.convert(llvm::APFloat::IEEEdouble(), + llvm::RoundingMode::Dynamic, &LoseInfo); + llvm::Type *Ty = ConvertType(ProbArg->getType()); + Constant *Confidence = ConstantFP::get(Ty, Probability); + // Don't generate llvm.expect.with.probability on -O0 as the backend + // won't use it for anything. + // Note, we still IRGen ExpectedValue because it could have side-effects. + if (CGM.getCodeGenOpts().OptimizationLevel == 0) + return RValue::get(ArgValue); + + Function *FnExpect = + CGM.getIntrinsic(Intrinsic::expect_with_probability, ArgType); + Value *Result = Builder.CreateCall( + FnExpect, {ArgValue, ExpectedValue, Confidence}, "expval"); + return RValue::get(Result); + } case Builtin::BI__builtin_assume_aligned: { const Expr *Ptr = E->getArg(0); Value *PtrValue = EmitScalarExpr(Ptr); @@ -4708,6 +4736,7 @@ struct ARMVectorIntrinsicInfo { TypeModifier } static const ARMVectorIntrinsicInfo ARMSIMDIntrinsicMap [] = { + NEONMAP1(__a32_vcvt_bf16_v, arm_neon_vcvtfp2bf, 0), NEONMAP0(splat_lane_v), NEONMAP0(splat_laneq_v), NEONMAP0(splatq_lane_v), @@ -4721,6 +4750,11 @@ static const ARMVectorIntrinsicInfo ARMSIMDIntrinsicMap [] = { NEONMAP1(vaeseq_v, arm_neon_aese, 0), NEONMAP1(vaesimcq_v, arm_neon_aesimc, 0), NEONMAP1(vaesmcq_v, arm_neon_aesmc, 0), + NEONMAP1(vbfdot_v, arm_neon_bfdot, 0), + NEONMAP1(vbfdotq_v, arm_neon_bfdot, 0), + NEONMAP1(vbfmlalbq_v, arm_neon_bfmlalb, 0), + NEONMAP1(vbfmlaltq_v, arm_neon_bfmlalt, 0), + NEONMAP1(vbfmmlaq_v, arm_neon_bfmmla, 0), NEONMAP1(vbsl_v, arm_neon_vbsl, AddRetType), NEONMAP1(vbslq_v, arm_neon_vbsl, AddRetType), NEONMAP1(vcadd_rot270_v, arm_neon_vcadd_rot270, Add1ArgType), @@ -4781,6 +4815,7 @@ static const ARMVectorIntrinsicInfo ARMSIMDIntrinsicMap [] = { NEONMAP1(vcvtaq_u16_v, arm_neon_vcvtau, 0), NEONMAP1(vcvtaq_u32_v, arm_neon_vcvtau, 0), NEONMAP1(vcvtaq_u64_v, arm_neon_vcvtau, 0), + NEONMAP1(vcvth_bf16_f32, arm_neon_vcvtbfp2bf, 0), NEONMAP1(vcvtm_s16_v, arm_neon_vcvtms, 0), NEONMAP1(vcvtm_s32_v, arm_neon_vcvtms, 0), NEONMAP1(vcvtm_s64_v, arm_neon_vcvtms, 0), @@ -4997,6 +5032,7 @@ static const ARMVectorIntrinsicInfo ARMSIMDIntrinsicMap [] = { }; static const ARMVectorIntrinsicInfo AArch64SIMDIntrinsicMap[] = { + NEONMAP1(__a64_vcvtq_low_bf16_v, aarch64_neon_bfcvtn, 0), NEONMAP0(splat_lane_v), NEONMAP0(splat_laneq_v), NEONMAP0(splatq_lane_v), @@ -5056,6 +5092,7 @@ static const ARMVectorIntrinsicInfo AArch64SIMDIntrinsicMap[] = { NEONMAP1(vcvt_n_u64_v, aarch64_neon_vcvtfp2fxu, 0), NEONMAP0(vcvtq_f16_v), NEONMAP0(vcvtq_f32_v), + NEONMAP1(vcvtq_high_bf16_v, aarch64_neon_bfcvtn2, 0), NEONMAP2(vcvtq_n_f16_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), NEONMAP2(vcvtq_n_f32_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), NEONMAP2(vcvtq_n_f64_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), @@ -5211,6 +5248,7 @@ static const ARMVectorIntrinsicInfo AArch64SISDIntrinsicMap[] = { NEONMAP1(vcvtd_n_f64_u64, aarch64_neon_vcvtfxu2fp, AddRetType | Add1ArgType), NEONMAP1(vcvtd_n_s64_f64, aarch64_neon_vcvtfp2fxs, AddRetType | Add1ArgType), NEONMAP1(vcvtd_n_u64_f64, aarch64_neon_vcvtfp2fxu, AddRetType | Add1ArgType), + NEONMAP1(vcvth_bf16_f32, aarch64_neon_bfcvt, 0), NEONMAP1(vcvtmd_s64_f64, aarch64_neon_fcvtms, AddRetType | Add1ArgType), NEONMAP1(vcvtmd_u64_f64, aarch64_neon_fcvtmu, AddRetType | Add1ArgType), NEONMAP1(vcvtms_s32_f32, aarch64_neon_fcvtms, AddRetType | Add1ArgType), @@ -6209,6 +6247,11 @@ Value *CodeGenFunction::EmitCommonNeonBuiltinExpr( llvm::Type *Tys[2] = { Ty, InputTy }; return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vbfmlalt"); } + case NEON::BI__builtin_neon___a32_vcvt_bf16_v: { + llvm::Type *Tys[1] = { Ty }; + Function *F = CGM.getIntrinsic(Int, Tys); + return EmitNeonCall(F, Ops, "vcvtfp2bf"); + } } @@ -6389,21 +6432,27 @@ static bool HasExtraNeonArgument(unsigned BuiltinID) { default: break; case NEON::BI__builtin_neon_vget_lane_i8: case NEON::BI__builtin_neon_vget_lane_i16: + case NEON::BI__builtin_neon_vget_lane_bf16: case NEON::BI__builtin_neon_vget_lane_i32: case NEON::BI__builtin_neon_vget_lane_i64: case NEON::BI__builtin_neon_vget_lane_f32: case NEON::BI__builtin_neon_vgetq_lane_i8: case NEON::BI__builtin_neon_vgetq_lane_i16: + case NEON::BI__builtin_neon_vgetq_lane_bf16: case NEON::BI__builtin_neon_vgetq_lane_i32: case NEON::BI__builtin_neon_vgetq_lane_i64: case NEON::BI__builtin_neon_vgetq_lane_f32: + case NEON::BI__builtin_neon_vduph_lane_bf16: + case NEON::BI__builtin_neon_vduph_laneq_bf16: case NEON::BI__builtin_neon_vset_lane_i8: case NEON::BI__builtin_neon_vset_lane_i16: + case NEON::BI__builtin_neon_vset_lane_bf16: case NEON::BI__builtin_neon_vset_lane_i32: case NEON::BI__builtin_neon_vset_lane_i64: case NEON::BI__builtin_neon_vset_lane_f32: case NEON::BI__builtin_neon_vsetq_lane_i8: case NEON::BI__builtin_neon_vsetq_lane_i16: + case NEON::BI__builtin_neon_vsetq_lane_bf16: case NEON::BI__builtin_neon_vsetq_lane_i32: case NEON::BI__builtin_neon_vsetq_lane_i64: case NEON::BI__builtin_neon_vsetq_lane_f32: @@ -6411,6 +6460,7 @@ static bool HasExtraNeonArgument(unsigned BuiltinID) { case NEON::BI__builtin_neon_vsha1cq_u32: case NEON::BI__builtin_neon_vsha1pq_u32: case NEON::BI__builtin_neon_vsha1mq_u32: + case NEON::BI__builtin_neon_vcvth_bf16_f32: case clang::ARM::BI_MoveToCoprocessor: case clang::ARM::BI_MoveToCoprocessor2: return false; @@ -6849,12 +6899,16 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, case NEON::BI__builtin_neon_vget_lane_i16: case NEON::BI__builtin_neon_vget_lane_i32: case NEON::BI__builtin_neon_vget_lane_i64: + case NEON::BI__builtin_neon_vget_lane_bf16: case NEON::BI__builtin_neon_vget_lane_f32: case NEON::BI__builtin_neon_vgetq_lane_i8: case NEON::BI__builtin_neon_vgetq_lane_i16: case NEON::BI__builtin_neon_vgetq_lane_i32: case NEON::BI__builtin_neon_vgetq_lane_i64: + case NEON::BI__builtin_neon_vgetq_lane_bf16: case NEON::BI__builtin_neon_vgetq_lane_f32: + case NEON::BI__builtin_neon_vduph_lane_bf16: + case NEON::BI__builtin_neon_vduph_laneq_bf16: return Builder.CreateExtractElement(Ops[0], Ops[1], "vget_lane"); case NEON::BI__builtin_neon_vrndns_f32: { @@ -6867,11 +6921,13 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, case NEON::BI__builtin_neon_vset_lane_i16: case NEON::BI__builtin_neon_vset_lane_i32: case NEON::BI__builtin_neon_vset_lane_i64: + case NEON::BI__builtin_neon_vset_lane_bf16: case NEON::BI__builtin_neon_vset_lane_f32: case NEON::BI__builtin_neon_vsetq_lane_i8: case NEON::BI__builtin_neon_vsetq_lane_i16: case NEON::BI__builtin_neon_vsetq_lane_i32: case NEON::BI__builtin_neon_vsetq_lane_i64: + case NEON::BI__builtin_neon_vsetq_lane_bf16: case NEON::BI__builtin_neon_vsetq_lane_f32: return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); @@ -6888,6 +6944,11 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1m), Ops, "vsha1h"); + case NEON::BI__builtin_neon_vcvth_bf16_f32: { + return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vcvtbfp2bf), Ops, + "vcvtbfp2bf"); + } + // The ARM _MoveToCoprocessor builtins put the input register value as // the first argument, but the LLVM intrinsic expects it as the third one. case ARM::BI_MoveToCoprocessor: @@ -7666,6 +7727,8 @@ CodeGenFunction::getSVEPredType(SVETypeFlags TypeFlags) { case SVETypeFlags::EltTyInt64: return llvm::ScalableVectorType::get(Builder.getInt1Ty(), 2); + case SVETypeFlags::EltTyBFloat16: + return llvm::ScalableVectorType::get(Builder.getInt1Ty(), 8); case SVETypeFlags::EltTyFloat16: return llvm::ScalableVectorType::get(Builder.getInt1Ty(), 8); case SVETypeFlags::EltTyFloat32: @@ -8324,6 +8387,7 @@ Value *CodeGenFunction::EmitAArch64SVEBuiltinExpr(unsigned BuiltinID, case SVE::BI__builtin_sve_svdupq_n_s64: case SVE::BI__builtin_sve_svdupq_n_u16: case SVE::BI__builtin_sve_svdupq_n_f16: + case SVE::BI__builtin_sve_svdupq_n_bf16: case SVE::BI__builtin_sve_svdupq_n_s16: case SVE::BI__builtin_sve_svdupq_n_u32: case SVE::BI__builtin_sve_svdupq_n_f32: @@ -8374,6 +8438,7 @@ Value *CodeGenFunction::EmitAArch64SVEBuiltinExpr(unsigned BuiltinID, case SVE::BI__builtin_sve_svpfalse_b: return ConstantInt::getFalse(Ty); + case SVE::BI__builtin_sve_svlen_bf16: case SVE::BI__builtin_sve_svlen_f16: case SVE::BI__builtin_sve_svlen_f32: case SVE::BI__builtin_sve_svlen_f64: @@ -8402,6 +8467,7 @@ Value *CodeGenFunction::EmitAArch64SVEBuiltinExpr(unsigned BuiltinID, case SVE::BI__builtin_sve_svtbl2_u64: case SVE::BI__builtin_sve_svtbl2_s64: case SVE::BI__builtin_sve_svtbl2_f16: + case SVE::BI__builtin_sve_svtbl2_bf16: case SVE::BI__builtin_sve_svtbl2_f32: case SVE::BI__builtin_sve_svtbl2_f64: { SVETypeFlags TF(Builtin->TypeModifier); @@ -9282,11 +9348,13 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, case NEON::BI__builtin_neon_vset_lane_i16: case NEON::BI__builtin_neon_vset_lane_i32: case NEON::BI__builtin_neon_vset_lane_i64: + case NEON::BI__builtin_neon_vset_lane_bf16: case NEON::BI__builtin_neon_vset_lane_f32: case NEON::BI__builtin_neon_vsetq_lane_i8: case NEON::BI__builtin_neon_vsetq_lane_i16: case NEON::BI__builtin_neon_vsetq_lane_i32: case NEON::BI__builtin_neon_vsetq_lane_i64: + case NEON::BI__builtin_neon_vsetq_lane_bf16: case NEON::BI__builtin_neon_vsetq_lane_f32: Ops.push_back(EmitScalarExpr(E->getArg(2))); return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); @@ -9565,11 +9633,13 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, : Intrinsic::aarch64_neon_sqsub; return EmitNeonCall(CGM.getIntrinsic(AccInt, Int64Ty), Ops, "vqdmlXl"); } + case NEON::BI__builtin_neon_vget_lane_bf16: case NEON::BI__builtin_neon_vduph_lane_bf16: case NEON::BI__builtin_neon_vduph_lane_f16: { return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), "vget_lane"); } + case NEON::BI__builtin_neon_vgetq_lane_bf16: case NEON::BI__builtin_neon_vduph_laneq_bf16: case NEON::BI__builtin_neon_vduph_laneq_f16: { return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), @@ -11585,11 +11655,11 @@ Value *CodeGenFunction::EmitX86CpuIs(StringRef CPUStr) { std::tie(Index, Value) = StringSwitch>(CPUStr) #define X86_VENDOR(ENUM, STRING) \ .Case(STRING, {0u, static_cast(llvm::X86::ENUM)}) -#define X86_CPU_TYPE_COMPAT_ALIAS(ENUM, ALIAS) \ +#define X86_CPU_TYPE_ALIAS(ENUM, ALIAS) \ .Case(ALIAS, {1u, static_cast(llvm::X86::ENUM)}) -#define X86_CPU_TYPE_COMPAT(ARCHNAME, ENUM, STR) \ +#define X86_CPU_TYPE(ENUM, STR) \ .Case(STR, {1u, static_cast(llvm::X86::ENUM)}) -#define X86_CPU_SUBTYPE_COMPAT(ARCHNAME, ENUM, STR) \ +#define X86_CPU_SUBTYPE(ENUM, STR) \ .Case(STR, {2u, static_cast(llvm::X86::ENUM)}) #include "llvm/Support/X86TargetParser.def" .Default({0, 0}); @@ -11619,7 +11689,7 @@ CodeGenFunction::GetX86CpuSupportsMask(ArrayRef FeatureStrs) { for (const StringRef &FeatureStr : FeatureStrs) { unsigned Feature = StringSwitch(FeatureStr) -#define X86_FEATURE_COMPAT(VAL, ENUM, STR) .Case(STR, VAL) +#define X86_FEATURE_COMPAT(ENUM, STR) .Case(STR, llvm::X86::FEATURE_##ENUM) #include "llvm/Support/X86TargetParser.def" ; FeaturesMask |= (1ULL << Feature); @@ -14168,9 +14238,14 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, case PPC::BI__builtin_vsx_xvsqrtdp: { llvm::Type *ResultType = ConvertType(E->getType()); Value *X = EmitScalarExpr(E->getArg(0)); - ID = Intrinsic::sqrt; - llvm::Function *F = CGM.getIntrinsic(ID, ResultType); - return Builder.CreateCall(F, X); + if (Builder.getIsFPConstrained()) { + llvm::Function *F = CGM.getIntrinsic( + Intrinsic::experimental_constrained_sqrt, ResultType); + return Builder.CreateConstrainedFPCall(F, X); + } else { + llvm::Function *F = CGM.getIntrinsic(Intrinsic::sqrt, ResultType); + return Builder.CreateCall(F, X); + } } // Count leading zeros case PPC::BI__builtin_altivec_vclzb: @@ -14227,21 +14302,32 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, Value *X = EmitScalarExpr(E->getArg(0)); if (BuiltinID == PPC::BI__builtin_vsx_xvrdpim || BuiltinID == PPC::BI__builtin_vsx_xvrspim) - ID = Intrinsic::floor; + ID = Builder.getIsFPConstrained() + ? Intrinsic::experimental_constrained_floor + : Intrinsic::floor; else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpi || BuiltinID == PPC::BI__builtin_vsx_xvrspi) - ID = Intrinsic::round; + ID = Builder.getIsFPConstrained() + ? Intrinsic::experimental_constrained_round + : Intrinsic::round; else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpic || BuiltinID == PPC::BI__builtin_vsx_xvrspic) - ID = Intrinsic::nearbyint; + ID = Builder.getIsFPConstrained() + ? Intrinsic::experimental_constrained_nearbyint + : Intrinsic::nearbyint; else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpip || BuiltinID == PPC::BI__builtin_vsx_xvrspip) - ID = Intrinsic::ceil; + ID = Builder.getIsFPConstrained() + ? Intrinsic::experimental_constrained_ceil + : Intrinsic::ceil; else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpiz || BuiltinID == PPC::BI__builtin_vsx_xvrspiz) - ID = Intrinsic::trunc; + ID = Builder.getIsFPConstrained() + ? Intrinsic::experimental_constrained_trunc + : Intrinsic::trunc; llvm::Function *F = CGM.getIntrinsic(ID, ResultType); - return Builder.CreateCall(F, X); + return Builder.getIsFPConstrained() ? Builder.CreateConstrainedFPCall(F, X) + : Builder.CreateCall(F, X); } // Absolute value @@ -14266,21 +14352,43 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, Value *X = EmitScalarExpr(E->getArg(0)); Value *Y = EmitScalarExpr(E->getArg(1)); Value *Z = EmitScalarExpr(E->getArg(2)); - llvm::Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); + llvm::Function *F; + if (Builder.getIsFPConstrained()) + F = CGM.getIntrinsic(Intrinsic::experimental_constrained_fma, ResultType); + else + F = CGM.getIntrinsic(Intrinsic::fma, ResultType); switch (BuiltinID) { case PPC::BI__builtin_vsx_xvmaddadp: case PPC::BI__builtin_vsx_xvmaddasp: - return Builder.CreateCall(F, {X, Y, Z}); + if (Builder.getIsFPConstrained()) + return Builder.CreateConstrainedFPCall(F, {X, Y, Z}); + else + return Builder.CreateCall(F, {X, Y, Z}); case PPC::BI__builtin_vsx_xvnmaddadp: case PPC::BI__builtin_vsx_xvnmaddasp: - return Builder.CreateFNeg(Builder.CreateCall(F, {X, Y, Z}), "neg"); + if (Builder.getIsFPConstrained()) + return Builder.CreateFNeg( + Builder.CreateConstrainedFPCall(F, {X, Y, Z}), "neg"); + else + return Builder.CreateFNeg(Builder.CreateCall(F, {X, Y, Z}), "neg"); case PPC::BI__builtin_vsx_xvmsubadp: case PPC::BI__builtin_vsx_xvmsubasp: - return Builder.CreateCall(F, {X, Y, Builder.CreateFNeg(Z, "neg")}); + if (Builder.getIsFPConstrained()) + return Builder.CreateConstrainedFPCall( + F, {X, Y, Builder.CreateFNeg(Z, "neg")}); + else + return Builder.CreateCall(F, {X, Y, Builder.CreateFNeg(Z, "neg")}); case PPC::BI__builtin_vsx_xvnmsubadp: case PPC::BI__builtin_vsx_xvnmsubasp: - return Builder.CreateFNeg( - Builder.CreateCall(F, {X, Y, Builder.CreateFNeg(Z, "neg")}), "neg"); + if (Builder.getIsFPConstrained()) + return Builder.CreateFNeg( + Builder.CreateConstrainedFPCall( + F, {X, Y, Builder.CreateFNeg(Z, "neg")}), + "neg"); + else + return Builder.CreateFNeg( + Builder.CreateCall(F, {X, Y, Builder.CreateFNeg(Z, "neg")}), + "neg"); } llvm_unreachable("Unknown FMA operation"); return nullptr; // Suppress no-return warning @@ -14596,6 +14704,10 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID, case AMDGPU::BI__builtin_amdgcn_rcpf: case AMDGPU::BI__builtin_amdgcn_rcph: return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rcp); + case AMDGPU::BI__builtin_amdgcn_sqrt: + case AMDGPU::BI__builtin_amdgcn_sqrtf: + case AMDGPU::BI__builtin_amdgcn_sqrth: + return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_sqrt); case AMDGPU::BI__builtin_amdgcn_rsq: case AMDGPU::BI__builtin_amdgcn_rsqf: case AMDGPU::BI__builtin_amdgcn_rsqh: @@ -15990,30 +16102,6 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_memory_grow, ResultType); return Builder.CreateCall(Callee, Args); } - case WebAssembly::BI__builtin_wasm_memory_init: { - llvm::APSInt SegConst; - if (!E->getArg(0)->isIntegerConstantExpr(SegConst, getContext())) - llvm_unreachable("Constant arg isn't actually constant?"); - llvm::APSInt MemConst; - if (!E->getArg(1)->isIntegerConstantExpr(MemConst, getContext())) - llvm_unreachable("Constant arg isn't actually constant?"); - if (!MemConst.isNullValue()) - ErrorUnsupported(E, "non-zero memory index"); - Value *Args[] = {llvm::ConstantInt::get(getLLVMContext(), SegConst), - llvm::ConstantInt::get(getLLVMContext(), MemConst), - EmitScalarExpr(E->getArg(2)), EmitScalarExpr(E->getArg(3)), - EmitScalarExpr(E->getArg(4))}; - Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_memory_init); - return Builder.CreateCall(Callee, Args); - } - case WebAssembly::BI__builtin_wasm_data_drop: { - llvm::APSInt SegConst; - if (!E->getArg(0)->isIntegerConstantExpr(SegConst, getContext())) - llvm_unreachable("Constant arg isn't actually constant?"); - Value *Arg = llvm::ConstantInt::get(getLLVMContext(), SegConst); - Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_data_drop); - return Builder.CreateCall(Callee, {Arg}); - } case WebAssembly::BI__builtin_wasm_tls_size: { llvm::Type *ResultType = ConvertType(E->getType()); Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_tls_size, ResultType); diff --git a/clang/lib/CodeGen/CGCUDANV.cpp b/clang/lib/CodeGen/CGCUDANV.cpp index 351c5058aa4c9..baf2c79cc2b66 100644 --- a/clang/lib/CodeGen/CGCUDANV.cpp +++ b/clang/lib/CodeGen/CGCUDANV.cpp @@ -242,7 +242,7 @@ void CGNVCUDARuntime::emitDeviceStub(CodeGenFunction &CGF, EmittedKernels.push_back({CGF.CurFn, CGF.CurFuncDecl}); if (CudaFeatureEnabled(CGM.getTarget().getSDKVersion(), CudaFeature::CUDA_USES_NEW_LAUNCH) || - CGF.getLangOpts().HIPUseNewLaunchAPI) + (CGF.getLangOpts().HIP && CGF.getLangOpts().HIPUseNewLaunchAPI)) emitDeviceStubBodyNew(CGF, Args); else emitDeviceStubBodyLegacy(CGF, Args); diff --git a/clang/lib/CodeGen/CGCXXABI.cpp b/clang/lib/CodeGen/CGCXXABI.cpp index 928fbaea82787..65327a2435b5b 100644 --- a/clang/lib/CodeGen/CGCXXABI.cpp +++ b/clang/lib/CodeGen/CGCXXABI.cpp @@ -156,6 +156,8 @@ void CGCXXABI::setCXXABIThisValue(CodeGenFunction &CGF, llvm::Value *ThisPtr) { void CGCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV, QualType ResultType) { + assert(!CGF.hasAggregateEvaluationKind(ResultType) && + "cannot handle aggregates"); CGF.EmitReturnOfRValue(RV, ResultType); } diff --git a/clang/lib/CodeGen/CGCXXABI.h b/clang/lib/CodeGen/CGCXXABI.h index 2b7f45fcab988..f5b3fc13bbbd4 100644 --- a/clang/lib/CodeGen/CGCXXABI.h +++ b/clang/lib/CodeGen/CGCXXABI.h @@ -402,6 +402,13 @@ class CGCXXABI { CXXCtorType Type, bool ForVirtualBase, bool Delegating, CallArgList &Args); + /// Get the implicit (second) parameter that comes after the "this" pointer, + /// or nullptr if there is isn't one. + virtual llvm::Value * + getCXXDestructorImplicitParam(CodeGenFunction &CGF, + const CXXDestructorDecl *DD, CXXDtorType Type, + bool ForVirtualBase, bool Delegating) = 0; + /// Emit the destructor call. virtual void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 87242442a57f8..e8235c775d8f5 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -2504,9 +2504,11 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, ArrSize) { llvm::AttrBuilder Attrs; Attrs.addDereferenceableAttr( - getContext().getTypeSizeInChars(ETy).getQuantity()*ArrSize); + getContext().getTypeSizeInChars(ETy).getQuantity() * + ArrSize); AI->addAttrs(Attrs); - } else if (getContext().getTargetAddressSpace(ETy) == 0 && + } else if (getContext().getTargetInfo().getNullPointerValue( + ETy.getAddressSpace()) == 0 && !CGM.getCodeGenOpts().NullPointerIsValid) { AI->addAttr(llvm::Attribute::NonNull); } @@ -4245,7 +4247,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, llvm::FunctionType *IRFuncTy = getTypes().GetFunctionType(CallInfo); const Decl *TargetDecl = Callee.getAbstractInfo().getCalleeDecl().getDecl(); - if (const FunctionDecl *FD = dyn_cast_or_null(TargetDecl)) + if (const FunctionDecl *FD = dyn_cast_or_null(TargetDecl)) { // We can only guarantee that a function is called from the correct // context/function based on the appropriate target attributes, // so only check in the case where we have both always_inline and target @@ -4256,6 +4258,12 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, TargetDecl->hasAttr()) checkTargetFeatures(Loc, FD); + // Some architectures (such as x86-64) have the ABI changed based on + // attribute-target/features. Give them a chance to diagnose. + CGM.getTargetCodeGenInfo().checkFunctionCallABI( + CGM, Loc, dyn_cast_or_null(CurCodeDecl), FD, CallArgs); + } + #ifndef NDEBUG if (!(CallInfo.isVariadic() && CallInfo.getArgStruct())) { // For an inalloca varargs function, we don't expect CallInfo to match the diff --git a/clang/lib/CodeGen/CGCleanup.h b/clang/lib/CodeGen/CGCleanup.h index a2b3f71a2f861..ef4f6b9ec1332 100644 --- a/clang/lib/CodeGen/CGCleanup.h +++ b/clang/lib/CodeGen/CGCleanup.h @@ -102,7 +102,7 @@ class EHScope { }; public: - enum Kind { Cleanup, Catch, Terminate, Filter, PadEnd }; + enum Kind { Cleanup, Catch, Terminate, Filter }; EHScope(Kind kind, EHScopeStack::stable_iterator enclosingEHScope) : CachedLandingPad(nullptr), CachedEHDispatchBlock(nullptr), @@ -487,17 +487,6 @@ class EHTerminateScope : public EHScope { } }; -class EHPadEndScope : public EHScope { -public: - EHPadEndScope(EHScopeStack::stable_iterator enclosingEHScope) - : EHScope(PadEnd, enclosingEHScope) {} - static size_t getSize() { return sizeof(EHPadEndScope); } - - static bool classof(const EHScope *scope) { - return scope->getKind() == PadEnd; - } -}; - /// A non-stable pointer into the scope stack. class EHScopeStack::iterator { char *Ptr; @@ -535,10 +524,6 @@ class EHScopeStack::iterator { case EHScope::Terminate: Size = EHTerminateScope::getSize(); break; - - case EHScope::PadEnd: - Size = EHPadEndScope::getSize(); - break; } Ptr += llvm::alignTo(Size, ScopeStackAlignment); return *this; diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index f2549769080e4..1729c7ed3c310 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -1400,10 +1400,15 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { Address address = Address::invalid(); Address AllocaAddr = Address::invalid(); - Address OpenMPLocalAddr = - getLangOpts().OpenMP - ? CGM.getOpenMPRuntime().getAddressOfLocalVariable(*this, &D) - : Address::invalid(); + Address OpenMPLocalAddr = Address::invalid(); + if (CGM.getLangOpts().OpenMPIRBuilder) + OpenMPLocalAddr = OMPBuilderCBHelpers::getAddressOfLocalVariable(*this, &D); + else + OpenMPLocalAddr = + getLangOpts().OpenMP + ? CGM.getOpenMPRuntime().getAddressOfLocalVariable(*this, &D) + : Address::invalid(); + bool NRVO = getLangOpts().ElideConstructors && D.isNRVOVariable(); if (getLangOpts().OpenMP && OpenMPLocalAddr.isValid()) { @@ -1875,9 +1880,7 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) { /// /// \param init the initializing expression /// \param D the object to act as if we're initializing -/// \param loc the address to initialize; its type is a pointer -/// to the LLVM mapping of the object's type -/// \param alignment the alignment of the address +/// \param lvalue the lvalue to initialize /// \param capturedByInit true if \p D is a __block variable /// whose address is potentially changed by the initializer void CodeGenFunction::EmitExprAsInit(const Expr *init, const ValueDecl *D, diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index de3d1b1291464..bdf70252b5ade 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -651,9 +651,6 @@ CodeGenFunction::getEHDispatchBlock(EHScopeStack::stable_iterator si) { case EHScope::Terminate: dispatchBlock = getTerminateHandler(); break; - - case EHScope::PadEnd: - llvm_unreachable("PadEnd unnecessary for Itanium!"); } scope.setCachedEHDispatchBlock(dispatchBlock); } @@ -695,9 +692,6 @@ CodeGenFunction::getFuncletEHDispatchBlock(EHScopeStack::stable_iterator SI) { case EHScope::Terminate: DispatchBlock->setName("terminate"); break; - - case EHScope::PadEnd: - llvm_unreachable("PadEnd dispatch block missing!"); } EHS.setCachedEHDispatchBlock(DispatchBlock); return DispatchBlock; @@ -713,7 +707,6 @@ static bool isNonEHScope(const EHScope &S) { case EHScope::Filter: case EHScope::Catch: case EHScope::Terminate: - case EHScope::PadEnd: return false; } @@ -780,9 +773,6 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() { case EHScope::Terminate: return getTerminateLandingPad(); - case EHScope::PadEnd: - llvm_unreachable("PadEnd unnecessary for Itanium!"); - case EHScope::Catch: case EHScope::Cleanup: case EHScope::Filter: @@ -848,9 +838,6 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() { case EHScope::Catch: break; - - case EHScope::PadEnd: - llvm_unreachable("PadEnd unnecessary for Itanium!"); } EHCatchScope &catchScope = cast(*I); @@ -1828,6 +1815,48 @@ void CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF, llvm::Constant *ParentI8Fn = llvm::ConstantExpr::getBitCast(ParentCGF.CurFn, Int8PtrTy); ParentFP = Builder.CreateCall(RecoverFPIntrin, {ParentI8Fn, EntryFP}); + + // if the parent is a _finally, the passed-in ParentFP is the FP + // of parent _finally, not Establisher's FP (FP of outermost function). + // Establkisher FP is 2nd paramenter passed into parent _finally. + // Fortunately, it's always saved in parent's frame. The following + // code retrieves it, and escapes it so that spill instruction won't be + // optimized away. + if (ParentCGF.ParentCGF != nullptr) { + // Locate and escape Parent's frame_pointer.addr alloca + // Depending on target, should be 1st/2nd one in LocalDeclMap. + // Let's just scan for ImplicitParamDecl with VoidPtrTy. + llvm::AllocaInst *FramePtrAddrAlloca = nullptr; + for (auto &I : ParentCGF.LocalDeclMap) { + const VarDecl *D = cast(I.first); + if (isa(D) && + D->getType() == getContext().VoidPtrTy) { + assert(D->getName().startswith("frame_pointer")); + FramePtrAddrAlloca = cast(I.second.getPointer()); + break; + } + } + assert(FramePtrAddrAlloca); + auto InsertPair = ParentCGF.EscapedLocals.insert( + std::make_pair(FramePtrAddrAlloca, ParentCGF.EscapedLocals.size())); + int FrameEscapeIdx = InsertPair.first->second; + + // an example of a filter's prolog:: + // %0 = call i8* @llvm.eh.recoverfp(bitcast(@"?fin$0@0@main@@"),..) + // %1 = call i8* @llvm.localrecover(bitcast(@"?fin$0@0@main@@"),..) + // %2 = bitcast i8* %1 to i8** + // %3 = load i8*, i8* *%2, align 8 + // ==> %3 is the frame-pointer of outermost host function + llvm::Function *FrameRecoverFn = llvm::Intrinsic::getDeclaration( + &CGM.getModule(), llvm::Intrinsic::localrecover); + llvm::Constant *ParentI8Fn = + llvm::ConstantExpr::getBitCast(ParentCGF.CurFn, Int8PtrTy); + ParentFP = Builder.CreateCall( + FrameRecoverFn, {ParentI8Fn, ParentFP, + llvm::ConstantInt::get(Int32Ty, FrameEscapeIdx)}); + ParentFP = Builder.CreateBitCast(ParentFP, CGM.VoidPtrPtrTy); + ParentFP = Builder.CreateLoad(Address(ParentFP, getPointerAlign())); + } } // Create llvm.localrecover calls for all captures. @@ -2026,6 +2055,7 @@ void CodeGenFunction::pushSEHCleanup(CleanupKind Kind, void CodeGenFunction::EnterSEHTryStmt(const SEHTryStmt &S) { CodeGenFunction HelperCGF(CGM, /*suppressNewContext=*/true); + HelperCGF.ParentCGF = this; if (const SEHFinallyStmt *Finally = S.getFinallyHandler()) { // Outline the finally block. llvm::Function *FinallyFunc = diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index bead7e8996c05..9e8770573d701 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -2398,7 +2398,13 @@ EmitBitCastOfLValueToProperType(CodeGenFunction &CGF, static LValue EmitThreadPrivateVarDeclLValue( CodeGenFunction &CGF, const VarDecl *VD, QualType T, Address Addr, llvm::Type *RealVarTy, SourceLocation Loc) { - Addr = CGF.CGM.getOpenMPRuntime().getAddrOfThreadPrivate(CGF, VD, Addr, Loc); + if (CGF.CGM.getLangOpts().OpenMPIRBuilder) + Addr = CodeGenFunction::OMPBuilderCBHelpers::getAddrOfThreadPrivate( + CGF, VD, Addr, Loc); + else + Addr = + CGF.CGM.getOpenMPRuntime().getAddrOfThreadPrivate(CGF, VD, Addr, Loc); + Addr = CGF.Builder.CreateElementBitCast(Addr, RealVarTy); return CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl); } @@ -3843,7 +3849,7 @@ LValue CodeGenFunction::EmitOMPArraySectionExpr(const OMPArraySectionExpr *E, else ResultExprTy = BaseTy->getPointeeType(); llvm::Value *Idx = nullptr; - if (IsLowerBound || E->getColonLoc().isInvalid()) { + if (IsLowerBound || E->getColonLocFirst().isInvalid()) { // Requesting lower bound or upper bound, but without provided length and // without ':' symbol for the default length -> length = 1. // Idx = LowerBound ?: 0; diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index 13a5713521374..a49817898ae39 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -98,7 +98,7 @@ class ComplexExprEmitter } ComplexPairTy VisitStmt(Stmt *S) { - S->dump(CGF.getContext().getSourceManager()); + S->dump(llvm::errs(), CGF.getContext()); llvm_unreachable("Stmt can't have complex result type!"); } ComplexPairTy VisitExpr(Expr *S); diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index a01571633f6c0..c6b2930faece1 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -777,7 +777,7 @@ bool ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD, if (const CXXRecordDecl *CD = dyn_cast(RD)) { // Add a vtable pointer, if we need one and it hasn't already been added. - if (CD->isDynamicClass() && !IsPrimaryBase) { + if (Layout.hasOwnVFPtr()) { llvm::Constant *VTableAddressPoint = CGM.getCXXABI().getVTableAddressPointForConstExpr( BaseSubobject(CD, Offset), VTableClass); diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index f48f7185b55f1..6131f97995dce 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -413,7 +413,7 @@ class ScalarExprEmitter } Value *VisitStmt(Stmt *S) { - S->dump(CGF.getContext().getSourceManager()); + S->dump(llvm::errs(), CGF.getContext()); llvm_unreachable("Stmt can't have complex result type!"); } Value *VisitExpr(Expr *S); @@ -2389,7 +2389,7 @@ llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior( if (!E->canOverflow()) return Builder.CreateNSWAdd(InVal, Amount, Name); return EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec( - E, InVal, IsInc, E->getFPFeatures(CGF.getLangOpts()))); + E, InVal, IsInc, E->getFPFeaturesInEffect(CGF.getLangOpts()))); } llvm_unreachable("Unknown SignedOverflowBehaviorTy"); } @@ -2536,7 +2536,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, } else if (E->canOverflow() && type->isUnsignedIntegerType() && CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) { value = EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec( - E, value, isInc, E->getFPFeatures(CGF.getLangOpts()))); + E, value, isInc, E->getFPFeaturesInEffect(CGF.getLangOpts()))); } else { llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount, true); value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec"); @@ -2736,7 +2736,7 @@ Value *ScalarExprEmitter::VisitUnaryMinus(const UnaryOperator *E) { BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType()); BinOp.Ty = E->getType(); BinOp.Opcode = BO_Sub; - BinOp.FPFeatures = E->getFPFeatures(CGF.getLangOpts()); + BinOp.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts()); BinOp.E = E; return EmitSub(BinOp); } @@ -2757,7 +2757,7 @@ Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) { Value *Result; if (Oper->getType()->isFPOrFPVectorTy()) { CodeGenFunction::CGFPOptionsRAII FPOptsRAII( - CGF, E->getFPFeatures(CGF.getLangOpts())); + CGF, E->getFPFeaturesInEffect(CGF.getLangOpts())); Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper, Zero, "cmp"); } else Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero, "cmp"); @@ -2960,7 +2960,7 @@ BinOpInfo ScalarExprEmitter::EmitBinOps(const BinaryOperator *E) { Result.RHS = Visit(E->getRHS()); Result.Ty = E->getType(); Result.Opcode = E->getOpcode(); - Result.FPFeatures = E->getFPFeatures(CGF.getLangOpts()); + Result.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts()); Result.E = E; return Result; } @@ -2980,7 +2980,7 @@ LValue ScalarExprEmitter::EmitCompoundAssignLValue( OpInfo.RHS = Visit(E->getRHS()); OpInfo.Ty = E->getComputationResultType(); OpInfo.Opcode = E->getOpcode(); - OpInfo.FPFeatures = E->getFPFeatures(CGF.getLangOpts()); + OpInfo.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts()); OpInfo.E = E; // Load/convert the LHS. LValue LHSLV = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store); @@ -3608,8 +3608,8 @@ Value *ScalarExprEmitter::EmitFixedPointBinOp(const BinOpInfo &op) { switch (op.Opcode) { case BO_AddAssign: case BO_Add: { - if (ResultFixedSema.isSaturated()) { - llvm::Intrinsic::ID IID = ResultFixedSema.isSigned() + if (CommonFixedSema.isSaturated()) { + llvm::Intrinsic::ID IID = CommonFixedSema.isSigned() ? llvm::Intrinsic::sadd_sat : llvm::Intrinsic::uadd_sat; Result = Builder.CreateBinaryIntrinsic(IID, FullLHS, FullRHS); @@ -3620,8 +3620,8 @@ Value *ScalarExprEmitter::EmitFixedPointBinOp(const BinOpInfo &op) { } case BO_SubAssign: case BO_Sub: { - if (ResultFixedSema.isSaturated()) { - llvm::Intrinsic::ID IID = ResultFixedSema.isSigned() + if (CommonFixedSema.isSaturated()) { + llvm::Intrinsic::ID IID = CommonFixedSema.isSigned() ? llvm::Intrinsic::ssub_sat : llvm::Intrinsic::usub_sat; Result = Builder.CreateBinaryIntrinsic(IID, FullLHS, FullRHS); @@ -3633,14 +3633,12 @@ Value *ScalarExprEmitter::EmitFixedPointBinOp(const BinOpInfo &op) { case BO_MulAssign: case BO_Mul: { llvm::Intrinsic::ID IID; - if (ResultFixedSema.isSaturated()) - IID = ResultFixedSema.isSigned() - ? llvm::Intrinsic::smul_fix_sat - : llvm::Intrinsic::umul_fix_sat; + if (CommonFixedSema.isSaturated()) + IID = CommonFixedSema.isSigned() ? llvm::Intrinsic::smul_fix_sat + : llvm::Intrinsic::umul_fix_sat; else - IID = ResultFixedSema.isSigned() - ? llvm::Intrinsic::smul_fix - : llvm::Intrinsic::umul_fix; + IID = CommonFixedSema.isSigned() ? llvm::Intrinsic::smul_fix + : llvm::Intrinsic::umul_fix; Result = Builder.CreateIntrinsic(IID, {FullLHS->getType()}, {FullLHS, FullRHS, Builder.getInt32(CommonFixedSema.getScale())}); break; @@ -3648,11 +3646,11 @@ Value *ScalarExprEmitter::EmitFixedPointBinOp(const BinOpInfo &op) { case BO_DivAssign: case BO_Div: { llvm::Intrinsic::ID IID; - if (ResultFixedSema.isSaturated()) - IID = ResultFixedSema.isSigned() ? llvm::Intrinsic::sdiv_fix_sat + if (CommonFixedSema.isSaturated()) + IID = CommonFixedSema.isSigned() ? llvm::Intrinsic::sdiv_fix_sat : llvm::Intrinsic::udiv_fix_sat; else - IID = ResultFixedSema.isSigned() ? llvm::Intrinsic::sdiv_fix + IID = CommonFixedSema.isSigned() ? llvm::Intrinsic::sdiv_fix : llvm::Intrinsic::udiv_fix; Result = Builder.CreateIntrinsic(IID, {FullLHS->getType()}, {FullLHS, FullRHS, Builder.getInt32(CommonFixedSema.getScale())}); @@ -4214,7 +4212,7 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType()); if (LHS->getType()->isFPOrFPVectorTy()) { CodeGenFunction::CGFPOptionsRAII FPOptsRAII( - CGF, E->getFPFeatures(CGF.getLangOpts())); + CGF, E->getFPFeaturesInEffect(CGF.getLangOpts())); LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero, "cmp"); RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero, "cmp"); } else { @@ -4300,7 +4298,7 @@ Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) { Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType()); if (LHS->getType()->isFPOrFPVectorTy()) { CodeGenFunction::CGFPOptionsRAII FPOptsRAII( - CGF, E->getFPFeatures(CGF.getLangOpts())); + CGF, E->getFPFeaturesInEffect(CGF.getLangOpts())); LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero, "cmp"); RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero, "cmp"); } else { diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index 4c5311cf001dd..158a548e66c1e 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -1493,8 +1493,7 @@ CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl, BinaryOperator *assign = BinaryOperator::Create( getContext(), &ivarRef, finalArg, BO_Assign, ivarRef.getType(), VK_RValue, - OK_Ordinary, SourceLocation(), - FPOptions(getContext().getLangOpts())); + OK_Ordinary, SourceLocation(), FPOptionsOverride()); EmitStmt(assign); } @@ -3556,18 +3555,18 @@ CodeGenFunction::GenerateObjCAtomicSetterCopyHelperFunction( DeclRefExpr DstExpr(C, &DstDecl, false, DestTy, VK_RValue, SourceLocation()); UnaryOperator *DST = UnaryOperator::Create( C, &DstExpr, UO_Deref, DestTy->getPointeeType(), VK_LValue, OK_Ordinary, - SourceLocation(), false, FPOptions(C.getLangOpts())); + SourceLocation(), false, FPOptionsOverride()); DeclRefExpr SrcExpr(C, &SrcDecl, false, SrcTy, VK_RValue, SourceLocation()); UnaryOperator *SRC = UnaryOperator::Create( C, &SrcExpr, UO_Deref, SrcTy->getPointeeType(), VK_LValue, OK_Ordinary, - SourceLocation(), false, FPOptions(C.getLangOpts())); + SourceLocation(), false, FPOptionsOverride()); Expr *Args[2] = {DST, SRC}; CallExpr *CalleeExp = cast(PID->getSetterCXXAssignment()); CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create( C, OO_Equal, CalleeExp->getCallee(), Args, DestTy->getPointeeType(), - VK_LValue, SourceLocation(), FPOptions(C.getLangOpts())); + VK_LValue, SourceLocation(), FPOptionsOverride()); EmitStmt(TheCall); @@ -3641,7 +3640,7 @@ CodeGenFunction::GenerateObjCAtomicGetterCopyHelperFunction( UnaryOperator *SRC = UnaryOperator::Create( C, &SrcExpr, UO_Deref, SrcTy->getPointeeType(), VK_LValue, OK_Ordinary, - SourceLocation(), false, FPOptions(C.getLangOpts())); + SourceLocation(), false, FPOptionsOverride()); CXXConstructExpr *CXXConstExpr = cast(PID->getGetterCXXConstructor()); diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index 1ff62fd5894a5..43cbe9c720ea3 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -1060,7 +1060,7 @@ static FieldDecl *addFieldToRecordDecl(ASTContext &C, DeclContext *DC, CGOpenMPRuntime::CGOpenMPRuntime(CodeGenModule &CGM, StringRef FirstSeparator, StringRef Separator) : CGM(CGM), FirstSeparator(FirstSeparator), Separator(Separator), - OffloadEntriesInfoManager(CGM) { + OMPBuilder(CGM.getModule()), OffloadEntriesInfoManager(CGM) { ASTContext &C = CGM.getContext(); RecordDecl *RD = C.buildImplicitRecord("ident_t"); QualType KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1); @@ -1081,7 +1081,7 @@ CGOpenMPRuntime::CGOpenMPRuntime(CodeGenModule &CGM, StringRef FirstSeparator, KmpCriticalNameTy = llvm::ArrayType::get(CGM.Int32Ty, /*NumElements*/ 8); // Initialize Types used in OpenMPIRBuilder from OMPKinds.def - llvm::omp::types::initializeTypes(CGM.getModule()); + OMPBuilder.initialize(); loadOffloadInfoMetadata(); } @@ -1278,8 +1278,8 @@ static llvm::Function *emitParallelOrTeamsOutlinedFunction( // TODO: Temporarily inform the OpenMPIRBuilder, if any, about the new // parallel region to make cancellation barriers work properly. - llvm::OpenMPIRBuilder *OMPBuilder = CGM.getOpenMPIRBuilder(); - PushAndPopStackRAII PSR(OMPBuilder, CGF, HasCancel); + llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder(); + PushAndPopStackRAII PSR(&OMPBuilder, CGF, HasCancel); CGOpenMPOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen, InnermostKind, HasCancel, OutlinedHelperName); CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo); @@ -1316,7 +1316,7 @@ llvm::Function *CGOpenMPRuntime::emitTaskOutlinedFunction( CGF.EmitLoadOfPointerLValue(CGF.GetAddrOfLocalVar(TaskTVar), TaskTVar->getType()->castAs()) .getPointer(CGF)}; - CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_omp_task), TaskArgs); }; @@ -1563,8 +1563,8 @@ llvm::Value *CGOpenMPRuntime::getThreadID(CodeGenFunction &CGF, CGBuilderTy::InsertPointGuard IPG(CGF.Builder); CGF.Builder.SetInsertPoint(Elem.second.ServiceInsertPt); llvm::CallInst *Call = CGF.Builder.CreateCall( - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( - CGM.getModule(), OMPRTL___kmpc_global_thread_num), + OMPBuilder.getOrCreateRuntimeFunction(CGM.getModule(), + OMPRTL___kmpc_global_thread_num), emitUpdateLocation(CGF, Loc)); Call->setCallingConv(CGF.getRuntimeCC()); Elem.second.ThreadID = Call; @@ -1783,7 +1783,7 @@ Address CGOpenMPRuntime::getAddrOfThreadPrivate(CodeGenFunction &CGF, CGM.getSize(CGM.GetTargetTypeStoreSize(VarTy)), getOrCreateThreadPrivateCache(VD)}; return Address(CGF.EmitRuntimeCall( - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_threadprivate_cached), Args), VDAddr.getAlignment()); @@ -1795,7 +1795,7 @@ void CGOpenMPRuntime::emitThreadPrivateVarInit( // Call kmp_int32 __kmpc_global_thread_num(&loc) to init OpenMP runtime // library. llvm::Value *OMPLoc = emitUpdateLocation(CGF, Loc); - CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_global_thread_num), OMPLoc); // Call __kmpc_threadprivate_register(&loc, &var, ctor, cctor/*NULL*/, dtor) @@ -1804,7 +1804,7 @@ void CGOpenMPRuntime::emitThreadPrivateVarInit( OMPLoc, CGF.Builder.CreatePointerCast(VDAddr.getPointer(), CGM.VoidPtrTy), Ctor, CopyCtor, Dtor}; CGF.EmitRuntimeCall( - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_threadprivate_register), Args); } @@ -2068,7 +2068,7 @@ Address CGOpenMPRuntime::getAddrOfArtificialThreadPrivate(CodeGenFunction &CGF, return Address( CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( CGF.EmitRuntimeCall( - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_threadprivate_cached), Args), VarLVType->getPointerTo(/*AddrSpace=*/0)), @@ -2122,8 +2122,8 @@ void CGOpenMPRuntime::emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc, return; llvm::Value *RTLoc = emitUpdateLocation(CGF, Loc); auto &M = CGM.getModule(); - auto &&ThenGen = [&M, OutlinedFn, CapturedVars, RTLoc](CodeGenFunction &CGF, - PrePostActionTy &) { + auto &&ThenGen = [&M, OutlinedFn, CapturedVars, RTLoc, + this](CodeGenFunction &CGF, PrePostActionTy &) { // Build call __kmpc_fork_call(loc, n, microtask, var1, .., varn); CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime(); llvm::Value *Args[] = { @@ -2135,18 +2135,17 @@ void CGOpenMPRuntime::emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc, RealArgs.append(CapturedVars.begin(), CapturedVars.end()); llvm::FunctionCallee RTLFn = - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( - M, OMPRTL___kmpc_fork_call); + OMPBuilder.getOrCreateRuntimeFunction(M, OMPRTL___kmpc_fork_call); CGF.EmitRuntimeCall(RTLFn, RealArgs); }; - auto &&ElseGen = [&M, OutlinedFn, CapturedVars, RTLoc, - Loc](CodeGenFunction &CGF, PrePostActionTy &) { + auto &&ElseGen = [&M, OutlinedFn, CapturedVars, RTLoc, Loc, + this](CodeGenFunction &CGF, PrePostActionTy &) { CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime(); llvm::Value *ThreadID = RT.getThreadID(CGF, Loc); // Build calls: // __kmpc_serialized_parallel(&Loc, GTid); llvm::Value *Args[] = {RTLoc, ThreadID}; - CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( M, OMPRTL___kmpc_serialized_parallel), Args); @@ -2165,7 +2164,7 @@ void CGOpenMPRuntime::emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc, // __kmpc_end_serialized_parallel(&Loc, GTid); llvm::Value *EndArgs[] = {RT.emitUpdateLocation(CGF, Loc), ThreadID}; - CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( M, OMPRTL___kmpc_end_serialized_parallel), EndArgs); }; @@ -2284,12 +2283,12 @@ void CGOpenMPRuntime::emitCriticalRegion(CodeGenFunction &CGF, CGF.EmitScalarExpr(Hint), CGM.Int32Ty, /*isSigned=*/false)); } CommonActionTy Action( - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), Hint ? OMPRTL___kmpc_critical_with_hint : OMPRTL___kmpc_critical), EnterArgs, - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( - CGM.getModule(), OMPRTL___kmpc_end_critical), + OMPBuilder.getOrCreateRuntimeFunction(CGM.getModule(), + OMPRTL___kmpc_end_critical), Args); CriticalOpGen.setAction(Action); emitInlinedDirective(CGF, OMPD_critical, CriticalOpGen); @@ -2306,10 +2305,10 @@ void CGOpenMPRuntime::emitMasterRegion(CodeGenFunction &CGF, // } // Prepare arguments and build a call to __kmpc_master llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)}; - CommonActionTy Action(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CommonActionTy Action(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_master), Args, - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_end_master), Args, /*Conditional=*/true); @@ -2322,15 +2321,14 @@ void CGOpenMPRuntime::emitTaskyieldCall(CodeGenFunction &CGF, SourceLocation Loc) { if (!CGF.HaveInsertPoint()) return; - llvm::OpenMPIRBuilder *OMPBuilder = CGF.CGM.getOpenMPIRBuilder(); - if (OMPBuilder) { - OMPBuilder->CreateTaskyield(CGF.Builder); + if (CGF.CGM.getLangOpts().OpenMPIRBuilder) { + OMPBuilder.CreateTaskyield(CGF.Builder); } else { // Build call __kmpc_omp_taskyield(loc, thread_id, 0); llvm::Value *Args[] = { emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc), llvm::ConstantInt::get(CGM.IntTy, /*V=*/0, /*isSigned=*/true)}; - CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_omp_taskyield), Args); } @@ -2349,10 +2347,10 @@ void CGOpenMPRuntime::emitTaskgroupRegion(CodeGenFunction &CGF, // __kmpc_end_taskgroup(ident_t *, gtid); // Prepare arguments and build a call to __kmpc_taskgroup llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)}; - CommonActionTy Action(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CommonActionTy Action(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_taskgroup), Args, - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_end_taskgroup), Args); TaskgroupOpGen.setAction(Action); @@ -2459,10 +2457,10 @@ void CGOpenMPRuntime::emitSingleRegion(CodeGenFunction &CGF, } // Prepare arguments and build a call to __kmpc_single llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)}; - CommonActionTy Action(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CommonActionTy Action(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_single), Args, - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_end_single), Args, /*Conditional=*/true); @@ -2509,7 +2507,7 @@ void CGOpenMPRuntime::emitSingleRegion(CodeGenFunction &CGF, CpyFn, // void (*) (void *, void *) DidItVal // i32 did_it }; - CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_copyprivate), Args); } @@ -2526,10 +2524,10 @@ void CGOpenMPRuntime::emitOrderedRegion(CodeGenFunction &CGF, // Prepare arguments and build a call to __kmpc_ordered if (IsThreads) { llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)}; - CommonActionTy Action(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CommonActionTy Action(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_ordered), Args, - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_end_ordered), Args); OrderedOpGen.setAction(Action); @@ -2578,9 +2576,8 @@ void CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc, // Check if we should use the OMPBuilder auto *OMPRegionInfo = dyn_cast_or_null(CGF.CapturedStmtInfo); - llvm::OpenMPIRBuilder *OMPBuilder = CGF.CGM.getOpenMPIRBuilder(); - if (OMPBuilder) { - CGF.Builder.restoreIP(OMPBuilder->CreateBarrier( + if (CGF.CGM.getLangOpts().OpenMPIRBuilder) { + CGF.Builder.restoreIP(OMPBuilder.CreateBarrier( CGF.Builder, Kind, ForceSimpleCall, EmitChecks)); return; } @@ -2597,8 +2594,8 @@ void CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc, if (OMPRegionInfo) { if (!ForceSimpleCall && OMPRegionInfo->hasCancel()) { llvm::Value *Result = CGF.EmitRuntimeCall( - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( - CGM.getModule(), OMPRTL___kmpc_cancel_barrier), + OMPBuilder.getOrCreateRuntimeFunction(CGM.getModule(), + OMPRTL___kmpc_cancel_barrier), Args); if (EmitChecks) { // if (__kmpc_cancel_barrier()) { @@ -2618,7 +2615,7 @@ void CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc, return; } } - CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_barrier), Args); } @@ -2870,7 +2867,7 @@ void CGOpenMPRuntime::emitForStaticFinish(CodeGenFunction &CGF, : OMP_IDENT_WORK_SECTIONS), getThreadID(CGF, Loc)}; auto DL = ApplyDebugLocation::CreateDefaultArtificial(CGF, Loc); - CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_for_static_fini), Args); } @@ -2919,7 +2916,7 @@ void CGOpenMPRuntime::emitNumThreadsClause(CodeGenFunction &CGF, llvm::Value *Args[] = { emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc), CGF.Builder.CreateIntCast(NumThreads, CGF.Int32Ty, /*isSigned*/ true)}; - CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_push_num_threads), Args); } @@ -2934,21 +2931,20 @@ void CGOpenMPRuntime::emitProcBindClause(CodeGenFunction &CGF, llvm::Value *Args[] = { emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc), llvm::ConstantInt::get(CGM.IntTy, unsigned(ProcBind), /*isSigned=*/true)}; - CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_push_proc_bind), Args); } void CGOpenMPRuntime::emitFlush(CodeGenFunction &CGF, ArrayRef, SourceLocation Loc, llvm::AtomicOrdering AO) { - llvm::OpenMPIRBuilder *OMPBuilder = CGF.CGM.getOpenMPIRBuilder(); - if (OMPBuilder) { - OMPBuilder->CreateFlush(CGF.Builder); + if (CGF.CGM.getLangOpts().OpenMPIRBuilder) { + OMPBuilder.CreateFlush(CGF.Builder); } else { if (!CGF.HaveInsertPoint()) return; // Build call void __kmpc_flush(ident_t *loc) - CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_flush), emitUpdateLocation(CGF, Loc)); } @@ -4302,12 +4298,12 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc, DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF); AllocArgs.push_back(DeviceID); NewTask = CGF.EmitRuntimeCall( - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_omp_target_task_alloc), AllocArgs); } else { NewTask = - CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_omp_task_alloc), AllocArgs); } @@ -4324,7 +4320,7 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *Tid = getThreadID(CGF, DC->getBeginLoc()); Tid = CGF.Builder.CreateIntCast(Tid, CGF.IntTy, /*isSigned=*/false); llvm::Value *EvtVal = CGF.EmitRuntimeCall( - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_task_allow_completion_event), {Loc, Tid, NewTask}); EvtVal = CGF.EmitScalarConversion(EvtVal, C.VoidPtrTy, Evt->getType(), @@ -4463,7 +4459,7 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc, // FIXME: Emit the function and ignore its result for now unless the // runtime function is properly implemented. (void)CGF.EmitRuntimeCall( - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_omp_reg_task_with_affinity), {LocRef, GTid, NewTask, NumOfElements, AffinListPtr}); } @@ -4966,7 +4962,7 @@ Address CGOpenMPRuntime::emitDepobjDependClause( llvm::Value *Args[] = {ThreadID, Size, Allocator}; llvm::Value *Addr = - CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_alloc), Args, ".dep.arr.addr"); Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( @@ -5019,7 +5015,7 @@ void CGOpenMPRuntime::emitDestroyClause(CodeGenFunction &CGF, LValue DepobjLVal, llvm::Value *Args[] = {ThreadID, DepObjAddr, Allocator}; // _kmpc_free(gtid, addr, nullptr); - (void)CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + (void)CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_free), Args); } @@ -5120,11 +5116,11 @@ void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc, } if (!Data.Dependences.empty()) { CGF.EmitRuntimeCall( - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_omp_task_with_deps), DepTaskArgs); } else { - CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_omp_task), TaskArgs); } @@ -5144,8 +5140,8 @@ void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc, DepWaitTaskArgs[5] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy); } auto &M = CGM.getModule(); - auto &&ElseCodeGen = [&M, &TaskArgs, ThreadID, NewTaskNewTaskTTy, TaskEntry, - &Data, &DepWaitTaskArgs, + auto &&ElseCodeGen = [this, &M, &TaskArgs, ThreadID, NewTaskNewTaskTTy, + TaskEntry, &Data, &DepWaitTaskArgs, Loc](CodeGenFunction &CGF, PrePostActionTy &) { CodeGenFunction::RunCleanupsScope LocalScope(CGF); // Build void __kmpc_omp_wait_deps(ident_t *, kmp_int32 gtid, @@ -5153,9 +5149,9 @@ void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc, // ndeps_noalias, kmp_depend_info_t *noalias_dep_list); if dependence info // is specified. if (!Data.Dependences.empty()) - CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( - M, OMPRTL___kmpc_omp_wait_deps), - DepWaitTaskArgs); + CGF.EmitRuntimeCall( + OMPBuilder.getOrCreateRuntimeFunction(M, OMPRTL___kmpc_omp_wait_deps), + DepWaitTaskArgs); // Call proxy_task_entry(gtid, new_task); auto &&CodeGen = [TaskEntry, ThreadID, NewTaskNewTaskTTy, Loc](CodeGenFunction &CGF, PrePostActionTy &Action) { @@ -5170,10 +5166,10 @@ void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc, // Build void __kmpc_omp_task_complete_if0(ident_t *, kmp_int32 gtid, // kmp_task_t *new_task); RegionCodeGenTy RCG(CodeGen); - CommonActionTy Action(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CommonActionTy Action(OMPBuilder.getOrCreateRuntimeFunction( M, OMPRTL___kmpc_omp_task_begin_if0), TaskArgs, - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + OMPBuilder.getOrCreateRuntimeFunction( M, OMPRTL___kmpc_omp_task_complete_if0), TaskArgs); RCG.setAction(Action); @@ -5269,7 +5265,7 @@ void CGOpenMPRuntime::emitTaskLoopCall(CodeGenFunction &CGF, SourceLocation Loc, Result.TaskDupFn ? CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( Result.TaskDupFn, CGF.VoidPtrTy) : llvm::ConstantPointerNull::get(CGF.VoidPtrTy)}; - CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_taskloop), TaskArgs); } @@ -5613,7 +5609,7 @@ void CGOpenMPRuntime::emitReduction(CodeGenFunction &CGF, SourceLocation Loc, Lock // kmp_critical_name *& }; llvm::Value *Res = CGF.EmitRuntimeCall( - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), WithNowait ? OMPRTL___kmpc_reduce_nowait : OMPRTL___kmpc_reduce), Args); @@ -5656,7 +5652,7 @@ void CGOpenMPRuntime::emitReduction(CodeGenFunction &CGF, SourceLocation Loc, RegionCodeGenTy RCG(CodeGen); CommonActionTy Action( nullptr, llvm::None, - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), WithNowait ? OMPRTL___kmpc_end_reduce_nowait : OMPRTL___kmpc_end_reduce), EndArgs); @@ -5781,7 +5777,7 @@ void CGOpenMPRuntime::emitReduction(CodeGenFunction &CGF, SourceLocation Loc, Lock // kmp_critical_name *& }; CommonActionTy Action(nullptr, llvm::None, - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_end_reduce), EndArgs); AtomicRCG.setAction(Action); @@ -6121,7 +6117,7 @@ llvm::Value *CGOpenMPRuntime::emitTaskReductionInit( CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( TaskRedInput.getPointer(), CGM.VoidPtrTy)}; return CGF.EmitRuntimeCall( - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_taskred_modifier_init), Args); } @@ -6132,7 +6128,7 @@ llvm::Value *CGOpenMPRuntime::emitTaskReductionInit( llvm::ConstantInt::get(CGM.IntTy, Size, /*isSigned=*/true), CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(TaskRedInput.getPointer(), CGM.VoidPtrTy)}; - return CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + return CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_taskred_init), Args); } @@ -6150,7 +6146,7 @@ void CGOpenMPRuntime::emitTaskReductionFini(CodeGenFunction &CGF, IsWorksharingReduction ? 1 : 0, /*isSigned=*/true)}; (void)CGF.EmitRuntimeCall( - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_task_reduction_modifier_fini), Args); } @@ -6186,7 +6182,7 @@ Address CGOpenMPRuntime::getTaskReductionItem(CodeGenFunction &CGF, SharedLVal.getPointer(CGF), CGM.VoidPtrTy)}; return Address( CGF.EmitRuntimeCall( - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_task_reduction_get_th_data), Args), SharedLVal.getAlignment()); @@ -6197,15 +6193,14 @@ void CGOpenMPRuntime::emitTaskwaitCall(CodeGenFunction &CGF, if (!CGF.HaveInsertPoint()) return; - llvm::OpenMPIRBuilder *OMPBuilder = CGF.CGM.getOpenMPIRBuilder(); - if (OMPBuilder) { - OMPBuilder->CreateTaskwait(CGF.Builder); + if (CGF.CGM.getLangOpts().OpenMPIRBuilder) { + OMPBuilder.CreateTaskwait(CGF.Builder); } else { // Build call kmp_int32 __kmpc_omp_taskwait(ident_t *loc, kmp_int32 // global_tid); llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)}; // Ignore return result until untied tasks are supported. - CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_omp_taskwait), Args); } @@ -6266,7 +6261,7 @@ void CGOpenMPRuntime::emitCancellationPointCall( CGF.Builder.getInt32(getCancellationKind(CancelRegion))}; // Ignore return result until untied tasks are supported. llvm::Value *Result = CGF.EmitRuntimeCall( - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_cancellationpoint), Args); // if (__kmpc_cancellationpoint()) { @@ -6296,17 +6291,15 @@ void CGOpenMPRuntime::emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc, auto &M = CGM.getModule(); if (auto *OMPRegionInfo = dyn_cast_or_null(CGF.CapturedStmtInfo)) { - auto &&ThenGen = [&M, Loc, CancelRegion, + auto &&ThenGen = [this, &M, Loc, CancelRegion, OMPRegionInfo](CodeGenFunction &CGF, PrePostActionTy &) { CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime(); llvm::Value *Args[] = { RT.emitUpdateLocation(CGF, Loc), RT.getThreadID(CGF, Loc), CGF.Builder.getInt32(getCancellationKind(CancelRegion))}; // Ignore return result until untied tasks are supported. - llvm::Value *Result = - CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( - M, OMPRTL___kmpc_cancel), - Args); + llvm::Value *Result = CGF.EmitRuntimeCall( + OMPBuilder.getOrCreateRuntimeFunction(M, OMPRTL___kmpc_cancel), Args); // if (__kmpc_cancel()) { // exit from construct; // } @@ -6402,7 +6395,7 @@ void CGOpenMPRuntime::emitUsesAllocatorsInit(CodeGenFunction &CGF, CGF.EmitLoadOfScalar(AllocatorTraitsLVal, AllocatorTraits->getExprLoc()); llvm::Value *AllocatorVal = - CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_init_allocator), {ThreadId, MemSpaceHandle, NumTraits, Traits}); // Store to allocator. @@ -6426,8 +6419,8 @@ void CGOpenMPRuntime::emitUsesAllocatorsFini(CodeGenFunction &CGF, CGF.getContext().VoidPtrTy, Allocator->getExprLoc()); (void)CGF.EmitRuntimeCall( - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( - CGM.getModule(), OMPRTL___kmpc_destroy_allocator), + OMPBuilder.getOrCreateRuntimeFunction(CGM.getModule(), + OMPRTL___kmpc_destroy_allocator), {ThreadId, AllocatorVal}); } @@ -6680,6 +6673,8 @@ emitNumTeamsForTargetDirective(CodeGenFunction &CGF, case OMPD_requires: case OMPD_unknown: break; + default: + break; } llvm_unreachable("Unexpected directive kind."); } @@ -6995,6 +6990,8 @@ emitNumThreadsForTargetDirective(CodeGenFunction &CGF, case OMPD_requires: case OMPD_unknown: break; + default: + break; } llvm_unreachable("Unsupported directive kind."); } @@ -7178,7 +7175,7 @@ class MappableExprsHandler { // If there is no length associated with the expression and lower bound is // not specified too, that means we are using the whole length of the // base. - if (!OAE->getLength() && OAE->getColonLoc().isValid() && + if (!OAE->getLength() && OAE->getColonLocFirst().isValid() && !OAE->getLowerBound()) return CGF.getTypeSize(BaseTy); @@ -7193,7 +7190,7 @@ class MappableExprsHandler { // If we don't have a length at this point, that is because we have an // array section with a single element. - if (!OAE->getLength() && OAE->getColonLoc().isInvalid()) + if (!OAE->getLength() && OAE->getColonLocFirst().isInvalid()) return ElemSize; if (const Expr *LenExpr = OAE->getLength()) { @@ -7203,7 +7200,7 @@ class MappableExprsHandler { LenExpr->getExprLoc()); return CGF.Builder.CreateNUWMul(LengthVal, ElemSize); } - assert(!OAE->getLength() && OAE->getColonLoc().isValid() && + assert(!OAE->getLength() && OAE->getColonLocFirst().isValid() && OAE->getLowerBound() && "expected array_section[lb:]."); // Size = sizetype - lb * elemtype; llvm::Value *LengthVal = CGF.getTypeSize(BaseTy); @@ -7276,7 +7273,7 @@ class MappableExprsHandler { return false; // An array section with no colon always refer to a single element. - if (OASE->getColonLoc().isInvalid()) + if (OASE->getColonLocFirst().isInvalid()) return false; const Expr *Length = OASE->getLength(); @@ -8914,6 +8911,7 @@ getNestedDistributeDirective(ASTContext &Ctx, const OMPExecutableDirective &D) { case OMPD_parallel_master_taskloop_simd: case OMPD_requires: case OMPD_unknown: + default: llvm_unreachable("Unexpected directive."); } } @@ -9063,8 +9061,8 @@ void CGOpenMPRuntime::emitUserDefinedMapper(const OMPDeclareMapperDecl *D, // pre-existing components. llvm::Value *OffloadingArgs[] = {Handle}; llvm::Value *PreviousSize = MapperCGF.EmitRuntimeCall( - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( - CGM.getModule(), OMPRTL___tgt_mapper_num_components), + OMPBuilder.getOrCreateRuntimeFunction(CGM.getModule(), + OMPRTL___tgt_mapper_num_components), OffloadingArgs); llvm::Value *ShiftedPreviousSize = MapperCGF.Builder.CreateShl( PreviousSize, @@ -9171,7 +9169,7 @@ void CGOpenMPRuntime::emitUserDefinedMapper(const OMPDeclareMapperDecl *D, llvm::Value *OffloadingArgs[] = {Handle, CurBaseArg, CurBeginArg, CurSizeArg, CurMapType}; MapperCGF.EmitRuntimeCall( - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___tgt_push_mapper_component), OffloadingArgs); } @@ -9253,8 +9251,8 @@ void CGOpenMPRuntime::emitUDMapperArrayInitOrDel( // data structure. llvm::Value *OffloadingArgs[] = {Handle, Base, Begin, ArraySize, MapTypeArg}; MapperCGF.EmitRuntimeCall( - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( - CGM.getModule(), OMPRTL___tgt_push_mapper_component), + OMPBuilder.getOrCreateRuntimeFunction(CGM.getModule(), + OMPRTL___tgt_push_mapper_component), OffloadingArgs); } @@ -9277,7 +9275,7 @@ void CGOpenMPRuntime::emitTargetNumIterationsCall( if (llvm::Value *NumIterations = SizeEmitter(CGF, *LD)) { llvm::Value *Args[] = {DeviceID, NumIterations}; CGF.EmitRuntimeCall( - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_push_target_tripcount), Args); } @@ -9406,7 +9404,7 @@ void CGOpenMPRuntime::emitTargetCall( NumTeams, NumThreads}; Return = CGF.EmitRuntimeCall( - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), HasNowait ? OMPRTL___tgt_target_teams_nowait : OMPRTL___tgt_target_teams), OffloadingArgs); @@ -9419,7 +9417,7 @@ void CGOpenMPRuntime::emitTargetCall( InputInfo.SizesArray.getPointer(), MapTypesArray}; Return = CGF.EmitRuntimeCall( - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), HasNowait ? OMPRTL___tgt_target_nowait : OMPRTL___tgt_target), OffloadingArgs); @@ -9704,6 +9702,7 @@ void CGOpenMPRuntime::scanForTargetRegionsFunctions(const Stmt *S, case OMPD_parallel_master_taskloop_simd: case OMPD_requires: case OMPD_unknown: + default: llvm_unreachable("Unknown target directive for OpenMP device codegen."); } return; @@ -10054,7 +10053,7 @@ llvm::Function *CGOpenMPRuntime::emitRequiresDirectiveRegFun() { "Target or declare target region expected."); if (HasRequiresUnifiedSharedMemory) Flags = OMP_REQ_UNIFIED_SHARED_MEMORY; - CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___tgt_register_requires), llvm::ConstantInt::get(CGM.Int64Ty, Flags)); CGF.FinishFunction(); @@ -10082,9 +10081,8 @@ void CGOpenMPRuntime::emitTeamsCall(CodeGenFunction &CGF, RealArgs.append(std::begin(Args), std::end(Args)); RealArgs.append(CapturedVars.begin(), CapturedVars.end()); - llvm::FunctionCallee RTLFn = - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( - CGM.getModule(), OMPRTL___kmpc_fork_teams); + llvm::FunctionCallee RTLFn = OMPBuilder.getOrCreateRuntimeFunction( + CGM.getModule(), OMPRTL___kmpc_fork_teams); CGF.EmitRuntimeCall(RTLFn, RealArgs); } @@ -10112,7 +10110,7 @@ void CGOpenMPRuntime::emitNumTeamsClause(CodeGenFunction &CGF, // Build call __kmpc_push_num_teamss(&loc, global_tid, num_teams, thread_limit) llvm::Value *PushNumTeamsArgs[] = {RTLoc, getThreadID(CGF, Loc), NumTeamsVal, ThreadLimitVal}; - CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_push_num_teams), PushNumTeamsArgs); } @@ -10167,7 +10165,7 @@ void CGOpenMPRuntime::emitTargetDataCalls( llvm::Value *OffloadingArgs[] = { DeviceID, PointerNum, BasePointersArrayArg, PointersArrayArg, SizesArrayArg, MapTypesArrayArg}; - CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___tgt_target_data_begin), OffloadingArgs); @@ -10204,7 +10202,7 @@ void CGOpenMPRuntime::emitTargetDataCalls( llvm::Value *OffloadingArgs[] = { DeviceID, PointerNum, BasePointersArrayArg, PointersArrayArg, SizesArrayArg, MapTypesArrayArg}; - CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___tgt_target_data_end), OffloadingArgs); }; @@ -10362,12 +10360,13 @@ void CGOpenMPRuntime::emitTargetDataStandAloneCall( case OMPD_target_parallel_for_simd: case OMPD_requires: case OMPD_unknown: + default: llvm_unreachable("Unexpected standalone target data directive."); break; } - CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( - CGM.getModule(), RTLFn), - OffloadingArgs); + CGF.EmitRuntimeCall( + OMPBuilder.getOrCreateRuntimeFunction(CGM.getModule(), RTLFn), + OffloadingArgs); }; auto &&TargetThenGen = [this, &ThenGen, &D, &InputInfo, &MapTypesArray]( @@ -11058,15 +11057,13 @@ void CGOpenMPRuntime::emitDoacrossInit(CodeGenFunction &CGF, CGF.Builder.CreateConstArrayGEP(DimsAddr, 0).getPointer(), CGM.VoidPtrTy)}; - llvm::FunctionCallee RTLFn = - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( - CGM.getModule(), OMPRTL___kmpc_doacross_init); + llvm::FunctionCallee RTLFn = OMPBuilder.getOrCreateRuntimeFunction( + CGM.getModule(), OMPRTL___kmpc_doacross_init); CGF.EmitRuntimeCall(RTLFn, Args); llvm::Value *FiniArgs[DoacrossCleanupTy::DoacrossFinArgs] = { emitUpdateLocation(CGF, D.getEndLoc()), getThreadID(CGF, D.getEndLoc())}; - llvm::FunctionCallee FiniRTLFn = - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( - CGM.getModule(), OMPRTL___kmpc_doacross_fini); + llvm::FunctionCallee FiniRTLFn = OMPBuilder.getOrCreateRuntimeFunction( + CGM.getModule(), OMPRTL___kmpc_doacross_fini); CGF.EHStack.pushCleanup(NormalAndEHCleanup, FiniRTLFn, llvm::makeArrayRef(FiniArgs)); } @@ -11094,12 +11091,12 @@ void CGOpenMPRuntime::emitDoacrossOrdered(CodeGenFunction &CGF, CGF.Builder.CreateConstArrayGEP(CntAddr, 0).getPointer()}; llvm::FunctionCallee RTLFn; if (C->getDependencyKind() == OMPC_DEPEND_source) { - RTLFn = llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( - CGM.getModule(), OMPRTL___kmpc_doacross_post); + RTLFn = OMPBuilder.getOrCreateRuntimeFunction(CGM.getModule(), + OMPRTL___kmpc_doacross_post); } else { assert(C->getDependencyKind() == OMPC_DEPEND_sink); - RTLFn = llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( - CGM.getModule(), OMPRTL___kmpc_doacross_wait); + RTLFn = OMPBuilder.getOrCreateRuntimeFunction(CGM.getModule(), + OMPRTL___kmpc_doacross_wait); } CGF.EmitRuntimeCall(RTLFn, Args); } @@ -11203,14 +11200,13 @@ Address CGOpenMPRuntime::getAddressOfLocalVariable(CodeGenFunction &CGF, llvm::Value *Args[] = {ThreadID, Size, Allocator}; llvm::Value *Addr = - CGF.EmitRuntimeCall(llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction( + CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction( CGM.getModule(), OMPRTL___kmpc_alloc), Args, getName({CVD->getName(), ".void.addr"})); llvm::Value *FiniArgs[OMPAllocateCleanupTy::CleanupArgs] = {ThreadID, Addr, Allocator}; - llvm::FunctionCallee FiniRTLFn = - llvm::OpenMPIRBuilder::getOrCreateRuntimeFunction(CGM.getModule(), - OMPRTL___kmpc_free); + llvm::FunctionCallee FiniRTLFn = OMPBuilder.getOrCreateRuntimeFunction( + CGM.getModule(), OMPRTL___kmpc_free); CGF.EHStack.pushCleanup(NormalAndEHCleanup, FiniRTLFn, llvm::makeArrayRef(FiniArgs)); diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.h b/clang/lib/CodeGen/CGOpenMPRuntime.h index dea92e16e59f8..eb22f155f5ef4 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.h +++ b/clang/lib/CodeGen/CGOpenMPRuntime.h @@ -25,6 +25,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringSet.h" #include "llvm/Frontend/OpenMP/OMPConstants.h" +#include "llvm/Frontend/OpenMP/OMPIRBuilder.h" #include "llvm/IR/Function.h" #include "llvm/IR/ValueHandle.h" #include "llvm/Support/AtomicOrdering.h" @@ -37,6 +38,7 @@ class GlobalVariable; class StructType; class Type; class Value; +class OpenMPIRBuilder; } // namespace llvm namespace clang { @@ -284,6 +286,8 @@ class CGOpenMPRuntime { ~LastprivateConditionalRAII(); }; + llvm::OpenMPIRBuilder &getOMPBuilder() { return OMPBuilder; } + protected: CodeGenModule &CGM; StringRef FirstSeparator, Separator; @@ -368,6 +372,8 @@ class CGOpenMPRuntime { llvm::Value *getCriticalRegionLock(StringRef CriticalName); private: + /// An OpenMP-IR-Builder instance. + llvm::OpenMPIRBuilder OMPBuilder; /// Default const ident_t object used for initialization of all other /// ident_t objects. llvm::Constant *DefaultOpenMPPSource = nullptr; diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp index 896442daa4012..cbd443134e7a8 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp @@ -38,11 +38,9 @@ enum OpenMPRTLFunctionNVPTX { /// Call to void __kmpc_spmd_kernel_deinit_v2(int16_t RequiresOMPRuntime); OMPRTL_NVPTX__kmpc_spmd_kernel_deinit_v2, /// Call to void __kmpc_kernel_prepare_parallel(void - /// *outlined_function, int16_t - /// IsOMPRuntimeInitialized); + /// *outlined_function); OMPRTL_NVPTX__kmpc_kernel_prepare_parallel, - /// Call to bool __kmpc_kernel_parallel(void **outlined_function, - /// int16_t IsOMPRuntimeInitialized); + /// Call to bool __kmpc_kernel_parallel(void **outlined_function); OMPRTL_NVPTX__kmpc_kernel_parallel, /// Call to void __kmpc_kernel_end_parallel(); OMPRTL_NVPTX__kmpc_kernel_end_parallel, @@ -85,6 +83,9 @@ enum OpenMPRTLFunctionNVPTX { /// Call to void* __kmpc_data_sharing_coalesced_push_stack(size_t size, /// int16_t UseSharedMemory); OMPRTL_NVPTX__kmpc_data_sharing_coalesced_push_stack, + /// Call to void* __kmpc_data_sharing_push_stack(size_t size, int16_t + /// UseSharedMemory); + OMPRTL_NVPTX__kmpc_data_sharing_push_stack, /// Call to void __kmpc_data_sharing_pop_stack(void *a); OMPRTL_NVPTX__kmpc_data_sharing_pop_stack, /// Call to void __kmpc_begin_sharing_variables(void ***args, @@ -816,6 +817,7 @@ static bool hasNestedSPMDDirective(ASTContext &Ctx, case OMPD_parallel_master_taskloop_simd: case OMPD_requires: case OMPD_unknown: + default: llvm_unreachable("Unexpected directive."); } } @@ -896,6 +898,7 @@ static bool supportsSPMDExecutionMode(ASTContext &Ctx, case OMPD_parallel_master_taskloop_simd: case OMPD_requires: case OMPD_unknown: + default: break; } llvm_unreachable( @@ -1069,6 +1072,7 @@ static bool hasNestedLightweightDirective(ASTContext &Ctx, case OMPD_parallel_master_taskloop_simd: case OMPD_requires: case OMPD_unknown: + default: llvm_unreachable("Unexpected directive."); } } @@ -1155,6 +1159,7 @@ static bool supportsLightweightRuntime(ASTContext &Ctx, case OMPD_parallel_master_taskloop_simd: case OMPD_requires: case OMPD_unknown: + default: break; } llvm_unreachable( @@ -1459,8 +1464,7 @@ void CGOpenMPRuntimeNVPTX::emitWorkerLoop(CodeGenFunction &CGF, CGF.InitTempAlloca(WorkFn, llvm::Constant::getNullValue(CGF.Int8PtrTy)); // TODO: Optimize runtime initialization and pass in correct value. - llvm::Value *Args[] = {WorkFn.getPointer(), - /*RequiresOMPRuntime=*/Bld.getInt16(1)}; + llvm::Value *Args[] = {WorkFn.getPointer()}; llvm::Value *Ret = CGF.EmitRuntimeCall( createNVPTXRuntimeFunction(OMPRTL_NVPTX__kmpc_kernel_parallel), Args); Bld.CreateStore(Bld.CreateZExt(Ret, CGF.Int8Ty), ExecStatus); @@ -1588,17 +1592,16 @@ CGOpenMPRuntimeNVPTX::createNVPTXRuntimeFunction(unsigned Function) { } case OMPRTL_NVPTX__kmpc_kernel_prepare_parallel: { /// Build void __kmpc_kernel_prepare_parallel( - /// void *outlined_function, int16_t IsOMPRuntimeInitialized); - llvm::Type *TypeParams[] = {CGM.Int8PtrTy, CGM.Int16Ty}; + /// void *outlined_function); + llvm::Type *TypeParams[] = {CGM.Int8PtrTy}; auto *FnTy = llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false); RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_kernel_prepare_parallel"); break; } case OMPRTL_NVPTX__kmpc_kernel_parallel: { - /// Build bool __kmpc_kernel_parallel(void **outlined_function, - /// int16_t IsOMPRuntimeInitialized); - llvm::Type *TypeParams[] = {CGM.Int8PtrPtrTy, CGM.Int16Ty}; + /// Build bool __kmpc_kernel_parallel(void **outlined_function); + llvm::Type *TypeParams[] = {CGM.Int8PtrPtrTy}; llvm::Type *RetTy = CGM.getTypes().ConvertType(CGM.getContext().BoolTy); auto *FnTy = llvm::FunctionType::get(RetTy, TypeParams, /*isVarArg*/ false); @@ -1753,6 +1756,16 @@ CGOpenMPRuntimeNVPTX::createNVPTXRuntimeFunction(unsigned Function) { FnTy, /*Name=*/"__kmpc_data_sharing_coalesced_push_stack"); break; } + case OMPRTL_NVPTX__kmpc_data_sharing_push_stack: { + // Build void *__kmpc_data_sharing_push_stack(size_t size, int16_t + // UseSharedMemory); + llvm::Type *TypeParams[] = {CGM.SizeTy, CGM.Int16Ty}; + auto *FnTy = + llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg=*/false); + RTLFn = CGM.CreateRuntimeFunction( + FnTy, /*Name=*/"__kmpc_data_sharing_push_stack"); + break; + } case OMPRTL_NVPTX__kmpc_data_sharing_pop_stack: { // Build void __kmpc_data_sharing_pop_stack(void *a); llvm::Type *TypeParams[] = {CGM.VoidPtrTy}; @@ -2210,7 +2223,7 @@ void CGOpenMPRuntimeNVPTX::emitGenericVarsProlog(CodeGenFunction &CGF, GlobalRecCastAddr = Phi; I->getSecond().GlobalRecordAddr = Phi; I->getSecond().IsInSPMDModeFlag = IsSPMD; - } else if (IsInTTDRegion) { + } else if (!CGM.getLangOpts().OpenMPCUDATargetParallel && IsInTTDRegion) { assert(GlobalizedRecords.back().Records.size() < 2 && "Expected less than 2 globalized records: one for target and one " "for teams."); @@ -2283,12 +2296,16 @@ void CGOpenMPRuntimeNVPTX::emitGenericVarsProlog(CodeGenFunction &CGF, } else { // TODO: allow the usage of shared memory to be controlled by // the user, for now, default to global. + bool UseSharedMemory = + IsInTTDRegion && GlobalRecordSize <= SharedMemorySize; llvm::Value *GlobalRecordSizeArg[] = { llvm::ConstantInt::get(CGM.SizeTy, GlobalRecordSize), - CGF.Builder.getInt16(/*UseSharedMemory=*/0)}; + CGF.Builder.getInt16(UseSharedMemory ? 1 : 0)}; llvm::Value *GlobalRecValue = CGF.EmitRuntimeCall( createNVPTXRuntimeFunction( - OMPRTL_NVPTX__kmpc_data_sharing_coalesced_push_stack), + IsInTTDRegion + ? OMPRTL_NVPTX__kmpc_data_sharing_push_stack + : OMPRTL_NVPTX__kmpc_data_sharing_coalesced_push_stack), GlobalRecordSizeArg); GlobalRecCastAddr = Bld.CreatePointerBitCastOrAddrSpaceCast( GlobalRecValue, GlobalRecPtrTy); @@ -2435,7 +2452,7 @@ void CGOpenMPRuntimeNVPTX::emitGenericVarsEpilog(CodeGenFunction &CGF, OMPRTL_NVPTX__kmpc_data_sharing_pop_stack), CGF.EmitCastToVoidPtr(I->getSecond().GlobalRecordAddr)); CGF.EmitBlock(ExitBB); - } else if (IsInTTDRegion) { + } else if (!CGM.getLangOpts().OpenMPCUDATargetParallel && IsInTTDRegion) { assert(GlobalizedRecords.back().RegionCounter > 0 && "region counter must be > 0."); --GlobalizedRecords.back().RegionCounter; @@ -2548,7 +2565,7 @@ void CGOpenMPRuntimeNVPTX::emitNonSPMDParallelCall( llvm::Value *ID = Bld.CreateBitOrPointerCast(WFn, CGM.Int8PtrTy); // Prepare for parallel region. Indicate the outlined function. - llvm::Value *Args[] = {ID, /*RequiresOMPRuntime=*/Bld.getInt16(1)}; + llvm::Value *Args[] = {ID}; CGF.EmitRuntimeCall( createNVPTXRuntimeFunction(OMPRTL_NVPTX__kmpc_kernel_prepare_parallel), Args); @@ -5085,7 +5102,8 @@ static std::pair getSMsBlocksPerSM(CodeGenModule &CGM) { } void CGOpenMPRuntimeNVPTX::clear() { - if (!GlobalizedRecords.empty()) { + if (!GlobalizedRecords.empty() && + !CGM.getLangOpts().OpenMPCUDATargetParallel) { ASTContext &C = CGM.getContext(); llvm::SmallVector GlobalRecs; llvm::SmallVector SharedRecs; diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index a3677bf7910b3..7135135d2a410 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -23,6 +23,7 @@ #include "clang/AST/StmtOpenMP.h" #include "clang/Basic/OpenMPKinds.h" #include "clang/Basic/PrettyStackTrace.h" +#include "llvm/Frontend/OpenMP/OMPConstants.h" #include "llvm/Frontend/OpenMP/OMPIRBuilder.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Instructions.h" @@ -1376,6 +1377,7 @@ void CodeGenFunction::EmitOMPReductionClauseInit( case OMPD_begin_declare_variant: case OMPD_end_declare_variant: case OMPD_unknown: + default: llvm_unreachable("Enexpected directive with task reductions."); } @@ -1564,8 +1566,97 @@ static void emitEmptyBoundParameters(CodeGenFunction &, const OMPExecutableDirective &, llvm::SmallVectorImpl &) {} +Address CodeGenFunction::OMPBuilderCBHelpers::getAddressOfLocalVariable( + CodeGenFunction &CGF, const VarDecl *VD) { + CodeGenModule &CGM = CGF.CGM; + auto &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder(); + + if (!VD) + return Address::invalid(); + const VarDecl *CVD = VD->getCanonicalDecl(); + if (!CVD->hasAttr()) + return Address::invalid(); + const auto *AA = CVD->getAttr(); + // Use the default allocation. + if (AA->getAllocatorType() == OMPAllocateDeclAttr::OMPDefaultMemAlloc && + !AA->getAllocator()) + return Address::invalid(); + llvm::Value *Size; + CharUnits Align = CGM.getContext().getDeclAlign(CVD); + if (CVD->getType()->isVariablyModifiedType()) { + Size = CGF.getTypeSize(CVD->getType()); + // Align the size: ((size + align - 1) / align) * align + Size = CGF.Builder.CreateNUWAdd( + Size, CGM.getSize(Align - CharUnits::fromQuantity(1))); + Size = CGF.Builder.CreateUDiv(Size, CGM.getSize(Align)); + Size = CGF.Builder.CreateNUWMul(Size, CGM.getSize(Align)); + } else { + CharUnits Sz = CGM.getContext().getTypeSizeInChars(CVD->getType()); + Size = CGM.getSize(Sz.alignTo(Align)); + } + + assert(AA->getAllocator() && + "Expected allocator expression for non-default allocator."); + llvm::Value *Allocator = CGF.EmitScalarExpr(AA->getAllocator()); + // According to the standard, the original allocator type is a enum (integer). + // Convert to pointer type, if required. + if (Allocator->getType()->isIntegerTy()) + Allocator = CGF.Builder.CreateIntToPtr(Allocator, CGM.VoidPtrTy); + else if (Allocator->getType()->isPointerTy()) + Allocator = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Allocator, + CGM.VoidPtrTy); + + llvm::Value *Addr = OMPBuilder.CreateOMPAlloc( + CGF.Builder, Size, Allocator, + getNameWithSeparators({CVD->getName(), ".void.addr"}, ".", ".")); + llvm::CallInst *FreeCI = + OMPBuilder.CreateOMPFree(CGF.Builder, Addr, Allocator); + + CGF.EHStack.pushCleanup(NormalAndEHCleanup, FreeCI); + Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( + Addr, + CGF.ConvertTypeForMem(CGM.getContext().getPointerType(CVD->getType())), + getNameWithSeparators({CVD->getName(), ".addr"}, ".", ".")); + return Address(Addr, Align); +} + +Address CodeGenFunction::OMPBuilderCBHelpers::getAddrOfThreadPrivate( + CodeGenFunction &CGF, const VarDecl *VD, Address VDAddr, + SourceLocation Loc) { + CodeGenModule &CGM = CGF.CGM; + if (CGM.getLangOpts().OpenMPUseTLS && + CGM.getContext().getTargetInfo().isTLSSupported()) + return VDAddr; + + llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder(); + + llvm::Type *VarTy = VDAddr.getElementType(); + llvm::Value *Data = + CGF.Builder.CreatePointerCast(VDAddr.getPointer(), CGM.Int8PtrTy); + llvm::ConstantInt *Size = CGM.getSize(CGM.GetTargetTypeStoreSize(VarTy)); + std::string Suffix = getNameWithSeparators({"cache", ""}); + llvm::Twine CacheName = Twine(CGM.getMangledName(VD)).concat(Suffix); + + llvm::CallInst *ThreadPrivateCacheCall = + OMPBuilder.CreateCachedThreadPrivate(CGF.Builder, Data, Size, CacheName); + + return Address(ThreadPrivateCacheCall, VDAddr.getAlignment()); +} + +std::string CodeGenFunction::OMPBuilderCBHelpers::getNameWithSeparators( + ArrayRef Parts, StringRef FirstSeparator, StringRef Separator) { + SmallString<128> Buffer; + llvm::raw_svector_ostream OS(Buffer); + StringRef Sep = FirstSeparator; + for (StringRef Part : Parts) { + OS << Sep << Part; + Sep = Separator; + } + return OS.str().str(); +} void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) { - if (llvm::OpenMPIRBuilder *OMPBuilder = CGM.getOpenMPIRBuilder()) { + if (CGM.getLangOpts().OpenMPIRBuilder) { + llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder(); // Check if we have any if clause associated with the directive. llvm::Value *IfCond = nullptr; if (const auto *C = S.getSingleClause()) @@ -1616,9 +1707,9 @@ void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) { CGCapturedStmtInfo CGSI(*CS, CR_OpenMP); CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(*this, &CGSI); - Builder.restoreIP(OMPBuilder->CreateParallel(Builder, BodyGenCB, PrivCB, - FiniCB, IfCond, NumThreads, - ProcBind, S.hasCancel())); + Builder.restoreIP(OMPBuilder.CreateParallel(Builder, BodyGenCB, PrivCB, + FiniCB, IfCond, NumThreads, + ProcBind, S.hasCancel())); return; } @@ -3328,11 +3419,11 @@ void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) { // Generate condition for loop. BinaryOperator *Cond = BinaryOperator::Create( C, &IVRefExpr, &UBRefExpr, BO_LE, C.BoolTy, VK_RValue, OK_Ordinary, - S.getBeginLoc(), FPOptions(C.getLangOpts())); + S.getBeginLoc(), FPOptionsOverride()); // Increment for loop counter. UnaryOperator *Inc = UnaryOperator::Create( C, &IVRefExpr, UO_PreInc, KmpInt32Ty, VK_RValue, OK_Ordinary, - S.getBeginLoc(), true, FPOptions(C.getLangOpts())); + S.getBeginLoc(), true, FPOptionsOverride()); auto &&BodyGen = [CapturedStmt, CS, &S, &IV](CodeGenFunction &CGF) { // Iterate through all sections and emit a switch construct: // switch (IV) { @@ -3523,7 +3614,8 @@ static void emitMaster(CodeGenFunction &CGF, const OMPExecutableDirective &S) { } void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) { - if (llvm::OpenMPIRBuilder *OMPBuilder = CGM.getOpenMPIRBuilder()) { + if (CGM.getLangOpts().OpenMPIRBuilder) { + llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder(); using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy; const CapturedStmt *CS = S.getInnermostCapturedStmt(); @@ -3543,7 +3635,7 @@ void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) { CGCapturedStmtInfo CGSI(*CS, CR_OpenMP); CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(*this, &CGSI); - Builder.restoreIP(OMPBuilder->CreateMaster(Builder, BodyGenCB, FiniCB)); + Builder.restoreIP(OMPBuilder.CreateMaster(Builder, BodyGenCB, FiniCB)); return; } @@ -3552,7 +3644,8 @@ void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) { } void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) { - if (llvm::OpenMPIRBuilder *OMPBuilder = CGM.getOpenMPIRBuilder()) { + if (CGM.getLangOpts().OpenMPIRBuilder) { + llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder(); using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy; const CapturedStmt *CS = S.getInnermostCapturedStmt(); @@ -3583,7 +3676,7 @@ void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) { CGCapturedStmtInfo CGSI(*CS, CR_OpenMP); CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(*this, &CGSI); - Builder.restoreIP(OMPBuilder->CreateCritical( + Builder.restoreIP(OMPBuilder.CreateCritical( Builder, BodyGenCB, FiniCB, S.getDirectiveName().getAsString(), HintInst)); @@ -3627,13 +3720,12 @@ void CodeGenFunction::EmitOMPParallelForSimdDirective( // directives: 'parallel' with 'for' directive. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { Action.Enter(CGF); - CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds, - emitDispatchForLoopBounds); + (void)emitWorksharingDirective(CGF, S, /*HasCancel=*/false); }; { auto LPCRegion = CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S); - emitCommonOMPParallelDirective(*this, S, OMPD_simd, CodeGen, + emitCommonOMPParallelDirective(*this, S, OMPD_for_simd, CodeGen, emitEmptyBoundParameters); } // Check for outer lastprivate conditional update. @@ -5212,6 +5304,7 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind, case OMPC_exclusive: case OMPC_uses_allocators: case OMPC_affinity: + default: llvm_unreachable("Clause is not allowed in 'omp atomic'."); } } @@ -5784,7 +5877,8 @@ void CodeGenFunction::EmitOMPCancelDirective(const OMPCancelDirective &S) { break; } } - if (llvm::OpenMPIRBuilder *OMPBuilder = CGM.getOpenMPIRBuilder()) { + if (CGM.getLangOpts().OpenMPIRBuilder) { + llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder(); // TODO: This check is necessary as we only generate `omp parallel` through // the OpenMPIRBuilder for now. if (S.getCancelRegion() == OMPD_parallel) { @@ -5793,7 +5887,7 @@ void CodeGenFunction::EmitOMPCancelDirective(const OMPCancelDirective &S) { IfCondition = EmitScalarExpr(IfCond, /*IgnoreResultAssign=*/true); return Builder.restoreIP( - OMPBuilder->CreateCancel(Builder, IfCondition, S.getCancelRegion())); + OMPBuilder.CreateCancel(Builder, IfCondition, S.getCancelRegion())); } } diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index 276993581117e..65b3b0c5f53d0 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -363,7 +363,8 @@ void CodeGenFunction::EmitCallAndReturnForThunk(llvm::FunctionCallee Callee, : FPT->getReturnType(); ReturnValueSlot Slot; if (!ResultType->isVoidType() && - CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect) + (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect || + hasAggregateEvaluationKind(ResultType))) Slot = ReturnValueSlot(ReturnValue, ResultType.isVolatileQualified(), /*IsUnused=*/false, /*IsExternallyDestructed=*/true); diff --git a/clang/lib/CodeGen/CodeGenABITypes.cpp b/clang/lib/CodeGen/CodeGenABITypes.cpp index 322cf45c47af8..d3a16a1d5accf 100644 --- a/clang/lib/CodeGen/CodeGenABITypes.cpp +++ b/clang/lib/CodeGen/CodeGenABITypes.cpp @@ -115,3 +115,16 @@ unsigned CodeGen::getLLVMFieldNumber(CodeGenModule &CGM, const FieldDecl *FD) { return CGM.getTypes().getCGRecordLayout(RD).getLLVMFieldNo(FD); } + +llvm::Value *CodeGen::getCXXDestructorImplicitParam( + CodeGenModule &CGM, llvm::BasicBlock *InsertBlock, + llvm::BasicBlock::iterator InsertPoint, const CXXDestructorDecl *D, + CXXDtorType Type, bool ForVirtualBase, bool Delegating) { + CodeGenFunction CGF(CGM, /*suppressNewContext=*/true); + CGF.CurCodeDecl = D; + CGF.CurFuncDecl = D; + CGF.CurFn = InsertBlock->getParent(); + CGF.Builder.SetInsertPoint(InsertBlock, InsertPoint); + return CGM.getCXXABI().getCXXDestructorImplicitParam( + CGF, D, Type, ForVirtualBase, Delegating); +} diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 613e7df9d364d..8ce488f35dd32 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -87,8 +87,8 @@ CodeGenFunction::~CodeGenFunction() { // seems to be a reasonable spot. We do it here, as opposed to the deletion // time of the CodeGenModule, because we have to ensure the IR has not yet // been "emitted" to the outside, thus, modifications are still sensible. - if (llvm::OpenMPIRBuilder *OMPBuilder = CGM.getOpenMPIRBuilder()) - OMPBuilder->finalize(); + if (CGM.getLangOpts().OpenMPIRBuilder) + CGM.getOpenMPRuntime().getOMPBuilder().finalize(); } // Map the LangOption for exception behavior into @@ -117,12 +117,12 @@ void CodeGenFunction::SetFPModel() { void CodeGenFunction::SetFastMathFlags(FPOptions FPFeatures) { llvm::FastMathFlags FMF; - FMF.setAllowReassoc(FPFeatures.allowAssociativeMath()); - FMF.setNoNaNs(FPFeatures.noHonorNaNs()); - FMF.setNoInfs(FPFeatures.noHonorInfs()); - FMF.setNoSignedZeros(FPFeatures.noSignedZeros()); - FMF.setAllowReciprocal(FPFeatures.allowReciprocalMath()); - FMF.setApproxFunc(FPFeatures.allowApproximateFunctions()); + FMF.setAllowReassoc(FPFeatures.getAllowFPReassociate()); + FMF.setNoNaNs(FPFeatures.getNoHonorNaNs()); + FMF.setNoInfs(FPFeatures.getNoHonorInfs()); + FMF.setNoSignedZeros(FPFeatures.getNoSignedZero()); + FMF.setAllowReciprocal(FPFeatures.getAllowReciprocal()); + FMF.setApproxFunc(FPFeatures.getAllowApproxFunc()); FMF.setAllowContract(FPFeatures.allowFPContractAcrossStatement()); Builder.setFastMathFlags(FMF); } @@ -137,10 +137,12 @@ CodeGenFunction::CGFPOptionsRAII::CGFPOptionsRAII(CodeGenFunction &CGF, FMFGuard.emplace(CGF.Builder); - auto NewRoundingBehavior = FPFeatures.getRoundingMode(); + llvm::RoundingMode NewRoundingBehavior = + static_cast(FPFeatures.getRoundingMode()); CGF.Builder.setDefaultConstrainedRounding(NewRoundingBehavior); auto NewExceptionBehavior = - ToConstrainedExceptMD(FPFeatures.getExceptionMode()); + ToConstrainedExceptMD(static_cast( + FPFeatures.getFPExceptionMode())); CGF.Builder.setDefaultConstrainedExcept(NewExceptionBehavior); CGF.SetFastMathFlags(FPFeatures); @@ -159,13 +161,13 @@ CodeGenFunction::CGFPOptionsRAII::CGFPOptionsRAII(CodeGenFunction &CGF, if (OldValue != NewValue) CGF.CurFn->addFnAttr(Name, llvm::toStringRef(NewValue)); }; - mergeFnAttrValue("no-infs-fp-math", FPFeatures.noHonorInfs()); - mergeFnAttrValue("no-nans-fp-math", FPFeatures.noHonorNaNs()); - mergeFnAttrValue("no-signed-zeros-fp-math", FPFeatures.noSignedZeros()); - mergeFnAttrValue( - "unsafe-fp-math", - FPFeatures.allowAssociativeMath() && FPFeatures.allowReciprocalMath() && - FPFeatures.allowApproximateFunctions() && FPFeatures.noSignedZeros()); + mergeFnAttrValue("no-infs-fp-math", FPFeatures.getNoHonorInfs()); + mergeFnAttrValue("no-nans-fp-math", FPFeatures.getNoHonorNaNs()); + mergeFnAttrValue("no-signed-zeros-fp-math", FPFeatures.getNoSignedZero()); + mergeFnAttrValue("unsafe-fp-math", FPFeatures.getAllowFPReassociate() && + FPFeatures.getAllowReciprocal() && + FPFeatures.getAllowApproxFunc() && + FPFeatures.getNoSignedZero()); } CodeGenFunction::CGFPOptionsRAII::~CGFPOptionsRAII() { diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 37a322567f51b..1fc2ed76ca9e6 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -26,6 +26,7 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/ExprOpenMP.h" +#include "clang/AST/StmtOpenMP.h" #include "clang/AST/Type.h" #include "clang/Basic/ABI.h" #include "clang/Basic/CapturedStmt.h" @@ -80,6 +81,7 @@ class OMPUseDevicePtrClause; class OMPUseDeviceAddrClause; class ReturnsNonNullAttr; class SVETypeFlags; +class OMPExecutableDirective; namespace analyze_os_log { class OSLogBufferLayout; @@ -259,117 +261,12 @@ class CodeGenFunction : public CodeGenTypeCache { unsigned Index; }; - // Helper class for the OpenMP IR Builder. Allows reusability of code used for - // region body, and finalization codegen callbacks. This will class will also - // contain privatization functions used by the privatization call backs - struct OMPBuilderCBHelpers { - - using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy; - - /// Emit the Finalization for an OMP region - /// \param CGF The Codegen function this belongs to - /// \param IP Insertion point for generating the finalization code. - static void FinalizeOMPRegion(CodeGenFunction &CGF, InsertPointTy IP) { - CGBuilderTy::InsertPointGuard IPG(CGF.Builder); - assert(IP.getBlock()->end() != IP.getPoint() && - "OpenMP IR Builder should cause terminated block!"); - - llvm::BasicBlock *IPBB = IP.getBlock(); - llvm::BasicBlock *DestBB = IPBB->getUniqueSuccessor(); - assert(DestBB && "Finalization block should have one successor!"); - - // erase and replace with cleanup branch. - IPBB->getTerminator()->eraseFromParent(); - CGF.Builder.SetInsertPoint(IPBB); - CodeGenFunction::JumpDest Dest = CGF.getJumpDestInCurrentScope(DestBB); - CGF.EmitBranchThroughCleanup(Dest); - } - - /// Emit the body of an OMP region - /// \param CGF The Codegen function this belongs to - /// \param RegionBodyStmt The body statement for the OpenMP region being - /// generated - /// \param CodeGenIP Insertion point for generating the body code. - /// \param FiniBB The finalization basic block - static void EmitOMPRegionBody(CodeGenFunction &CGF, - const Stmt *RegionBodyStmt, - InsertPointTy CodeGenIP, - llvm::BasicBlock &FiniBB) { - llvm::BasicBlock *CodeGenIPBB = CodeGenIP.getBlock(); - if (llvm::Instruction *CodeGenIPBBTI = CodeGenIPBB->getTerminator()) - CodeGenIPBBTI->eraseFromParent(); - - CGF.Builder.SetInsertPoint(CodeGenIPBB); - - CGF.EmitStmt(RegionBodyStmt); - - if (CGF.Builder.saveIP().isSet()) - CGF.Builder.CreateBr(&FiniBB); - } - - /// RAII for preserving necessary info during Outlined region body codegen. - class OutlinedRegionBodyRAII { - - llvm::AssertingVH OldAllocaIP; - CodeGenFunction::JumpDest OldReturnBlock; - CodeGenFunction &CGF; - - public: - OutlinedRegionBodyRAII(CodeGenFunction &cgf, InsertPointTy &AllocaIP, - llvm::BasicBlock &RetBB) - : CGF(cgf) { - assert(AllocaIP.isSet() && - "Must specify Insertion point for allocas of outlined function"); - OldAllocaIP = CGF.AllocaInsertPt; - CGF.AllocaInsertPt = &*AllocaIP.getPoint(); - - OldReturnBlock = CGF.ReturnBlock; - CGF.ReturnBlock = CGF.getJumpDestInCurrentScope(&RetBB); - } - - ~OutlinedRegionBodyRAII() { - CGF.AllocaInsertPt = OldAllocaIP; - CGF.ReturnBlock = OldReturnBlock; - } - }; - - /// RAII for preserving necessary info during inlined region body codegen. - class InlinedRegionBodyRAII { - - llvm::AssertingVH OldAllocaIP; - CodeGenFunction &CGF; - - public: - InlinedRegionBodyRAII(CodeGenFunction &cgf, InsertPointTy &AllocaIP, - llvm::BasicBlock &FiniBB) - : CGF(cgf) { - // Alloca insertion block should be in the entry block of the containing - // function so it expects an empty AllocaIP in which case will reuse the - // old alloca insertion point, or a new AllocaIP in the same block as - // the old one - assert((!AllocaIP.isSet() || - CGF.AllocaInsertPt->getParent() == AllocaIP.getBlock()) && - "Insertion point should be in the entry block of containing " - "function!"); - OldAllocaIP = CGF.AllocaInsertPt; - if (AllocaIP.isSet()) - CGF.AllocaInsertPt = &*AllocaIP.getPoint(); - - // TODO: Remove the call, after making sure the counter is not used by - // the EHStack. - // Since this is an inlined region, it should not modify the - // ReturnBlock, and should reuse the one for the enclosing outlined - // region. So, the JumpDest being return by the function is discarded - (void)CGF.getJumpDestInCurrentScope(&FiniBB); - } - - ~InlinedRegionBodyRAII() { CGF.AllocaInsertPt = OldAllocaIP; } - }; - }; - CodeGenModule &CGM; // Per-module state. const TargetInfo &Target; + // For EH/SEH outlined funclets, this field points to parent's CGF + CodeGenFunction *ParentCGF = nullptr; + typedef std::pair ComplexPairTy; LoopInfoStack LoopStack; CGBuilderTy Builder; @@ -1695,6 +1592,169 @@ class CodeGenFunction : public CodeGenTypeCache { CallArgList OldCXXInheritedCtorInitExprArgs; }; + // Helper class for the OpenMP IR Builder. Allows reusability of code used for + // region body, and finalization codegen callbacks. This will class will also + // contain privatization functions used by the privatization call backs + // + // TODO: this is temporary class for things that are being moved out of + // CGOpenMPRuntime, new versions of current CodeGenFunction methods, or + // utility function for use with the OMPBuilder. Once that move to use the + // OMPBuilder is done, everything here will either become part of CodeGenFunc. + // directly, or a new helper class that will contain functions used by both + // this and the OMPBuilder + + struct OMPBuilderCBHelpers { + + OMPBuilderCBHelpers() = delete; + OMPBuilderCBHelpers(const OMPBuilderCBHelpers &) = delete; + OMPBuilderCBHelpers &operator=(const OMPBuilderCBHelpers &) = delete; + + using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy; + + /// Cleanup action for allocate support. + class OMPAllocateCleanupTy final : public EHScopeStack::Cleanup { + + private: + llvm::CallInst *RTLFnCI; + + public: + OMPAllocateCleanupTy(llvm::CallInst *RLFnCI) : RTLFnCI(RLFnCI) { + RLFnCI->removeFromParent(); + } + + void Emit(CodeGenFunction &CGF, Flags /*flags*/) override { + if (!CGF.HaveInsertPoint()) + return; + CGF.Builder.Insert(RTLFnCI); + } + }; + + /// Returns address of the threadprivate variable for the current + /// thread. This Also create any necessary OMP runtime calls. + /// + /// \param VD VarDecl for Threadprivate variable. + /// \param VDAddr Address of the Vardecl + /// \param Loc The location where the barrier directive was encountered + static Address getAddrOfThreadPrivate(CodeGenFunction &CGF, + const VarDecl *VD, Address VDAddr, + SourceLocation Loc); + + /// Gets the OpenMP-specific address of the local variable /p VD. + static Address getAddressOfLocalVariable(CodeGenFunction &CGF, + const VarDecl *VD); + /// Get the platform-specific name separator. + /// \param Parts different parts of the final name that needs separation + /// \param FirstSeparator First separator used between the initial two + /// parts of the name. + /// \param Separator separator used between all of the rest consecutinve + /// parts of the name + static std::string getNameWithSeparators(ArrayRef Parts, + StringRef FirstSeparator = ".", + StringRef Separator = "."); + /// Emit the Finalization for an OMP region + /// \param CGF The Codegen function this belongs to + /// \param IP Insertion point for generating the finalization code. + static void FinalizeOMPRegion(CodeGenFunction &CGF, InsertPointTy IP) { + CGBuilderTy::InsertPointGuard IPG(CGF.Builder); + assert(IP.getBlock()->end() != IP.getPoint() && + "OpenMP IR Builder should cause terminated block!"); + + llvm::BasicBlock *IPBB = IP.getBlock(); + llvm::BasicBlock *DestBB = IPBB->getUniqueSuccessor(); + assert(DestBB && "Finalization block should have one successor!"); + + // erase and replace with cleanup branch. + IPBB->getTerminator()->eraseFromParent(); + CGF.Builder.SetInsertPoint(IPBB); + CodeGenFunction::JumpDest Dest = CGF.getJumpDestInCurrentScope(DestBB); + CGF.EmitBranchThroughCleanup(Dest); + } + + /// Emit the body of an OMP region + /// \param CGF The Codegen function this belongs to + /// \param RegionBodyStmt The body statement for the OpenMP region being + /// generated + /// \param CodeGenIP Insertion point for generating the body code. + /// \param FiniBB The finalization basic block + static void EmitOMPRegionBody(CodeGenFunction &CGF, + const Stmt *RegionBodyStmt, + InsertPointTy CodeGenIP, + llvm::BasicBlock &FiniBB) { + llvm::BasicBlock *CodeGenIPBB = CodeGenIP.getBlock(); + if (llvm::Instruction *CodeGenIPBBTI = CodeGenIPBB->getTerminator()) + CodeGenIPBBTI->eraseFromParent(); + + CGF.Builder.SetInsertPoint(CodeGenIPBB); + + CGF.EmitStmt(RegionBodyStmt); + + if (CGF.Builder.saveIP().isSet()) + CGF.Builder.CreateBr(&FiniBB); + } + + /// RAII for preserving necessary info during Outlined region body codegen. + class OutlinedRegionBodyRAII { + + llvm::AssertingVH OldAllocaIP; + CodeGenFunction::JumpDest OldReturnBlock; + CGBuilderTy::InsertPoint IP; + CodeGenFunction &CGF; + + public: + OutlinedRegionBodyRAII(CodeGenFunction &cgf, InsertPointTy &AllocaIP, + llvm::BasicBlock &RetBB) + : CGF(cgf) { + assert(AllocaIP.isSet() && + "Must specify Insertion point for allocas of outlined function"); + OldAllocaIP = CGF.AllocaInsertPt; + CGF.AllocaInsertPt = &*AllocaIP.getPoint(); + IP = CGF.Builder.saveIP(); + + OldReturnBlock = CGF.ReturnBlock; + CGF.ReturnBlock = CGF.getJumpDestInCurrentScope(&RetBB); + } + + ~OutlinedRegionBodyRAII() { + CGF.AllocaInsertPt = OldAllocaIP; + CGF.ReturnBlock = OldReturnBlock; + CGF.Builder.restoreIP(IP); + } + }; + + /// RAII for preserving necessary info during inlined region body codegen. + class InlinedRegionBodyRAII { + + llvm::AssertingVH OldAllocaIP; + CodeGenFunction &CGF; + + public: + InlinedRegionBodyRAII(CodeGenFunction &cgf, InsertPointTy &AllocaIP, + llvm::BasicBlock &FiniBB) + : CGF(cgf) { + // Alloca insertion block should be in the entry block of the containing + // function so it expects an empty AllocaIP in which case will reuse the + // old alloca insertion point, or a new AllocaIP in the same block as + // the old one + assert((!AllocaIP.isSet() || + CGF.AllocaInsertPt->getParent() == AllocaIP.getBlock()) && + "Insertion point should be in the entry block of containing " + "function!"); + OldAllocaIP = CGF.AllocaInsertPt; + if (AllocaIP.isSet()) + CGF.AllocaInsertPt = &*AllocaIP.getPoint(); + + // TODO: Remove the call, after making sure the counter is not used by + // the EHStack. + // Since this is an inlined region, it should not modify the + // ReturnBlock, and should reuse the one for the enclosing outlined + // region. So, the JumpDest being return by the function is discarded + (void)CGF.getJumpDestInCurrentScope(&FiniBB); + } + + ~InlinedRegionBodyRAII() { CGF.AllocaInsertPt = OldAllocaIP; } + }; + }; + private: /// CXXThisDecl - When generating code for a C++ member function, /// this will hold the implicit 'this' declaration. diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 7a9df700581e9..4ae8ce7e5ccf1 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -222,14 +222,6 @@ void CodeGenModule::createOpenMPRuntime() { OpenMPRuntime.reset(new CGOpenMPRuntime(*this)); break; } - - // The OpenMP-IR-Builder should eventually replace the above runtime codegens - // but we are not there yet so they both reside in CGModule for now and the - // OpenMP-IR-Builder is opt-in only. - if (LangOpts.OpenMPIRBuilder) { - OMPBuilder.reset(new llvm::OpenMPIRBuilder(TheModule)); - OMPBuilder->initialize(); - } } void CodeGenModule::createCUDARuntime() { @@ -663,7 +655,7 @@ void CodeGenModule::Release() { if (!getCodeGenOpts().RecordCommandLine.empty()) EmitCommandLineMetadata(); - EmitTargetMetadata(); + getTargetCodeGenInfo().emitTargetMetadata(*this, MangledDeclNames); EmitBackendOptionsMetadata(getCodeGenOpts()); } @@ -3656,26 +3648,29 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, } llvm::Constant * -CodeGenModule::GetAddrOfGlobal(GlobalDecl GD, - ForDefinition_t IsForDefinition) { +CodeGenModule::GetAddrOfGlobal(GlobalDecl GD, ForDefinition_t IsForDefinition) { const Decl *D = GD.getDecl(); + if (isa(D) || isa(D)) return getAddrOfCXXStructor(GD, /*FnInfo=*/nullptr, /*FnType=*/nullptr, /*DontDefer=*/false, IsForDefinition); - else if (isa(D)) { - auto FInfo = &getTypes().arrangeCXXMethodDeclaration( - cast(D)); + + if (isa(D)) { + auto FInfo = + &getTypes().arrangeCXXMethodDeclaration(cast(D)); auto Ty = getTypes().GetFunctionType(*FInfo); return GetAddrOfFunction(GD, Ty, /*ForVTable=*/false, /*DontDefer=*/false, IsForDefinition); - } else if (isa(D)) { + } + + if (isa(D)) { const CGFunctionInfo &FI = getTypes().arrangeGlobalDeclaration(GD); llvm::FunctionType *Ty = getTypes().GetFunctionType(FI); return GetAddrOfFunction(GD, Ty, /*ForVTable=*/false, /*DontDefer=*/false, IsForDefinition); - } else - return GetAddrOfGlobalVar(cast(D), /*Ty=*/nullptr, - IsForDefinition); + } + + return GetAddrOfGlobalVar(cast(D), /*Ty=*/nullptr, IsForDefinition); } llvm::GlobalVariable *CodeGenModule::CreateOrReplaceCXXRuntimeVariable( @@ -5788,21 +5783,6 @@ void CodeGenModule::EmitCommandLineMetadata() { CommandLineMetadata->addOperand(llvm::MDNode::get(Ctx, CommandLineNode)); } -void CodeGenModule::EmitTargetMetadata() { - // Warning, new MangledDeclNames may be appended within this loop. - // We rely on MapVector insertions adding new elements to the end - // of the container. - // FIXME: Move this loop into the one target that needs it, and only - // loop over those declarations for which we couldn't emit the target - // metadata when we emitted the declaration. - for (unsigned I = 0; I != MangledDeclNames.size(); ++I) { - auto Val = *(MangledDeclNames.begin() + I); - const Decl *D = Val.first.getDecl()->getMostRecentDecl(); - llvm::GlobalValue *GV = GetGlobalValue(Val.second); - getTargetCodeGenInfo().emitTargetMD(D, GV, *this); - } -} - void CodeGenModule::EmitCoverageFile() { if (getCodeGenOpts().CoverageDataFile.empty() && getCodeGenOpts().CoverageNotesFile.empty()) @@ -5990,6 +5970,9 @@ CharUnits CodeGenModule::getNaturalTypeAlignment(QualType T, if (TBAAInfo) *TBAAInfo = getTBAAAccessInfo(T); + // FIXME: This duplicates logic in ASTContext::getTypeAlignIfKnown. But + // that doesn't return the information we need to compute BaseInfo. + // Honor alignment typedef attributes even on incomplete types. // We also honor them straight for C++ class types, even as pointees; // there's an expressivity gap here. @@ -6001,32 +5984,46 @@ CharUnits CodeGenModule::getNaturalTypeAlignment(QualType T, } } + bool AlignForArray = T->isArrayType(); + + // Analyze the base element type, so we don't get confused by incomplete + // array types. + T = getContext().getBaseElementType(T); + + if (T->isIncompleteType()) { + // We could try to replicate the logic from + // ASTContext::getTypeAlignIfKnown, but nothing uses the alignment if the + // type is incomplete, so it's impossible to test. We could try to reuse + // getTypeAlignIfKnown, but that doesn't return the information we need + // to set BaseInfo. So just ignore the possibility that the alignment is + // greater than one. + if (BaseInfo) + *BaseInfo = LValueBaseInfo(AlignmentSource::Type); + return CharUnits::One(); + } + if (BaseInfo) *BaseInfo = LValueBaseInfo(AlignmentSource::Type); CharUnits Alignment; - if (T->isIncompleteType()) { - Alignment = CharUnits::One(); // Shouldn't be used, but pessimistic is best. + // For C++ class pointees, we don't know whether we're pointing at a + // base or a complete object, so we generally need to use the + // non-virtual alignment. + const CXXRecordDecl *RD; + if (forPointeeType && !AlignForArray && (RD = T->getAsCXXRecordDecl())) { + Alignment = getClassPointerAlignment(RD); } else { - // For C++ class pointees, we don't know whether we're pointing at a - // base or a complete object, so we generally need to use the - // non-virtual alignment. - const CXXRecordDecl *RD; - if (forPointeeType && (RD = T->getAsCXXRecordDecl())) { - Alignment = getClassPointerAlignment(RD); - } else { - Alignment = getContext().getTypeAlignInChars(T); - if (T.getQualifiers().hasUnaligned()) - Alignment = CharUnits::One(); - } + Alignment = getContext().getTypeAlignInChars(T); + if (T.getQualifiers().hasUnaligned()) + Alignment = CharUnits::One(); + } - // Cap to the global maximum type alignment unless the alignment - // was somehow explicit on the type. - if (unsigned MaxAlign = getLangOpts().MaxTypeAlign) { - if (Alignment.getQuantity() > MaxAlign && - !getContext().isAlignmentRequired(T)) - Alignment = CharUnits::fromQuantity(MaxAlign); - } + // Cap to the global maximum type alignment unless the alignment + // was somehow explicit on the type. + if (unsigned MaxAlign = getLangOpts().MaxTypeAlign) { + if (Alignment.getQuantity() > MaxAlign && + !getContext().isAlignmentRequired(T)) + Alignment = CharUnits::fromQuantity(MaxAlign); } return Alignment; } diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 59b27fa32a1b3..a6c4a1f7b278c 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -324,7 +324,6 @@ class CodeGenModule : public CodeGenTypeCache { std::unique_ptr ObjCRuntime; std::unique_ptr OpenCLRuntime; std::unique_ptr OpenMPRuntime; - std::unique_ptr OMPBuilder; std::unique_ptr CUDARuntime; std::unique_ptr DebugInfo; std::unique_ptr ObjCData; @@ -597,9 +596,6 @@ class CodeGenModule : public CodeGenTypeCache { return *OpenMPRuntime; } - /// Return a pointer to the configured OpenMPIRBuilder, if any. - llvm::OpenMPIRBuilder *getOpenMPIRBuilder() { return OMPBuilder.get(); } - /// Return a reference to the configured CUDA runtime. CGCUDARuntime &getCUDARuntime() { assert(CUDARuntime != nullptr); @@ -1532,9 +1528,6 @@ class CodeGenModule : public CodeGenTypeCache { /// Emit the Clang commandline as llvm.commandline metadata. void EmitCommandLineMetadata(); - /// Emits target specific Metadata for global declarations. - void EmitTargetMetadata(); - /// Emit the module flag metadata used to pass options controlling the /// the backend to LLVM. void EmitBackendOptionsMetadata(const CodeGenOptions CodeGenOpts); diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index 4811e309abbe9..d431c0263666e 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -619,6 +619,12 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { return GET_SVE_FP_VEC(DoubleTy, false, 8); case BuiltinType::SveBFloat16: return GET_SVE_FP_VEC(BFloat16Ty, false, 8); + case BuiltinType::SveBFloat16x2: + return GET_SVE_FP_VEC(BFloat16Ty, false, 16); + case BuiltinType::SveBFloat16x3: + return GET_SVE_FP_VEC(BFloat16Ty, false, 24); + case BuiltinType::SveBFloat16x4: + return GET_SVE_FP_VEC(BFloat16Ty, false, 32); #undef GET_SVE_FP_VEC case BuiltinType::Dependent: #define BUILTIN_TYPE(Id, SingletonId) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index cdbfc88e7b707..78b268f423cbf 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -908,6 +908,18 @@ struct CounterCoverageMappingBuilder terminateRegion(S); } + void VisitCoroutineBodyStmt(const CoroutineBodyStmt *S) { + extendRegion(S); + Visit(S->getBody()); + } + + void VisitCoreturnStmt(const CoreturnStmt *S) { + extendRegion(S); + if (S->getOperand()) + Visit(S->getOperand()); + terminateRegion(S); + } + void VisitCXXThrowExpr(const CXXThrowExpr *E) { extendRegion(E); if (E->getSubExpr()) diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 2829877cfe5d9..80de2a6e39505 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -228,6 +228,12 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI { bool ForVirtualBase, bool Delegating) override; + llvm::Value *getCXXDestructorImplicitParam(CodeGenFunction &CGF, + const CXXDestructorDecl *DD, + CXXDtorType Type, + bool ForVirtualBase, + bool Delegating) override; + void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, @@ -1693,13 +1699,21 @@ CGCXXABI::AddedStructorArgs ItaniumCXXABI::getImplicitConstructorArgs( return AddedStructorArgs::prefix({{VTT, VTTTy}}); } +llvm::Value *ItaniumCXXABI::getCXXDestructorImplicitParam( + CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, + bool ForVirtualBase, bool Delegating) { + GlobalDecl GD(DD, Type); + return CGF.GetVTTParameter(GD, ForVirtualBase, Delegating); +} + void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy) { GlobalDecl GD(DD, Type); - llvm::Value *VTT = CGF.GetVTTParameter(GD, ForVirtualBase, Delegating); + llvm::Value *VTT = + getCXXDestructorImplicitParam(CGF, DD, Type, ForVirtualBase, Delegating); QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy); CGCallee Callee; diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index 08e30527af47c..45c6cb6b2e0d1 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -259,6 +259,12 @@ class MicrosoftCXXABI : public CGCXXABI { bool ForVirtualBase, bool Delegating) override; + llvm::Value *getCXXDestructorImplicitParam(CodeGenFunction &CGF, + const CXXDestructorDecl *DD, + CXXDtorType Type, + bool ForVirtualBase, + bool Delegating) override; + void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, @@ -1577,6 +1583,12 @@ CGCXXABI::AddedStructorArgs MicrosoftCXXABI::getImplicitConstructorArgs( return AddedStructorArgs::suffix({{MostDerivedArg, getContext().IntTy}}); } +llvm::Value *MicrosoftCXXABI::getCXXDestructorImplicitParam( + CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, + bool ForVirtualBase, bool Delegating) { + return nullptr; +} + void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, @@ -1603,8 +1615,11 @@ void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF, BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF); } + llvm::Value *Implicit = + getCXXDestructorImplicitParam(CGF, DD, Type, ForVirtualBase, + Delegating); // = nullptr CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy, - /*ImplicitParam=*/nullptr, + /*ImplicitParam=*/Implicit, /*ImplicitParamTy=*/QualType(), nullptr); if (BaseDtorEndBB) { // Complete object handler should continue to be the remaining diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 9710e676e58f8..9cd63ebe29ee0 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -20,6 +20,7 @@ #include "clang/AST/Attr.h" #include "clang/AST/RecordLayout.h" #include "clang/Basic/CodeGenOptions.h" +#include "clang/Basic/DiagnosticFrontend.h" #include "clang/CodeGen/CGFunctionInfo.h" #include "clang/CodeGen/SwiftCallingConv.h" #include "llvm/ADT/SmallBitVector.h" @@ -498,11 +499,15 @@ static bool isEmptyField(ASTContext &Context, const FieldDecl *FD, // Constant arrays of empty records count as empty, strip them off. // Constant arrays of zero length always count as empty. + bool WasArray = false; if (AllowArrays) while (const ConstantArrayType *AT = Context.getAsConstantArrayType(FT)) { if (AT->getSize() == 0) return true; FT = AT->getElementType(); + // The [[no_unique_address]] special case below does not apply to + // arrays of C++ empty records, so we need to remember this fact. + WasArray = true; } const RecordType *RT = FT->getAs(); @@ -513,7 +518,14 @@ static bool isEmptyField(ASTContext &Context, const FieldDecl *FD, // // FIXME: We should use a predicate for whether this behavior is true in the // current ABI. - if (isa(RT->getDecl())) + // + // The exception to the above rule are fields marked with the + // [[no_unique_address]] attribute (since C++20). Those do count as empty + // 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(RT->getDecl()) && + (WasArray || !FD->hasAttr())) return false; return isEmptyRecord(Context, FT, AllowArrays); @@ -2466,8 +2478,110 @@ class X86_64TargetCodeGenInfo : public TargetCodeGenInfo { } } } + + void checkFunctionCallABI(CodeGenModule &CGM, SourceLocation CallLoc, + const FunctionDecl *Caller, + const FunctionDecl *Callee, + const CallArgList &Args) const override; }; +static void initFeatureMaps(const ASTContext &Ctx, + llvm::StringMap &CallerMap, + const FunctionDecl *Caller, + llvm::StringMap &CalleeMap, + const FunctionDecl *Callee) { + if (CalleeMap.empty() && CallerMap.empty()) { + // The caller is potentially nullptr in the case where the call isn't in a + // function. In this case, the getFunctionFeatureMap ensures we just get + // the TU level setting (since it cannot be modified by 'target'.. + Ctx.getFunctionFeatureMap(CallerMap, Caller); + Ctx.getFunctionFeatureMap(CalleeMap, Callee); + } +} + +static bool checkAVXParamFeature(DiagnosticsEngine &Diag, + SourceLocation CallLoc, + const llvm::StringMap &CallerMap, + const llvm::StringMap &CalleeMap, + QualType Ty, StringRef Feature, + bool IsArgument) { + bool CallerHasFeat = CallerMap.lookup(Feature); + bool CalleeHasFeat = CalleeMap.lookup(Feature); + if (!CallerHasFeat && !CalleeHasFeat) + return Diag.Report(CallLoc, diag::warn_avx_calling_convention) + << IsArgument << Ty << Feature; + + // Mixing calling conventions here is very clearly an error. + if (!CallerHasFeat || !CalleeHasFeat) + return Diag.Report(CallLoc, diag::err_avx_calling_convention) + << IsArgument << Ty << Feature; + + // Else, both caller and callee have the required feature, so there is no need + // to diagnose. + return false; +} + +static bool checkAVXParam(DiagnosticsEngine &Diag, ASTContext &Ctx, + SourceLocation CallLoc, + const llvm::StringMap &CallerMap, + const llvm::StringMap &CalleeMap, QualType Ty, + bool IsArgument) { + uint64_t Size = Ctx.getTypeSize(Ty); + if (Size > 256) + return checkAVXParamFeature(Diag, CallLoc, CallerMap, CalleeMap, Ty, + "avx512f", IsArgument); + + if (Size > 128) + return checkAVXParamFeature(Diag, CallLoc, CallerMap, CalleeMap, Ty, "avx", + IsArgument); + + return false; +} + +void X86_64TargetCodeGenInfo::checkFunctionCallABI( + CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, + const FunctionDecl *Callee, const CallArgList &Args) const { + llvm::StringMap CallerMap; + llvm::StringMap CalleeMap; + unsigned ArgIndex = 0; + + // We need to loop through the actual call arguments rather than the the + // function's parameters, in case this variadic. + for (const CallArg &Arg : Args) { + // The "avx" feature changes how vectors >128 in size are passed. "avx512f" + // additionally changes how vectors >256 in size are passed. Like GCC, we + // warn when a function is called with an argument where this will change. + // Unlike GCC, we also error when it is an obvious ABI mismatch, that is, + // the caller and callee features are mismatched. + // Unfortunately, we cannot do this diagnostic in SEMA, since the callee can + // change its ABI with attribute-target after this call. + if (Arg.getType()->isVectorType() && + CGM.getContext().getTypeSize(Arg.getType()) > 128) { + initFeatureMaps(CGM.getContext(), CallerMap, Caller, CalleeMap, Callee); + QualType Ty = Arg.getType(); + // The CallArg seems to have desugared the type already, so for clearer + // diagnostics, replace it with the type in the FunctionDecl if possible. + if (ArgIndex < Callee->getNumParams()) + Ty = Callee->getParamDecl(ArgIndex)->getType(); + + if (checkAVXParam(CGM.getDiags(), CGM.getContext(), CallLoc, CallerMap, + CalleeMap, Ty, /*IsArgument*/ true)) + return; + } + ++ArgIndex; + } + + // Check return always, as we don't have a good way of knowing in codegen + // whether this value is used, tail-called, etc. + if (Callee->getReturnType()->isVectorType() && + CGM.getContext().getTypeSize(Callee->getReturnType()) > 128) { + initFeatureMaps(CGM.getContext(), CallerMap, Caller, CalleeMap, Callee); + checkAVXParam(CGM.getDiags(), CGM.getContext(), CallLoc, CallerMap, + CalleeMap, Callee->getReturnType(), + /*IsArgument*/ false); + } +} + static std::string qualifyWindowsLibrary(llvm::StringRef Lib) { // If the argument does not end in .lib, automatically add the suffix. // If the argument contains a space, enclose it in quotes. @@ -7105,7 +7219,9 @@ bool SystemZABIInfo::isFPArgumentType(QualType Ty) const { } QualType SystemZABIInfo::GetSingleElementType(QualType Ty) const { - if (const RecordType *RT = Ty->getAsStructureType()) { + const RecordType *RT = Ty->getAs(); + + if (RT && RT->isStructureOrClassType()) { const RecordDecl *RD = RT->getDecl(); QualType Found; @@ -7131,6 +7247,10 @@ QualType SystemZABIInfo::GetSingleElementType(QualType Ty) const { if (getContext().getLangOpts().CPlusPlus && FD->isZeroLengthBitField(getContext())) continue; + // Like isSingleElementStruct(), ignore C++20 empty data members. + if (FD->hasAttr() && + isEmptyRecord(getContext(), FD->getType(), true)) + continue; // Unlike isSingleElementStruct(), arrays do not count. // Nested structures still do though. @@ -7370,10 +7490,49 @@ ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const { namespace { +class MSP430ABIInfo : public DefaultABIInfo { + static ABIArgInfo complexArgInfo() { + ABIArgInfo Info = ABIArgInfo::getDirect(); + Info.setCanBeFlattened(false); + return Info; + } + +public: + MSP430ABIInfo(CodeGenTypes &CGT) : DefaultABIInfo(CGT) {} + + ABIArgInfo classifyReturnType(QualType RetTy) const { + if (RetTy->isAnyComplexType()) + return complexArgInfo(); + + return DefaultABIInfo::classifyReturnType(RetTy); + } + + ABIArgInfo classifyArgumentType(QualType RetTy) const { + if (RetTy->isAnyComplexType()) + return complexArgInfo(); + + return DefaultABIInfo::classifyArgumentType(RetTy); + } + + // Just copy the original implementations because + // DefaultABIInfo::classify{Return,Argument}Type() are not virtual + void computeInfo(CGFunctionInfo &FI) const override { + if (!getCXXABI().classifyReturnType(FI)) + FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + for (auto &I : FI.arguments()) + I.info = classifyArgumentType(I.type); + } + + Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, + QualType Ty) const override { + return EmitVAArgInstr(CGF, VAListAddr, Ty, classifyArgumentType(Ty)); + } +}; + class MSP430TargetCodeGenInfo : public TargetCodeGenInfo { public: MSP430TargetCodeGenInfo(CodeGenTypes &CGT) - : TargetCodeGenInfo(std::make_unique(CGT)) {} + : TargetCodeGenInfo(std::make_unique(CGT)) {} void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const override; }; @@ -9535,11 +9694,15 @@ class XCoreABIInfo : public DefaultABIInfo { class XCoreTargetCodeGenInfo : public TargetCodeGenInfo { mutable TypeStringCache TSC; + void emitTargetMD(const Decl *D, llvm::GlobalValue *GV, + const CodeGen::CodeGenModule &M) const; + public: XCoreTargetCodeGenInfo(CodeGenTypes &CGT) : TargetCodeGenInfo(std::make_unique(CGT)) {} - void emitTargetMD(const Decl *D, llvm::GlobalValue *GV, - CodeGen::CodeGenModule &M) const override; + void emitTargetMetadata(CodeGen::CodeGenModule &CGM, + const llvm::MapVector + &MangledDeclNames) const override; }; } // End anonymous namespace. @@ -9700,11 +9863,13 @@ StringRef TypeStringCache::lookupStr(const IdentifierInfo *ID) { /// The output is tested by test/CodeGen/xcore-stringtype.c. /// static bool getTypeString(SmallStringEnc &Enc, const Decl *D, - CodeGen::CodeGenModule &CGM, TypeStringCache &TSC); + const CodeGen::CodeGenModule &CGM, + TypeStringCache &TSC); /// XCore uses emitTargetMD to emit TypeString metadata for global symbols. -void XCoreTargetCodeGenInfo::emitTargetMD(const Decl *D, llvm::GlobalValue *GV, - CodeGen::CodeGenModule &CGM) const { +void XCoreTargetCodeGenInfo::emitTargetMD( + const Decl *D, llvm::GlobalValue *GV, + const CodeGen::CodeGenModule &CGM) const { SmallStringEnc Enc; if (getTypeString(Enc, D, CGM, TSC)) { llvm::LLVMContext &Ctx = CGM.getModule().getContext(); @@ -9716,6 +9881,21 @@ void XCoreTargetCodeGenInfo::emitTargetMD(const Decl *D, llvm::GlobalValue *GV, } } +void XCoreTargetCodeGenInfo::emitTargetMetadata( + CodeGen::CodeGenModule &CGM, + const llvm::MapVector &MangledDeclNames) const { + // Warning, new MangledDeclNames may be appended within this loop. + // We rely on MapVector insertions adding new elements to the end + // of the container. + for (unsigned I = 0; I != MangledDeclNames.size(); ++I) { + auto Val = *(MangledDeclNames.begin() + I); + llvm::GlobalValue *GV = CGM.GetGlobalValue(Val.second); + if (GV) { + const Decl *D = Val.first.getDecl()->getMostRecentDecl(); + emitTargetMD(D, GV, CGM); + } + } +} //===----------------------------------------------------------------------===// // SPIR ABI Implementation //===----------------------------------------------------------------------===// @@ -10049,7 +10229,8 @@ static bool appendType(SmallStringEnc &Enc, QualType QType, } static bool getTypeString(SmallStringEnc &Enc, const Decl *D, - CodeGen::CodeGenModule &CGM, TypeStringCache &TSC) { + const CodeGen::CodeGenModule &CGM, + TypeStringCache &TSC) { if (!D) return false; @@ -10548,6 +10729,56 @@ class RISCVTargetCodeGenInfo : public TargetCodeGenInfo { }; } // namespace +//===----------------------------------------------------------------------===// +// VE ABI Implementation. +// +namespace { +class VEABIInfo : public DefaultABIInfo { +public: + VEABIInfo(CodeGenTypes &CGT) : DefaultABIInfo(CGT) {} + +private: + ABIArgInfo classifyReturnType(QualType RetTy) const; + ABIArgInfo classifyArgumentType(QualType RetTy) const; + void computeInfo(CGFunctionInfo &FI) const override; +}; +} // end anonymous namespace + +ABIArgInfo VEABIInfo::classifyReturnType(QualType Ty) const { + if (Ty->isAnyComplexType()) { + return ABIArgInfo::getDirect(); + } + return DefaultABIInfo::classifyReturnType(Ty); +} + +ABIArgInfo VEABIInfo::classifyArgumentType(QualType Ty) const { + if (Ty->isAnyComplexType()) { + return ABIArgInfo::getDirect(); + } + return DefaultABIInfo::classifyArgumentType(Ty); +} + +void VEABIInfo::computeInfo(CGFunctionInfo &FI) const { + + FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + for (auto &Arg : FI.arguments()) + Arg.info = classifyArgumentType(Arg.type); +} + +namespace { +class VETargetCodeGenInfo : public TargetCodeGenInfo { +public: + VETargetCodeGenInfo(CodeGenTypes &CGT) + : TargetCodeGenInfo(std::make_unique(CGT)) {} + // VE ABI requires the arguments of variadic and prototype-less functions + // are passed in both registers and memory. + bool isNoProtoCallVariadic(const CallArgList &args, + const FunctionNoProtoType *fnType) const override { + return true; + } +}; +} // end anonymous namespace + //===----------------------------------------------------------------------===// // Driver code //===----------------------------------------------------------------------===// @@ -10750,6 +10981,8 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { case llvm::Triple::spir: case llvm::Triple::spir64: return SetCGInfo(new SPIRTargetCodeGenInfo(Types)); + case llvm::Triple::ve: + return SetCGInfo(new VETargetCodeGenInfo(Types)); } } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index 85565475eee79..1152cabce4a0d 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -57,10 +57,18 @@ class TargetCodeGenInfo { virtual void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const {} - /// emitTargetMD - Provides a convenient hook to handle extra - /// target-specific metadata for the given global. - virtual void emitTargetMD(const Decl *D, llvm::GlobalValue *GV, - CodeGen::CodeGenModule &M) const {} + /// emitTargetMetadata - Provides a convenient hook to handle extra + /// target-specific metadata for the given globals. + virtual void emitTargetMetadata( + CodeGen::CodeGenModule &CGM, + const llvm::MapVector &MangledDeclNames) const {} + + /// Any further codegen related checks that need to be done on a function call + /// in a target specific manner. + virtual void checkFunctionCallABI(CodeGenModule &CGM, SourceLocation CallLoc, + const FunctionDecl *Caller, + const FunctionDecl *Callee, + const CallArgList &Args) const {} /// Determines the size of struct _Unwind_Exception on this platform, /// in 8-bit units. The Itanium ABI defines this as: diff --git a/clang/lib/CrossTU/CrossTranslationUnit.cpp b/clang/lib/CrossTU/CrossTranslationUnit.cpp index 24c3143db4107..80465c41d1515 100644 --- a/clang/lib/CrossTU/CrossTranslationUnit.cpp +++ b/clang/lib/CrossTU/CrossTranslationUnit.cpp @@ -12,6 +12,7 @@ #include "clang/CrossTU/CrossTranslationUnit.h" #include "clang/AST/ASTImporter.h" #include "clang/AST/Decl.h" +#include "clang/AST/ParentMapContext.h" #include "clang/Basic/TargetInfo.h" #include "clang/CrossTU/CrossTUDiagnostic.h" #include "clang/Frontend/ASTUnit.h" @@ -366,7 +367,9 @@ CrossTranslationUnitContext::ASTUnitStorage::ASTUnitStorage( CompilerInstance &CI) : Loader(CI, CI.getAnalyzerOpts()->CTUDir, CI.getAnalyzerOpts()->CTUInvocationList), - LoadGuard(CI.getAnalyzerOpts()->CTUImportThreshold) {} + LoadGuard(CI.getASTContext().getLangOpts().CPlusPlus + ? CI.getAnalyzerOpts()->CTUImportCppThreshold + : CI.getAnalyzerOpts()->CTUImportThreshold) {} llvm::Expected CrossTranslationUnitContext::ASTUnitStorage::getASTUnitForFile( @@ -718,6 +721,9 @@ CrossTranslationUnitContext::importDefinitionImpl(const T *D, ASTUnit *Unit) { assert(hasBodyOrInit(ToDecl) && "Imported Decl should have body or init."); ++NumGetCTUSuccess; + // Parent map is invalidated after changing the AST. + ToDecl->getASTContext().getParentMapContext().clear(); + return ToDecl; } diff --git a/clang/lib/Driver/Action.cpp b/clang/lib/Driver/Action.cpp index 0eb4c7257e7a8..2ec063d873be7 100644 --- a/clang/lib/Driver/Action.cpp +++ b/clang/lib/Driver/Action.cpp @@ -43,6 +43,8 @@ const char *Action::getClassName(ActionClass AC) { return "clang-offload-unbundler"; case OffloadWrapperJobClass: return "clang-offload-wrapper"; + case StaticLibJobClass: + return "static-lib-linker"; } llvm_unreachable("invalid class"); @@ -415,3 +417,8 @@ void OffloadWrapperJobAction::anchor() {} OffloadWrapperJobAction::OffloadWrapperJobAction(ActionList &Inputs, types::ID Type) : JobAction(OffloadWrapperJobClass, Inputs, Type) {} + +void StaticLibJobAction::anchor() {} + +StaticLibJobAction::StaticLibJobAction(ActionList &Inputs, types::ID Type) + : JobAction(StaticLibJobClass, Inputs, Type) {} diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt index 6f25d3588ebba..9463ca5c109d6 100644 --- a/clang/lib/Driver/CMakeLists.txt +++ b/clang/lib/Driver/CMakeLists.txt @@ -31,6 +31,7 @@ add_clang_library(clangDriver ToolChains/Arch/RISCV.cpp ToolChains/Arch/Sparc.cpp ToolChains/Arch/SystemZ.cpp + ToolChains/Arch/VE.cpp ToolChains/Arch/X86.cpp ToolChains/AIX.cpp ToolChains/Ananas.cpp @@ -67,6 +68,7 @@ add_clang_library(clangDriver ToolChains/RISCVToolchain.cpp ToolChains/Solaris.cpp ToolChains/TCE.cpp + ToolChains/VEToolchain.cpp ToolChains/WebAssembly.cpp ToolChains/XCore.cpp ToolChains/PPCLinux.cpp diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index a48761af400fd..ece8222dcf24f 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -43,6 +43,7 @@ #include "ToolChains/RISCVToolchain.h" #include "ToolChains/Solaris.h" #include "ToolChains/TCE.h" +#include "ToolChains/VEToolchain.h" #include "ToolChains/WebAssembly.h" #include "ToolChains/XCore.h" #include "clang/Basic/Version.h" @@ -474,6 +475,26 @@ static llvm::Triple computeTargetTriple(const Driver &D, Target.getOS() == llvm::Triple::Minix) return Target; + // On AIX, the env OBJECT_MODE may affect the resulting arch variant. + if (Target.isOSAIX()) { + if (Optional ObjectModeValue = + llvm::sys::Process::GetEnv("OBJECT_MODE")) { + StringRef ObjectMode = *ObjectModeValue; + llvm::Triple::ArchType AT = llvm::Triple::UnknownArch; + + if (ObjectMode.equals("64")) { + AT = Target.get64BitArchVariant().getArch(); + } else if (ObjectMode.equals("32")) { + AT = Target.get32BitArchVariant().getArch(); + } else { + D.Diag(diag::err_drv_invalid_object_mode) << ObjectMode; + } + + if (AT != llvm::Triple::UnknownArch && AT != Target.getArch()) + Target.setArch(AT); + } + } + // Handle pseudo-target flags '-m64', '-mx32', '-m32' and '-m16'. Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32, options::OPT_m32, options::OPT_m16); @@ -1455,7 +1476,8 @@ void Driver::setUpResponseFiles(Compilation &C, Command &Cmd) { // capacity if the tool does not support response files, there is a chance/ // that things will just work without a response file, so we silently just // skip it. - if (Cmd.getCreator().getResponseFilesSupport() == Tool::RF_None || + if (Cmd.getResponseFileSupport().ResponseKind == + ResponseFileSupport::RF_None || llvm::sys::commandLineFitsWithinSystemLimits(Cmd.getExecutable(), Cmd.getArguments())) return; @@ -2325,8 +2347,11 @@ class OffloadingActionBuilder final { /// Append top level actions generated by the builder. virtual void appendTopLevelActions(ActionList &AL) {} - /// Append linker actions generated by the builder. - virtual void appendLinkActions(ActionList &AL) {} + /// Append linker device actions generated by the builder. + virtual void appendLinkDeviceActions(ActionList &AL) {} + + /// Append linker host action generated by the builder. + virtual Action* appendLinkHostActions(ActionList &AL) { return nullptr; } /// Append linker actions generated by the builder. virtual void appendLinkDependences(OffloadAction::DeviceDependences &DA) {} @@ -2796,17 +2821,45 @@ class OffloadingActionBuilder final { : ABRT_Success; } - void appendLinkDependences(OffloadAction::DeviceDependences &DA) override { + void appendLinkDeviceActions(ActionList &AL) override { + if (DeviceLinkerInputs.size() == 0) + return; + + assert(DeviceLinkerInputs.size() == GpuArchList.size() && + "Linker inputs and GPU arch list sizes do not match."); + // Append a new link action for each device. unsigned I = 0; for (auto &LI : DeviceLinkerInputs) { + // Each entry in DeviceLinkerInputs corresponds to a GPU arch. auto *DeviceLinkAction = C.MakeAction(LI, types::TY_Image); - DA.add(*DeviceLinkAction, *ToolChains[0], - CudaArchToString(GpuArchList[I]), AssociatedOffloadKind); + // Linking all inputs for the current GPU arch. + // LI contains all the inputs for the linker. + OffloadAction::DeviceDependences DeviceLinkDeps; + DeviceLinkDeps.add(*DeviceLinkAction, *ToolChains[0], + CudaArchToString(GpuArchList[I]), AssociatedOffloadKind); + AL.push_back(C.MakeAction(DeviceLinkDeps, + DeviceLinkAction->getType())); ++I; } + DeviceLinkerInputs.clear(); + + // Create a host object from all the device images by embedding them + // in a fat binary. + OffloadAction::DeviceDependences DDeps; + auto *TopDeviceLinkAction = + C.MakeAction(AL, types::TY_Object); + DDeps.add(*TopDeviceLinkAction, *ToolChains[0], + nullptr, AssociatedOffloadKind); + + // Offload the host object to the host linker. + AL.push_back(C.MakeAction(DDeps, TopDeviceLinkAction->getType())); } + + Action* appendLinkHostActions(ActionList &AL) override { return AL.back(); } + + void appendLinkDependences(OffloadAction::DeviceDependences &DA) override {} }; /// OpenMP action builder. The host bitcode is passed to the device frontend @@ -2934,7 +2987,7 @@ class OffloadingActionBuilder final { OpenMPDeviceActions.clear(); } - void appendLinkActions(ActionList &AL) override { + void appendLinkDeviceActions(ActionList &AL) override { assert(ToolChains.size() == DeviceLinkerInputs.size() && "Toolchains and linker inputs sizes do not match."); @@ -2953,6 +3006,14 @@ class OffloadingActionBuilder final { DeviceLinkerInputs.clear(); } + Action* appendLinkHostActions(ActionList &AL) override { + // Create wrapper bitcode from the result of device link actions and compile + // it to an object which will be added to the host link command. + auto *BC = C.MakeAction(AL, types::TY_LLVM_BC); + auto *ASM = C.MakeAction(BC, types::TY_PP_Asm); + return C.MakeAction(ASM, types::TY_Object); + } + void appendLinkDependences(OffloadAction::DeviceDependences &DA) override {} bool initialize() override { @@ -3185,17 +3246,20 @@ class OffloadingActionBuilder final { for (DeviceActionBuilder *SB : SpecializedBuilders) { if (!SB->isValid()) continue; - SB->appendLinkActions(DeviceAL); + SB->appendLinkDeviceActions(DeviceAL); } if (DeviceAL.empty()) return nullptr; - // Create wrapper bitcode from the result of device link actions and compile - // it to an object which will be added to the host link command. - auto *BC = C.MakeAction(DeviceAL, types::TY_LLVM_BC); - auto *ASM = C.MakeAction(BC, types::TY_PP_Asm); - return C.MakeAction(ASM, types::TY_Object); + // Let builders add host linking actions. + Action* HA; + for (DeviceActionBuilder *SB : SpecializedBuilders) { + if (!SB->isValid()) + continue; + HA = SB->appendLinkHostActions(DeviceAL); + } + return HA; } /// Processes the host linker action. This currently consists of replacing it @@ -3500,7 +3564,13 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args, if (!LinkerInputs.empty()) { if (Action *Wrapper = OffloadBuilder.makeHostLinkAction()) LinkerInputs.push_back(Wrapper); - Action *LA = C.MakeAction(LinkerInputs, types::TY_Image); + Action *LA; + // Check if this Linker Job should emit a static library. + if (ShouldEmitStaticLibrary(Args)) { + LA = C.MakeAction(LinkerInputs, types::TY_Image); + } else { + LA = C.MakeAction(LinkerInputs, types::TY_Image); + } LA = OffloadBuilder.processHostLinkAction(LA); Actions.push_back(LA); } @@ -4717,13 +4787,11 @@ void Driver::generatePrefixedToolNames( } static bool ScanDirForExecutable(SmallString<128> &Dir, - ArrayRef Names) { - for (const auto &Name : Names) { - llvm::sys::path::append(Dir, Name); - if (llvm::sys::fs::can_execute(Twine(Dir))) - return true; - llvm::sys::path::remove_filename(Dir); - } + const std::string &Name) { + llvm::sys::path::append(Dir, Name); + if (llvm::sys::fs::can_execute(Twine(Dir))) + return true; + llvm::sys::path::remove_filename(Dir); return false; } @@ -4736,8 +4804,9 @@ std::string Driver::GetProgramPath(StringRef Name, const ToolChain &TC) const { for (const auto &PrefixDir : PrefixDirs) { if (llvm::sys::fs::is_directory(PrefixDir)) { SmallString<128> P(PrefixDir); - if (ScanDirForExecutable(P, TargetSpecificExecutables)) - return std::string(P.str()); + for (const auto &TargetSpecificExecutable : TargetSpecificExecutables) + if (ScanDirForExecutable(P, TargetSpecificExecutable)) + return std::string(P.str()); } else { SmallString<128> P((PrefixDir + Name).str()); if (llvm::sys::fs::can_execute(Twine(P))) @@ -4746,17 +4815,25 @@ std::string Driver::GetProgramPath(StringRef Name, const ToolChain &TC) const { } const ToolChain::path_list &List = TC.getProgramPaths(); - for (const auto &Path : List) { - SmallString<128> P(Path); - if (ScanDirForExecutable(P, TargetSpecificExecutables)) - return std::string(P.str()); - } + for (const auto &TargetSpecificExecutable : TargetSpecificExecutables) { + // For each possible name of the tool look for it in + // program paths first, then the path. + // Higher priority names will be first, meaning that + // a higher priority name in the path will be found + // instead of a lower priority name in the program path. + // E.g. -gcc on the path will be found instead + // of gcc in the program path + for (const auto &Path : List) { + SmallString<128> P(Path); + if (ScanDirForExecutable(P, TargetSpecificExecutable)) + return std::string(P.str()); + } - // If all else failed, search the path. - for (const auto &TargetSpecificExecutable : TargetSpecificExecutables) + // Fall back to the path if (llvm::ErrorOr P = llvm::sys::findProgramByName(TargetSpecificExecutable)) return *P; + } return std::string(Name); } @@ -4859,6 +4936,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, Target.getArch() == llvm::Triple::ppc64le) TC = std::make_unique(*this, Target, Args); + else if (Target.getArch() == llvm::Triple::ve) + TC = std::make_unique(*this, Target, Args); + else TC = std::make_unique(*this, Target, Args); break; @@ -4951,6 +5031,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, case llvm::Triple::riscv64: TC = std::make_unique(*this, Target, Args); break; + case llvm::Triple::ve: + TC = std::make_unique(*this, Target, Args); + break; default: if (Target.getVendor() == llvm::Triple::Myriad) TC = std::make_unique(*this, Target, @@ -5002,6 +5085,13 @@ bool Driver::ShouldUseFlangCompiler(const JobAction &JA) const { return true; } +bool Driver::ShouldEmitStaticLibrary(const ArgList &Args) const { + // Only emit static library if the flag is set explicitly. + if (Args.hasArg(options::OPT_emit_static_lib)) + return true; + return false; +} + /// GetReleaseVersion - Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and return the /// grouped values as integers. Numbers which are not provided are set to 0. /// diff --git a/clang/lib/Driver/Job.cpp b/clang/lib/Driver/Job.cpp index 274bda9dc9f16..4808a9f4628d5 100644 --- a/clang/lib/Driver/Job.cpp +++ b/clang/lib/Driver/Job.cpp @@ -36,11 +36,11 @@ using namespace clang; using namespace driver; Command::Command(const Action &Source, const Tool &Creator, - const char *Executable, + ResponseFileSupport ResponseSupport, const char *Executable, const llvm::opt::ArgStringList &Arguments, ArrayRef Inputs) - : Source(Source), Creator(Creator), Executable(Executable), - Arguments(Arguments) { + : Source(Source), Creator(Creator), ResponseSupport(ResponseSupport), + Executable(Executable), Arguments(Arguments) { for (const auto &II : Inputs) if (II.isFilename()) InputFilenames.push_back(II.getFilename()); @@ -102,7 +102,7 @@ static bool skipArgs(const char *Flag, bool HaveCrashVFS, int &SkipNum, void Command::writeResponseFile(raw_ostream &OS) const { // In a file list, we only write the set of inputs to the response file - if (Creator.getResponseFilesSupport() == Tool::RF_FileList) { + if (ResponseSupport.ResponseKind == ResponseFileSupport::RF_FileList) { for (const auto *Arg : InputFileList) { OS << Arg << '\n'; } @@ -131,7 +131,7 @@ void Command::buildArgvForResponseFile( // When not a file list, all arguments are sent to the response file. // This leaves us to set the argv to a single parameter, requesting the tool // to read the response file. - if (Creator.getResponseFilesSupport() != Tool::RF_FileList) { + if (ResponseSupport.ResponseKind != ResponseFileSupport::RF_FileList) { Out.push_back(Executable); Out.push_back(ResponseFileFlag.c_str()); return; @@ -149,7 +149,7 @@ void Command::buildArgvForResponseFile( Out.push_back(Arg); } else if (FirstInput) { FirstInput = false; - Out.push_back(Creator.getResponseFileFlag()); + Out.push_back(ResponseSupport.ResponseFlag); Out.push_back(ResponseFile); } } @@ -277,7 +277,7 @@ void Command::Print(raw_ostream &OS, const char *Terminator, bool Quote, writeResponseFile(OS); // Avoiding duplicated newline terminator, since FileLists are // newline-separated. - if (Creator.getResponseFilesSupport() != Tool::RF_FileList) + if (ResponseSupport.ResponseKind != ResponseFileSupport::RF_FileList) OS << "\n"; OS << " (end of response file)"; } @@ -287,7 +287,7 @@ void Command::Print(raw_ostream &OS, const char *Terminator, bool Quote, void Command::setResponseFile(const char *FileName) { ResponseFile = FileName; - ResponseFileFlag = Creator.getResponseFileFlag(); + ResponseFileFlag = ResponseSupport.ResponseFlag; ResponseFileFlag += FileName; } @@ -327,7 +327,7 @@ int Command::Execute(ArrayRef> Redirects, // Save the response file in the appropriate encoding if (std::error_code EC = writeFileWithEncoding( - ResponseFile, RespContents, Creator.getResponseFileEncoding())) { + ResponseFile, RespContents, ResponseSupport.ResponseEncoding)) { if (ErrMsg) *ErrMsg = EC.message(); if (ExecutionFailed) @@ -354,10 +354,11 @@ int Command::Execute(ArrayRef> Redirects, } CC1Command::CC1Command(const Action &Source, const Tool &Creator, + ResponseFileSupport ResponseSupport, const char *Executable, const llvm::opt::ArgStringList &Arguments, ArrayRef Inputs) - : Command(Source, Creator, Executable, Arguments, Inputs) { + : Command(Source, Creator, ResponseSupport, Executable, Arguments, Inputs) { InProcess = true; } @@ -410,11 +411,13 @@ void CC1Command::setEnvironment(llvm::ArrayRef NewEnvironment) { } FallbackCommand::FallbackCommand(const Action &Source_, const Tool &Creator_, + ResponseFileSupport ResponseSupport, const char *Executable_, const llvm::opt::ArgStringList &Arguments_, ArrayRef Inputs, std::unique_ptr Fallback_) - : Command(Source_, Creator_, Executable_, Arguments_, Inputs), + : Command(Source_, Creator_, ResponseSupport, Executable_, Arguments_, + Inputs), Fallback(std::move(Fallback_)) {} void FallbackCommand::Print(raw_ostream &OS, const char *Terminator, @@ -451,9 +454,11 @@ int FallbackCommand::Execute(ArrayRef> Redirects, } ForceSuccessCommand::ForceSuccessCommand( - const Action &Source_, const Tool &Creator_, const char *Executable_, + const Action &Source_, const Tool &Creator_, + ResponseFileSupport ResponseSupport, const char *Executable_, const llvm::opt::ArgStringList &Arguments_, ArrayRef Inputs) - : Command(Source_, Creator_, Executable_, Arguments_, Inputs) {} + : Command(Source_, Creator_, ResponseSupport, Executable_, Arguments_, + Inputs) {} void ForceSuccessCommand::Print(raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo) const { diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index 9d307e8097cbc..0b81152d57f6b 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -1068,7 +1068,7 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, CmdArgs.push_back(Args.MakeArgString("hwasan-abi=" + HwasanAbi)); } - if (Sanitizers.has(SanitizerKind::HWAddress)) { + if (Sanitizers.has(SanitizerKind::HWAddress) && TC.getTriple().isAArch64()) { CmdArgs.push_back("-target-feature"); CmdArgs.push_back("+tagged-globals"); } diff --git a/clang/lib/Driver/Tool.cpp b/clang/lib/Driver/Tool.cpp index 9ff6e863a1242..449f69cfcb357 100644 --- a/clang/lib/Driver/Tool.cpp +++ b/clang/lib/Driver/Tool.cpp @@ -11,13 +11,8 @@ using namespace clang::driver; -Tool::Tool(const char *_Name, const char *_ShortName, const ToolChain &TC, - ResponseFileSupport _ResponseSupport, - llvm::sys::WindowsEncodingMethod _ResponseEncoding, - const char *_ResponseFlag) - : Name(_Name), ShortName(_ShortName), TheToolChain(TC), - ResponseSupport(_ResponseSupport), ResponseEncoding(_ResponseEncoding), - ResponseFlag(_ResponseFlag) {} +Tool::Tool(const char *_Name, const char *_ShortName, const ToolChain &TC) + : Name(_Name), ShortName(_ShortName), TheToolChain(TC) {} Tool::~Tool() { } diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index c21bc0dc2a799..b8c12fc9241a6 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -275,6 +275,10 @@ Tool *ToolChain::buildLinker() const { llvm_unreachable("Linking is not supported by this toolchain"); } +Tool *ToolChain::buildStaticLibTool() const { + llvm_unreachable("Creating static lib is not supported by this toolchain"); +} + Tool *ToolChain::getAssemble() const { if (!Assemble) Assemble.reset(buildAssembler()); @@ -293,6 +297,12 @@ Tool *ToolChain::getLink() const { return Link.get(); } +Tool *ToolChain::getStaticLibTool() const { + if (!StaticLibTool) + StaticLibTool.reset(buildStaticLibTool()); + return StaticLibTool.get(); +} + Tool *ToolChain::getIfsMerge() const { if (!IfsMerge) IfsMerge.reset(new tools::ifstool::Merger(*this)); @@ -322,6 +332,9 @@ Tool *ToolChain::getTool(Action::ActionClass AC) const { case Action::LinkJobClass: return getLink(); + case Action::StaticLibJobClass: + return getStaticLibTool(); + case Action::InputClass: case Action::BindArchClass: case Action::OffloadClass: @@ -565,6 +578,11 @@ std::string ToolChain::GetLinkerPath() const { return GetProgramPath(getDefaultLinker()); } +std::string ToolChain::GetStaticLibToolPath() const { + // TODO: Add support for static lib archiving on Windows + return GetProgramPath("llvm-ar"); +} + types::ID ToolChain::LookupTypeForExtension(StringRef Ext) const { types::ID id = types::lookupTypeForExtension(Ext); diff --git a/clang/lib/Driver/ToolChains/AIX.cpp b/clang/lib/Driver/ToolChains/AIX.cpp index df2e30da32a8c..ac5544eedb00b 100644 --- a/clang/lib/Driver/ToolChains/AIX.cpp +++ b/clang/lib/Driver/ToolChains/AIX.cpp @@ -13,12 +13,15 @@ #include "clang/Driver/Options.h" #include "clang/Driver/SanitizerArgs.h" #include "llvm/Option/ArgList.h" +#include "llvm/Support/Path.h" using AIX = clang::driver::toolchains::AIX; using namespace clang::driver; using namespace clang::driver::tools; +using namespace clang::driver::toolchains; using namespace llvm::opt; +using namespace llvm::sys; void aix::Assembler::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, @@ -73,7 +76,8 @@ void aix::Assembler::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(II.getFilename()); const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::None(), + Exec, CmdArgs, Inputs)); } void aix::Linker::ConstructJob(Compilation &C, const JobAction &JA, @@ -152,7 +156,8 @@ void aix::Linker::ConstructJob(Compilation &C, const JobAction &JA, } const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::None(), + Exec, CmdArgs, Inputs)); } /// AIX - AIX tool chain which can call as(1) and ld(1) directly. @@ -161,6 +166,43 @@ AIX::AIX(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) getFilePaths().push_back(getDriver().SysRoot + "/usr/lib"); } +// Returns the effective header sysroot path to use. +// This comes from either -isysroot or --sysroot. +llvm::StringRef +AIX::GetHeaderSysroot(const llvm::opt::ArgList &DriverArgs) const { + if (DriverArgs.hasArg(options::OPT_isysroot)) + return DriverArgs.getLastArgValue(options::OPT_isysroot); + if (!getDriver().SysRoot.empty()) + return getDriver().SysRoot; + return "/"; +} + +void AIX::AddClangSystemIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + // Return if -nostdinc is specified as a driver option. + if (DriverArgs.hasArg(options::OPT_nostdinc)) + return; + + llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs); + const Driver &D = getDriver(); + + // Add the Clang builtin headers (/include). + if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { + SmallString<128> P(D.ResourceDir); + path::append(P, "/include"); + addSystemInclude(DriverArgs, CC1Args, P.str()); + } + + // Return if -nostdlibinc is specified as a driver option. + if (DriverArgs.hasArg(options::OPT_nostdlibinc)) + return; + + // Add /usr/include. + SmallString<128> UP(Sysroot); + path::append(UP, "/usr/include"); + addSystemInclude(DriverArgs, CC1Args, UP.str()); +} + auto AIX::buildAssembler() const -> Tool * { return new aix::Assembler(*this); } auto AIX::buildLinker() const -> Tool * { return new aix::Linker(*this); } diff --git a/clang/lib/Driver/ToolChains/AIX.h b/clang/lib/Driver/ToolChains/AIX.h index 69b948bc0ea82..942bb3cceb8a7 100644 --- a/clang/lib/Driver/ToolChains/AIX.h +++ b/clang/lib/Driver/ToolChains/AIX.h @@ -63,9 +63,16 @@ class LLVM_LIBRARY_VISIBILITY AIX : public ToolChain { bool isPIEDefault() const override { return false; } bool isPICDefaultForced() const override { return true; } + void + AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; + protected: Tool *buildAssembler() const override; Tool *buildLinker() const override; + +private: + llvm::StringRef GetHeaderSysroot(const llvm::opt::ArgList &DriverArgs) const; }; } // end namespace toolchains diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp index edc52b86e45a9..bc6d1fcd4a008 100644 --- a/clang/lib/Driver/ToolChains/AMDGPU.cpp +++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp @@ -21,16 +21,14 @@ using namespace clang::driver::toolchains; using namespace clang; using namespace llvm::opt; -void RocmInstallationDetector::scanLibDevicePath() { - assert(!LibDevicePath.empty()); +void RocmInstallationDetector::scanLibDevicePath(llvm::StringRef Path) { + assert(!Path.empty()); const StringRef Suffix(".bc"); const StringRef Suffix2(".amdgcn.bc"); std::error_code EC; - for (llvm::vfs::directory_iterator - LI = D.getVFS().dir_begin(LibDevicePath, EC), - LE; + for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin(Path, EC), LE; !EC && LI != LE; LI = LI.increment(EC)) { StringRef FilePath = LI->path(); StringRef FileName = llvm::sys::path::filename(FilePath); @@ -89,60 +87,114 @@ void RocmInstallationDetector::scanLibDevicePath() { } } -RocmInstallationDetector::RocmInstallationDetector( - const Driver &D, const llvm::Triple &HostTriple, - const llvm::opt::ArgList &Args) - : D(D) { - struct Candidate { - std::string Path; - bool StrictChecking; - - Candidate(std::string Path, bool StrictChecking = false) - : Path(Path), StrictChecking(StrictChecking) {} - }; +void RocmInstallationDetector::ParseHIPVersionFile(llvm::StringRef V) { + SmallVector VersionParts; + V.split(VersionParts, '\n'); + unsigned Major; + unsigned Minor; + for (auto Part : VersionParts) { + auto Splits = Part.split('='); + if (Splits.first == "HIP_VERSION_MAJOR") + Splits.second.getAsInteger(0, Major); + else if (Splits.first == "HIP_VERSION_MINOR") + Splits.second.getAsInteger(0, Minor); + else if (Splits.first == "HIP_VERSION_PATCH") + VersionPatch = Splits.second.str(); + } + VersionMajorMinor = llvm::VersionTuple(Major, Minor); + DetectedVersion = + (Twine(Major) + "." + Twine(Minor) + "." + VersionPatch).str(); +} +// For candidate specified by --rocm-path we do not do strict check. +SmallVector +RocmInstallationDetector::getInstallationPathCandidates() { SmallVector Candidates; + if (!RocmPathArg.empty()) { + Candidates.emplace_back(RocmPathArg.str()); + return Candidates; + } - if (Args.hasArg(clang::driver::options::OPT_rocm_path_EQ)) { - Candidates.emplace_back( - Args.getLastArgValue(clang::driver::options::OPT_rocm_path_EQ).str()); - } else { - // Try to find relative to the compiler binary. - const char *InstallDir = D.getInstalledDir(); + // Try to find relative to the compiler binary. + const char *InstallDir = D.getInstalledDir(); - // Check both a normal Unix prefix position of the clang binary, as well as - // the Windows-esque layout the ROCm packages use with the host architecture - // subdirectory of bin. + // Check both a normal Unix prefix position of the clang binary, as well as + // the Windows-esque layout the ROCm packages use with the host architecture + // subdirectory of bin. - // Strip off directory (usually bin) - StringRef ParentDir = llvm::sys::path::parent_path(InstallDir); - StringRef ParentName = llvm::sys::path::filename(ParentDir); + // Strip off directory (usually bin) + StringRef ParentDir = llvm::sys::path::parent_path(InstallDir); + StringRef ParentName = llvm::sys::path::filename(ParentDir); - // Some builds use bin/{host arch}, so go up again. - if (ParentName == "bin") { - ParentDir = llvm::sys::path::parent_path(ParentDir); - ParentName = llvm::sys::path::filename(ParentDir); - } + // Some builds use bin/{host arch}, so go up again. + if (ParentName == "bin") { + ParentDir = llvm::sys::path::parent_path(ParentDir); + ParentName = llvm::sys::path::filename(ParentDir); + } - if (ParentName == "llvm") { - // Some versions of the rocm llvm package install to /opt/rocm/llvm/bin - Candidates.emplace_back(llvm::sys::path::parent_path(ParentDir).str(), - /*StrictChecking=*/true); - } + // Some versions of the rocm llvm package install to /opt/rocm/llvm/bin + if (ParentName == "llvm") + ParentDir = llvm::sys::path::parent_path(ParentDir); + + Candidates.emplace_back(ParentDir.str(), /*StrictChecking=*/true); + + // Device library may be installed in clang resource directory. + Candidates.emplace_back(D.ResourceDir, /*StrictChecking=*/true); + + Candidates.emplace_back(D.SysRoot + "/opt/rocm", /*StrictChecking=*/true); + return Candidates; +} - Candidates.emplace_back(D.SysRoot + "/opt/rocm"); +RocmInstallationDetector::RocmInstallationDetector( + const Driver &D, const llvm::Triple &HostTriple, + const llvm::opt::ArgList &Args, bool DetectHIPRuntime, bool DetectDeviceLib) + : D(D) { + RocmPathArg = Args.getLastArgValue(clang::driver::options::OPT_rocm_path_EQ); + RocmDeviceLibPathArg = + Args.getAllArgValues(clang::driver::options::OPT_rocm_device_lib_path_EQ); + if (auto *A = Args.getLastArg(clang::driver::options::OPT_hip_version_EQ)) { + HIPVersionArg = A->getValue(); + unsigned Major = 0; + unsigned Minor = 0; + SmallVector Parts; + HIPVersionArg.split(Parts, '.'); + if (Parts.size()) + Parts[0].getAsInteger(0, Major); + if (Parts.size() > 1) + Parts[1].getAsInteger(0, Minor); + if (Parts.size() > 2) + VersionPatch = Parts[2].str(); + if (VersionPatch.empty()) + VersionPatch = "0"; + if (Major == 0 || Minor == 0) + D.Diag(diag::err_drv_invalid_value) + << A->getAsString(Args) << HIPVersionArg; + + VersionMajorMinor = llvm::VersionTuple(Major, Minor); + DetectedVersion = + (Twine(Major) + "." + Twine(Minor) + "." + VersionPatch).str(); + } else { + VersionPatch = DefaultVersionPatch; + VersionMajorMinor = + llvm::VersionTuple(DefaultVersionMajor, DefaultVersionMinor); + DetectedVersion = (Twine(DefaultVersionMajor) + "." + + Twine(DefaultVersionMinor) + "." + VersionPatch) + .str(); } - bool NoBuiltinLibs = Args.hasArg(options::OPT_nogpulib); + if (DetectHIPRuntime) + detectHIPRuntime(); + if (DetectDeviceLib) + detectDeviceLibrary(); +} +void RocmInstallationDetector::detectDeviceLibrary() { assert(LibDevicePath.empty()); - if (Args.hasArg(clang::driver::options::OPT_hip_device_lib_path_EQ)) { - LibDevicePath - = Args.getLastArgValue(clang::driver::options::OPT_hip_device_lib_path_EQ); - } else if (const char *LibPathEnv = ::getenv("HIP_DEVICE_LIB_PATH")) { + if (!RocmDeviceLibPathArg.empty()) + LibDevicePath = RocmDeviceLibPathArg[RocmDeviceLibPathArg.size() - 1]; + else if (const char *LibPathEnv = ::getenv("HIP_DEVICE_LIB_PATH")) LibDevicePath = LibPathEnv; - } auto &FS = D.getVFS(); if (!LibDevicePath.empty()) { @@ -152,61 +204,109 @@ RocmInstallationDetector::RocmInstallationDetector( if (!FS.exists(LibDevicePath)) return; - scanLibDevicePath(); - IsValid = allGenericLibsValid() && !LibDeviceMap.empty(); + scanLibDevicePath(LibDevicePath); + HasDeviceLibrary = allGenericLibsValid() && !LibDeviceMap.empty(); return; } + // The install path situation in old versions of ROCm is a real mess, and + // use a different install layout. Multiple copies of the device libraries + // exist for each frontend project, and differ depending on which build + // system produced the packages. Standalone OpenCL builds also have a + // different directory structure from the ROCm OpenCL package. + auto Candidates = getInstallationPathCandidates(); + for (const auto &Candidate : Candidates) { + auto CandidatePath = Candidate.Path; + + // Check device library exists at the given path. + auto CheckDeviceLib = [&](StringRef Path) { + bool CheckLibDevice = (!NoBuiltinLibs || Candidate.StrictChecking); + if (CheckLibDevice && !FS.exists(Path)) + return false; + + scanLibDevicePath(Path); + + if (!NoBuiltinLibs) { + // Check that the required non-target libraries are all available. + if (!allGenericLibsValid()) + return false; + + // Check that we have found at least one libdevice that we can link in + // if -nobuiltinlib hasn't been specified. + if (LibDeviceMap.empty()) + return false; + } + return true; + }; + + // The possible structures are: + // - ${ROCM_ROOT}/amdgcn/bitcode/* + // - ${ROCM_ROOT}/lib/* + // - ${ROCM_ROOT}/lib/bitcode/* + // so try to detect these layouts. + static llvm::SmallVector SubDirsList[] = { + {"amdgcn", "bitcode"}, + {"lib"}, + {"lib", "bitcode"}, + }; + + // Make a path by appending sub-directories to InstallPath. + auto MakePath = [&](const llvm::ArrayRef &SubDirs) { + auto Path = CandidatePath; + for (auto SubDir : SubDirs) + llvm::sys::path::append(Path, SubDir); + return Path; + }; + + for (auto SubDirs : SubDirsList) { + LibDevicePath = MakePath(SubDirs); + HasDeviceLibrary = CheckDeviceLib(LibDevicePath); + if (HasDeviceLibrary) + return; + } + } +} + +void RocmInstallationDetector::detectHIPRuntime() { + auto Candidates = getInstallationPathCandidates(); + auto &FS = D.getVFS(); + for (const auto &Candidate : Candidates) { InstallPath = Candidate.Path; if (InstallPath.empty() || !FS.exists(InstallPath)) continue; - // The install path situation in old versions of ROCm is a real mess, and - // use a different install layout. Multiple copies of the device libraries - // exist for each frontend project, and differ depending on which build - // system produced the packages. Standalone OpenCL builds also have a - // different directory structure from the ROCm OpenCL package. - // - // The desired structure is (${ROCM_ROOT} or - // ${OPENCL_ROOT})/amdgcn/bitcode/*, so try to detect this layout. - - // BinPath = InstallPath + "/bin"; - llvm::sys::path::append(IncludePath, InstallPath, "include"); - llvm::sys::path::append(LibDevicePath, InstallPath, "amdgcn", "bitcode"); + BinPath = InstallPath; + llvm::sys::path::append(BinPath, "bin"); + IncludePath = InstallPath; + llvm::sys::path::append(IncludePath, "include"); + LibPath = InstallPath; + llvm::sys::path::append(LibPath, "lib"); - // We don't need the include path for OpenCL, since clang already ships with - // the default header. - - bool CheckLibDevice = (!NoBuiltinLibs || Candidate.StrictChecking); - if (CheckLibDevice && !FS.exists(LibDevicePath)) + llvm::ErrorOr> VersionFile = + FS.getBufferForFile(BinPath + "/.hipVersion"); + if (!VersionFile && Candidate.StrictChecking) continue; - scanLibDevicePath(); - - if (!NoBuiltinLibs) { - // Check that the required non-target libraries are all available. - if (!allGenericLibsValid()) - continue; - - // Check that we have found at least one libdevice that we can link in if - // -nobuiltinlib hasn't been specified. - if (LibDeviceMap.empty()) - continue; - } + if (HIPVersionArg.empty() && VersionFile) + ParseHIPVersionFile((*VersionFile)->getBuffer()); - IsValid = true; - break; + HasHIPRuntime = true; + return; } + HasHIPRuntime = false; } void RocmInstallationDetector::print(raw_ostream &OS) const { - if (isValid()) - OS << "Found ROCm installation: " << InstallPath << '\n'; + if (hasHIPRuntime()) + OS << "Found HIP installation: " << InstallPath << ", version " + << DetectedVersion << '\n'; } void RocmInstallationDetector::AddHIPIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { + bool UsesRuntimeWrapper = VersionMajorMinor > llvm::VersionTuple(3, 5); + if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { // HIP header includes standard library wrapper headers under clang // cuda_wrappers directory. Since these wrapper headers include_next @@ -218,25 +318,28 @@ void RocmInstallationDetector::AddHIPIncludeArgs(const ArgList &DriverArgs, // Since standard C++ and other clang include paths are added in other // places after this function, here we only need to make sure wrapper // include path is added. + // + // ROCm 3.5 does not fully support the wrapper headers. Therefore it needs + // a workaround. SmallString<128> P(D.ResourceDir); - llvm::sys::path::append(P, "include"); - llvm::sys::path::append(P, "cuda_wrappers"); + if (UsesRuntimeWrapper) + llvm::sys::path::append(P, "include", "cuda_wrappers"); CC1Args.push_back("-internal-isystem"); CC1Args.push_back(DriverArgs.MakeArgString(P)); - CC1Args.push_back("-include"); - CC1Args.push_back("__clang_hip_runtime_wrapper.h"); } if (DriverArgs.hasArg(options::OPT_nogpuinc)) return; - if (!isValid()) { - D.Diag(diag::err_drv_no_rocm_installation); + if (!hasHIPRuntime()) { + D.Diag(diag::err_drv_no_hip_runtime); return; } CC1Args.push_back("-internal-isystem"); CC1Args.push_back(DriverArgs.MakeArgString(getIncludePath())); + if (UsesRuntimeWrapper) + CC1Args.append({"-include", "__clang_hip_runtime_wrapper.h"}); } void amdgpu::Linker::ConstructJob(Compilation &C, const JobAction &JA, @@ -251,8 +354,9 @@ void amdgpu::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-shared"); CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); - C.addCommand(std::make_unique(JA, *this, Args.MakeArgString(Linker), - CmdArgs, Inputs)); + C.addCommand( + std::make_unique(JA, *this, ResponseFileSupport::AtFileCurCP(), + Args.MakeArgString(Linker), CmdArgs, Inputs)); } void amdgpu::getAMDGPUTargetFeatures(const Driver &D, @@ -385,8 +489,9 @@ bool AMDGPUToolChain::isWave64(const llvm::opt::ArgList &DriverArgs, /// ROCM Toolchain ROCMToolChain::ROCMToolChain(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) - : AMDGPUToolChain(D, Triple, Args), - RocmInstallation(D, Triple, Args) { } + : AMDGPUToolChain(D, Triple, Args) { + RocmInstallation.detectDeviceLibrary(); +} void AMDGPUToolChain::addClangTargetOptions( const llvm::opt::ArgList &DriverArgs, @@ -417,8 +522,8 @@ void ROCMToolChain::addClangTargetOptions( if (DriverArgs.hasArg(options::OPT_nogpulib)) return; - if (!RocmInstallation.isValid()) { - getDriver().Diag(diag::err_drv_no_rocm_installation); + if (!RocmInstallation.hasDeviceLibrary()) { + getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 0; return; } @@ -428,7 +533,7 @@ void ROCMToolChain::addClangTargetOptions( const StringRef CanonArch = llvm::AMDGPU::getArchNameAMDGCN(Kind); std::string LibDeviceFile = RocmInstallation.getLibDeviceFile(CanonArch); if (LibDeviceFile.empty()) { - getDriver().Diag(diag::err_drv_no_rocm_device_lib) << GpuArch; + getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 1 << GpuArch; return; } diff --git a/clang/lib/Driver/ToolChains/AMDGPU.h b/clang/lib/Driver/ToolChains/AMDGPU.h index 671a987bf9fc2..5d44faf28b053 100644 --- a/clang/lib/Driver/ToolChains/AMDGPU.h +++ b/clang/lib/Driver/ToolChains/AMDGPU.h @@ -25,9 +25,9 @@ namespace driver { namespace tools { namespace amdgpu { -class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Linker : public Tool { public: - Linker(const ToolChain &TC) : GnuTool("amdgpu::Linker", "ld.lld", TC) {} + Linker(const ToolChain &TC) : Tool("amdgpu::Linker", "ld.lld", TC) {} bool isLinkJob() const override { return true; } bool hasIntegratedCPP() const override { return false; } void ConstructJob(Compilation &C, const JobAction &JA, @@ -85,12 +85,11 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUToolChain : public Generic_ELF { return true; } + /// Needed for translating LTO options. + const char *getDefaultLinker() const override { return "ld.lld"; } }; class LLVM_LIBRARY_VISIBILITY ROCMToolChain : public AMDGPUToolChain { -protected: - RocmInstallationDetector RocmInstallation; - public: ROCMToolChain(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args); diff --git a/clang/lib/Driver/ToolChains/AVR.cpp b/clang/lib/Driver/ToolChains/AVR.cpp index a86d6fa9f3572..092bade53c635 100644 --- a/clang/lib/Driver/ToolChains/AVR.cpp +++ b/clang/lib/Driver/ToolChains/AVR.cpp @@ -118,13 +118,6 @@ void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA, Args.AddAllArgs(CmdArgs, options::OPT_L); getToolChain().AddFilePathLibArgs(Args, CmdArgs); - // "Not [sic] that addr must be offset by adding 0x800000 the to - // real SRAM address so that the linker knows that the address - // is in the SRAM memory space." - // - // - https://www.nongnu.org/avr-libc/user-manual/mem_sections.html - CmdArgs.push_back("-Tdata=0x800100"); - // If the family name is known, we can link with the device-specific libgcc. // Without it, libgcc will simply not be linked. This matches avr-gcc // behavior. @@ -149,8 +142,9 @@ void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName)); } - C.addCommand(std::make_unique(JA, *this, Args.MakeArgString(Linker), - CmdArgs, Inputs)); + C.addCommand( + std::make_unique(JA, *this, ResponseFileSupport::AtFileCurCP(), + Args.MakeArgString(Linker), CmdArgs, Inputs)); } llvm::Optional AVRToolChain::findAVRLibcInstallation() const { diff --git a/clang/lib/Driver/ToolChains/AVR.h b/clang/lib/Driver/ToolChains/AVR.h index d244fc4f90e90..a3198b2495803 100644 --- a/clang/lib/Driver/ToolChains/AVR.h +++ b/clang/lib/Driver/ToolChains/AVR.h @@ -40,10 +40,10 @@ class LLVM_LIBRARY_VISIBILITY AVRToolChain : public Generic_ELF { namespace tools { namespace AVR { -class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Linker : public Tool { public: Linker(const llvm::Triple &Triple, const ToolChain &TC, bool LinkStdlib) - : GnuTool("AVR::Linker", "avr-ld", TC), Triple(Triple), + : Tool("AVR::Linker", "avr-ld", TC), Triple(Triple), LinkStdlib(LinkStdlib) {} bool hasIntegratedCPP() const override { return false; } diff --git a/clang/lib/Driver/ToolChains/Ananas.cpp b/clang/lib/Driver/ToolChains/Ananas.cpp index 10e4ea70db41d..a4141a57acccb 100644 --- a/clang/lib/Driver/ToolChains/Ananas.cpp +++ b/clang/lib/Driver/ToolChains/Ananas.cpp @@ -39,7 +39,8 @@ void ananas::Assembler::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(II.getFilename()); const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); } void ananas::Linker::ConstructJob(Compilation &C, const JobAction &JA, @@ -123,7 +124,8 @@ void ananas::Linker::ConstructJob(Compilation &C, const JobAction &JA, } const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); } // Ananas - Ananas tool chain which can call as(1) and ld(1) directly. diff --git a/clang/lib/Driver/ToolChains/Ananas.h b/clang/lib/Driver/ToolChains/Ananas.h index 5e45b47fc1083..72ad3edcf0567 100644 --- a/clang/lib/Driver/ToolChains/Ananas.h +++ b/clang/lib/Driver/ToolChains/Ananas.h @@ -19,10 +19,9 @@ namespace tools { /// ananas -- Directly call GNU Binutils assembler and linker namespace ananas { -class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Assembler : public Tool { public: - Assembler(const ToolChain &TC) - : GnuTool("ananas::Assembler", "assembler", TC) {} + Assembler(const ToolChain &TC) : Tool("ananas::Assembler", "assembler", TC) {} bool hasIntegratedCPP() const override { return false; } @@ -32,9 +31,9 @@ class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { const char *LinkingOutput) const override; }; -class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Linker : public Tool { public: - Linker(const ToolChain &TC) : GnuTool("ananas::Linker", "linker", TC) {} + Linker(const ToolChain &TC) : Tool("ananas::Linker", "linker", TC) {} bool hasIntegratedCPP() const override { return false; } bool isLinkJob() const override { return true; } diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp index f16827e00f1f8..8659ebf17a722 100644 --- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp +++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -62,6 +62,8 @@ isExperimentalExtension(StringRef Ext) { Ext == "zbf" || Ext == "zbm" || Ext == "zbp" || Ext == "zbr" || Ext == "zbs" || Ext == "zbt" || Ext == "zbproposedc") return RISCVExtensionVersion{"0", "92"}; + if (Ext == "v") + return RISCVExtensionVersion{"0", "8"}; return None; } @@ -399,6 +401,9 @@ static bool getArchFeatures(const Driver &D, StringRef MArch, case 'b': Features.push_back("+experimental-b"); break; + case 'v': + Features.push_back("+experimental-v"); + break; } // Consume full extension name and version, including any optional '_' diff --git a/clang/lib/Driver/ToolChains/Arch/VE.cpp b/clang/lib/Driver/ToolChains/Arch/VE.cpp new file mode 100644 index 0000000000000..fa10e4810f1c9 --- /dev/null +++ b/clang/lib/Driver/ToolChains/Arch/VE.cpp @@ -0,0 +1,26 @@ +//===--- VE.cpp - Tools Implementations -------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "VE.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/DriverDiagnostic.h" +#include "clang/Driver/Options.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Option/ArgList.h" + +using namespace clang::driver; +using namespace clang::driver::tools; +using namespace clang; +using namespace llvm::opt; + +const char *ve::getVEAsmModeForCPU(StringRef Name, const llvm::Triple &Triple) { + return ""; +} + +void ve::getVETargetFeatures(const Driver &D, const ArgList &Args, + std::vector &Features) {} diff --git a/clang/lib/Driver/ToolChains/Arch/VE.h b/clang/lib/Driver/ToolChains/Arch/VE.h new file mode 100644 index 0000000000000..713e3e7d042f2 --- /dev/null +++ b/clang/lib/Driver/ToolChains/Arch/VE.h @@ -0,0 +1,33 @@ +//===--- VE.h - VE-specific Tool Helpers ------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_VE_H +#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_VE_H + +#include "clang/Driver/Driver.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Option/Option.h" +#include +#include + +namespace clang { +namespace driver { +namespace tools { +namespace ve { + +void getVETargetFeatures(const Driver &D, const llvm::opt::ArgList &Args, + std::vector &Features); +const char *getVEAsmModeForCPU(llvm::StringRef Name, + const llvm::Triple &Triple); + +} // end namespace ve +} // namespace tools +} // end namespace driver +} // end namespace clang + +#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_VE_H diff --git a/clang/lib/Driver/ToolChains/Arch/X86.cpp b/clang/lib/Driver/ToolChains/Arch/X86.cpp index dbbc025de38c0..2cc44c09917f5 100644 --- a/clang/lib/Driver/ToolChains/Arch/X86.cpp +++ b/clang/lib/Driver/ToolChains/Arch/X86.cpp @@ -94,6 +94,7 @@ const char *x86::getX86TargetCPU(const ArgList &Args, switch (Triple.getOS()) { case llvm::Triple::FreeBSD: + return "i686"; case llvm::Triple::NetBSD: case llvm::Triple::OpenBSD: return "i486"; @@ -184,6 +185,24 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, LVIOpt = options::OPT_mlvi_cfi; } + if (Args.hasFlag(options::OPT_m_seses, options::OPT_mno_seses, false)) { + if (LVIOpt == options::OPT_mlvi_hardening) + D.Diag(diag::err_drv_argument_not_allowed_with) + << D.getOpts().getOptionName(options::OPT_mlvi_hardening) + << D.getOpts().getOptionName(options::OPT_m_seses); + + if (SpectreOpt != clang::driver::options::ID::OPT_INVALID) + D.Diag(diag::err_drv_argument_not_allowed_with) + << D.getOpts().getOptionName(SpectreOpt) + << D.getOpts().getOptionName(options::OPT_m_seses); + + Features.push_back("+seses"); + if (!Args.hasArg(options::OPT_mno_lvi_cfi)) { + Features.push_back("+lvi-cfi"); + LVIOpt = options::OPT_mlvi_cfi; + } + } + if (SpectreOpt != clang::driver::options::ID::OPT_INVALID && LVIOpt != clang::driver::options::ID::OPT_INVALID) { D.Diag(diag::err_drv_argument_not_allowed_with) diff --git a/clang/lib/Driver/ToolChains/BareMetal.cpp b/clang/lib/Driver/ToolChains/BareMetal.cpp index 95f46b489e469..97cfa7d0e1569 100644 --- a/clang/lib/Driver/ToolChains/BareMetal.cpp +++ b/clang/lib/Driver/ToolChains/BareMetal.cpp @@ -191,7 +191,7 @@ void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); - C.addCommand(std::make_unique(JA, *this, - Args.MakeArgString(TC.GetLinkerPath()), - CmdArgs, Inputs)); + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::None(), + Args.MakeArgString(TC.GetLinkerPath()), + CmdArgs, Inputs)); } diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index aa18727671be0..9d6333bb5f1dd 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -15,6 +15,7 @@ #include "Arch/RISCV.h" #include "Arch/Sparc.h" #include "Arch/SystemZ.h" +#include "Arch/VE.h" #include "Arch/X86.h" #include "CommonArgs.h" #include "Hexagon.h" @@ -368,27 +369,14 @@ static void getTargetFeatures(const Driver &D, const llvm::Triple &Triple, break; case llvm::Triple::msp430: msp430::getMSP430TargetFeatures(D, Args, Features); + break; + case llvm::Triple::ve: + ve::getVETargetFeatures(D, Args, Features); } - // Find the last of each feature. - llvm::StringMap LastOpt; - for (unsigned I = 0, N = Features.size(); I < N; ++I) { - StringRef Name = Features[I]; - assert(Name[0] == '-' || Name[0] == '+'); - LastOpt[Name.drop_front(1)] = I; - } - - for (unsigned I = 0, N = Features.size(); I < N; ++I) { - // If this feature was overridden, ignore it. - StringRef Name = Features[I]; - llvm::StringMap::iterator LastI = LastOpt.find(Name.drop_front(1)); - assert(LastI != LastOpt.end()); - unsigned Last = LastI->second; - if (Last != I) - continue; - + for (auto Feature : unifyTargetFeatures(Features)) { CmdArgs.push_back(IsAux ? "-aux-target-feature" : "-target-feature"); - CmdArgs.push_back(Name.data()); + CmdArgs.push_back(Feature.data()); } } @@ -510,7 +498,7 @@ static codegenoptions::DebugInfoKind DebugLevelToInfoKind(const Arg &A) { return codegenoptions::DebugLineTablesOnly; if (A.getOption().matches(options::OPT_gline_directives_only)) return codegenoptions::DebugDirectivesOnly; - return codegenoptions::LimitedDebugInfo; + return codegenoptions::DebugInfoConstructor; } static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple) { @@ -733,38 +721,6 @@ static void addDashXForInput(const ArgList &Args, const InputInfo &Input, } } -static void appendUserToPath(SmallVectorImpl &Result) { -#ifdef LLVM_ON_UNIX - const char *Username = getenv("LOGNAME"); -#else - const char *Username = getenv("USERNAME"); -#endif - if (Username) { - // Validate that LoginName can be used in a path, and get its length. - size_t Len = 0; - for (const char *P = Username; *P; ++P, ++Len) { - if (!clang::isAlphanumeric(*P) && *P != '_') { - Username = nullptr; - break; - } - } - - if (Username && Len > 0) { - Result.append(Username, Username + Len); - return; - } - } - -// Fallback to user id. -#ifdef LLVM_ON_UNIX - std::string UID = llvm::utostr(getuid()); -#else - // FIXME: Windows seems to have an 'SID' that might work. - std::string UID = "9999"; -#endif - Result.append(UID.begin(), UID.end()); -} - static void addPGOAndCoverageFlags(const ToolChain &TC, Compilation &C, const Driver &D, const InputInfo &Output, const ArgList &Args, @@ -1663,6 +1619,10 @@ void Clang::RenderTargetOptions(const llvm::Triple &EffectiveTriple, case llvm::Triple::wasm64: AddWebAssemblyTargetArgs(Args, CmdArgs); break; + + case llvm::Triple::ve: + AddVETargetArgs(Args, CmdArgs); + break; } } @@ -2160,6 +2120,12 @@ void Clang::AddWebAssemblyTargetArgs(const ArgList &Args, } } +void Clang::AddVETargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const { + // Floating point operations and argument passing are hard. + CmdArgs.push_back("-mfloat-abi"); + CmdArgs.push_back("hard"); +} + void Clang::DumpCompilationDatabase(Compilation &C, StringRef Filename, StringRef Target, const InputInfo &Output, const InputInfo &Input, const ArgList &Args) const { @@ -2414,7 +2380,7 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, CmdArgs.push_back(Value.data()); } else { RenderDebugEnablingArgs(Args, CmdArgs, - codegenoptions::LimitedDebugInfo, + codegenoptions::DebugInfoConstructor, DwarfVersion, llvm::DebuggerKind::Default); } } else if (Value.startswith("-mcpu") || Value.startswith("-mfpu") || @@ -3000,7 +2966,8 @@ static void RenderSCPOptions(const ToolChain &TC, const ArgList &Args, if (!EffectiveTriple.isOSLinux()) return; - if (!EffectiveTriple.isX86() && !EffectiveTriple.isSystemZ()) + if (!EffectiveTriple.isX86() && !EffectiveTriple.isSystemZ() && + !EffectiveTriple.isPPC64()) return; if (Args.hasFlag(options::OPT_fstack_clash_protection, @@ -3203,11 +3170,13 @@ static void RenderBuiltinOptions(const ToolChain &TC, const llvm::Triple &T, CmdArgs.push_back("-fno-math-builtin"); } -void Driver::getDefaultModuleCachePath(SmallVectorImpl &Result) { - llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false, Result); - llvm::sys::path::append(Result, "org.llvm.clang."); - appendUserToPath(Result); - llvm::sys::path::append(Result, "ModuleCache"); +bool Driver::getDefaultModuleCachePath(SmallVectorImpl &Result) { + if (llvm::sys::path::cache_directory(Result)) { + llvm::sys::path::append(Result, "clang"); + llvm::sys::path::append(Result, "ModuleCache"); + return true; + } + return false; } static void RenderModulesOptions(Compilation &C, const Driver &D, @@ -3264,6 +3233,7 @@ static void RenderModulesOptions(Compilation &C, const Driver &D, if (Arg *A = Args.getLastArg(options::OPT_fmodules_cache_path)) Path = A->getValue(); + bool HasPath = true; if (C.isForDiagnostics()) { // When generating crash reports, we want to emit the modules along with // the reproduction sources, so we ignore any provided module path. @@ -3272,12 +3242,16 @@ static void RenderModulesOptions(Compilation &C, const Driver &D, llvm::sys::path::append(Path, "modules"); } else if (Path.empty()) { // No module path was provided: use the default. - Driver::getDefaultModuleCachePath(Path); + HasPath = Driver::getDefaultModuleCachePath(Path); } - const char Arg[] = "-fmodules-cache-path="; - Path.insert(Path.begin(), Arg, Arg + strlen(Arg)); - CmdArgs.push_back(Args.MakeArgString(Path)); + // `HasPath` will only be false if getDefaultModuleCachePath() fails. + // That being said, that failure is unlikely and not caching is harmless. + if (HasPath) { + const char Arg[] = "-fmodules-cache-path="; + Path.insert(Path.begin(), Arg, Arg + strlen(Arg)); + CmdArgs.push_back(Args.MakeArgString(Path)); + } } if (HaveModules) { @@ -3679,7 +3653,7 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D, if (const Arg *A = Args.getLastArg(options::OPT_g_Group, options::OPT_gsplit_dwarf, options::OPT_gsplit_dwarf_EQ)) { - DebugInfoKind = codegenoptions::LimitedDebugInfo; + DebugInfoKind = codegenoptions::DebugInfoConstructor; // If the last option explicitly specified a debug-info level, use it. if (checkDebugInfoOption(A, Args, D, TC) && @@ -3774,10 +3748,9 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D, // not to include any column info. if (const Arg *A = Args.getLastArg(options::OPT_gcolumn_info)) (void)checkDebugInfoOption(A, Args, D, TC); - if (Args.hasFlag(options::OPT_gcolumn_info, options::OPT_gno_column_info, - /*Default=*/!EmitCodeView && - DebuggerTuning != llvm::DebuggerKind::SCE)) - CmdArgs.push_back("-dwarf-column-info"); + if (!Args.hasFlag(options::OPT_gcolumn_info, options::OPT_gno_column_info, + !EmitCodeView && DebuggerTuning != llvm::DebuggerKind::SCE)) + CmdArgs.push_back("-gno-column-info"); // FIXME: Move backend command line options to the module. // If -gline-tables-only or -gline-directives-only is the last option it wins. @@ -3785,7 +3758,7 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D, if (checkDebugInfoOption(A, Args, D, TC)) { if (DebugInfoKind != codegenoptions::DebugLineTablesOnly && DebugInfoKind != codegenoptions::DebugDirectivesOnly) { - DebugInfoKind = codegenoptions::LimitedDebugInfo; + DebugInfoKind = codegenoptions::DebugInfoConstructor; CmdArgs.push_back("-dwarf-ext-refs"); CmdArgs.push_back("-fmodule-format=obj"); } @@ -3805,7 +3778,9 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D, TC.GetDefaultStandaloneDebug()); if (const Arg *A = Args.getLastArg(options::OPT_fstandalone_debug)) (void)checkDebugInfoOption(A, Args, D, TC); - if (DebugInfoKind == codegenoptions::LimitedDebugInfo && NeedFullDebug) + if ((DebugInfoKind == codegenoptions::LimitedDebugInfo || + DebugInfoKind == codegenoptions::DebugInfoConstructor) && + NeedFullDebug) DebugInfoKind = codegenoptions::FullDebugInfo; if (Args.hasFlag(options::OPT_gembed_source, options::OPT_gno_embed_source, @@ -3978,7 +3953,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } } - const llvm::Triple *AuxTriple = IsCuda ? TC.getAuxTriple() : nullptr; + const llvm::Triple *AuxTriple = + (IsCuda || IsHIP) ? TC.getAuxTriple() : nullptr; bool IsWindowsMSVC = RawTriple.isWindowsMSVCEnvironment(); bool IsIAMCU = RawTriple.isOSIAMCU(); @@ -4068,9 +4044,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Triple.isOSWindows() && (Triple.getArch() == llvm::Triple::arm || Triple.getArch() == llvm::Triple::thumb)) { unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6; - unsigned Version; - Triple.getArchName().substr(Offset).getAsInteger(10, Version); - if (Version < 7) + unsigned Version = 0; + bool Failure = + Triple.getArchName().substr(Offset).consumeInteger(10, Version); + if (Failure || Version < 7) D.Diag(diag::err_target_unsupported_arch) << Triple.getArchName() << TripleStr; } @@ -4323,8 +4300,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, II.getInputArg().renderAsInput(Args, CmdArgs); } - C.addCommand(std::make_unique(JA, *this, D.getClangProgramPath(), - CmdArgs, Inputs)); + C.addCommand( + std::make_unique(JA, *this, ResponseFileSupport::AtFileUTF8(), + D.getClangProgramPath(), CmdArgs, Inputs)); return; } @@ -4580,8 +4558,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(FPKeepKindStr); if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss, - options::OPT_fno_zero_initialized_in_bss)) - CmdArgs.push_back("-mno-zero-initialized-in-bss"); + options::OPT_fno_zero_initialized_in_bss, true)) + CmdArgs.push_back("-fno-zero-initialized-in-bss"); bool OFastEnabled = isOptimizationLevelFast(Args); // If -Ofast is the optimization level, then -fstrict-aliasing should be @@ -4891,10 +4869,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_finstrument_functions_after_inlining, options::OPT_finstrument_function_entry_bare); - // NVPTX doesn't support PGO or coverage. There's no runtime support for - // sampling, overhead of call arc collection is way too high and there's no - // way to collect the output. - if (!Triple.isNVPTX()) + // NVPTX/AMDGCN doesn't support PGO or coverage. There's no runtime support + // for sampling, overhead of call arc collection is way too high and there's + // no way to collect the output. + if (!Triple.isNVPTX() && !Triple.isAMDGCN()) addPGOAndCoverageFlags(TC, C, D, Output, Args, CmdArgs); Args.AddLastArg(CmdArgs, options::OPT_fclang_abi_compat_EQ); @@ -5013,6 +4991,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_ftrigraphs, options::OPT_fno_trigraphs); + + // HIP headers has minimum C++ standard requirements. Therefore set the + // default language standard. + if (IsHIP) + CmdArgs.push_back(IsWindowsMSVC ? "-std=c++14" : "-std=c++11"); } // GCC's behavior for -Wwrite-strings is a bit strange: @@ -5243,6 +5226,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fno_openmp_cuda_mode, /*Default=*/false)) CmdArgs.push_back("-fopenmp-cuda-mode"); + // When in OpenMP offloading mode with NVPTX target, forward + // cuda-parallel-target-regions flag + if (Args.hasFlag(options::OPT_fopenmp_cuda_parallel_target_regions, + options::OPT_fno_openmp_cuda_parallel_target_regions, + /*Default=*/true)) + CmdArgs.push_back("-fopenmp-cuda-parallel-target-regions"); + // When in OpenMP offloading mode with NVPTX target, check if full runtime // is required. if (Args.hasFlag(options::OPT_fopenmp_cuda_force_full_runtime, @@ -5414,8 +5404,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Forward -cl options to -cc1 RenderOpenCLOptions(Args, CmdArgs); - if (Args.hasFlag(options::OPT_fhip_new_launch_api, - options::OPT_fno_hip_new_launch_api, false)) + if (IsHIP && Args.hasFlag(options::OPT_fhip_new_launch_api, + options::OPT_fno_hip_new_launch_api, true)) CmdArgs.push_back("-fhip-new-launch-api"); if (Arg *A = Args.getLastArg(options::OPT_fcf_protection_EQ)) { @@ -6235,19 +6225,21 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, auto CLCommand = getCLFallback()->GetCommand(C, JA, Output, Inputs, Args, LinkingOutput); C.addCommand(std::make_unique( - JA, *this, Exec, CmdArgs, Inputs, std::move(CLCommand))); + JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs, + std::move(CLCommand))); } else if (Args.hasArg(options::OPT__SLASH_fallback) && isa(JA)) { // In /fallback builds, run the main compilation even if the pch generation // fails, so that the main compilation's fallback to cl.exe runs. - C.addCommand(std::make_unique(JA, *this, Exec, - CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs)); } else if (D.CC1Main && !D.CCGenDiagnostics) { // Invoke the CC1 directly in this process - C.addCommand( - std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs)); } else { - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs)); } // Make the compile command echo its inputs for /showFilenames. @@ -6282,7 +6274,7 @@ Clang::Clang(const ToolChain &TC) // CAUTION! The first constructor argument ("clang") is not arbitrary, // as it is for other tools. Some operations on a Tool actually test // whether that tool is Clang based on the Tool's Name as a string. - : Tool("clang", "clang frontend", TC, RF_Full) {} + : Tool("clang", "clang frontend", TC) {} Clang::~Clang() {} @@ -6568,7 +6560,7 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType, options::OPT_gline_tables_only)) { *EmitCodeView = true; if (DebugInfoArg->getOption().matches(options::OPT__SLASH_Z7)) - *DebugInfoKind = codegenoptions::LimitedDebugInfo; + *DebugInfoKind = codegenoptions::DebugInfoConstructor; else *DebugInfoKind = codegenoptions::DebugLineTablesOnly; } else { @@ -6865,7 +6857,7 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, // the guard for source type, however there is a test which asserts // that some assembler invocation receives no -debug-info-kind, // and it's not clear whether that test is just overly restrictive. - DebugInfoKind = (WantDebug ? codegenoptions::LimitedDebugInfo + DebugInfoKind = (WantDebug ? codegenoptions::DebugInfoConstructor : codegenoptions::NoDebugInfo); // Add the -fdebug-compilation-dir flag if needed. addDebugCompDirArg(Args, CmdArgs, C.getDriver().getVFS()); @@ -6985,7 +6977,8 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Input.getFilename()); const char *Exec = getToolChain().getDriver().getClangProgramPath(); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs)); } // Begin OffloadBundler @@ -7069,7 +7062,7 @@ void OffloadBundler::ConstructJob(Compilation &C, const JobAction &JA, // All the inputs are encoded as commands. C.addCommand(std::make_unique( - JA, *this, + JA, *this, ResponseFileSupport::None(), TCArgs.MakeArgString(getToolChain().GetProgramPath(getShortName())), CmdArgs, None)); } @@ -7135,7 +7128,7 @@ void OffloadBundler::ConstructJobMultipleOutputs( // All the inputs are encoded as commands. C.addCommand(std::make_unique( - JA, *this, + JA, *this, ResponseFileSupport::None(), TCArgs.MakeArgString(getToolChain().GetProgramPath(getShortName())), CmdArgs, None)); } @@ -7165,7 +7158,7 @@ void OffloadWrapper::ConstructJob(Compilation &C, const JobAction &JA, } C.addCommand(std::make_unique( - JA, *this, + JA, *this, ResponseFileSupport::None(), Args.MakeArgString(getToolChain().GetProgramPath(getShortName())), CmdArgs, Inputs)); } diff --git a/clang/lib/Driver/ToolChains/Clang.h b/clang/lib/Driver/ToolChains/Clang.h index 48100c2fc6ec3..a607e3c27de9f 100644 --- a/clang/lib/Driver/ToolChains/Clang.h +++ b/clang/lib/Driver/ToolChains/Clang.h @@ -73,6 +73,8 @@ class LLVM_LIBRARY_VISIBILITY Clang : public Tool { llvm::opt::ArgStringList &CmdArgs) const; void AddWebAssemblyTargetArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; + void AddVETargetArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const; enum RewriteKind { RK_None, RK_Fragile, RK_NonFragile }; @@ -119,7 +121,7 @@ class LLVM_LIBRARY_VISIBILITY Clang : public Tool { class LLVM_LIBRARY_VISIBILITY ClangAs : public Tool { public: ClangAs(const ToolChain &TC) - : Tool("clang::as", "clang integrated assembler", TC, RF_Full) {} + : Tool("clang::as", "clang integrated assembler", TC) {} void AddMIPSTargetArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; void AddX86TargetArgs(const llvm::opt::ArgList &Args, diff --git a/clang/lib/Driver/ToolChains/CloudABI.cpp b/clang/lib/Driver/ToolChains/CloudABI.cpp index 0602e4f6d0b3d..8dcfd4951bbfe 100644 --- a/clang/lib/Driver/ToolChains/CloudABI.cpp +++ b/clang/lib/Driver/ToolChains/CloudABI.cpp @@ -92,7 +92,8 @@ void cloudabi::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o"))); const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); } // CloudABI - CloudABI tool chain which can call ld(1) directly. diff --git a/clang/lib/Driver/ToolChains/CloudABI.h b/clang/lib/Driver/ToolChains/CloudABI.h index cc381c2b1e1fe..98bf23127706e 100644 --- a/clang/lib/Driver/ToolChains/CloudABI.h +++ b/clang/lib/Driver/ToolChains/CloudABI.h @@ -19,9 +19,9 @@ namespace tools { /// cloudabi -- Directly call GNU Binutils linker namespace cloudabi { -class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Linker : public Tool { public: - Linker(const ToolChain &TC) : GnuTool("cloudabi::Linker", "linker", TC) {} + Linker(const ToolChain &TC) : Tool("cloudabi::Linker", "linker", TC) {} bool hasIntegratedCPP() const override { return false; } bool isLinkJob() const override { return true; } diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 7fdb3fdf00094..1cac5a0822a4b 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -12,6 +12,7 @@ #include "Arch/Mips.h" #include "Arch/PPC.h" #include "Arch/SystemZ.h" +#include "Arch/VE.h" #include "Arch/X86.h" #include "HIP.h" #include "Hexagon.h" @@ -83,6 +84,31 @@ void tools::handleTargetFeaturesGroup(const ArgList &Args, } } +std::vector +tools::unifyTargetFeatures(const std::vector &Features) { + std::vector UnifiedFeatures; + // Find the last of each feature. + llvm::StringMap LastOpt; + for (unsigned I = 0, N = Features.size(); I < N; ++I) { + StringRef Name = Features[I]; + assert(Name[0] == '-' || Name[0] == '+'); + LastOpt[Name.drop_front(1)] = I; + } + + for (unsigned I = 0, N = Features.size(); I < N; ++I) { + // If this feature was overridden, ignore it. + StringRef Name = Features[I]; + llvm::StringMap::iterator LastI = LastOpt.find(Name.drop_front(1)); + assert(LastI != LastOpt.end()); + unsigned Last = LastI->second; + if (Last != I) + continue; + + UnifiedFeatures.push_back(Name); + } + return UnifiedFeatures; +} + void tools::addDirectoryList(const ArgList &Args, ArgStringList &CmdArgs, const char *ArgName, const char *EnvVar) { const char *DirList = ::getenv(EnvVar); @@ -152,14 +178,12 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH"); for (const auto &II : Inputs) { - // If the current tool chain refers to an OpenMP or HIP offloading host, we - // should ignore inputs that refer to OpenMP or HIP offloading devices - + // If the current tool chain refers to an OpenMP offloading host, we + // should ignore inputs that refer to OpenMP offloading devices - // they will be embedded according to a proper linker script. if (auto *IA = II.getAction()) if ((JA.isHostOffloading(Action::OFK_OpenMP) && - IA->isDeviceOffloading(Action::OFK_OpenMP)) || - (JA.isHostOffloading(Action::OFK_HIP) && - IA->isDeviceOffloading(Action::OFK_HIP))) + IA->isDeviceOffloading(Action::OFK_OpenMP))) continue; if (!TC.HasNativeLLVMSupport() && types::isLLVMIR(II.getType())) @@ -506,8 +530,11 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args, void tools::addArchSpecificRPath(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { + // Enable -frtlib-add-rpath by default for the case of VE. + const bool IsVE = TC.getTriple().isVE(); + bool DefaultValue = IsVE; if (!Args.hasFlag(options::OPT_frtlib_add_rpath, - options::OPT_fno_rtlib_add_rpath, false)) + options::OPT_fno_rtlib_add_rpath, DefaultValue)) return; std::string CandidateRPath = TC.getArchSpecificLibPath(); @@ -862,10 +889,12 @@ void tools::SplitDebugInfo(const ToolChain &TC, Compilation &C, const Tool &T, InputInfo II(types::TY_Object, Output.getFilename(), Output.getFilename()); // First extract the dwo sections. - C.addCommand(std::make_unique(JA, T, Exec, ExtractArgs, II)); + C.addCommand(std::make_unique( + JA, T, ResponseFileSupport::AtFileCurCP(), Exec, ExtractArgs, II)); // Then remove them from the original .o file. - C.addCommand(std::make_unique(JA, T, Exec, StripArgs, II)); + C.addCommand(std::make_unique( + JA, T, ResponseFileSupport::AtFileCurCP(), Exec, StripArgs, II)); } // Claim options we don't want to warn if they are unused. We do this for @@ -1298,115 +1327,6 @@ void tools::AddRunTimeLibs(const ToolChain &TC, const Driver &D, } } -/// Add HIP linker script arguments at the end of the argument list so that -/// the fat binary is built by embedding the device images into the host. The -/// linker script also defines a symbol required by the code generation so that -/// the image can be retrieved at runtime. This should be used only in tool -/// chains that support linker scripts. -void tools::AddHIPLinkerScript(const ToolChain &TC, Compilation &C, - const InputInfo &Output, - const InputInfoList &Inputs, const ArgList &Args, - ArgStringList &CmdArgs, const JobAction &JA, - const Tool &T) { - - // If this is not a HIP host toolchain, we don't need to do anything. - if (!JA.isHostOffloading(Action::OFK_HIP)) - return; - - InputInfoList DeviceInputs; - for (const auto &II : Inputs) { - const Action *A = II.getAction(); - // Is this a device linking action? - if (A && isa(A) && A->isDeviceOffloading(Action::OFK_HIP)) { - DeviceInputs.push_back(II); - } - } - - if (DeviceInputs.empty()) - return; - - // Create temporary linker script. Keep it if save-temps is enabled. - const char *LKS; - std::string Name = - std::string(llvm::sys::path::filename(Output.getFilename())); - if (C.getDriver().isSaveTempsEnabled()) { - LKS = C.getArgs().MakeArgString(Name + ".lk"); - } else { - auto TmpName = C.getDriver().GetTemporaryPath(Name, "lk"); - LKS = C.addTempFile(C.getArgs().MakeArgString(TmpName)); - } - - // Add linker script option to the command. - CmdArgs.push_back("-T"); - CmdArgs.push_back(LKS); - - // Create a buffer to write the contents of the linker script. - std::string LksBuffer; - llvm::raw_string_ostream LksStream(LksBuffer); - - // Get the HIP offload tool chain. - auto *HIPTC = static_cast( - C.getSingleOffloadToolChain()); - assert(HIPTC->getTriple().getArch() == llvm::Triple::amdgcn && - "Wrong platform"); - (void)HIPTC; - - const char *BundleFile; - if (C.getDriver().isSaveTempsEnabled()) { - BundleFile = C.getArgs().MakeArgString(Name + ".hipfb"); - } else { - auto TmpName = C.getDriver().GetTemporaryPath(Name, "hipfb"); - BundleFile = C.addTempFile(C.getArgs().MakeArgString(TmpName)); - } - AMDGCN::constructHIPFatbinCommand(C, JA, BundleFile, DeviceInputs, Args, T); - - // Add commands to embed target binaries. We ensure that each section and - // image is 16-byte aligned. This is not mandatory, but increases the - // likelihood of data to be aligned with a cache block in several main host - // machines. - LksStream << "/*\n"; - LksStream << " HIP Offload Linker Script\n"; - LksStream << " *** Automatically generated by Clang ***\n"; - LksStream << "*/\n"; - LksStream << "TARGET(binary)\n"; - LksStream << "INPUT(" << BundleFile << ")\n"; - LksStream << "SECTIONS\n"; - LksStream << "{\n"; - LksStream << " .hip_fatbin :\n"; - LksStream << " ALIGN(0x10)\n"; - LksStream << " {\n"; - LksStream << " PROVIDE_HIDDEN(__hip_fatbin = .);\n"; - LksStream << " " << BundleFile << "\n"; - LksStream << " }\n"; - LksStream << " /DISCARD/ :\n"; - LksStream << " {\n"; - LksStream << " * ( __CLANG_OFFLOAD_BUNDLE__* )\n"; - LksStream << " }\n"; - LksStream << "}\n"; - LksStream << "INSERT BEFORE .data\n"; - LksStream.flush(); - - // Dump the contents of the linker script if the user requested that. We - // support this option to enable testing of behavior with -###. - if (C.getArgs().hasArg(options::OPT_fhip_dump_offload_linker_script)) - llvm::errs() << LksBuffer; - - // If this is a dry run, do not create the linker script file. - if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) - return; - - // Open script file and write the contents. - std::error_code EC; - llvm::raw_fd_ostream Lksf(LKS, EC, llvm::sys::fs::OF_None); - - if (EC) { - C.getDriver().Diag(clang::diag::err_unable_to_make_temp) << EC.message(); - return; - } - - Lksf << LksBuffer; -} - SmallString<128> tools::getStatsFileName(const llvm::opt::ArgList &Args, const InputInfo &Output, const InputInfo &Input, diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h index 58bc92c9b7569..29dedec9b09cd 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -45,12 +45,6 @@ void AddRunTimeLibs(const ToolChain &TC, const Driver &D, llvm::opt::ArgStringList &CmdArgs, const llvm::opt::ArgList &Args); -void AddHIPLinkerScript(const ToolChain &TC, Compilation &C, - const InputInfo &Output, const InputInfoList &Inputs, - const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs, const JobAction &JA, - const Tool &T); - const char *SplitDebugName(const llvm::opt::ArgList &Args, const InputInfo &Input, const InputInfo &Output); @@ -112,10 +106,20 @@ void AddTargetFeature(const llvm::opt::ArgList &Args, std::string getCPUName(const llvm::opt::ArgList &Args, const llvm::Triple &T, bool FromAs = false); +/// Iterate \p Args and convert -mxxx to +xxx and -mno-xxx to -xxx and +/// append it to \p Features. +/// +/// Note: Since \p Features may contain default values before calling +/// this function, or may be appended with entries to override arguments, +/// entries in \p Features are not unique. void handleTargetFeaturesGroup(const llvm::opt::ArgList &Args, std::vector &Features, llvm::opt::OptSpecifier Group); +/// If there are multiple +xxx or -xxx features, keep the last one. +std::vector +unifyTargetFeatures(const std::vector &Features); + /// Handles the -save-stats option and returns the filename to save statistics /// to. SmallString<128> getStatsFileName(const llvm::opt::ArgList &Args, diff --git a/clang/lib/Driver/ToolChains/CrossWindows.cpp b/clang/lib/Driver/ToolChains/CrossWindows.cpp index dbf6114eb2ecc..127a8a5f24cce 100644 --- a/clang/lib/Driver/ToolChains/CrossWindows.cpp +++ b/clang/lib/Driver/ToolChains/CrossWindows.cpp @@ -57,7 +57,8 @@ void tools::CrossWindows::Assembler::ConstructJob( const std::string Assembler = TC.GetProgramPath("as"); Exec = Args.MakeArgString(Assembler); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::None(), + Exec, CmdArgs, Inputs)); } void tools::CrossWindows::Linker::ConstructJob( @@ -202,7 +203,8 @@ void tools::CrossWindows::Linker::ConstructJob( Exec = Args.MakeArgString(TC.GetLinkerPath()); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs)); } CrossWindowsToolChain::CrossWindowsToolChain(const Driver &D, diff --git a/clang/lib/Driver/ToolChains/CrossWindows.h b/clang/lib/Driver/ToolChains/CrossWindows.h index 7267a35d48b94..df9a7f71bf9ff 100644 --- a/clang/lib/Driver/ToolChains/CrossWindows.h +++ b/clang/lib/Driver/ToolChains/CrossWindows.h @@ -33,8 +33,7 @@ class LLVM_LIBRARY_VISIBILITY Assembler : public Tool { class LLVM_LIBRARY_VISIBILITY Linker : public Tool { public: - Linker(const ToolChain &TC) - : Tool("CrossWindows::Linker", "ld", TC, RF_Full) {} + Linker(const ToolChain &TC) : Tool("CrossWindows::Linker", "ld", TC) {} bool hasIntegratedCPP() const override { return false; } bool isLinkJob() const override { return true; } diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp index a25541cf31e90..110a0bca9bc18 100644 --- a/clang/lib/Driver/ToolChains/Cuda.cpp +++ b/clang/lib/Driver/ToolChains/Cuda.cpp @@ -423,7 +423,11 @@ void NVPTX::Assembler::ConstructJob(Compilation &C, const JobAction &JA, Exec = A->getValue(); else Exec = Args.MakeArgString(TC.GetProgramPath("ptxas")); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, + ResponseFileSupport{ResponseFileSupport::RF_Full, llvm::sys::WEM_UTF8, + "--options-file"}, + Exec, CmdArgs, Inputs)); } static bool shouldIncludePTX(const ArgList &Args, const char *gpu_arch) { @@ -488,7 +492,11 @@ void NVPTX::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString(A)); const char *Exec = Args.MakeArgString(TC.GetProgramPath("fatbinary")); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, + ResponseFileSupport{ResponseFileSupport::RF_Full, llvm::sys::WEM_UTF8, + "--options-file"}, + Exec, CmdArgs, Inputs)); } void NVPTX::OpenMPLinker::ConstructJob(Compilation &C, const JobAction &JA, @@ -565,7 +573,11 @@ void NVPTX::OpenMPLinker::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("nvlink")); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, + ResponseFileSupport{ResponseFileSupport::RF_Full, llvm::sys::WEM_UTF8, + "--options-file"}, + Exec, CmdArgs, Inputs)); } /// CUDA toolchain. Our assembler is ptxas, and our "linker" is fatbinary, diff --git a/clang/lib/Driver/ToolChains/Cuda.h b/clang/lib/Driver/ToolChains/Cuda.h index bf462d7025877..873eb7338a30a 100644 --- a/clang/lib/Driver/ToolChains/Cuda.h +++ b/clang/lib/Driver/ToolChains/Cuda.h @@ -89,9 +89,7 @@ namespace NVPTX { // Run ptxas, the NVPTX assembler. class LLVM_LIBRARY_VISIBILITY Assembler : public Tool { public: - Assembler(const ToolChain &TC) - : Tool("NVPTX::Assembler", "ptxas", TC, RF_Full, llvm::sys::WEM_UTF8, - "--options-file") {} + Assembler(const ToolChain &TC) : Tool("NVPTX::Assembler", "ptxas", TC) {} bool hasIntegratedCPP() const override { return false; } @@ -105,9 +103,7 @@ class LLVM_LIBRARY_VISIBILITY Assembler : public Tool { // assembly into a single output file. class LLVM_LIBRARY_VISIBILITY Linker : public Tool { public: - Linker(const ToolChain &TC) - : Tool("NVPTX::Linker", "fatbinary", TC, RF_Full, llvm::sys::WEM_UTF8, - "--options-file") {} + Linker(const ToolChain &TC) : Tool("NVPTX::Linker", "fatbinary", TC) {} bool hasIntegratedCPP() const override { return false; } @@ -120,8 +116,7 @@ class LLVM_LIBRARY_VISIBILITY Linker : public Tool { class LLVM_LIBRARY_VISIBILITY OpenMPLinker : public Tool { public: OpenMPLinker(const ToolChain &TC) - : Tool("NVPTX::OpenMPLinker", "nvlink", TC, RF_Full, llvm::sys::WEM_UTF8, - "--options-file") {} + : Tool("NVPTX::OpenMPLinker", "nvlink", TC) {} bool hasIntegratedCPP() const override { return false; } diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 3bf7f9cbc139b..2e1190c34ea7a 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -148,7 +148,8 @@ void darwin::Assembler::ConstructJob(Compilation &C, const JobAction &JA, // asm_final spec is empty. const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::None(), + Exec, CmdArgs, Inputs)); } void darwin::MachOTool::anchor() {} @@ -202,16 +203,11 @@ static bool shouldLinkerNotDedup(bool IsLinkerOnlyAction, const ArgList &Args) { void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args, ArgStringList &CmdArgs, - const InputInfoList &Inputs) const { + const InputInfoList &Inputs, + unsigned Version[5]) const { const Driver &D = getToolChain().getDriver(); const toolchains::MachO &MachOTC = getMachOToolChain(); - unsigned Version[5] = {0, 0, 0, 0, 0}; - if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) { - if (!Driver::GetReleaseVersion(A->getValue(), Version)) - D.Diag(diag::err_drv_invalid_version_number) << A->getAsString(Args); - } - // Newer linkers support -demangle. Pass it if supported and not disabled by // the user. if (Version[0] >= 100 && !Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) @@ -525,13 +521,21 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("touch")); CmdArgs.push_back(Output.getFilename()); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, None)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::None(), Exec, CmdArgs, None)); return; } + unsigned Version[5] = {0, 0, 0, 0, 0}; + if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) { + if (!Driver::GetReleaseVersion(A->getValue(), Version)) + getToolChain().getDriver().Diag(diag::err_drv_invalid_version_number) + << A->getAsString(Args); + } + // I'm not sure why this particular decomposition exists in gcc, but // we follow suite for ease of comparison. - AddLinkArgs(C, Args, CmdArgs, Inputs); + AddLinkArgs(C, Args, CmdArgs, Inputs, Version); if (willEmitRemarks(Args) && checkRemarksOptions(getToolChain().getDriver(), Args, @@ -682,9 +686,16 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, } } + ResponseFileSupport ResponseSupport = ResponseFileSupport::AtFileUTF8(); + if (Version[0] < 607) { + // For older versions of the linker, use the legacy filelist method instead. + ResponseSupport = {ResponseFileSupport::RF_FileList, llvm::sys::WEM_UTF8, + "-filelist"}; + } + const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); - std::unique_ptr Cmd = - std::make_unique(JA, *this, Exec, CmdArgs, Inputs); + std::unique_ptr Cmd = std::make_unique( + JA, *this, ResponseSupport, Exec, CmdArgs, Inputs); Cmd->setInputFileList(std::move(InputFileList)); C.addCommand(std::move(Cmd)); } @@ -708,7 +719,8 @@ void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA, } const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("lipo")); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::None(), + Exec, CmdArgs, Inputs)); } void darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA, @@ -728,7 +740,8 @@ void darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("dsymutil")); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::None(), + Exec, CmdArgs, Inputs)); } void darwin::VerifyDebug::ConstructJob(Compilation &C, const JobAction &JA, @@ -751,7 +764,8 @@ void darwin::VerifyDebug::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("dwarfdump")); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::None(), + Exec, CmdArgs, Inputs)); } MachO::MachO(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) @@ -765,7 +779,7 @@ MachO::MachO(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) /// Darwin - Darwin tool chain for i386 and x86_64. Darwin::Darwin(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) : MachO(D, Triple, Args), TargetInitialized(false), - CudaInstallation(D, Triple, Args) {} + CudaInstallation(D, Triple, Args), RocmInstallation(D, Triple, Args) {} types::ID MachO::LookupTypeForExtension(StringRef Ext) const { types::ID Ty = ToolChain::LookupTypeForExtension(Ext); @@ -817,6 +831,11 @@ void Darwin::AddCudaIncludeArgs(const ArgList &DriverArgs, CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args); } +void Darwin::AddHIPIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + RocmInstallation.AddHIPIncludeArgs(DriverArgs, CC1Args); +} + // This is just a MachO name translation routine and there's no // way to join this into ARMTargetParser without breaking all // other assumptions. Maybe MachO should consider standardising @@ -940,6 +959,10 @@ DarwinClang::DarwinClang(const Driver &D, const llvm::Triple &Triple, : Darwin(D, Triple, Args) {} void DarwinClang::addClangWarningOptions(ArgStringList &CC1Args) const { + // Always error about undefined 'TARGET_OS_*' macros. + CC1Args.push_back("-Wundef-prefix=TARGET_OS_"); + CC1Args.push_back("-Werror=undef-prefix"); + // For modern targets, promote certain warnings to errors. if (isTargetWatchOSBased() || getTriple().isArch64Bit()) { // Always enable -Wdeprecated-objc-isa-usage and promote it @@ -971,6 +994,8 @@ void DarwinClang::AddLinkARCArgs(const ArgList &Args, // Avoid linking compatibility stubs on i386 mac. if (isTargetMacOS() && getArch() == llvm::Triple::x86) return; + if (isTargetAppleSiliconMac()) + return; ObjCRuntime runtime = getDefaultObjCRuntime(/*nonfragile*/ true); @@ -1672,8 +1697,16 @@ inferDeploymentTargetFromArch(DerivedArgList &Args, const Darwin &Toolchain, llvm::Triple::OSType OSTy = llvm::Triple::UnknownOS; StringRef MachOArchName = Toolchain.getMachOArchName(Args); - if (MachOArchName == "armv7" || MachOArchName == "armv7s" || - MachOArchName == "arm64") + if (MachOArchName == "arm64") { +#if __arm64__ + // A clang running on an Apple Silicon mac defaults + // to building for mac when building for arm64 rather than + // defaulting to iOS. + OSTy = llvm::Triple::MacOSX; +#else + OSTy = llvm::Triple::IOS; +#endif + } else if (MachOArchName == "armv7" || MachOArchName == "armv7s") OSTy = llvm::Triple::IOS; else if (MachOArchName == "armv7k" || MachOArchName == "arm64_32") OSTy = llvm::Triple::WatchOS; @@ -1822,7 +1855,7 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { if (Platform == MacOS) { if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor, Micro, HadExtra) || - HadExtra || Major != 10 || Minor >= 100 || Micro >= 100) + HadExtra || Major < 10 || Major >= 100 || Minor >= 100 || Micro >= 100) getDriver().Diag(diag::err_drv_invalid_version_number) << OSTarget->getAsString(Args, Opts); } else if (Platform == IPhoneOS) { @@ -2522,6 +2555,9 @@ void Darwin::addMinVersionArgs(const ArgList &Args, CmdArgs.push_back("-macosx_version_min"); } + VersionTuple MinTgtVers = getEffectiveTriple().getMinimumSupportedOSVersion(); + if (!MinTgtVers.empty() && MinTgtVers > TargetVersion) + TargetVersion = MinTgtVers; CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString())); } @@ -2554,6 +2590,9 @@ void Darwin::addPlatformVersionArgs(const llvm::opt::ArgList &Args, PlatformName += "-simulator"; CmdArgs.push_back(Args.MakeArgString(PlatformName)); VersionTuple TargetVersion = getTargetVersion().withoutBuild(); + VersionTuple MinTgtVers = getEffectiveTriple().getMinimumSupportedOSVersion(); + if (!MinTgtVers.empty() && MinTgtVers > TargetVersion) + TargetVersion = MinTgtVers; CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString())); if (SDKInfo) { VersionTuple SDKVersion = SDKInfo->getVersion().withoutBuild(); @@ -2564,98 +2603,102 @@ void Darwin::addPlatformVersionArgs(const llvm::opt::ArgList &Args, } } -void Darwin::addStartObjectFileArgs(const ArgList &Args, - ArgStringList &CmdArgs) const { - // Derived from startfile spec. - if (Args.hasArg(options::OPT_dynamiclib)) { - // Derived from darwin_dylib1 spec. - if (isTargetWatchOSBased()) { - ; // watchOS does not need dylib1.o. - } else if (isTargetIOSSimulator()) { - ; // iOS simulator does not need dylib1.o. - } else if (isTargetIPhoneOS()) { - if (isIPhoneOSVersionLT(3, 1)) - CmdArgs.push_back("-ldylib1.o"); +// Add additional link args for the -dynamiclib option. +static void addDynamicLibLinkArgs(const Darwin &D, const ArgList &Args, + ArgStringList &CmdArgs) { + // Derived from darwin_dylib1 spec. + if (D.isTargetIPhoneOS()) { + if (D.isIPhoneOSVersionLT(3, 1)) + CmdArgs.push_back("-ldylib1.o"); + return; + } + + if (!D.isTargetMacOS()) + return; + if (D.isMacosxVersionLT(10, 5)) + CmdArgs.push_back("-ldylib1.o"); + else if (D.isMacosxVersionLT(10, 6)) + CmdArgs.push_back("-ldylib1.10.5.o"); +} + +// Add additional link args for the -bundle option. +static void addBundleLinkArgs(const Darwin &D, const ArgList &Args, + ArgStringList &CmdArgs) { + if (Args.hasArg(options::OPT_static)) + return; + // Derived from darwin_bundle1 spec. + if ((D.isTargetIPhoneOS() && D.isIPhoneOSVersionLT(3, 1)) || + (D.isTargetMacOS() && D.isMacosxVersionLT(10, 6))) + CmdArgs.push_back("-lbundle1.o"); +} + +// Add additional link args for the -pg option. +static void addPgProfilingLinkArgs(const Darwin &D, const ArgList &Args, + ArgStringList &CmdArgs) { + if (D.isTargetMacOS() && D.isMacosxVersionLT(10, 9)) { + if (Args.hasArg(options::OPT_static) || Args.hasArg(options::OPT_object) || + Args.hasArg(options::OPT_preload)) { + CmdArgs.push_back("-lgcrt0.o"); } else { - if (isMacosxVersionLT(10, 5)) - CmdArgs.push_back("-ldylib1.o"); - else if (isMacosxVersionLT(10, 6)) - CmdArgs.push_back("-ldylib1.10.5.o"); + CmdArgs.push_back("-lgcrt1.o"); + + // darwin_crt2 spec is empty. } + // By default on OS X 10.8 and later, we don't link with a crt1.o + // file and the linker knows to use _main as the entry point. But, + // when compiling with -pg, we need to link with the gcrt1.o file, + // so pass the -no_new_main option to tell the linker to use the + // "start" symbol as the entry point. + if (!D.isMacosxVersionLT(10, 8)) + CmdArgs.push_back("-no_new_main"); } else { - if (Args.hasArg(options::OPT_bundle)) { - if (!Args.hasArg(options::OPT_static)) { - // Derived from darwin_bundle1 spec. - if (isTargetWatchOSBased()) { - ; // watchOS does not need bundle1.o. - } else if (isTargetIOSSimulator()) { - ; // iOS simulator does not need bundle1.o. - } else if (isTargetIPhoneOS()) { - if (isIPhoneOSVersionLT(3, 1)) - CmdArgs.push_back("-lbundle1.o"); - } else { - if (isMacosxVersionLT(10, 6)) - CmdArgs.push_back("-lbundle1.o"); - } - } - } else { - if (Args.hasArg(options::OPT_pg) && SupportsProfiling()) { - if (isTargetMacOS() && isMacosxVersionLT(10, 9)) { - if (Args.hasArg(options::OPT_static) || - Args.hasArg(options::OPT_object) || - Args.hasArg(options::OPT_preload)) { - CmdArgs.push_back("-lgcrt0.o"); - } else { - CmdArgs.push_back("-lgcrt1.o"); - - // darwin_crt2 spec is empty. - } - // By default on OS X 10.8 and later, we don't link with a crt1.o - // file and the linker knows to use _main as the entry point. But, - // when compiling with -pg, we need to link with the gcrt1.o file, - // so pass the -no_new_main option to tell the linker to use the - // "start" symbol as the entry point. - if (isTargetMacOS() && !isMacosxVersionLT(10, 8)) - CmdArgs.push_back("-no_new_main"); - } else { - getDriver().Diag(diag::err_drv_clang_unsupported_opt_pg_darwin) - << isTargetMacOS(); - } - } else { - if (Args.hasArg(options::OPT_static) || - Args.hasArg(options::OPT_object) || - Args.hasArg(options::OPT_preload)) { - CmdArgs.push_back("-lcrt0.o"); - } else { - // Derived from darwin_crt1 spec. - if (isTargetWatchOSBased()) { - ; // watchOS does not need crt1.o. - } else if (isTargetIOSSimulator()) { - ; // iOS simulator does not need crt1.o. - } else if (isTargetIPhoneOS()) { - if (getArch() == llvm::Triple::aarch64) - ; // iOS does not need any crt1 files for arm64 - else if (isIPhoneOSVersionLT(3, 1)) - CmdArgs.push_back("-lcrt1.o"); - else if (isIPhoneOSVersionLT(6, 0)) - CmdArgs.push_back("-lcrt1.3.1.o"); - } else { - if (isMacosxVersionLT(10, 5)) - CmdArgs.push_back("-lcrt1.o"); - else if (isMacosxVersionLT(10, 6)) - CmdArgs.push_back("-lcrt1.10.5.o"); - else if (isMacosxVersionLT(10, 8)) - CmdArgs.push_back("-lcrt1.10.6.o"); - - // darwin_crt2 spec is empty. - } - } - } - } + D.getDriver().Diag(diag::err_drv_clang_unsupported_opt_pg_darwin) + << D.isTargetMacOS(); } +} + +static void addDefaultCRTLinkArgs(const Darwin &D, const ArgList &Args, + ArgStringList &CmdArgs) { + // Derived from darwin_crt1 spec. + if (D.isTargetIPhoneOS()) { + if (D.getArch() == llvm::Triple::aarch64) + ; // iOS does not need any crt1 files for arm64 + else if (D.isIPhoneOSVersionLT(3, 1)) + CmdArgs.push_back("-lcrt1.o"); + else if (D.isIPhoneOSVersionLT(6, 0)) + CmdArgs.push_back("-lcrt1.3.1.o"); + return; + } + + if (!D.isTargetMacOS()) + return; + if (D.isMacosxVersionLT(10, 5)) + CmdArgs.push_back("-lcrt1.o"); + else if (D.isMacosxVersionLT(10, 6)) + CmdArgs.push_back("-lcrt1.10.5.o"); + else if (D.isMacosxVersionLT(10, 8)) + CmdArgs.push_back("-lcrt1.10.6.o"); + // darwin_crt2 spec is empty. +} + +void Darwin::addStartObjectFileArgs(const ArgList &Args, + ArgStringList &CmdArgs) const { + // Derived from startfile spec. + if (Args.hasArg(options::OPT_dynamiclib)) + addDynamicLibLinkArgs(*this, Args, CmdArgs); + else if (Args.hasArg(options::OPT_bundle)) + addBundleLinkArgs(*this, Args, CmdArgs); + else if (Args.hasArg(options::OPT_pg) && SupportsProfiling()) + addPgProfilingLinkArgs(*this, Args, CmdArgs); + else if (Args.hasArg(options::OPT_static) || + Args.hasArg(options::OPT_object) || + Args.hasArg(options::OPT_preload)) + CmdArgs.push_back("-lcrt0.o"); + else + addDefaultCRTLinkArgs(*this, Args, CmdArgs); - if (!isTargetIPhoneOS() && Args.hasArg(options::OPT_shared_libgcc) && - !isTargetWatchOS() && isMacosxVersionLT(10, 5)) { + if (isTargetMacOS() && Args.hasArg(options::OPT_shared_libgcc) && + isMacosxVersionLT(10, 5)) { const char *Str = Args.MakeArgString(GetFilePath("crt3.o")); CmdArgs.push_back(Str); } @@ -2698,4 +2741,5 @@ SanitizerMask Darwin::getSupportedSanitizers() const { void Darwin::printVerboseInfo(raw_ostream &OS) const { CudaInstallation.print(OS); + RocmInstallation.print(OS); } diff --git a/clang/lib/Driver/ToolChains/Darwin.h b/clang/lib/Driver/ToolChains/Darwin.h index 1b193a4c4eb96..64c252efea7df 100644 --- a/clang/lib/Driver/ToolChains/Darwin.h +++ b/clang/lib/Driver/ToolChains/Darwin.h @@ -10,6 +10,7 @@ #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_DARWIN_H #include "Cuda.h" +#include "ROCm.h" #include "clang/Driver/DarwinSDKInfo.h" #include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" @@ -40,13 +41,8 @@ class LLVM_LIBRARY_VISIBILITY MachOTool : public Tool { } public: - MachOTool( - const char *Name, const char *ShortName, const ToolChain &TC, - ResponseFileSupport ResponseSupport = RF_None, - llvm::sys::WindowsEncodingMethod ResponseEncoding = llvm::sys::WEM_UTF8, - const char *ResponseFlag = "@") - : Tool(Name, ShortName, TC, ResponseSupport, ResponseEncoding, - ResponseFlag) {} + MachOTool(const char *Name, const char *ShortName, const ToolChain &TC) + : Tool(Name, ShortName, TC) {} }; class LLVM_LIBRARY_VISIBILITY Assembler : public MachOTool { @@ -66,12 +62,10 @@ class LLVM_LIBRARY_VISIBILITY Linker : public MachOTool { bool NeedsTempPath(const InputInfoList &Inputs) const; void AddLinkArgs(Compilation &C, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, - const InputInfoList &Inputs) const; + const InputInfoList &Inputs, unsigned Version[5]) const; public: - Linker(const ToolChain &TC) - : MachOTool("darwin::Linker", "linker", TC, RF_FileList, - llvm::sys::WEM_UTF8, "-filelist") {} + Linker(const ToolChain &TC) : MachOTool("darwin::Linker", "linker", TC) {} bool hasIntegratedCPP() const override { return false; } bool isLinkJob() const override { return true; } @@ -300,6 +294,7 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO { mutable Optional SDKInfo; CudaInstallationDetector CudaInstallation; + RocmInstallationDetector RocmInstallation; private: void AddDeploymentTarget(llvm::opt::DerivedArgList &Args) const; @@ -357,6 +352,7 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO { const_cast(this)->setTripleEnvironment(llvm::Triple::Simulator); } +public: bool isTargetIPhoneOS() const { assert(TargetInitialized && "Target not initialized!"); return (TargetPlatform == IPhoneOS || TargetPlatform == TvOS) && @@ -409,6 +405,17 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO { return TargetPlatform == MacOS; } + bool isTargetMacOSBased() const { + assert(TargetInitialized && "Target not initialized!"); + // FIXME (Alex L): Add remaining MacCatalyst suppport. + return TargetPlatform == MacOS; + } + + bool isTargetAppleSiliconMac() const { + assert(TargetInitialized && "Target not initialized!"); + return isTargetMacOSBased() && getArch() == llvm::Triple::aarch64; + } + bool isTargetInitialized() const { return TargetInitialized; } VersionTuple getTargetVersion() const { @@ -422,11 +429,20 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO { return TargetVersion < VersionTuple(V0, V1, V2); } + /// Returns true if the minimum supported macOS version for the slice that's + /// being built is less than the specified version. If there's no minimum + /// supported macOS version, the deployment target version is compared to the + /// specifed version instead. bool isMacosxVersionLT(unsigned V0, unsigned V1 = 0, unsigned V2 = 0) const { - assert(isTargetMacOS() && "Unexpected call for non OS X target!"); - return TargetVersion < VersionTuple(V0, V1, V2); + assert(isTargetMacOS() && getTriple().isMacOSX() && + "Unexpected call for non OS X target!"); + VersionTuple MinVers = getTriple().getMinimumSupportedOSVersion(); + return (!MinVers.empty() && MinVers > TargetVersion + ? MinVers + : TargetVersion) < VersionTuple(V0, V1, V2); } +protected: /// Return true if c++17 aligned allocation/deallocation functions are not /// implemented in the c++ standard library of the deployment target we are /// targeting. @@ -461,6 +477,8 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO { void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; bool UseObjCMixedDispatch() const override { // This is only used with the non-fragile ABI and non-legacy dispatch. diff --git a/clang/lib/Driver/ToolChains/DragonFly.cpp b/clang/lib/Driver/ToolChains/DragonFly.cpp index 424331fbc6fe0..88dd0c899d8a8 100644 --- a/clang/lib/Driver/ToolChains/DragonFly.cpp +++ b/clang/lib/Driver/ToolChains/DragonFly.cpp @@ -45,7 +45,8 @@ void dragonfly::Assembler::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(II.getFilename()); const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); } void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA, @@ -169,7 +170,8 @@ void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA, getToolChain().addProfileRTLibs(Args, CmdArgs); const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); } /// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly. diff --git a/clang/lib/Driver/ToolChains/DragonFly.h b/clang/lib/Driver/ToolChains/DragonFly.h index 7e76904f10558..3ed5acefaefb5 100644 --- a/clang/lib/Driver/ToolChains/DragonFly.h +++ b/clang/lib/Driver/ToolChains/DragonFly.h @@ -18,10 +18,10 @@ namespace driver { namespace tools { /// dragonfly -- Directly call GNU Binutils assembler and linker namespace dragonfly { -class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Assembler : public Tool { public: Assembler(const ToolChain &TC) - : GnuTool("dragonfly::Assembler", "assembler", TC) {} + : Tool("dragonfly::Assembler", "assembler", TC) {} bool hasIntegratedCPP() const override { return false; } @@ -31,9 +31,9 @@ class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { const char *LinkingOutput) const override; }; -class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Linker : public Tool { public: - Linker(const ToolChain &TC) : GnuTool("dragonfly::Linker", "linker", TC) {} + Linker(const ToolChain &TC) : Tool("dragonfly::Linker", "linker", TC) {} bool hasIntegratedCPP() const override { return false; } bool isLinkJob() const override { return true; } diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index 9b9eb81fa111d..80f6db7ea6427 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -70,10 +70,10 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA, const auto& D = C.getDriver(); const char* Exec = Args.MakeArgString(D.GetProgramPath("flang", TC)); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs)); } -Flang::Flang(const ToolChain &TC) - : Tool("flang", "flang frontend", TC, RF_Full) {} +Flang::Flang(const ToolChain &TC) : Tool("flang", "flang frontend", TC) {} Flang::~Flang() {} diff --git a/clang/lib/Driver/ToolChains/FreeBSD.cpp b/clang/lib/Driver/ToolChains/FreeBSD.cpp index b2525e427cf95..909ac5e992129 100644 --- a/clang/lib/Driver/ToolChains/FreeBSD.cpp +++ b/clang/lib/Driver/ToolChains/FreeBSD.cpp @@ -128,7 +128,8 @@ void freebsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(II.getFilename()); const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); } void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, @@ -358,7 +359,8 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, ToolChain.addProfileRTLibs(Args, CmdArgs); const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); } /// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly. @@ -423,6 +425,11 @@ void FreeBSD::AddCudaIncludeArgs(const ArgList &DriverArgs, CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args); } +void FreeBSD::AddHIPIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + RocmInstallation.AddHIPIncludeArgs(DriverArgs, CC1Args); +} + Tool *FreeBSD::buildAssembler() const { return new tools::freebsd::Assembler(*this); } diff --git a/clang/lib/Driver/ToolChains/FreeBSD.h b/clang/lib/Driver/ToolChains/FreeBSD.h index 7e13f48b7167a..abc0876cef260 100644 --- a/clang/lib/Driver/ToolChains/FreeBSD.h +++ b/clang/lib/Driver/ToolChains/FreeBSD.h @@ -19,10 +19,10 @@ namespace tools { /// freebsd -- Directly call GNU Binutils assembler and linker namespace freebsd { -class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Assembler : public Tool { public: Assembler(const ToolChain &TC) - : GnuTool("freebsd::Assembler", "assembler", TC) {} + : Tool("freebsd::Assembler", "assembler", TC) {} bool hasIntegratedCPP() const override { return false; } @@ -32,9 +32,9 @@ class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { const char *LinkingOutput) const override; }; -class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Linker : public Tool { public: - Linker(const ToolChain &TC) : GnuTool("freebsd::Linker", "linker", TC) {} + Linker(const ToolChain &TC) : Tool("freebsd::Linker", "linker", TC) {} bool hasIntegratedCPP() const override { return false; } bool isLinkJob() const override { return true; } @@ -68,6 +68,8 @@ class LLVM_LIBRARY_VISIBILITY FreeBSD : public Generic_ELF { llvm::opt::ArgStringList &CmdArgs) const override; void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; llvm::ExceptionHandling GetExceptionModel(const llvm::opt::ArgList &Args) const override; diff --git a/clang/lib/Driver/ToolChains/Fuchsia.cpp b/clang/lib/Driver/ToolChains/Fuchsia.cpp index 5ac10e37176c0..94e025e3055a3 100644 --- a/clang/lib/Driver/ToolChains/Fuchsia.cpp +++ b/clang/lib/Driver/ToolChains/Fuchsia.cpp @@ -164,7 +164,8 @@ void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-lc"); } - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::None(), + Exec, CmdArgs, Inputs)); } /// Fuchsia - Fuchsia tool chain which can call as(1) and ld(1) directly. diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index 93a285d42a08e..c8a7fce07ef1c 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -37,8 +37,6 @@ using namespace llvm::opt; using tools::addMultilibFlag; using tools::addPathIfExists; -void tools::GnuTool::anchor() {} - static bool forwardToGCC(const Option &O) { // Don't forward inputs from the original command line. They are added from // InputInfoList. @@ -190,7 +188,8 @@ void tools::gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, GCCName = "gcc"; const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(GCCName)); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); } void tools::gcc::Preprocessor::RenderExtraToolArgs( @@ -305,6 +304,8 @@ static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) { if (T.getEnvironment() == llvm::Triple::GNUX32) return "elf32_x86_64"; return "elf_x86_64"; + case llvm::Triple::ve: + return "elf64ve"; default: return nullptr; } @@ -341,6 +342,44 @@ static bool getStatic(const ArgList &Args) { !Args.hasArg(options::OPT_static_pie); } +void tools::gnutools::StaticLibTool::ConstructJob( + Compilation &C, const JobAction &JA, const InputInfo &Output, + const InputInfoList &Inputs, const ArgList &Args, + const char *LinkingOutput) const { + const Driver &D = getToolChain().getDriver(); + + // Silence warning for "clang -g foo.o -o foo" + Args.ClaimAllArgs(options::OPT_g_Group); + // and "clang -emit-llvm foo.o -o foo" + Args.ClaimAllArgs(options::OPT_emit_llvm); + // and for "clang -w foo.o -o foo". Other warning options are already + // handled somewhere else. + Args.ClaimAllArgs(options::OPT_w); + // Silence warnings when linking C code with a C++ '-stdlib' argument. + Args.ClaimAllArgs(options::OPT_stdlib_EQ); + + // GNU ar tool command "ar ". + ArgStringList CmdArgs; + // Create and insert file members with a deterministic index. + CmdArgs.push_back("rcsD"); + CmdArgs.push_back(Output.getFilename()); + AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); + + // Delete old output archive file if it already exists before generating a new + // archive file. + auto OutputFileName = Output.getFilename(); + if (Output.isFilename() && llvm::sys::fs::exists(OutputFileName)) { + if (std::error_code EC = llvm::sys::fs::remove(OutputFileName)) { + D.Diag(diag::err_drv_unable_to_remove_file) << EC.message(); + return; + } + } + + const char *Exec = Args.MakeArgString(getToolChain().GetStaticLibToolPath()); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); +} + void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -359,6 +398,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, const llvm::Triple::ArchType Arch = ToolChain.getArch(); const bool isAndroid = ToolChain.getTriple().isAndroid(); const bool IsIAMCU = ToolChain.getTriple().isOSIAMCU(); + const bool IsVE = ToolChain.getTriple().isVE(); const bool IsPIE = getPIE(Args, ToolChain); const bool IsStaticPIE = getStaticPIE(Args, ToolChain); const bool IsStatic = getStatic(Args); @@ -477,6 +517,11 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o"))); } + if (IsVE) { + CmdArgs.push_back("-z"); + CmdArgs.push_back("max-page-size=0x4000000"); + } + if (IsIAMCU) CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o"))); else if (HasCRTBeginEndFiles) { @@ -625,14 +670,11 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, } } - // Add HIP offloading linker script args if required. - AddHIPLinkerScript(getToolChain(), C, Output, Inputs, Args, CmdArgs, JA, - *this); - Args.AddAllArgs(CmdArgs, options::OPT_T); const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); } void tools::gnutools::Assembler::ConstructJob(Compilation &C, @@ -650,6 +692,7 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C, llvm::Reloc::Model RelocationModel; unsigned PICLevel; bool IsPIE; + const char *DefaultAssembler = "as"; std::tie(RelocationModel, PICLevel, IsPIE) = ParsePICArgs(getToolChain(), Args); @@ -870,6 +913,8 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C, CmdArgs.push_back(Args.MakeArgString("-march=" + CPUName)); break; } + case llvm::Triple::ve: + DefaultAssembler = "nas"; } for (const Arg *A : Args.filtered(options::OPT_ffile_prefix_map_EQ, @@ -894,8 +939,10 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C, for (const auto &II : Inputs) CmdArgs.push_back(II.getFilename()); - const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + const char *Exec = + Args.MakeArgString(getToolChain().GetProgramPath(DefaultAssembler)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); // Handle the debug info splitting at object creation time if we're // creating an object. @@ -2611,6 +2658,7 @@ void Generic_GCC::printVerboseInfo(raw_ostream &OS) const { // Print the information about how we detected the GCC installation. GCCInstallation.print(OS); CudaInstallation.print(OS); + RocmInstallation.print(OS); } bool Generic_GCC::IsUnwindTablesDefault(const ArgList &Args) const { diff --git a/clang/lib/Driver/ToolChains/Gnu.h b/clang/lib/Driver/ToolChains/Gnu.h index 8ef9b4fdb6cd9..52690ab4b83c2 100644 --- a/clang/lib/Driver/ToolChains/Gnu.h +++ b/clang/lib/Driver/ToolChains/Gnu.h @@ -36,23 +36,26 @@ bool findMIPSMultilibs(const Driver &D, const llvm::Triple &TargetTriple, namespace tools { -/// Base class for all GNU tools that provide the same behavior when -/// it comes to response files support -class LLVM_LIBRARY_VISIBILITY GnuTool : public Tool { - virtual void anchor(); - +/// Directly call GNU Binutils' assembler and linker. +namespace gnutools { +class LLVM_LIBRARY_VISIBILITY Assembler : public Tool { public: - GnuTool(const char *Name, const char *ShortName, const ToolChain &TC) - : Tool(Name, ShortName, TC, RF_Full, llvm::sys::WEM_CurrentCodePage) {} + Assembler(const ToolChain &TC) : Tool("GNU::Assembler", "assembler", TC) {} + + bool hasIntegratedCPP() const override { return false; } + + void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, const InputInfoList &Inputs, + const llvm::opt::ArgList &TCArgs, + const char *LinkingOutput) const override; }; -/// Directly call GNU Binutils' assembler and linker. -namespace gnutools { -class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Linker : public Tool { public: - Assembler(const ToolChain &TC) : GnuTool("GNU::Assembler", "assembler", TC) {} + Linker(const ToolChain &TC) : Tool("GNU::Linker", "linker", TC) {} bool hasIntegratedCPP() const override { return false; } + bool isLinkJob() const override { return true; } void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -60,9 +63,10 @@ class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { const char *LinkingOutput) const override; }; -class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +class LLVM_LIBRARY_VISIBILITY StaticLibTool : public Tool { public: - Linker(const ToolChain &TC) : GnuTool("GNU::Linker", "linker", TC) {} + StaticLibTool(const ToolChain &TC) + : Tool("GNU::StaticLibTool", "static-lib-linker", TC) {} bool hasIntegratedCPP() const override { return false; } bool isLinkJob() const override { return true; } @@ -76,10 +80,10 @@ class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { /// gcc - Generic GCC tool implementations. namespace gcc { -class LLVM_LIBRARY_VISIBILITY Common : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Common : public Tool { public: Common(const char *Name, const char *ShortName, const ToolChain &TC) - : GnuTool(Name, ShortName, TC) {} + : Tool(Name, ShortName, TC) {} // A gcc tool has an "integrated" assembler that it will call to produce an // object. Let it use that assembler so that we don't have to deal with diff --git a/clang/lib/Driver/ToolChains/HIP.cpp b/clang/lib/Driver/ToolChains/HIP.cpp index b9143f98f1526..7d17f809690ea 100644 --- a/clang/lib/Driver/ToolChains/HIP.cpp +++ b/clang/lib/Driver/ToolChains/HIP.cpp @@ -57,18 +57,43 @@ void AMDGCN::Linker::constructLldCommand(Compilation &C, const JobAction &JA, const llvm::opt::ArgList &Args) const { // Construct lld command. // The output from ld.lld is an HSA code object file. - ArgStringList LldArgs{"-flavor", - "gnu", - "--no-undefined", - "-shared", - "-mllvm", - "-amdgpu-internalize-symbols", - "-o", - Output.getFilename()}; + ArgStringList LldArgs{"-flavor", "gnu", "--no-undefined", "-shared", + "-plugin-opt=-amdgpu-internalize-symbols"}; + + auto &TC = getToolChain(); + auto &D = TC.getDriver(); + assert(!Inputs.empty() && "Must have at least one input."); + addLTOOptions(TC, Args, LldArgs, Output, Inputs[0], + D.getLTOMode() == LTOK_Thin); + + // Extract all the -m options + std::vector Features; + amdgpu::getAMDGPUTargetFeatures(D, Args, Features); + + // Add features to mattr such as cumode + std::string MAttrString = "-plugin-opt=-mattr="; + for (auto OneFeature : unifyTargetFeatures(Features)) { + MAttrString.append(Args.MakeArgString(OneFeature)); + if (OneFeature != Features.back()) + MAttrString.append(","); + } + if (!Features.empty()) + LldArgs.push_back(Args.MakeArgString(MAttrString)); + + for (const Arg *A : Args.filtered(options::OPT_mllvm)) { + LldArgs.push_back( + Args.MakeArgString(Twine("-plugin-opt=") + A->getValue(0))); + } + + if (C.getDriver().isSaveTempsEnabled()) + LldArgs.push_back("-save-temps"); + + LldArgs.append({"-o", Output.getFilename()}); for (auto Input : Inputs) LldArgs.push_back(Input.getFilename()); const char *Lld = Args.MakeArgString(getToolChain().GetProgramPath("lld")); - C.addCommand(std::make_unique(JA, *this, Lld, LldArgs, Inputs)); + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::None(), + Lld, LldArgs, Inputs)); } // Construct a clang-offload-bundler command to bundle code objects for @@ -101,7 +126,78 @@ void AMDGCN::constructHIPFatbinCommand(Compilation &C, const JobAction &JA, const char *Bundler = Args.MakeArgString( T.getToolChain().GetProgramPath("clang-offload-bundler")); - C.addCommand(std::make_unique(JA, T, Bundler, BundlerArgs, Inputs)); + C.addCommand(std::make_unique(JA, T, ResponseFileSupport::None(), + Bundler, BundlerArgs, Inputs)); +} + +/// Add Generated HIP Object File which has device images embedded into the +/// host to the argument list for linking. Using MC directives, embed the +/// device code and also define symbols required by the code generation so that +/// the image can be retrieved at runtime. +void AMDGCN::Linker::constructGenerateObjFileFromHIPFatBinary( + Compilation &C, const InputInfo &Output, + const InputInfoList &Inputs, const ArgList &Args, + const JobAction &JA) const { + const ToolChain &TC = getToolChain(); + std::string Name = + std::string(llvm::sys::path::stem(Output.getFilename())); + + // Create Temp Object File Generator, + // Offload Bundled file and Bundled Object file. + // Keep them if save-temps is enabled. + const char *McinFile; + const char *BundleFile; + if (C.getDriver().isSaveTempsEnabled()) { + McinFile = C.getArgs().MakeArgString(Name + ".mcin"); + BundleFile = C.getArgs().MakeArgString(Name + ".hipfb"); + } else { + auto TmpNameMcin = C.getDriver().GetTemporaryPath(Name, "mcin"); + McinFile = C.addTempFile(C.getArgs().MakeArgString(TmpNameMcin)); + auto TmpNameFb = C.getDriver().GetTemporaryPath(Name, "hipfb"); + BundleFile = C.addTempFile(C.getArgs().MakeArgString(TmpNameFb)); + } + constructHIPFatbinCommand(C, JA, BundleFile, Inputs, Args, *this); + + // Create a buffer to write the contents of the temp obj generator. + std::string ObjBuffer; + llvm::raw_string_ostream ObjStream(ObjBuffer); + + // Add MC directives to embed target binaries. We ensure that each + // section and image is 16-byte aligned. This is not mandatory, but + // increases the likelihood of data to be aligned with a cache block + // in several main host machines. + ObjStream << "# HIP Object Generator\n"; + ObjStream << "# *** Automatically generated by Clang ***\n"; + ObjStream << " .type __hip_fatbin,@object\n"; + ObjStream << " .section .hip_fatbin,\"aMS\",@progbits,1\n"; + ObjStream << " .data\n"; + ObjStream << " .globl __hip_fatbin\n"; + ObjStream << " .p2align 3\n"; + ObjStream << "__hip_fatbin:\n"; + ObjStream << " .incbin \"" << BundleFile << "\"\n"; + ObjStream.flush(); + + // Dump the contents of the temp object file gen if the user requested that. + // We support this option to enable testing of behavior with -###. + if (C.getArgs().hasArg(options::OPT_fhip_dump_offload_linker_script)) + llvm::errs() << ObjBuffer; + + // Open script file and write the contents. + std::error_code EC; + llvm::raw_fd_ostream Objf(McinFile, EC, llvm::sys::fs::OF_None); + + if (EC) { + C.getDriver().Diag(clang::diag::err_unable_to_make_temp) << EC.message(); + return; + } + + Objf << ObjBuffer; + + ArgStringList McArgs{"-o", Output.getFilename(), + McinFile, "--filetype=obj"}; + const char *Mc = Args.MakeArgString(TC.GetProgramPath("llvm-mc")); + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::None(), + Mc, McArgs, Inputs)); } // For amdgcn the inputs of the linker job are device bitcode and output is @@ -111,6 +207,10 @@ void AMDGCN::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { + if (Inputs.size() > 0 && + Inputs[0].getType() == types::TY_Image && + JA.getType() == types::TY_Object) + return constructGenerateObjFileFromHIPFatBinary(C, Output, Inputs, Args, JA); if (JA.getType() == types::TY_HIP_FATBIN) return constructHIPFatbinCommand(C, JA, Output.getFilename(), Inputs, Args, *this); @@ -179,8 +279,7 @@ void HIPToolChain::addClangTargetOptions( ArgStringList LibraryPaths; // Find in --hip-device-lib-path and HIP_LIBRARY_PATH. - for (auto Path : - DriverArgs.getAllArgValues(options::OPT_hip_device_lib_path_EQ)) + for (auto Path : RocmInstallation.getRocmDeviceLibPathArg()) LibraryPaths.push_back(DriverArgs.MakeArgString(Path)); addDirectoryList(DriverArgs, LibraryPaths, "", "HIP_DEVICE_LIB_PATH"); @@ -191,14 +290,14 @@ void HIPToolChain::addClangTargetOptions( for (auto Lib : BCLibs) addBCLib(getDriver(), DriverArgs, CC1Args, LibraryPaths, Lib); } else { - if (!RocmInstallation.isValid()) { - getDriver().Diag(diag::err_drv_no_rocm_installation); + if (!RocmInstallation.hasDeviceLibrary()) { + getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 0; return; } std::string LibDeviceFile = RocmInstallation.getLibDeviceFile(CanonArch); if (LibDeviceFile.empty()) { - getDriver().Diag(diag::err_drv_no_rocm_device_lib) << GpuArch; + getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 1 << GpuArch; return; } diff --git a/clang/lib/Driver/ToolChains/HIP.h b/clang/lib/Driver/ToolChains/HIP.h index fa6984ed9f52f..5e2be7138579a 100644 --- a/clang/lib/Driver/ToolChains/HIP.h +++ b/clang/lib/Driver/ToolChains/HIP.h @@ -42,6 +42,13 @@ class LLVM_LIBRARY_VISIBILITY Linker : public Tool { void constructLldCommand(Compilation &C, const JobAction &JA, const InputInfoList &Inputs, const InputInfo &Output, const llvm::opt::ArgList &Args) const; + + // Construct command for creating Object from HIP fatbin. + void constructGenerateObjFileFromHIPFatBinary(Compilation &C, + const InputInfo &Output, + const InputInfoList &Inputs, + const llvm::opt::ArgList &Args, + const JobAction &JA) const; }; } // end namespace AMDGCN diff --git a/clang/lib/Driver/ToolChains/Hexagon.cpp b/clang/lib/Driver/ToolChains/Hexagon.cpp index cf0a0335fbdf7..775f6e1094fa6 100644 --- a/clang/lib/Driver/ToolChains/Hexagon.cpp +++ b/clang/lib/Driver/ToolChains/Hexagon.cpp @@ -189,7 +189,8 @@ void hexagon::Assembler::ConstructJob(Compilation &C, const JobAction &JA, } auto *Exec = Args.MakeArgString(HTC.GetProgramPath(AsName)); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); } void hexagon::Linker::RenderExtraToolArgs(const JobAction &JA, @@ -406,7 +407,8 @@ void hexagon::Linker::ConstructJob(Compilation &C, const JobAction &JA, LinkingOutput); const char *Exec = Args.MakeArgString(HTC.GetLinkerPath()); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); } // Hexagon tools end. diff --git a/clang/lib/Driver/ToolChains/Hexagon.h b/clang/lib/Driver/ToolChains/Hexagon.h index 7b2af9a799ccf..c32cb7f09591a 100644 --- a/clang/lib/Driver/ToolChains/Hexagon.h +++ b/clang/lib/Driver/ToolChains/Hexagon.h @@ -20,10 +20,10 @@ namespace hexagon { // For Hexagon, we do not need to instantiate tools for PreProcess, PreCompile // and Compile. // We simply use "clang -cc1" for those actions. -class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Assembler : public Tool { public: Assembler(const ToolChain &TC) - : GnuTool("hexagon::Assembler", "hexagon-as", TC) {} + : Tool("hexagon::Assembler", "hexagon-as", TC) {} bool hasIntegratedCPP() const override { return false; } @@ -35,9 +35,9 @@ class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { const char *LinkingOutput) const override; }; -class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Linker : public Tool { public: - Linker(const ToolChain &TC) : GnuTool("hexagon::Linker", "hexagon-ld", TC) {} + Linker(const ToolChain &TC) : Tool("hexagon::Linker", "hexagon-ld", TC) {} bool hasIntegratedCPP() const override { return false; } bool isLinkJob() const override { return true; } diff --git a/clang/lib/Driver/ToolChains/InterfaceStubs.cpp b/clang/lib/Driver/ToolChains/InterfaceStubs.cpp index 8f947e79bd1f1..f7c11421e8094 100644 --- a/clang/lib/Driver/ToolChains/InterfaceStubs.cpp +++ b/clang/lib/Driver/ToolChains/InterfaceStubs.cpp @@ -54,8 +54,9 @@ void Merger::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString(InputFilename.c_str())); } - C.addCommand(std::make_unique(JA, *this, Args.MakeArgString(Merger), - CmdArgs, Inputs)); + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::None(), + Args.MakeArgString(Merger), CmdArgs, + Inputs)); } } // namespace ifstool } // namespace tools diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp index 222c351016a79..180350476c38b 100644 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -363,6 +363,10 @@ bool Linux::HasNativeLLVMSupport() const { return true; } Tool *Linux::buildLinker() const { return new tools::gnutools::Linker(*this); } +Tool *Linux::buildStaticLibTool() const { + return new tools::gnutools::StaticLibTool(*this); +} + Tool *Linux::buildAssembler() const { return new tools::gnutools::Assembler(*this); } @@ -537,6 +541,8 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const { Loader = X32 ? "ld-linux-x32.so.2" : "ld-linux-x86-64.so.2"; break; } + case llvm::Triple::ve: + return "/opt/nec/ve/lib/ld-linux-ve.so.1"; } if (Distro == Distro::Exherbo && diff --git a/clang/lib/Driver/ToolChains/Linux.h b/clang/lib/Driver/ToolChains/Linux.h index fba5c24441e48..6b16b0e64990d 100644 --- a/clang/lib/Driver/ToolChains/Linux.h +++ b/clang/lib/Driver/ToolChains/Linux.h @@ -57,6 +57,7 @@ class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF { protected: Tool *buildAssembler() const override; Tool *buildLinker() const override; + Tool *buildStaticLibTool() const override; std::string getMultiarchTriple(const Driver &D, const llvm::Triple &TargetTriple, diff --git a/clang/lib/Driver/ToolChains/MSP430.cpp b/clang/lib/Driver/ToolChains/MSP430.cpp index 1c507655541f8..b0bc2e014b487 100644 --- a/clang/lib/Driver/ToolChains/MSP430.cpp +++ b/clang/lib/Driver/ToolChains/MSP430.cpp @@ -227,6 +227,7 @@ void msp430::Linker::ConstructJob(Compilation &C, const JobAction &JA, } CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); - C.addCommand(std::make_unique(JA, *this, Args.MakeArgString(Linker), - CmdArgs, Inputs)); + C.addCommand( + std::make_unique(JA, *this, ResponseFileSupport::AtFileCurCP(), + Args.MakeArgString(Linker), CmdArgs, Inputs)); } diff --git a/clang/lib/Driver/ToolChains/MSP430.h b/clang/lib/Driver/ToolChains/MSP430.h index ff5002b8b553d..58fd158cd12f9 100644 --- a/clang/lib/Driver/ToolChains/MSP430.h +++ b/clang/lib/Driver/ToolChains/MSP430.h @@ -52,10 +52,9 @@ class LLVM_LIBRARY_VISIBILITY MSP430ToolChain : public Generic_ELF { namespace tools { namespace msp430 { -class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Linker : public Tool { public: - Linker(const ToolChain &TC) - : GnuTool("MSP430::Linker", "msp430-elf-ld", TC) {} + Linker(const ToolChain &TC) : Tool("MSP430::Linker", "msp430-elf-ld", TC) {} bool hasIntegratedCPP() const override { return false; } bool isLinkJob() const override { return true; } void ConstructJob(Compilation &C, const JobAction &JA, diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp index 8271ca780f801..6b3c00e2ab6d5 100644 --- a/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/clang/lib/Driver/ToolChains/MSVC.cpp @@ -592,8 +592,9 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, linkPath = TC.GetProgramPath(Linker.str().c_str()); } - auto LinkCmd = std::make_unique( - JA, *this, Args.MakeArgString(linkPath), CmdArgs, Inputs); + auto LinkCmd = + std::make_unique(JA, *this, ResponseFileSupport::AtFileUTF16(), + Args.MakeArgString(linkPath), CmdArgs, Inputs); if (!Environment.empty()) LinkCmd->setEnvironment(Environment); C.addCommand(std::move(LinkCmd)); @@ -733,8 +734,9 @@ std::unique_ptr visualstudio::Compiler::GetCommand( CmdArgs.push_back(Fo); std::string Exec = FindVisualStudioExecutable(getToolChain(), "cl.exe"); - return std::make_unique(JA, *this, Args.MakeArgString(Exec), - CmdArgs, Inputs); + return std::make_unique(JA, *this, + ResponseFileSupport::AtFileUTF16(), + Args.MakeArgString(Exec), CmdArgs, Inputs); } MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple, @@ -805,6 +807,7 @@ void MSVCToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs, void MSVCToolChain::printVerboseInfo(raw_ostream &OS) const { CudaInstallation.print(OS); + RocmInstallation.print(OS); } // Windows SDKs and VC Toolchains group their contents into subdirectories based diff --git a/clang/lib/Driver/ToolChains/MSVC.h b/clang/lib/Driver/ToolChains/MSVC.h index 85208eaa3cc31..dba99ed77246c 100644 --- a/clang/lib/Driver/ToolChains/MSVC.h +++ b/clang/lib/Driver/ToolChains/MSVC.h @@ -24,9 +24,7 @@ namespace tools { namespace visualstudio { class LLVM_LIBRARY_VISIBILITY Linker : public Tool { public: - Linker(const ToolChain &TC) - : Tool("visualstudio::Linker", "linker", TC, RF_Full, - llvm::sys::WEM_UTF16) {} + Linker(const ToolChain &TC) : Tool("visualstudio::Linker", "linker", TC) {} bool hasIntegratedCPP() const override { return false; } bool isLinkJob() const override { return true; } @@ -40,8 +38,7 @@ class LLVM_LIBRARY_VISIBILITY Linker : public Tool { class LLVM_LIBRARY_VISIBILITY Compiler : public Tool { public: Compiler(const ToolChain &TC) - : Tool("visualstudio::Compiler", "compiler", TC, RF_Full, - llvm::sys::WEM_UTF16) {} + : Tool("visualstudio::Compiler", "compiler", TC) {} bool hasIntegratedAssembler() const override { return true; } bool hasIntegratedCPP() const override { return true; } diff --git a/clang/lib/Driver/ToolChains/MinGW.cpp b/clang/lib/Driver/ToolChains/MinGW.cpp index 3c2ba40323d92..a1a1b413fb6c6 100644 --- a/clang/lib/Driver/ToolChains/MinGW.cpp +++ b/clang/lib/Driver/ToolChains/MinGW.cpp @@ -50,7 +50,8 @@ void tools::MinGW::Assembler::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(II.getFilename()); const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::None(), + Exec, CmdArgs, Inputs)); if (Args.hasArg(options::OPT_gsplit_dwarf)) SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, @@ -321,7 +322,8 @@ void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA, } } const char *Exec = Args.MakeArgString(TC.GetLinkerPath()); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs)); } // Simplified from Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple. @@ -396,7 +398,8 @@ llvm::ErrorOr toolchains::MinGW::findClangRelativeSysroot() { toolchains::MinGW::MinGW(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) - : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) { + : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args), + RocmInstallation(D, Triple, Args) { getProgramPaths().push_back(getDriver().getInstalledDir()); if (getDriver().SysRoot.size()) @@ -498,8 +501,14 @@ void toolchains::MinGW::AddCudaIncludeArgs(const ArgList &DriverArgs, CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args); } +void toolchains::MinGW::AddHIPIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + RocmInstallation.AddHIPIncludeArgs(DriverArgs, CC1Args); +} + void toolchains::MinGW::printVerboseInfo(raw_ostream &OS) const { CudaInstallation.print(OS); + RocmInstallation.print(OS); } // Include directories for various hosts: diff --git a/clang/lib/Driver/ToolChains/MinGW.h b/clang/lib/Driver/ToolChains/MinGW.h index 6752a405be879..2f1559fcf34cd 100644 --- a/clang/lib/Driver/ToolChains/MinGW.h +++ b/clang/lib/Driver/ToolChains/MinGW.h @@ -11,8 +11,10 @@ #include "Cuda.h" #include "Gnu.h" +#include "ROCm.h" #include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" +#include "llvm/Support/ErrorOr.h" namespace clang { namespace driver { @@ -34,8 +36,7 @@ class LLVM_LIBRARY_VISIBILITY Assembler : public Tool { class LLVM_LIBRARY_VISIBILITY Linker : public Tool { public: - Linker(const ToolChain &TC) - : Tool("MinGW::Linker", "linker", TC, Tool::RF_Full) {} + Linker(const ToolChain &TC) : Tool("MinGW::Linker", "linker", TC) {} bool hasIntegratedCPP() const override { return false; } bool isLinkJob() const override { return true; } @@ -81,6 +82,8 @@ class LLVM_LIBRARY_VISIBILITY MinGW : public ToolChain { void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; void printVerboseInfo(raw_ostream &OS) const override; @@ -91,6 +94,7 @@ class LLVM_LIBRARY_VISIBILITY MinGW : public ToolChain { private: CudaInstallationDetector CudaInstallation; + RocmInstallationDetector RocmInstallation; std::string Base; std::string GccLibDir; diff --git a/clang/lib/Driver/ToolChains/Minix.cpp b/clang/lib/Driver/ToolChains/Minix.cpp index 6947049ea52ee..d0314795620ce 100644 --- a/clang/lib/Driver/ToolChains/Minix.cpp +++ b/clang/lib/Driver/ToolChains/Minix.cpp @@ -36,7 +36,8 @@ void tools::minix::Assembler::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(II.getFilename()); const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); } void tools::minix::Linker::ConstructJob(Compilation &C, const JobAction &JA, @@ -88,7 +89,8 @@ void tools::minix::Linker::ConstructJob(Compilation &C, const JobAction &JA, } const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); } /// Minix - Minix tool chain which can call as(1) and ld(1) directly. diff --git a/clang/lib/Driver/ToolChains/Minix.h b/clang/lib/Driver/ToolChains/Minix.h index 1ed6acebab9c0..af8d59c5085a9 100644 --- a/clang/lib/Driver/ToolChains/Minix.h +++ b/clang/lib/Driver/ToolChains/Minix.h @@ -18,10 +18,9 @@ namespace driver { namespace tools { /// minix -- Directly call GNU Binutils assembler and linker namespace minix { -class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Assembler : public Tool { public: - Assembler(const ToolChain &TC) - : GnuTool("minix::Assembler", "assembler", TC) {} + Assembler(const ToolChain &TC) : Tool("minix::Assembler", "assembler", TC) {} bool hasIntegratedCPP() const override { return false; } @@ -31,9 +30,9 @@ class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { const char *LinkingOutput) const override; }; -class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Linker : public Tool { public: - Linker(const ToolChain &TC) : GnuTool("minix::Linker", "linker", TC) {} + Linker(const ToolChain &TC) : Tool("minix::Linker", "linker", TC) {} bool hasIntegratedCPP() const override { return false; } bool isLinkJob() const override { return true; } diff --git a/clang/lib/Driver/ToolChains/Myriad.cpp b/clang/lib/Driver/ToolChains/Myriad.cpp index 2ce0f13ce3d1a..84fe4748b6faf 100644 --- a/clang/lib/Driver/ToolChains/Myriad.cpp +++ b/clang/lib/Driver/ToolChains/Myriad.cpp @@ -77,8 +77,9 @@ void tools::SHAVE::Compiler::ConstructJob(Compilation &C, const JobAction &JA, std::string Exec = Args.MakeArgString(getToolChain().GetProgramPath("moviCompile")); - C.addCommand(std::make_unique(JA, *this, Args.MakeArgString(Exec), - CmdArgs, Inputs)); + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::None(), + Args.MakeArgString(Exec), CmdArgs, + Inputs)); } void tools::SHAVE::Assembler::ConstructJob(Compilation &C, const JobAction &JA, @@ -112,8 +113,9 @@ void tools::SHAVE::Assembler::ConstructJob(Compilation &C, const JobAction &JA, std::string Exec = Args.MakeArgString(getToolChain().GetProgramPath("moviAsm")); - C.addCommand(std::make_unique(JA, *this, Args.MakeArgString(Exec), - CmdArgs, Inputs)); + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::None(), + Args.MakeArgString(Exec), CmdArgs, + Inputs)); } void tools::Myriad::Linker::ConstructJob(Compilation &C, const JobAction &JA, @@ -198,8 +200,9 @@ void tools::Myriad::Linker::ConstructJob(Compilation &C, const JobAction &JA, std::string Exec = Args.MakeArgString(TC.GetProgramPath("sparc-myriad-rtems-ld")); - C.addCommand(std::make_unique(JA, *this, Args.MakeArgString(Exec), - CmdArgs, Inputs)); + C.addCommand( + std::make_unique(JA, *this, ResponseFileSupport::AtFileCurCP(), + Args.MakeArgString(Exec), CmdArgs, Inputs)); } MyriadToolChain::MyriadToolChain(const Driver &D, const llvm::Triple &Triple, diff --git a/clang/lib/Driver/ToolChains/Myriad.h b/clang/lib/Driver/ToolChains/Myriad.h index 9f5225fbc62c9..cae574bdcfea3 100644 --- a/clang/lib/Driver/ToolChains/Myriad.h +++ b/clang/lib/Driver/ToolChains/Myriad.h @@ -49,9 +49,9 @@ class LLVM_LIBRARY_VISIBILITY Assembler : public Tool { /// whereas the linker, which accepts code for a mixture of Sparc and SHAVE, /// is in the Myriad namespace. namespace Myriad { -class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Linker : public Tool { public: - Linker(const ToolChain &TC) : GnuTool("shave::Linker", "ld", TC) {} + Linker(const ToolChain &TC) : Tool("shave::Linker", "ld", TC) {} bool hasIntegratedCPP() const override { return false; } bool isLinkJob() const override { return true; } void ConstructJob(Compilation &C, const JobAction &JA, diff --git a/clang/lib/Driver/ToolChains/NaCl.cpp b/clang/lib/Driver/ToolChains/NaCl.cpp index 97241c8840273..15a773675299a 100644 --- a/clang/lib/Driver/ToolChains/NaCl.cpp +++ b/clang/lib/Driver/ToolChains/NaCl.cpp @@ -193,7 +193,8 @@ void nacltools::Linker::ConstructJob(Compilation &C, const JobAction &JA, } const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); } /// NaCl Toolchain diff --git a/clang/lib/Driver/ToolChains/NaCl.h b/clang/lib/Driver/ToolChains/NaCl.h index ab243f8087bb1..5e5fdb583bb60 100644 --- a/clang/lib/Driver/ToolChains/NaCl.h +++ b/clang/lib/Driver/ToolChains/NaCl.h @@ -27,9 +27,9 @@ class LLVM_LIBRARY_VISIBILITY AssemblerARM : public gnutools::Assembler { const char *LinkingOutput) const override; }; -class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Linker : public Tool { public: - Linker(const ToolChain &TC) : GnuTool("NaCl::Linker", "linker", TC) {} + Linker(const ToolChain &TC) : Tool("NaCl::Linker", "linker", TC) {} bool hasIntegratedCPP() const override { return false; } bool isLinkJob() const override { return true; } diff --git a/clang/lib/Driver/ToolChains/NetBSD.cpp b/clang/lib/Driver/ToolChains/NetBSD.cpp index 0100a387d6c35..253ee6ce0f721 100644 --- a/clang/lib/Driver/ToolChains/NetBSD.cpp +++ b/clang/lib/Driver/ToolChains/NetBSD.cpp @@ -103,7 +103,8 @@ void netbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(II.getFilename()); const char *Exec = Args.MakeArgString((getToolChain().GetProgramPath("as"))); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); } void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, @@ -337,7 +338,8 @@ void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, ToolChain.addProfileRTLibs(Args, CmdArgs); const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); } /// NetBSD - NetBSD tool chain which can call as(1) and ld(1) directly. diff --git a/clang/lib/Driver/ToolChains/NetBSD.h b/clang/lib/Driver/ToolChains/NetBSD.h index 6d404263f625c..8348554fd1492 100644 --- a/clang/lib/Driver/ToolChains/NetBSD.h +++ b/clang/lib/Driver/ToolChains/NetBSD.h @@ -19,10 +19,9 @@ namespace tools { /// netbsd -- Directly call GNU Binutils assembler and linker namespace netbsd { -class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Assembler : public Tool { public: - Assembler(const ToolChain &TC) - : GnuTool("netbsd::Assembler", "assembler", TC) {} + Assembler(const ToolChain &TC) : Tool("netbsd::Assembler", "assembler", TC) {} bool hasIntegratedCPP() const override { return false; } @@ -32,9 +31,9 @@ class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { const char *LinkingOutput) const override; }; -class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Linker : public Tool { public: - Linker(const ToolChain &TC) : GnuTool("netbsd::Linker", "linker", TC) {} + Linker(const ToolChain &TC) : Tool("netbsd::Linker", "linker", TC) {} bool hasIntegratedCPP() const override { return false; } bool isLinkJob() const override { return true; } diff --git a/clang/lib/Driver/ToolChains/OpenBSD.cpp b/clang/lib/Driver/ToolChains/OpenBSD.cpp index 80343c0394cb5..9c1a9c5f82280 100644 --- a/clang/lib/Driver/ToolChains/OpenBSD.cpp +++ b/clang/lib/Driver/ToolChains/OpenBSD.cpp @@ -89,7 +89,8 @@ void openbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(II.getFilename()); const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); } void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, @@ -227,7 +228,8 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, } const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs)); } SanitizerMask OpenBSD::getSupportedSanitizers() const { diff --git a/clang/lib/Driver/ToolChains/OpenBSD.h b/clang/lib/Driver/ToolChains/OpenBSD.h index 9f1ee0f66402b..897eee57ab684 100644 --- a/clang/lib/Driver/ToolChains/OpenBSD.h +++ b/clang/lib/Driver/ToolChains/OpenBSD.h @@ -19,10 +19,10 @@ namespace tools { /// openbsd -- Directly call GNU Binutils assembler and linker namespace openbsd { -class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Assembler : public Tool { public: Assembler(const ToolChain &TC) - : GnuTool("openbsd::Assembler", "assembler", TC) {} + : Tool("openbsd::Assembler", "assembler", TC) {} bool hasIntegratedCPP() const override { return false; } @@ -32,9 +32,9 @@ class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { const char *LinkingOutput) const override; }; -class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Linker : public Tool { public: - Linker(const ToolChain &TC) : GnuTool("openbsd::Linker", "linker", TC) {} + Linker(const ToolChain &TC) : Tool("openbsd::Linker", "linker", TC) {} bool hasIntegratedCPP() const override { return false; } bool isLinkJob() const override { return true; } diff --git a/clang/lib/Driver/ToolChains/PS4CPU.cpp b/clang/lib/Driver/ToolChains/PS4CPU.cpp index 49f26c3701681..6dc81899cbaac 100644 --- a/clang/lib/Driver/ToolChains/PS4CPU.cpp +++ b/clang/lib/Driver/ToolChains/PS4CPU.cpp @@ -66,7 +66,8 @@ void tools::PS4cpu::Assemble::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("orbis-as")); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs)); } static void AddPS4SanitizerArgs(const ToolChain &TC, ArgStringList &CmdArgs) { @@ -151,7 +152,8 @@ void tools::PS4cpu::Link::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(ToolChain.GetProgramPath("orbis-ld")); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs)); } toolchains::PS4CPU::PS4CPU(const Driver &D, const llvm::Triple &Triple, diff --git a/clang/lib/Driver/ToolChains/PS4CPU.h b/clang/lib/Driver/ToolChains/PS4CPU.h index 6b1efd25f43a8..968be015d4113 100644 --- a/clang/lib/Driver/ToolChains/PS4CPU.h +++ b/clang/lib/Driver/ToolChains/PS4CPU.h @@ -26,8 +26,7 @@ void addSanitizerArgs(const ToolChain &TC, llvm::opt::ArgStringList &CmdArgs); class LLVM_LIBRARY_VISIBILITY Assemble : public Tool { public: - Assemble(const ToolChain &TC) - : Tool("PS4cpu::Assemble", "assembler", TC, RF_Full) {} + Assemble(const ToolChain &TC) : Tool("PS4cpu::Assemble", "assembler", TC) {} bool hasIntegratedCPP() const override { return false; } @@ -40,7 +39,7 @@ class LLVM_LIBRARY_VISIBILITY Assemble : public Tool { class LLVM_LIBRARY_VISIBILITY Link : public Tool { public: - Link(const ToolChain &TC) : Tool("PS4cpu::Link", "linker", TC, RF_Full) {} + Link(const ToolChain &TC) : Tool("PS4cpu::Link", "linker", TC) {} bool hasIntegratedCPP() const override { return false; } bool isLinkJob() const override { return true; } diff --git a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp index 21106d0038590..cc912d94cb92f 100644 --- a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp +++ b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp @@ -191,7 +191,8 @@ void RISCV::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); - C.addCommand(std::make_unique(JA, *this, Args.MakeArgString(Linker), - CmdArgs, Inputs)); + C.addCommand( + std::make_unique(JA, *this, ResponseFileSupport::AtFileCurCP(), + Args.MakeArgString(Linker), CmdArgs, Inputs)); } // RISCV tools end. diff --git a/clang/lib/Driver/ToolChains/RISCVToolchain.h b/clang/lib/Driver/ToolChains/RISCVToolchain.h index b40ef366ff492..4734aee5f1ab7 100644 --- a/clang/lib/Driver/ToolChains/RISCVToolchain.h +++ b/clang/lib/Driver/ToolChains/RISCVToolchain.h @@ -46,9 +46,9 @@ class LLVM_LIBRARY_VISIBILITY RISCVToolChain : public Generic_ELF { namespace tools { namespace RISCV { -class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Linker : public Tool { public: - Linker(const ToolChain &TC) : GnuTool("RISCV::Linker", "ld", TC) {} + Linker(const ToolChain &TC) : Tool("RISCV::Linker", "ld", TC) {} bool hasIntegratedCPP() const override { return false; } bool isLinkJob() const override { return true; } void ConstructJob(Compilation &C, const JobAction &JA, diff --git a/clang/lib/Driver/ToolChains/ROCm.h b/clang/lib/Driver/ToolChains/ROCm.h index 779e2e133becd..962c72fedfe07 100644 --- a/clang/lib/Driver/ToolChains/ROCm.h +++ b/clang/lib/Driver/ToolChains/ROCm.h @@ -18,6 +18,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/Triple.h" #include "llvm/Option/ArgList.h" +#include "llvm/Support/VersionTuple.h" namespace clang { namespace driver { @@ -38,11 +39,43 @@ class RocmInstallationDetector { } }; + // Installation path candidate. + struct Candidate { + llvm::SmallString<0> Path; + bool StrictChecking; + + Candidate(std::string Path, bool StrictChecking = false) + : Path(Path), StrictChecking(StrictChecking) {} + }; + const Driver &D; - bool IsValid = false; - // RocmVersion Version = RocmVersion::UNKNOWN; + bool HasHIPRuntime = false; + bool HasDeviceLibrary = false; + + // Default version if not detected or specified. + const unsigned DefaultVersionMajor = 3; + const unsigned DefaultVersionMinor = 5; + const char *DefaultVersionPatch = "0"; + + // The version string in Major.Minor.Patch format. + std::string DetectedVersion; + // Version containing major and minor. + llvm::VersionTuple VersionMajorMinor; + // Version containing patch. + std::string VersionPatch; + + // ROCm path specified by --rocm-path. + StringRef RocmPathArg; + // ROCm device library paths specified by --rocm-device-lib-path. + std::vector RocmDeviceLibPathArg; + // HIP version specified by --hip-version. + StringRef HIPVersionArg; + // Wheter -nogpulib is specified. + bool NoBuiltinLibs = false; + + // Paths SmallString<0> InstallPath; - // SmallString<0> BinPath; + SmallString<0> BinPath; SmallString<0> LibPath; SmallString<0> LibDevicePath; SmallString<0> IncludePath; @@ -74,11 +107,15 @@ class RocmInstallationDetector { // CheckRocmVersionSupportsArch. mutable llvm::SmallSet ArchsWithBadVersion; - void scanLibDevicePath(); + void scanLibDevicePath(llvm::StringRef Path); + void ParseHIPVersionFile(llvm::StringRef V); + SmallVector getInstallationPathCandidates(); public: RocmInstallationDetector(const Driver &D, const llvm::Triple &HostTriple, - const llvm::opt::ArgList &Args); + const llvm::opt::ArgList &Args, + bool DetectHIPRuntime = true, + bool DetectDeviceLib = false); /// Add arguments needed to link default bitcode libraries. void addCommonBitcodeLibCC1Args(const llvm::opt::ArgList &DriverArgs, @@ -93,8 +130,12 @@ class RocmInstallationDetector { /// most one error per Arch. void CheckRocmVersionSupportsArch(CudaArch Arch) const; - /// Check whether we detected a valid Rocm install. - bool isValid() const { return IsValid; } + /// Check whether we detected a valid HIP runtime. + bool hasHIPRuntime() const { return HasHIPRuntime; } + + /// Check whether we detected a valid ROCm device library. + bool hasDeviceLibrary() const { return HasDeviceLibrary; } + /// Print information about the detected ROCm installation. void print(raw_ostream &OS) const; @@ -163,6 +204,22 @@ class RocmInstallationDetector { void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const; + + void detectDeviceLibrary(); + void detectHIPRuntime(); + + /// Get the values for --rocm-device-lib-path arguments + std::vector getRocmDeviceLibPathArg() const { + return RocmDeviceLibPathArg; + } + + /// Get the value for --rocm-path argument + StringRef getRocmPathArg() const { return RocmPathArg; } + + /// Get the value for --hip-version argument + StringRef getHIPVersionArg() const { return HIPVersionArg; } + + std::string getHIPVersion() const { return DetectedVersion; } }; } // end namespace driver diff --git a/clang/lib/Driver/ToolChains/Solaris.cpp b/clang/lib/Driver/ToolChains/Solaris.cpp index 0a1ac0b225868..b8fdc87478bc6 100644 --- a/clang/lib/Driver/ToolChains/Solaris.cpp +++ b/clang/lib/Driver/ToolChains/Solaris.cpp @@ -41,7 +41,8 @@ void solaris::Assembler::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(II.getFilename()); const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::None(), + Exec, CmdArgs, Inputs)); } void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA, @@ -150,7 +151,8 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA, getToolChain().addProfileRTLibs(Args, CmdArgs); const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::None(), + Exec, CmdArgs, Inputs)); } static StringRef getSolarisLibSuffix(const llvm::Triple &Triple) { diff --git a/clang/lib/Driver/ToolChains/VEToolchain.cpp b/clang/lib/Driver/ToolChains/VEToolchain.cpp new file mode 100644 index 0000000000000..6ea405c0269c7 --- /dev/null +++ b/clang/lib/Driver/ToolChains/VEToolchain.cpp @@ -0,0 +1,119 @@ +//===--- VE.cpp - VE ToolChain Implementations ------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "VEToolchain.h" +#include "CommonArgs.h" +#include "clang/Driver/Compilation.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/Options.h" +#include "llvm/Option/ArgList.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" +#include // ::getenv + +using namespace clang::driver; +using namespace clang::driver::toolchains; +using namespace clang; +using namespace llvm::opt; + +/// VE tool chain +VEToolChain::VEToolChain(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args) + : Linux(D, Triple, Args) { + getProgramPaths().push_back("/opt/nec/ve/bin"); + // ProgramPaths are found via 'PATH' environment variable. + + // default file paths are: + // ${RESOURCEDIR}/lib/linux/ve (== getArchSpecificLibPath) + // /lib/../lib64 + // /usr/lib/../lib64 + // ${BINPATH}/../lib + // /lib + // /usr/lib + // + // These are OK for host, but no go for VE. So, defines them all + // from scratch here. + getFilePaths().clear(); + getFilePaths().push_back(getArchSpecificLibPath()); + getFilePaths().push_back(computeSysRoot() + "/opt/nec/ve/lib"); +} + +Tool *VEToolChain::buildAssembler() const { + return new tools::gnutools::Assembler(*this); +} + +Tool *VEToolChain::buildLinker() const { + return new tools::gnutools::Linker(*this); +} + +bool VEToolChain::isPICDefault() const { return false; } + +bool VEToolChain::isPIEDefault() const { return false; } + +bool VEToolChain::isPICDefaultForced() const { return false; } + +bool VEToolChain::SupportsProfiling() const { return false; } + +bool VEToolChain::hasBlocksRuntime() const { return false; } + +void VEToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc)) + return; + + if (DriverArgs.hasArg(options::OPT_nobuiltininc) && + DriverArgs.hasArg(options::OPT_nostdlibinc)) + return; + + if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { + SmallString<128> P(getDriver().ResourceDir); + llvm::sys::path::append(P, "include"); + addSystemInclude(DriverArgs, CC1Args, P); + } + + if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) { + if (const char *cl_include_dir = getenv("NCC_C_INCLUDE_PATH")) { + SmallVector Dirs; + const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'}; + StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr)); + ArrayRef DirVec(Dirs); + addSystemIncludes(DriverArgs, CC1Args, DirVec); + } else { + addSystemInclude(DriverArgs, CC1Args, + getDriver().SysRoot + "/opt/nec/ve/include"); + } + } +} + +void VEToolChain::addClangTargetOptions(const ArgList &DriverArgs, + ArgStringList &CC1Args, + Action::OffloadKind) const { + CC1Args.push_back("-nostdsysteminc"); + bool UseInitArrayDefault = true; + if (!DriverArgs.hasFlag(options::OPT_fuse_init_array, + options::OPT_fno_use_init_array, UseInitArrayDefault)) + CC1Args.push_back("-fno-use-init-array"); +} + +void VEToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + // TODO upstream VE libc++ patches + llvm_unreachable("The VE target has no C++ stdlib for Clang yet"); +} + +void VEToolChain::AddCXXStdlibLibArgs(const ArgList &Args, + ArgStringList &CmdArgs) const { + // TODO upstream VE libc++ patches + llvm_unreachable("The VE target has no C++ stdlib for Clang yet"); +} + +llvm::ExceptionHandling +VEToolChain::GetExceptionModel(const ArgList &Args) const { + // VE uses SjLj exceptions. + return llvm::ExceptionHandling::SjLj; +} diff --git a/clang/lib/Driver/ToolChains/VEToolchain.h b/clang/lib/Driver/ToolChains/VEToolchain.h new file mode 100644 index 0000000000000..59069c0a75959 --- /dev/null +++ b/clang/lib/Driver/ToolChains/VEToolchain.h @@ -0,0 +1,66 @@ +//===--- VE.h - VE ToolChain Implementations --------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_VE_H +#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_VE_H + +#include "Linux.h" +#include "clang/Driver/ToolChain.h" + +namespace clang { +namespace driver { +namespace toolchains { + +class LLVM_LIBRARY_VISIBILITY VEToolChain : public Linux { +public: + VEToolChain(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args); + +protected: + Tool *buildAssembler() const override; + Tool *buildLinker() const override; + +public: + bool isPICDefault() const override; + bool isPIEDefault() const override; + bool isPICDefaultForced() const override; + bool SupportsProfiling() const override; + bool hasBlocksRuntime() const override; + void + AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; + void + addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args, + Action::OffloadKind DeviceOffloadKind) const override; + void AddClangCXXStdlibIncludeArgs( + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; + void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const override; + + llvm::ExceptionHandling + GetExceptionModel(const llvm::opt::ArgList &Args) const override; + + CXXStdlibType + GetCXXStdlibType(const llvm::opt::ArgList &Args) const override { + return ToolChain::CST_Libcxx; + } + + RuntimeLibType GetDefaultRuntimeLibType() const override { + return ToolChain::RLT_CompilerRT; + } + + const char *getDefaultLinker() const override { return "nld"; } +}; + +} // end namespace toolchains +} // end namespace driver +} // end namespace clang + +#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_VE_H diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp b/clang/lib/Driver/ToolChains/WebAssembly.cpp index 48f9a9b603dbe..10168736400f8 100644 --- a/clang/lib/Driver/ToolChains/WebAssembly.cpp +++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp @@ -62,6 +62,12 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA, const char *Linker = Args.MakeArgString(getLinkerPath(Args)); ArgStringList CmdArgs; + CmdArgs.push_back("-m"); + if (getToolChain().getTriple().isArch64Bit()) + CmdArgs.push_back("wasm64"); + else + CmdArgs.push_back("wasm32"); + if (Args.hasArg(options::OPT_s)) CmdArgs.push_back("--strip-all"); @@ -108,7 +114,8 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); - C.addCommand(std::make_unique(JA, *this, Linker, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), Linker, CmdArgs, Inputs)); // When optimizing, if wasm-opt is available, run it. if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { @@ -130,7 +137,9 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString(llvm::Twine("-O") + OOpt)); CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); - C.addCommand(std::make_unique(JA, *this, WasmOpt, CmdArgs, Inputs)); + C.addCommand(std::make_unique( + JA, *this, ResponseFileSupport::AtFileCurCP(), WasmOpt, CmdArgs, + Inputs)); } } } diff --git a/clang/lib/Driver/ToolChains/WebAssembly.h b/clang/lib/Driver/ToolChains/WebAssembly.h index 67d5fce845765..616bfb5d3d0c1 100644 --- a/clang/lib/Driver/ToolChains/WebAssembly.h +++ b/clang/lib/Driver/ToolChains/WebAssembly.h @@ -18,10 +18,9 @@ namespace driver { namespace tools { namespace wasm { -class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +class LLVM_LIBRARY_VISIBILITY Linker : public Tool { public: - explicit Linker(const ToolChain &TC) - : GnuTool("wasm::Linker", "linker", TC) {} + explicit Linker(const ToolChain &TC) : Tool("wasm::Linker", "linker", TC) {} bool isLinkJob() const override { return true; } bool hasIntegratedCPP() const override { return false; } std::string getLinkerPath(const llvm::opt::ArgList &Args) const; diff --git a/clang/lib/Driver/ToolChains/XCore.cpp b/clang/lib/Driver/ToolChains/XCore.cpp index ba3a6d44addaf..5030c73c7d825 100644 --- a/clang/lib/Driver/ToolChains/XCore.cpp +++ b/clang/lib/Driver/ToolChains/XCore.cpp @@ -52,7 +52,8 @@ void tools::XCore::Assembler::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(II.getFilename()); const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc")); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::None(), + Exec, CmdArgs, Inputs)); } void tools::XCore::Linker::ConstructJob(Compilation &C, const JobAction &JA, @@ -80,7 +81,8 @@ void tools::XCore::Linker::ConstructJob(Compilation &C, const JobAction &JA, AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc")); - C.addCommand(std::make_unique(JA, *this, Exec, CmdArgs, Inputs)); + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::None(), + Exec, CmdArgs, Inputs)); } /// XCore tool chain diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index 2ac43b6cfa4bc..b1497651a8fef 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -1041,8 +1041,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { // * not remove the 'lead' ContinuationIndentWidth // * always un-indent by the operator when // BreakBeforeTernaryOperators=true - unsigned Indent = - State.Stack.back().Indent - Style.ContinuationIndentWidth; + unsigned Indent = State.Stack.back().Indent; + if (Style.AlignOperands != FormatStyle::OAS_DontAlign) { + Indent -= Style.ContinuationIndentWidth; + } if (Style.BreakBeforeTernaryOperators && State.Stack.back().UnindentOperator) Indent -= 2; diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index d83410b1f7e1a..0d277a6464af2 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -599,6 +599,8 @@ template <> struct MappingTraits { IO.mapOptional("TypenameMacros", Style.TypenameMacros); IO.mapOptional("UseCRLF", Style.UseCRLF); IO.mapOptional("UseTab", Style.UseTab); + IO.mapOptional("WhitespaceSensitiveMacros", + Style.WhitespaceSensitiveMacros); } }; @@ -933,6 +935,9 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.SortUsingDeclarations = true; LLVMStyle.StatementMacros.push_back("Q_UNUSED"); LLVMStyle.StatementMacros.push_back("QT_REQUIRE_VERSION"); + LLVMStyle.WhitespaceSensitiveMacros.push_back("STRINGIZE"); + LLVMStyle.WhitespaceSensitiveMacros.push_back("PP_STRINGIZE"); + LLVMStyle.WhitespaceSensitiveMacros.push_back("BOOST_PP_STRINGIZE"); // Defaults that differ when not C++. if (Language == FormatStyle::LK_TableGen) { diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index 2ad839a6a4f00..d4287f53fde37 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -102,6 +102,7 @@ namespace format { TYPE(TrailingUnaryOperator) \ TYPE(TypenameMacro) \ TYPE(UnaryOperator) \ + TYPE(UntouchableMacroFunc) \ TYPE(CSharpStringLiteral) \ TYPE(CSharpNamedArgumentColon) \ TYPE(CSharpNullable) \ diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp index f64ab389d02fb..1fd153d1112eb 100644 --- a/clang/lib/Format/FormatTokenLexer.cpp +++ b/clang/lib/Format/FormatTokenLexer.cpp @@ -22,13 +22,15 @@ namespace clang { namespace format { -FormatTokenLexer::FormatTokenLexer(const SourceManager &SourceMgr, FileID ID, - unsigned Column, const FormatStyle &Style, - encoding::Encoding Encoding) +FormatTokenLexer::FormatTokenLexer( + const SourceManager &SourceMgr, FileID ID, unsigned Column, + const FormatStyle &Style, encoding::Encoding Encoding, + llvm::SpecificBumpPtrAllocator &Allocator, + IdentifierTable &IdentTable) : FormatTok(nullptr), IsFirstToken(true), StateStack({LexerState::NORMAL}), Column(Column), TrailingWhitespace(0), SourceMgr(SourceMgr), ID(ID), - Style(Style), IdentTable(getFormattingLangOpts(Style)), - Keywords(IdentTable), Encoding(Encoding), FirstInLineIndex(0), + Style(Style), IdentTable(IdentTable), Keywords(IdentTable), + Encoding(Encoding), Allocator(Allocator), FirstInLineIndex(0), FormattingDisabled(false), MacroBlockBeginRegex(Style.MacroBlockBegin), MacroBlockEndRegex(Style.MacroBlockEnd) { Lex.reset(new Lexer(ID, SourceMgr.getBuffer(ID), SourceMgr, @@ -43,6 +45,11 @@ FormatTokenLexer::FormatTokenLexer(const SourceManager &SourceMgr, FileID ID, Macros.insert({&IdentTable.get(TypenameMacro), TT_TypenameMacro}); for (const std::string &NamespaceMacro : Style.NamespaceMacros) Macros.insert({&IdentTable.get(NamespaceMacro), TT_NamespaceMacro}); + for (const std::string &WhitespaceSensitiveMacro : + Style.WhitespaceSensitiveMacros) { + Macros.insert( + {&IdentTable.get(WhitespaceSensitiveMacro), TT_UntouchableMacroFunc}); + } } ArrayRef FormatTokenLexer::lex() { diff --git a/clang/lib/Format/FormatTokenLexer.h b/clang/lib/Format/FormatTokenLexer.h index 219cd46f98edf..6b08677e33697 100644 --- a/clang/lib/Format/FormatTokenLexer.h +++ b/clang/lib/Format/FormatTokenLexer.h @@ -38,7 +38,9 @@ enum LexerState { class FormatTokenLexer { public: FormatTokenLexer(const SourceManager &SourceMgr, FileID ID, unsigned Column, - const FormatStyle &Style, encoding::Encoding Encoding); + const FormatStyle &Style, encoding::Encoding Encoding, + llvm::SpecificBumpPtrAllocator &Allocator, + IdentifierTable &IdentTable); ArrayRef lex(); @@ -103,10 +105,10 @@ class FormatTokenLexer { const SourceManager &SourceMgr; FileID ID; const FormatStyle &Style; - IdentifierTable IdentTable; + IdentifierTable &IdentTable; AdditionalKeywords Keywords; encoding::Encoding Encoding; - llvm::SpecificBumpPtrAllocator Allocator; + llvm::SpecificBumpPtrAllocator &Allocator; // Index (in 'Tokens') of the last token that starts a new line. unsigned FirstInLineIndex; SmallVector Tokens; diff --git a/clang/lib/Format/TokenAnalyzer.cpp b/clang/lib/Format/TokenAnalyzer.cpp index eb98a205d5260..f1459a808ff84 100644 --- a/clang/lib/Format/TokenAnalyzer.cpp +++ b/clang/lib/Format/TokenAnalyzer.cpp @@ -64,11 +64,16 @@ TokenAnalyzer::TokenAnalyzer(const Environment &Env, const FormatStyle &Style) std::pair TokenAnalyzer::process() { tooling::Replacements Result; - FormatTokenLexer Tokens(Env.getSourceManager(), Env.getFileID(), - Env.getFirstStartColumn(), Style, Encoding); + llvm::SpecificBumpPtrAllocator Allocator; + IdentifierTable IdentTable(getFormattingLangOpts(Style)); + FormatTokenLexer Lex(Env.getSourceManager(), Env.getFileID(), + Env.getFirstStartColumn(), Style, Encoding, Allocator, - UnwrappedLineParser Parser(Style, Tokens.getKeywords(), - Env.getFirstStartColumn(), Tokens.lex(), *this); + IdentTable); + ArrayRef Toks(Lex.lex()); + SmallVector Tokens(Toks.begin(), Toks.end()); + UnwrappedLineParser Parser(Style, Lex.getKeywords(), + Env.getFirstStartColumn(), Tokens, *this); Parser.parse(); assert(UnwrappedLines.rbegin()->empty()); unsigned Penalty = 0; @@ -76,14 +81,14 @@ std::pair TokenAnalyzer::process() { LLVM_DEBUG(llvm::dbgs() << "Run " << Run << "...\n"); SmallVector AnnotatedLines; - TokenAnnotator Annotator(Style, Tokens.getKeywords()); + TokenAnnotator Annotator(Style, Lex.getKeywords()); for (unsigned i = 0, e = UnwrappedLines[Run].size(); i != e; ++i) { AnnotatedLines.push_back(new AnnotatedLine(UnwrappedLines[Run][i])); Annotator.annotate(*AnnotatedLines.back()); } std::pair RunResult = - analyze(Annotator, AnnotatedLines, Tokens); + analyze(Annotator, AnnotatedLines, Lex); LLVM_DEBUG({ llvm::dbgs() << "Replacements for run " << Run << ":\n"; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 6e8dc690eeb9a..7f8e351265127 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -160,6 +160,27 @@ class AnnotatingParser { return false; } + bool parseUntouchableParens() { + while (CurrentToken) { + CurrentToken->Finalized = true; + switch (CurrentToken->Tok.getKind()) { + case tok::l_paren: + next(); + if (!parseUntouchableParens()) + return false; + continue; + case tok::r_paren: + next(); + return true; + default: + // no-op + break; + } + next(); + } + return false; + } + bool parseParens(bool LookForDecls = false) { if (!CurrentToken) return false; @@ -171,6 +192,11 @@ class AnnotatingParser { Contexts.back().ColonIsForRangeExpr = Contexts.size() == 2 && Contexts[0].ColonIsForRangeExpr; + if (Left->Previous && Left->Previous->is(TT_UntouchableMacroFunc)) { + Left->Finalized = true; + return parseUntouchableParens(); + } + bool StartsObjCMethodExpr = false; if (FormatToken *MaybeSel = Left->Previous) { // @selector( starts a selector. @@ -1311,7 +1337,7 @@ class AnnotatingParser { TT_TypenameMacro, TT_FunctionLBrace, TT_ImplicitStringLiteral, TT_InlineASMBrace, TT_JsFatArrow, TT_LambdaArrow, TT_NamespaceMacro, TT_OverloadedOperator, TT_RegexLiteral, TT_TemplateString, - TT_ObjCStringLiteral)) + TT_ObjCStringLiteral, TT_UntouchableMacroFunc)) CurrentToken->setType(TT_Unknown); CurrentToken->Role.reset(); CurrentToken->MatchingParen = nullptr; @@ -2818,6 +2844,11 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, Left.Previous && !Left.Previous->isOneOf(tok::l_paren, tok::coloncolon, tok::l_square)); + // Ensure right pointer alignement with ellipsis e.g. int *...P + if (Left.is(tok::ellipsis) && Left.Previous && + Left.Previous->isOneOf(tok::star, tok::amp, tok::ampamp)) + return Style.PointerAlignment != FormatStyle::PAS_Right; + if (Right.is(tok::star) && Left.is(tok::l_paren)) return false; if (Left.is(tok::star) && Right.isOneOf(tok::star, tok::amp, tok::ampamp)) @@ -3970,7 +4001,7 @@ void TokenAnnotator::printDebugInfo(const AnnotatedLine &Line) { << " C=" << Tok->CanBreakBefore << " T=" << getTokenTypeName(Tok->getType()) << " S=" << Tok->SpacesRequiredBefore - << " B=" << Tok->BlockParameterCount + << " F=" << Tok->Finalized << " B=" << Tok->BlockParameterCount << " BK=" << Tok->BlockKind << " P=" << Tok->SplitPenalty << " Name=" << Tok->Tok.getName() << " L=" << Tok->TotalLength << " PPK=" << Tok->PackingKind << " FakeLParens="; diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp index 3392a055c0c67..22f27a668dccd 100644 --- a/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -1230,7 +1230,8 @@ void UnwrappedLineFormatter::formatFirstToken( // If in Whitemsmiths mode, indent start and end of blocks if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths) { - if (RootToken.isOneOf(tok::l_brace, tok::r_brace, tok::kw_case)) + if (RootToken.isOneOf(tok::l_brace, tok::r_brace, tok::kw_case, + tok::kw_default)) Indent += Style.IndentWidth; } diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 577b60bc51e22..a37386425aaed 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -2220,8 +2220,13 @@ void UnwrappedLineParser::parseLabel(bool LeftAlignLabel) { parseBlock(/*MustBeDeclaration=*/false); if (FormatTok->Tok.is(tok::kw_break)) { if (Style.BraceWrapping.AfterControlStatement == - FormatStyle::BWACS_Always) + FormatStyle::BWACS_Always) { addUnwrappedLine(); + if (!Style.IndentCaseBlocks && + Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths) { + Line->Level++; + } + } parseStructuralElement(); } addUnwrappedLine(); diff --git a/clang/lib/Frontend/ASTConsumers.cpp b/clang/lib/Frontend/ASTConsumers.cpp index 043b2541b8f87..a73cc8876d5d8 100644 --- a/clang/lib/Frontend/ASTConsumers.cpp +++ b/clang/lib/Frontend/ASTConsumers.cpp @@ -36,10 +36,10 @@ namespace { enum Kind { DumpFull, Dump, Print, None }; ASTPrinter(std::unique_ptr Out, Kind K, ASTDumpOutputFormat Format, StringRef FilterString, - bool DumpLookups = false) + bool DumpLookups = false, bool DumpDeclTypes = false) : Out(Out ? *Out : llvm::outs()), OwnedOut(std::move(Out)), OutputKind(K), OutputFormat(Format), FilterString(FilterString), - DumpLookups(DumpLookups) {} + DumpLookups(DumpLookups), DumpDeclTypes(DumpDeclTypes) {} void HandleTranslationUnit(ASTContext &Context) override { TranslationUnitDecl *D = Context.getTranslationUnitDecl(); @@ -91,8 +91,22 @@ namespace { } else if (OutputKind == Print) { PrintingPolicy Policy(D->getASTContext().getLangOpts()); D->print(Out, Policy, /*Indentation=*/0, /*PrintInstantiation=*/true); - } else if (OutputKind != None) + } else if (OutputKind != None) { D->dump(Out, OutputKind == DumpFull, OutputFormat); + } + + if (DumpDeclTypes) { + Decl *InnerD = D; + if (auto *TD = dyn_cast(D)) + InnerD = TD->getTemplatedDecl(); + + // FIXME: Support OutputFormat in type dumping. + // FIXME: Support combining -ast-dump-decl-types with -ast-dump-lookups. + if (auto *VD = dyn_cast(InnerD)) + VD->getType().dump(Out, VD->getASTContext()); + if (auto *TD = dyn_cast(InnerD)) + TD->getTypeForDecl()->dump(Out, TD->getASTContext()); + } } raw_ostream &Out; @@ -111,6 +125,9 @@ namespace { /// results will be output with a format determined by OutputKind. This is /// incompatible with OutputKind == Print. bool DumpLookups; + + /// Whether to dump the type for each declaration dumped. + bool DumpDeclTypes; }; class ASTDeclNodeLister : public ASTConsumer, @@ -146,13 +163,13 @@ clang::CreateASTPrinter(std::unique_ptr Out, std::unique_ptr clang::CreateASTDumper(std::unique_ptr Out, StringRef FilterString, bool DumpDecls, bool Deserialize, bool DumpLookups, - ASTDumpOutputFormat Format) { + bool DumpDeclTypes, ASTDumpOutputFormat Format) { assert((DumpDecls || Deserialize || DumpLookups) && "nothing to dump"); - return std::make_unique(std::move(Out), - Deserialize ? ASTPrinter::DumpFull : - DumpDecls ? ASTPrinter::Dump : - ASTPrinter::None, Format, - FilterString, DumpLookups); + return std::make_unique( + std::move(Out), + Deserialize ? ASTPrinter::DumpFull + : DumpDecls ? ASTPrinter::Dump : ASTPrinter::None, + Format, FilterString, DumpLookups, DumpDeclTypes); } std::unique_ptr clang::CreateASTDeclNodeLister() { diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index 0140a756b7dde..4613ed8d7f61f 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -815,17 +815,15 @@ std::unique_ptr CompilerInstance::createOutputFile( // Initialization Utilities bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input){ - return InitializeSourceManager( - Input, getDiagnostics(), getFileManager(), getSourceManager(), - hasPreprocessor() ? &getPreprocessor().getHeaderSearchInfo() : nullptr, - getDependencyOutputOpts(), getFrontendOpts()); + return InitializeSourceManager(Input, getDiagnostics(), getFileManager(), + getSourceManager()); } // static -bool CompilerInstance::InitializeSourceManager( - const FrontendInputFile &Input, DiagnosticsEngine &Diags, - FileManager &FileMgr, SourceManager &SourceMgr, HeaderSearch *HS, - DependencyOutputOptions &DepOpts, const FrontendOptions &Opts) { +bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input, + DiagnosticsEngine &Diags, + FileManager &FileMgr, + SourceManager &SourceMgr) { SrcMgr::CharacteristicKind Kind = Input.getKind().getFormat() == InputKind::ModuleMap ? Input.isSystem() ? SrcMgr::C_System_ModuleMap @@ -935,6 +933,19 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) { setAuxTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), TO)); } + if (!getTarget().hasStrictFP() && !getLangOpts().ExpStrictFP) { + if (getLangOpts().getFPRoundingMode() != + llvm::RoundingMode::NearestTiesToEven) { + getDiagnostics().Report(diag::warn_fe_backend_unsupported_fp_rounding); + getLangOpts().setFPRoundingMode(llvm::RoundingMode::NearestTiesToEven); + } + if (getLangOpts().getFPExceptionMode() != LangOptions::FPE_Ignore) { + getDiagnostics().Report(diag::warn_fe_backend_unsupported_fp_exceptions); + getLangOpts().setFPExceptionMode(LangOptions::FPE_Ignore); + } + // FIXME: can we disable FEnvAccess? + } + // Inform the target of the language options. // // FIXME: We shouldn't need to do this, the target should be immutable once diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 1cd483081dc2b..863c6b3ca4f31 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -117,6 +117,62 @@ CompilerInvocationBase::CompilerInvocationBase(const CompilerInvocationBase &X) CompilerInvocationBase::~CompilerInvocationBase() = default; +//===----------------------------------------------------------------------===// +// Normalizers +//===----------------------------------------------------------------------===// + +#define SIMPLE_ENUM_VALUE_TABLE +#include "clang/Driver/Options.inc" +#undef SIMPLE_ENUM_VALUE_TABLE + +static llvm::Optional normalizeSimpleEnum(OptSpecifier Opt, + unsigned TableIndex, + const ArgList &Args, + DiagnosticsEngine &Diags) { + assert(TableIndex < SimpleEnumValueTablesSize); + const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex]; + + auto *Arg = Args.getLastArg(Opt); + if (!Arg) + return None; + + StringRef ArgValue = Arg->getValue(); + for (int I = 0, E = Table.Size; I != E; ++I) + if (ArgValue == Table.Table[I].Name) + return Table.Table[I].Value; + + Diags.Report(diag::err_drv_invalid_value) + << Arg->getAsString(Args) << ArgValue; + return None; +} + +static const char *denormalizeSimpleEnum(CompilerInvocation::StringAllocator SA, + unsigned TableIndex, unsigned Value) { + assert(TableIndex < SimpleEnumValueTablesSize); + const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex]; + for (int I = 0, E = Table.Size; I != E; ++I) + if (Value == Table.Table[I].Value) + return Table.Table[I].Name; + + llvm_unreachable("The simple enum value was not correctly defined in " + "the tablegen option description"); +} + +static const char *denormalizeString(CompilerInvocation::StringAllocator SA, + unsigned TableIndex, + const std::string &Value) { + return SA(Value); +} + +static Optional normalizeTriple(OptSpecifier Opt, int TableIndex, + const ArgList &Args, + DiagnosticsEngine &Diags) { + auto *Arg = Args.getLastArg(Opt); + if (!Arg) + return None; + return llvm::Triple::normalize(Arg->getValue()); +} + //===----------------------------------------------------------------------===// // Deserialization (from args) //===----------------------------------------------------------------------===// @@ -528,25 +584,6 @@ static void ParseCommentArgs(CommentOptions &Opts, ArgList &Args) { Opts.ParseAllComments = Args.hasArg(OPT_fparse_all_comments); } -static llvm::Reloc::Model getRelocModel(ArgList &Args, - DiagnosticsEngine &Diags) { - if (Arg *A = Args.getLastArg(OPT_mrelocation_model)) { - StringRef Value = A->getValue(); - auto RM = llvm::StringSwitch>(Value) - .Case("static", llvm::Reloc::Static) - .Case("pic", llvm::Reloc::PIC_) - .Case("ropi", llvm::Reloc::ROPI) - .Case("rwpi", llvm::Reloc::RWPI) - .Case("ropi-rwpi", llvm::Reloc::ROPI_RWPI) - .Case("dynamic-no-pic", llvm::Reloc::DynamicNoPIC) - .Default(None); - if (RM.hasValue()) - return *RM; - Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Value; - } - return llvm::Reloc::PIC_; -} - /// Create a new Regex instance out of the string value in \p RpassArg. /// It returns a pointer to the newly generated Regex instance. static std::shared_ptr @@ -750,7 +787,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.setDebuggerTuning(static_cast(Val)); } Opts.DwarfVersion = getLastArgIntValue(Args, OPT_dwarf_version_EQ, 0, Diags); - Opts.DebugColumnInfo = Args.hasArg(OPT_dwarf_column_info); + Opts.DebugColumnInfo = !Args.hasArg(OPT_gno_column_info); Opts.EmitCodeView = Args.hasArg(OPT_gcodeview); Opts.CodeViewGHash = Args.hasArg(OPT_gcodeview_ghash); Opts.MacroDebugInfo = Args.hasArg(OPT_debug_info_macro); @@ -823,7 +860,6 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.RerollLoops = Args.hasArg(OPT_freroll_loops); Opts.DisableIntegratedAS = Args.hasArg(OPT_fno_integrated_as); - Opts.CallGraphProfile = !Opts.DisableIntegratedAS; Opts.Autolink = !Args.hasArg(OPT_fno_autolink); Opts.SampleProfileFile = std::string(Args.getLastArgValue(OPT_fprofile_sample_use_EQ)); @@ -905,7 +941,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.StrictFloatCastOverflow = !Args.hasArg(OPT_fno_strict_float_cast_overflow); - Opts.NoZeroInitializedInBSS = Args.hasArg(OPT_mno_zero_initialized_in_bss); + Opts.NoZeroInitializedInBSS = Args.hasArg(OPT_fno_zero_initialized_in_bss); Opts.NumRegisterParameters = getLastArgIntValue(Args, OPT_mregparm, 0, Diags); Opts.NoExecStack = Args.hasArg(OPT_mno_exec_stack); Opts.SmallDataLimit = @@ -927,7 +963,6 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.StrictVTablePointers = Args.hasArg(OPT_fstrict_vtable_pointers); Opts.ForceEmitVTables = Args.hasArg(OPT_fforce_emit_vtables); Opts.UnwindTables = Args.hasArg(OPT_munwind_tables); - Opts.RelocationModel = getRelocModel(Args, Diags); Opts.ThreadModel = std::string(Args.getLastArgValue(OPT_mthread_model, "posix")); if (Opts.ThreadModel != "posix" && Opts.ThreadModel != "single") @@ -1544,8 +1579,6 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, Opts.AbsolutePath = Args.hasArg(OPT_fdiagnostics_absolute_paths); Opts.ShowOptionNames = !Args.hasArg(OPT_fno_diagnostics_show_option); - llvm::sys::Process::UseANSIEscapeCodes(Args.hasArg(OPT_fansi_escape_codes)); - // Default behavior is to not to show note include stacks. Opts.ShowNoteIncludeStack = false; if (Arg *A = Args.getLastArg(OPT_fdiagnostics_show_note_include_stack, @@ -1652,6 +1685,9 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, } Opts.MessageLength = getLastArgIntValue(Args, OPT_fmessage_length_EQ, 0, Diags); + + Opts.UndefPrefixes = Args.getAllArgValues(OPT_Wundef_prefix_EQ); + addDiagnosticArgs(Args, OPT_W_Group, OPT_W_value_Group, Opts.Warnings); addDiagnosticArgs(Args, OPT_R_Group, OPT_R_value_Group, Opts.Remarks); @@ -1715,6 +1751,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, case OPT_ast_dump: case OPT_ast_dump_all: case OPT_ast_dump_lookups: + case OPT_ast_dump_decl_types: Opts.ProgramAction = frontend::ASTDump; break; case OPT_ast_print: Opts.ProgramAction = frontend::ASTPrint; break; @@ -1872,6 +1909,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.ASTDumpAll = Args.hasArg(OPT_ast_dump_all, OPT_ast_dump_all_EQ); Opts.ASTDumpFilter = std::string(Args.getLastArgValue(OPT_ast_dump_filter)); Opts.ASTDumpLookups = Args.hasArg(OPT_ast_dump_lookups); + Opts.ASTDumpDeclTypes = Args.hasArg(OPT_ast_dump_decl_types); Opts.UseGlobalModuleIndex = !Args.hasArg(OPT_fno_modules_global_index); Opts.GenerateGlobalModuleIndex = Opts.UseGlobalModuleIndex; Opts.ModuleMapFiles = Args.getAllArgValues(OPT_fmodule_map_file); @@ -2105,7 +2143,6 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, Opts.AddPrebuiltModulePath(A->getValue()); Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash); Opts.ModulesHashContent = Args.hasArg(OPT_fmodules_hash_content); - Opts.ModulesStrictContextHash = Args.hasArg(OPT_fmodules_strict_context_hash); Opts.ModulesValidateDiagnosticOptions = !Args.hasArg(OPT_fmodules_disable_diagnostic_validation); Opts.ImplicitModuleMaps = Args.hasArg(OPT_fimplicit_module_maps); @@ -3062,8 +3099,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, } } - // Check if -fopenmp is specified and set default version to 4.5. - Opts.OpenMP = Args.hasArg(options::OPT_fopenmp) ? 45 : 0; + // Check if -fopenmp is specified and set default version to 5.0. + Opts.OpenMP = Args.hasArg(options::OPT_fopenmp) ? 50 : 0; // Check if -fopenmp-simd is specified. bool IsSimdSpecified = Args.hasFlag(options::OPT_fopenmp_simd, options::OPT_fno_openmp_simd, @@ -3081,10 +3118,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, if (Opts.OpenMP || Opts.OpenMPSimd) { if (int Version = getLastArgIntValue( Args, OPT_fopenmp_version_EQ, - (IsSimdSpecified || IsTargetSpecified) ? 45 : Opts.OpenMP, Diags)) + (IsSimdSpecified || IsTargetSpecified) ? 50 : Opts.OpenMP, Diags)) Opts.OpenMP = Version; - else if (IsSimdSpecified || IsTargetSpecified) - Opts.OpenMP = 45; // Provide diagnostic when a given target is not expected to be an OpenMP // device or host. if (!Opts.OpenMPIsDevice) { @@ -3160,6 +3195,12 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.OpenMPCUDAMode = Opts.OpenMPIsDevice && (T.isNVPTX() || T.isAMDGCN()) && Args.hasArg(options::OPT_fopenmp_cuda_mode); + // Set CUDA support for parallel execution of target regions for OpenMP target + // NVPTX/AMDGCN if specified in options. + Opts.OpenMPCUDATargetParallel = + Opts.OpenMPIsDevice && (T.isNVPTX() || T.isAMDGCN()) && + Args.hasArg(options::OPT_fopenmp_cuda_parallel_target_regions); + // Set CUDA mode for OpenMP target NVPTX/AMDGCN if specified in options Opts.OpenMPCUDAForceFullRuntime = Opts.OpenMPIsDevice && (T.isNVPTX() || T.isAMDGCN()) && @@ -3239,6 +3280,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val; } + if (Args.hasArg(OPT_fexperimental_strict_floating_point)) + Opts.ExpStrictFP = true; + auto FPRM = llvm::RoundingMode::NearestTiesToEven; if (Args.hasArg(OPT_frounding_math)) { FPRM = llvm::RoundingMode::Dynamic; @@ -3607,11 +3651,6 @@ static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args, Opts.FeaturesAsWritten = Args.getAllArgValues(OPT_target_feature); Opts.LinkerVersion = std::string(Args.getLastArgValue(OPT_target_linker_version)); - Opts.Triple = std::string(Args.getLastArgValue(OPT_triple)); - // Use the default target triple if unspecified. - if (Opts.Triple.empty()) - Opts.Triple = llvm::sys::getDefaultTargetTriple(); - Opts.Triple = llvm::Triple::normalize(Opts.Triple); Opts.OpenCLExtensionsAsWritten = Args.getAllArgValues(OPT_cl_ext_EQ); Opts.ForceEnableInt128 = Args.hasArg(OPT_fforce_enable_int128); Opts.NVPTXUseShortPointers = Args.hasFlag( @@ -3626,6 +3665,31 @@ static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args, } } +bool CompilerInvocation::parseSimpleArgs(const ArgList &Args, + DiagnosticsEngine &Diags) { +#define OPTION_WITH_MARSHALLING_FLAG(PREFIX_TYPE, NAME, ID, KIND, GROUP, \ + ALIAS, ALIASARGS, FLAGS, PARAM, HELPTEXT, \ + METAVAR, VALUES, SPELLING, ALWAYS_EMIT, \ + KEYPATH, DEFAULT_VALUE, IS_POSITIVE) \ + this->KEYPATH = Args.hasArg(OPT_##ID) && IS_POSITIVE; + +#define OPTION_WITH_MARSHALLING_STRING( \ + PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR, VALUES, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \ + TYPE, NORMALIZER, DENORMALIZER, TABLE_INDEX) \ + { \ + if (auto MaybeValue = NORMALIZER(OPT_##ID, TABLE_INDEX, Args, Diags)) \ + this->KEYPATH = static_cast(*MaybeValue); \ + else \ + this->KEYPATH = DEFAULT_VALUE; \ + } + +#include "clang/Driver/Options.inc" +#undef OPTION_WITH_MARSHALLING_STRING +#undef OPTION_WITH_MARSHALLING_FLAG + return true; +} + bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, ArrayRef CommandLineArgs, DiagnosticsEngine &Diags, @@ -3659,6 +3723,11 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, Success = false; } + Success &= Res.parseSimpleArgs(Args, Diags); + + llvm::sys::Process::UseANSIEscapeCodes( + Res.DiagnosticOpts->UseANSIEscapeCodes); + Success &= ParseAnalyzerArgs(*Res.getAnalyzerOpts(), Args, Diags); Success &= ParseMigratorArgs(Res.getMigratorOpts(), Args); ParseDependencyOutputArgs(Res.getDependencyOutputOpts(), Args); @@ -3787,6 +3856,10 @@ std::string CompilerInvocation::getModuleHash() const { for (StringRef Feature : LangOpts->ModuleFeatures) code = hash_combine(code, Feature); + code = hash_combine(code, LangOpts->ObjCRuntime); + const auto &BCN = LangOpts->CommentOpts.BlockCommandNames; + code = hash_combine(code, hash_combine_range(BCN.begin(), BCN.end())); + // Extend the signature with the target options. code = hash_combine(code, TargetOpts->Triple, TargetOpts->CPU, TargetOpts->ABI); @@ -3866,6 +3939,33 @@ std::string CompilerInvocation::getModuleHash() const { return llvm::APInt(64, code).toString(36, /*Signed=*/false); } +void CompilerInvocation::generateCC1CommandLine( + SmallVectorImpl &Args, StringAllocator SA) const { +#define OPTION_WITH_MARSHALLING_FLAG(PREFIX_TYPE, NAME, ID, KIND, GROUP, \ + ALIAS, ALIASARGS, FLAGS, PARAM, HELPTEXT, \ + METAVAR, VALUES, SPELLING, ALWAYS_EMIT, \ + KEYPATH, DEFAULT_VALUE, IS_POSITIVE) \ + if ((FLAGS) & options::CC1Option && \ + (ALWAYS_EMIT || this->KEYPATH != DEFAULT_VALUE)) \ + Args.push_back(SPELLING); + +#define OPTION_WITH_MARSHALLING_STRING( \ + PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR, VALUES, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \ + NORMALIZER_RET_TY, NORMALIZER, DENORMALIZER, TABLE_INDEX) \ + if (((FLAGS) & options::CC1Option) && \ + (ALWAYS_EMIT || this->KEYPATH != DEFAULT_VALUE)) { \ + if (Option::KIND##Class == Option::SeparateClass) { \ + Args.push_back(SPELLING); \ + Args.push_back(DENORMALIZER(SA, TABLE_INDEX, this->KEYPATH)); \ + } \ + } + +#include "clang/Driver/Options.inc" +#undef OPTION_WITH_MARSHALLING_STRING +#undef OPTION_WITH_MARSHALLING_FLAG +} + namespace clang { IntrusiveRefCntPtr diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index 3a86a8d05c49b..711e7336c8203 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -79,7 +79,8 @@ ASTDumpAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { const FrontendOptions &Opts = CI.getFrontendOpts(); return CreateASTDumper(nullptr /*Dump to stdout.*/, Opts.ASTDumpFilter, Opts.ASTDumpDecls, Opts.ASTDumpAll, - Opts.ASTDumpLookups, Opts.ASTDumpFormat); + Opts.ASTDumpLookups, Opts.ASTDumpDeclTypes, + Opts.ASTDumpFormat); } std::unique_ptr diff --git a/clang/lib/Frontend/InitHeaderSearch.cpp b/clang/lib/Frontend/InitHeaderSearch.cpp index 159cd47f78316..16f1f1670e8de 100644 --- a/clang/lib/Frontend/InitHeaderSearch.cpp +++ b/clang/lib/Frontend/InitHeaderSearch.cpp @@ -381,6 +381,7 @@ void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths( case llvm::Triple::Linux: case llvm::Triple::Hurd: case llvm::Triple::Solaris: + case llvm::Triple::AIX: llvm_unreachable("Include management is handled in the driver."); break; case llvm::Triple::Win32: @@ -424,6 +425,7 @@ void InitHeaderSearch::AddDefaultIncludePaths(const LangOptions &Lang, case llvm::Triple::Hurd: case llvm::Triple::Solaris: case llvm::Triple::WASI: + case llvm::Triple::AIX: return; case llvm::Triple::Win32: diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index ca3697606023c..6eef1e2376f6d 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -1076,12 +1076,12 @@ static void InitializePredefinedMacros(const TargetInfo &TI, case 40: Builder.defineMacro("_OPENMP", "201307"); break; - case 50: - Builder.defineMacro("_OPENMP", "201811"); + case 45: + Builder.defineMacro("_OPENMP", "201511"); break; default: - // Default version is OpenMP 4.5 - Builder.defineMacro("_OPENMP", "201511"); + // Default version is OpenMP 5.0 + Builder.defineMacro("_OPENMP", "201811"); break; } } diff --git a/clang/lib/Frontend/Rewrite/CMakeLists.txt b/clang/lib/Frontend/Rewrite/CMakeLists.txt index 61a22b5b13b4d..64aa651394dff 100644 --- a/clang/lib/Frontend/Rewrite/CMakeLists.txt +++ b/clang/lib/Frontend/Rewrite/CMakeLists.txt @@ -20,4 +20,7 @@ add_clang_library(clangRewriteFrontend clangLex clangRewrite clangSerialization + + DEPENDS + omp_gen ) diff --git a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp index bb195ade1409b..e122b10e76d37 100644 --- a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp +++ b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp @@ -2590,7 +2590,7 @@ Stmt *RewriteModernObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) { Expr *Unop = UnaryOperator::Create( const_cast(*Context), DRE, UO_AddrOf, Context->getPointerType(DRE->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + SourceLocation(), false, FPOptionsOverride()); // cast to NSConstantString * CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(), CK_CPointerToObjCPointerCast, Unop); @@ -3287,7 +3287,7 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp, SuperRep = UnaryOperator::Create( const_cast(*Context), SuperRep, UO_AddrOf, Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + SourceLocation(), false, FPOptionsOverride()); SuperRep = NoTypeInfoCStyleCastExpr(Context, Context->getPointerType(superType), CK_BitCast, SuperRep); @@ -3305,7 +3305,7 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp, SuperRep = UnaryOperator::Create( const_cast(*Context), SuperRep, UO_AddrOf, Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + SourceLocation(), false, FPOptionsOverride()); } MsgExprs.push_back(SuperRep); break; @@ -3382,7 +3382,7 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp, SuperRep = UnaryOperator::Create( const_cast(*Context), SuperRep, UO_AddrOf, Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + SourceLocation(), false, FPOptionsOverride()); SuperRep = NoTypeInfoCStyleCastExpr(Context, Context->getPointerType(superType), CK_BitCast, SuperRep); @@ -4706,10 +4706,9 @@ Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) { if (VarDecl *Var = dyn_cast(VD)) if (!ImportedLocalExternalDecls.count(Var)) return DRE; - Expr *Exp = UnaryOperator::Create(const_cast(*Context), DRE, - UO_Deref, DRE->getType(), VK_LValue, - OK_Ordinary, DRE->getLocation(), false, - FPOptions(Context->getLangOpts())); + Expr *Exp = UnaryOperator::Create( + const_cast(*Context), DRE, UO_Deref, DRE->getType(), + VK_LValue, OK_Ordinary, DRE->getLocation(), false, FPOptionsOverride()); // Need parens to enforce precedence. ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), Exp); @@ -5300,7 +5299,7 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp, new (Context) DeclRefExpr(*Context, NewVD, false, Context->VoidPtrTy, VK_LValue, SourceLocation()), UO_AddrOf, Context->getPointerType(Context->VoidPtrTy), VK_RValue, - OK_Ordinary, SourceLocation(), false, FPOptions(Context->getLangOpts())); + OK_Ordinary, SourceLocation(), false, FPOptionsOverride()); InitExprs.push_back(DescRefExpr); // Add initializers for any closure decl refs. @@ -5317,10 +5316,9 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp, if (HasLocalVariableExternalStorage(*I)) { QualType QT = (*I)->getType(); QT = Context->getPointerType(QT); - Exp = UnaryOperator::Create(const_cast(*Context), Exp, - UO_AddrOf, QT, VK_RValue, OK_Ordinary, - SourceLocation(), false, - FPOptions(Context->getLangOpts())); + Exp = UnaryOperator::Create( + const_cast(*Context), Exp, UO_AddrOf, QT, VK_RValue, + OK_Ordinary, SourceLocation(), false, FPOptionsOverride()); } } else if (isTopLevelBlockPointerType((*I)->getType())) { FD = SynthBlockInitFunctionDecl((*I)->getName()); @@ -5335,10 +5333,9 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp, if (HasLocalVariableExternalStorage(*I)) { QualType QT = (*I)->getType(); QT = Context->getPointerType(QT); - Exp = UnaryOperator::Create(const_cast(*Context), Exp, - UO_AddrOf, QT, VK_RValue, OK_Ordinary, - SourceLocation(), false, - FPOptions(Context->getLangOpts())); + Exp = UnaryOperator::Create( + const_cast(*Context), Exp, UO_AddrOf, QT, VK_RValue, + OK_Ordinary, SourceLocation(), false, FPOptionsOverride()); } } @@ -5379,7 +5376,7 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp, Exp = UnaryOperator::Create( const_cast(*Context), Exp, UO_AddrOf, Context->getPointerType(Exp->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + SourceLocation(), false, FPOptionsOverride()); Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp); InitExprs.push_back(Exp); } @@ -5406,7 +5403,7 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp, NewRep = UnaryOperator::Create( const_cast(*Context), NewRep, UO_AddrOf, Context->getPointerType(NewRep->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + SourceLocation(), false, FPOptionsOverride()); NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast, NewRep); // Put Paren around the call. @@ -7494,7 +7491,7 @@ Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { BinaryOperator *addExpr = BinaryOperator::Create( *Context, castExpr, DRE, BO_Add, Context->getPointerType(Context->CharTy), VK_RValue, OK_Ordinary, - SourceLocation(), FPOptions(Context->getLangOpts())); + SourceLocation(), FPOptionsOverride()); // Don't forget the parens to enforce the proper binding. ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), @@ -7545,10 +7542,9 @@ Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { CK_BitCast, PE); - Expr *Exp = UnaryOperator::Create(const_cast(*Context), - castExpr, UO_Deref, IvarT, VK_LValue, - OK_Ordinary, SourceLocation(), false, - FPOptions(Context->getLangOpts())); + Expr *Exp = UnaryOperator::Create( + const_cast(*Context), castExpr, UO_Deref, IvarT, + VK_LValue, OK_Ordinary, SourceLocation(), false, FPOptionsOverride()); PE = new (Context) ParenExpr(OldRange.getBegin(), OldRange.getEnd(), Exp); diff --git a/clang/lib/Frontend/Rewrite/RewriteObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteObjC.cpp index 8b618d90b47ec..3f320dc57aa69 100644 --- a/clang/lib/Frontend/Rewrite/RewriteObjC.cpp +++ b/clang/lib/Frontend/Rewrite/RewriteObjC.cpp @@ -2517,7 +2517,7 @@ Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) { Expr *Unop = UnaryOperator::Create( const_cast(*Context), DRE, UO_AddrOf, Context->getPointerType(DRE->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + SourceLocation(), false, FPOptionsOverride()); // cast to NSConstantString * CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(), CK_CPointerToObjCPointerCast, Unop); @@ -2718,7 +2718,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, SuperRep = UnaryOperator::Create( const_cast(*Context), SuperRep, UO_AddrOf, Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + SourceLocation(), false, FPOptionsOverride()); SuperRep = NoTypeInfoCStyleCastExpr(Context, Context->getPointerType(superType), CK_BitCast, SuperRep); @@ -2736,7 +2736,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, SuperRep = UnaryOperator::Create( const_cast(*Context), SuperRep, UO_AddrOf, Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + SourceLocation(), false, FPOptionsOverride()); } MsgExprs.push_back(SuperRep); break; @@ -2813,7 +2813,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, SuperRep = UnaryOperator::Create( const_cast(*Context), SuperRep, UO_AddrOf, Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + SourceLocation(), false, FPOptionsOverride()); SuperRep = NoTypeInfoCStyleCastExpr(Context, Context->getPointerType(superType), CK_BitCast, SuperRep); @@ -2999,7 +2999,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, SourceLocation()); BinaryOperator *lessThanExpr = BinaryOperator::Create( *Context, sizeofExpr, limit, BO_LE, Context->IntTy, VK_RValue, - OK_Ordinary, SourceLocation(), FPOptions(Context->getLangOpts())); + OK_Ordinary, SourceLocation(), FPOptionsOverride()); // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...)) ConditionalOperator *CondExpr = new (Context) ConditionalOperator(lessThanExpr, @@ -3052,7 +3052,7 @@ Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) { Expr *DerefExpr = UnaryOperator::Create( const_cast(*Context), DRE, UO_AddrOf, Context->getPointerType(DRE->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + SourceLocation(), false, FPOptionsOverride()); CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, DerefExpr->getType(), CK_BitCast, DerefExpr); @@ -3877,10 +3877,9 @@ Stmt *RewriteObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) { if (VarDecl *Var = dyn_cast(VD)) if (!ImportedLocalExternalDecls.count(Var)) return DRE; - Expr *Exp = UnaryOperator::Create(const_cast(*Context), DRE, - UO_Deref, DRE->getType(), VK_LValue, - OK_Ordinary, DRE->getLocation(), false, - FPOptions(Context->getLangOpts())); + Expr *Exp = UnaryOperator::Create( + const_cast(*Context), DRE, UO_Deref, DRE->getType(), + VK_LValue, OK_Ordinary, DRE->getLocation(), false, FPOptionsOverride()); // Need parens to enforce precedence. ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), Exp); @@ -4440,7 +4439,7 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, new (Context) DeclRefExpr(*Context, NewVD, false, Context->VoidPtrTy, VK_LValue, SourceLocation()), UO_AddrOf, Context->getPointerType(Context->VoidPtrTy), VK_RValue, - OK_Ordinary, SourceLocation(), false, FPOptions(Context->getLangOpts())); + OK_Ordinary, SourceLocation(), false, FPOptionsOverride()); InitExprs.push_back(DescRefExpr); // Add initializers for any closure decl refs. @@ -4457,10 +4456,9 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, if (HasLocalVariableExternalStorage(*I)) { QualType QT = (*I)->getType(); QT = Context->getPointerType(QT); - Exp = UnaryOperator::Create(const_cast(*Context), Exp, - UO_AddrOf, QT, VK_RValue, OK_Ordinary, - SourceLocation(), false, - FPOptions(Context->getLangOpts())); + Exp = UnaryOperator::Create( + const_cast(*Context), Exp, UO_AddrOf, QT, VK_RValue, + OK_Ordinary, SourceLocation(), false, FPOptionsOverride()); } } else if (isTopLevelBlockPointerType((*I)->getType())) { FD = SynthBlockInitFunctionDecl((*I)->getName()); @@ -4475,10 +4473,9 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, if (HasLocalVariableExternalStorage(*I)) { QualType QT = (*I)->getType(); QT = Context->getPointerType(QT); - Exp = UnaryOperator::Create(const_cast(*Context), Exp, - UO_AddrOf, QT, VK_RValue, OK_Ordinary, - SourceLocation(), false, - FPOptions(Context->getLangOpts())); + Exp = UnaryOperator::Create( + const_cast(*Context), Exp, UO_AddrOf, QT, VK_RValue, + OK_Ordinary, SourceLocation(), false, FPOptionsOverride()); } } InitExprs.push_back(Exp); @@ -4518,7 +4515,7 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, Exp = UnaryOperator::Create( const_cast(*Context), Exp, UO_AddrOf, Context->getPointerType(Exp->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + SourceLocation(), false, FPOptionsOverride()); Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp); InitExprs.push_back(Exp); } @@ -4537,7 +4534,7 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, NewRep = UnaryOperator::Create( const_cast(*Context), NewRep, UO_AddrOf, Context->getPointerType(NewRep->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + SourceLocation(), false, FPOptionsOverride()); NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast, NewRep); BlockDeclRefs.clear(); diff --git a/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp b/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp index e3ca8fdec3934..462aeda6e027f 100644 --- a/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp +++ b/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp @@ -239,6 +239,9 @@ class SDiagsWriter : public DiagnosticConsumer { /// generated from child processes. bool MergeChildRecords; + /// Whether we've started finishing and tearing down this instance. + bool IsFinishing = false; + /// State that is shared among the various clones of this diagnostic /// consumer. struct SharedState { @@ -568,6 +571,17 @@ unsigned SDiagsWriter::getEmitDiagnosticFlag(StringRef FlagName) { void SDiagsWriter::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) { + assert(!IsFinishing && + "Received a diagnostic after we've already started teardown."); + if (IsFinishing) { + SmallString<256> diagnostic; + Info.FormatDiagnostic(diagnostic); + getMetaDiags()->Report( + diag::warn_fe_serialized_diag_failure_during_finalisation) + << diagnostic; + return; + } + // Enter the block for a non-note diagnostic immediately, rather than waiting // for beginDiagnostic, in case associated notes are emitted before we get // there. @@ -761,6 +775,9 @@ void SDiagsWriter::RemoveOldDiagnostics() { } void SDiagsWriter::finish() { + assert(!IsFinishing); + IsFinishing = true; + // The original instance is responsible for writing the file. if (!OriginalInstance) return; @@ -786,12 +803,20 @@ void SDiagsWriter::finish() { if (EC) { getMetaDiags()->Report(diag::warn_fe_serialized_diag_failure) << State->OutputFile << EC.message(); + OS->clear_error(); return; } // Write the generated bitstream to "Out". OS->write((char *)&State->Buffer.front(), State->Buffer.size()); OS->flush(); + + assert(!OS->has_error()); + if (OS->has_error()) { + getMetaDiags()->Report(diag::warn_fe_serialized_diag_failure) + << State->OutputFile << OS->error().message(); + OS->clear_error(); + } } std::error_code SDiagsMerger::visitStartOfDiagnostic() { diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index fd9e3a0d672f6..0692fe75a4417 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -2,6 +2,7 @@ set(files adxintrin.h altivec.h ammintrin.h + amxintrin.h arm_acle.h arm_cmse.h armintr.h @@ -150,6 +151,8 @@ set(ppc_wrapper_files set(openmp_wrapper_files openmp_wrappers/math.h openmp_wrappers/cmath + openmp_wrappers/complex.h + openmp_wrappers/complex openmp_wrappers/__clang_openmp_device_functions.h openmp_wrappers/new ) diff --git a/clang/lib/Headers/__clang_cuda_cmath.h b/clang/lib/Headers/__clang_cuda_cmath.h index f406112164e53..8ba182689a4f9 100644 --- a/clang/lib/Headers/__clang_cuda_cmath.h +++ b/clang/lib/Headers/__clang_cuda_cmath.h @@ -12,7 +12,7 @@ #error "This file is for CUDA compilation only." #endif -#ifndef _OPENMP +#ifndef __OPENMP_NVPTX__ #include #endif @@ -32,7 +32,7 @@ // implementation. Declaring in the global namespace and pulling into namespace // std covers all of the known knowns. -#ifdef _OPENMP +#ifdef __OPENMP_NVPTX__ #define __DEVICE__ static constexpr __attribute__((always_inline, nothrow)) #else #define __DEVICE__ static __device__ __inline__ __attribute__((always_inline)) @@ -69,7 +69,7 @@ __DEVICE__ float frexp(float __arg, int *__exp) { // Windows. For OpenMP we omit these as some old system headers have // non-conforming `isinf(float)` and `isnan(float)` implementations that return // an `int`. The system versions of these functions should be fine anyway. -#if !defined(_MSC_VER) && !defined(_OPENMP) +#if !defined(_MSC_VER) && !defined(__OPENMP_NVPTX__) __DEVICE__ bool isinf(float __x) { return ::__isinff(__x); } __DEVICE__ bool isinf(double __x) { return ::__isinf(__x); } __DEVICE__ bool isfinite(float __x) { return ::__finitef(__x); } @@ -146,7 +146,7 @@ __DEVICE__ float tanh(float __x) { return ::tanhf(__x); } // libdevice doesn't provide an implementation, and we don't want to be in the // business of implementing tricky libm functions in this header. -#ifndef _OPENMP +#ifndef __OPENMP_NVPTX__ // Now we've defined everything we promised we'd define in // __clang_cuda_math_forward_declares.h. We need to do two additional things to @@ -463,7 +463,7 @@ _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif -#endif // _OPENMP +#endif // __OPENMP_NVPTX__ #undef __DEVICE__ diff --git a/clang/lib/Headers/__clang_cuda_complex_builtins.h b/clang/lib/Headers/__clang_cuda_complex_builtins.h index 576a958b16bb2..8c10ff6b461fd 100644 --- a/clang/lib/Headers/__clang_cuda_complex_builtins.h +++ b/clang/lib/Headers/__clang_cuda_complex_builtins.h @@ -13,10 +13,57 @@ // This header defines __muldc3, __mulsc3, __divdc3, and __divsc3. These are // libgcc functions that clang assumes are available when compiling c99 complex // operations. (These implementations come from libc++, and have been modified -// to work with CUDA.) +// to work with CUDA and OpenMP target offloading [in C and C++ mode].) -extern "C" inline __device__ double _Complex __muldc3(double __a, double __b, - double __c, double __d) { +#pragma push_macro("__DEVICE__") +#ifdef _OPENMP +#pragma omp declare target +#define __DEVICE__ __attribute__((noinline, nothrow, cold, weak)) +#else +#define __DEVICE__ __device__ inline +#endif + +// To make the algorithms available for C and C++ in CUDA and OpenMP we select +// different but equivalent function versions. TODO: For OpenMP we currently +// select the native builtins as the overload support for templates is lacking. +#if !defined(_OPENMP) +#define _ISNANd std::isnan +#define _ISNANf std::isnan +#define _ISINFd std::isinf +#define _ISINFf std::isinf +#define _ISFINITEd std::isfinite +#define _ISFINITEf std::isfinite +#define _COPYSIGNd std::copysign +#define _COPYSIGNf std::copysign +#define _SCALBNd std::scalbn +#define _SCALBNf std::scalbn +#define _ABSd std::abs +#define _ABSf std::abs +#define _LOGBd std::logb +#define _LOGBf std::logb +#else +#define _ISNANd __nv_isnand +#define _ISNANf __nv_isnanf +#define _ISINFd __nv_isinfd +#define _ISINFf __nv_isinff +#define _ISFINITEd __nv_isfinited +#define _ISFINITEf __nv_finitef +#define _COPYSIGNd __nv_copysign +#define _COPYSIGNf __nv_copysignf +#define _SCALBNd __nv_scalbn +#define _SCALBNf __nv_scalbnf +#define _ABSd __nv_fabs +#define _ABSf __nv_fabsf +#define _LOGBd __nv_logb +#define _LOGBf __nv_logbf +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +__DEVICE__ double _Complex __muldc3(double __a, double __b, double __c, + double __d) { double __ac = __a * __c; double __bd = __b * __d; double __ad = __a * __d; @@ -24,50 +71,49 @@ extern "C" inline __device__ double _Complex __muldc3(double __a, double __b, double _Complex z; __real__(z) = __ac - __bd; __imag__(z) = __ad + __bc; - if (std::isnan(__real__(z)) && std::isnan(__imag__(z))) { + if (_ISNANd(__real__(z)) && _ISNANd(__imag__(z))) { int __recalc = 0; - if (std::isinf(__a) || std::isinf(__b)) { - __a = std::copysign(std::isinf(__a) ? 1 : 0, __a); - __b = std::copysign(std::isinf(__b) ? 1 : 0, __b); - if (std::isnan(__c)) - __c = std::copysign(0, __c); - if (std::isnan(__d)) - __d = std::copysign(0, __d); + if (_ISINFd(__a) || _ISINFd(__b)) { + __a = _COPYSIGNd(_ISINFd(__a) ? 1 : 0, __a); + __b = _COPYSIGNd(_ISINFd(__b) ? 1 : 0, __b); + if (_ISNANd(__c)) + __c = _COPYSIGNd(0, __c); + if (_ISNANd(__d)) + __d = _COPYSIGNd(0, __d); __recalc = 1; } - if (std::isinf(__c) || std::isinf(__d)) { - __c = std::copysign(std::isinf(__c) ? 1 : 0, __c); - __d = std::copysign(std::isinf(__d) ? 1 : 0, __d); - if (std::isnan(__a)) - __a = std::copysign(0, __a); - if (std::isnan(__b)) - __b = std::copysign(0, __b); + if (_ISINFd(__c) || _ISINFd(__d)) { + __c = _COPYSIGNd(_ISINFd(__c) ? 1 : 0, __c); + __d = _COPYSIGNd(_ISINFd(__d) ? 1 : 0, __d); + if (_ISNANd(__a)) + __a = _COPYSIGNd(0, __a); + if (_ISNANd(__b)) + __b = _COPYSIGNd(0, __b); __recalc = 1; } - if (!__recalc && (std::isinf(__ac) || std::isinf(__bd) || - std::isinf(__ad) || std::isinf(__bc))) { - if (std::isnan(__a)) - __a = std::copysign(0, __a); - if (std::isnan(__b)) - __b = std::copysign(0, __b); - if (std::isnan(__c)) - __c = std::copysign(0, __c); - if (std::isnan(__d)) - __d = std::copysign(0, __d); + if (!__recalc && + (_ISINFd(__ac) || _ISINFd(__bd) || _ISINFd(__ad) || _ISINFd(__bc))) { + if (_ISNANd(__a)) + __a = _COPYSIGNd(0, __a); + if (_ISNANd(__b)) + __b = _COPYSIGNd(0, __b); + if (_ISNANd(__c)) + __c = _COPYSIGNd(0, __c); + if (_ISNANd(__d)) + __d = _COPYSIGNd(0, __d); __recalc = 1; } if (__recalc) { // Can't use std::numeric_limits::infinity() -- that doesn't have // a device overload (and isn't constexpr before C++11, naturally). - __real__(z) = __builtin_huge_valf() * (__a * __c - __b * __d); - __imag__(z) = __builtin_huge_valf() * (__a * __d + __b * __c); + __real__(z) = __builtin_huge_val() * (__a * __c - __b * __d); + __imag__(z) = __builtin_huge_val() * (__a * __d + __b * __c); } } return z; } -extern "C" inline __device__ float _Complex __mulsc3(float __a, float __b, - float __c, float __d) { +__DEVICE__ float _Complex __mulsc3(float __a, float __b, float __c, float __d) { float __ac = __a * __c; float __bd = __b * __d; float __ad = __a * __d; @@ -75,36 +121,36 @@ extern "C" inline __device__ float _Complex __mulsc3(float __a, float __b, float _Complex z; __real__(z) = __ac - __bd; __imag__(z) = __ad + __bc; - if (std::isnan(__real__(z)) && std::isnan(__imag__(z))) { + if (_ISNANf(__real__(z)) && _ISNANf(__imag__(z))) { int __recalc = 0; - if (std::isinf(__a) || std::isinf(__b)) { - __a = std::copysign(std::isinf(__a) ? 1 : 0, __a); - __b = std::copysign(std::isinf(__b) ? 1 : 0, __b); - if (std::isnan(__c)) - __c = std::copysign(0, __c); - if (std::isnan(__d)) - __d = std::copysign(0, __d); + if (_ISINFf(__a) || _ISINFf(__b)) { + __a = _COPYSIGNf(_ISINFf(__a) ? 1 : 0, __a); + __b = _COPYSIGNf(_ISINFf(__b) ? 1 : 0, __b); + if (_ISNANf(__c)) + __c = _COPYSIGNf(0, __c); + if (_ISNANf(__d)) + __d = _COPYSIGNf(0, __d); __recalc = 1; } - if (std::isinf(__c) || std::isinf(__d)) { - __c = std::copysign(std::isinf(__c) ? 1 : 0, __c); - __d = std::copysign(std::isinf(__d) ? 1 : 0, __d); - if (std::isnan(__a)) - __a = std::copysign(0, __a); - if (std::isnan(__b)) - __b = std::copysign(0, __b); + if (_ISINFf(__c) || _ISINFf(__d)) { + __c = _COPYSIGNf(_ISINFf(__c) ? 1 : 0, __c); + __d = _COPYSIGNf(_ISINFf(__d) ? 1 : 0, __d); + if (_ISNANf(__a)) + __a = _COPYSIGNf(0, __a); + if (_ISNANf(__b)) + __b = _COPYSIGNf(0, __b); __recalc = 1; } - if (!__recalc && (std::isinf(__ac) || std::isinf(__bd) || - std::isinf(__ad) || std::isinf(__bc))) { - if (std::isnan(__a)) - __a = std::copysign(0, __a); - if (std::isnan(__b)) - __b = std::copysign(0, __b); - if (std::isnan(__c)) - __c = std::copysign(0, __c); - if (std::isnan(__d)) - __d = std::copysign(0, __d); + if (!__recalc && + (_ISINFf(__ac) || _ISINFf(__bd) || _ISINFf(__ad) || _ISINFf(__bc))) { + if (_ISNANf(__a)) + __a = _COPYSIGNf(0, __a); + if (_ISNANf(__b)) + __b = _COPYSIGNf(0, __b); + if (_ISNANf(__c)) + __c = _COPYSIGNf(0, __c); + if (_ISNANf(__d)) + __d = _COPYSIGNf(0, __d); __recalc = 1; } if (__recalc) { @@ -115,36 +161,36 @@ extern "C" inline __device__ float _Complex __mulsc3(float __a, float __b, return z; } -extern "C" inline __device__ double _Complex __divdc3(double __a, double __b, - double __c, double __d) { +__DEVICE__ double _Complex __divdc3(double __a, double __b, double __c, + double __d) { int __ilogbw = 0; // Can't use std::max, because that's defined in , and we don't // want to pull that in for every compile. The CUDA headers define // ::max(float, float) and ::max(double, double), which is sufficient for us. - double __logbw = std::logb(max(std::abs(__c), std::abs(__d))); - if (std::isfinite(__logbw)) { + double __logbw = _LOGBd(max(_ABSd(__c), _ABSd(__d))); + if (_ISFINITEd(__logbw)) { __ilogbw = (int)__logbw; - __c = std::scalbn(__c, -__ilogbw); - __d = std::scalbn(__d, -__ilogbw); + __c = _SCALBNd(__c, -__ilogbw); + __d = _SCALBNd(__d, -__ilogbw); } double __denom = __c * __c + __d * __d; double _Complex z; - __real__(z) = std::scalbn((__a * __c + __b * __d) / __denom, -__ilogbw); - __imag__(z) = std::scalbn((__b * __c - __a * __d) / __denom, -__ilogbw); - if (std::isnan(__real__(z)) && std::isnan(__imag__(z))) { - if ((__denom == 0.0) && (!std::isnan(__a) || !std::isnan(__b))) { - __real__(z) = std::copysign(__builtin_huge_valf(), __c) * __a; - __imag__(z) = std::copysign(__builtin_huge_valf(), __c) * __b; - } else if ((std::isinf(__a) || std::isinf(__b)) && std::isfinite(__c) && - std::isfinite(__d)) { - __a = std::copysign(std::isinf(__a) ? 1.0 : 0.0, __a); - __b = std::copysign(std::isinf(__b) ? 1.0 : 0.0, __b); - __real__(z) = __builtin_huge_valf() * (__a * __c + __b * __d); - __imag__(z) = __builtin_huge_valf() * (__b * __c - __a * __d); - } else if (std::isinf(__logbw) && __logbw > 0.0 && std::isfinite(__a) && - std::isfinite(__b)) { - __c = std::copysign(std::isinf(__c) ? 1.0 : 0.0, __c); - __d = std::copysign(std::isinf(__d) ? 1.0 : 0.0, __d); + __real__(z) = _SCALBNd((__a * __c + __b * __d) / __denom, -__ilogbw); + __imag__(z) = _SCALBNd((__b * __c - __a * __d) / __denom, -__ilogbw); + if (_ISNANd(__real__(z)) && _ISNANd(__imag__(z))) { + if ((__denom == 0.0) && (!_ISNANd(__a) || !_ISNANd(__b))) { + __real__(z) = _COPYSIGNd(__builtin_huge_val(), __c) * __a; + __imag__(z) = _COPYSIGNd(__builtin_huge_val(), __c) * __b; + } else if ((_ISINFd(__a) || _ISINFd(__b)) && _ISFINITEd(__c) && + _ISFINITEd(__d)) { + __a = _COPYSIGNd(_ISINFd(__a) ? 1.0 : 0.0, __a); + __b = _COPYSIGNd(_ISINFd(__b) ? 1.0 : 0.0, __b); + __real__(z) = __builtin_huge_val() * (__a * __c + __b * __d); + __imag__(z) = __builtin_huge_val() * (__b * __c - __a * __d); + } else if (_ISINFd(__logbw) && __logbw > 0.0 && _ISFINITEd(__a) && + _ISFINITEd(__b)) { + __c = _COPYSIGNd(_ISINFd(__c) ? 1.0 : 0.0, __c); + __d = _COPYSIGNd(_ISINFd(__d) ? 1.0 : 0.0, __d); __real__(z) = 0.0 * (__a * __c + __b * __d); __imag__(z) = 0.0 * (__b * __c - __a * __d); } @@ -152,33 +198,32 @@ extern "C" inline __device__ double _Complex __divdc3(double __a, double __b, return z; } -extern "C" inline __device__ float _Complex __divsc3(float __a, float __b, - float __c, float __d) { +__DEVICE__ float _Complex __divsc3(float __a, float __b, float __c, float __d) { int __ilogbw = 0; - float __logbw = std::logb(max(std::abs(__c), std::abs(__d))); - if (std::isfinite(__logbw)) { + float __logbw = _LOGBf(max(_ABSf(__c), _ABSf(__d))); + if (_ISFINITEf(__logbw)) { __ilogbw = (int)__logbw; - __c = std::scalbn(__c, -__ilogbw); - __d = std::scalbn(__d, -__ilogbw); + __c = _SCALBNf(__c, -__ilogbw); + __d = _SCALBNf(__d, -__ilogbw); } float __denom = __c * __c + __d * __d; float _Complex z; - __real__(z) = std::scalbn((__a * __c + __b * __d) / __denom, -__ilogbw); - __imag__(z) = std::scalbn((__b * __c - __a * __d) / __denom, -__ilogbw); - if (std::isnan(__real__(z)) && std::isnan(__imag__(z))) { - if ((__denom == 0) && (!std::isnan(__a) || !std::isnan(__b))) { - __real__(z) = std::copysign(__builtin_huge_valf(), __c) * __a; - __imag__(z) = std::copysign(__builtin_huge_valf(), __c) * __b; - } else if ((std::isinf(__a) || std::isinf(__b)) && std::isfinite(__c) && - std::isfinite(__d)) { - __a = std::copysign(std::isinf(__a) ? 1 : 0, __a); - __b = std::copysign(std::isinf(__b) ? 1 : 0, __b); + __real__(z) = _SCALBNf((__a * __c + __b * __d) / __denom, -__ilogbw); + __imag__(z) = _SCALBNf((__b * __c - __a * __d) / __denom, -__ilogbw); + if (_ISNANf(__real__(z)) && _ISNANf(__imag__(z))) { + if ((__denom == 0) && (!_ISNANf(__a) || !_ISNANf(__b))) { + __real__(z) = _COPYSIGNf(__builtin_huge_valf(), __c) * __a; + __imag__(z) = _COPYSIGNf(__builtin_huge_valf(), __c) * __b; + } else if ((_ISINFf(__a) || _ISINFf(__b)) && _ISFINITEf(__c) && + _ISFINITEf(__d)) { + __a = _COPYSIGNf(_ISINFf(__a) ? 1 : 0, __a); + __b = _COPYSIGNf(_ISINFf(__b) ? 1 : 0, __b); __real__(z) = __builtin_huge_valf() * (__a * __c + __b * __d); __imag__(z) = __builtin_huge_valf() * (__b * __c - __a * __d); - } else if (std::isinf(__logbw) && __logbw > 0 && std::isfinite(__a) && - std::isfinite(__b)) { - __c = std::copysign(std::isinf(__c) ? 1 : 0, __c); - __d = std::copysign(std::isinf(__d) ? 1 : 0, __d); + } else if (_ISINFf(__logbw) && __logbw > 0 && _ISFINITEf(__a) && + _ISFINITEf(__b)) { + __c = _COPYSIGNf(_ISINFf(__c) ? 1 : 0, __c); + __d = _COPYSIGNf(_ISINFf(__d) ? 1 : 0, __d); __real__(z) = 0 * (__a * __c + __b * __d); __imag__(z) = 0 * (__b * __c - __a * __d); } @@ -186,4 +231,29 @@ extern "C" inline __device__ float _Complex __divsc3(float __a, float __b, return z; } +#if defined(__cplusplus) +} // extern "C" +#endif + +#undef _ISNANd +#undef _ISNANf +#undef _ISINFd +#undef _ISINFf +#undef _COPYSIGNd +#undef _COPYSIGNf +#undef _ISFINITEd +#undef _ISFINITEf +#undef _SCALBNd +#undef _SCALBNf +#undef _ABSd +#undef _ABSf +#undef _LOGBd +#undef _LOGBf + +#ifdef _OPENMP +#pragma omp end declare target +#endif + +#pragma pop_macro("__DEVICE__") + #endif // __CLANG_CUDA_COMPLEX_BUILTINS diff --git a/clang/lib/Headers/__clang_cuda_device_functions.h b/clang/lib/Headers/__clang_cuda_device_functions.h index 76c588997f187..f801e5426aa43 100644 --- a/clang/lib/Headers/__clang_cuda_device_functions.h +++ b/clang/lib/Headers/__clang_cuda_device_functions.h @@ -10,7 +10,7 @@ #ifndef __CLANG_CUDA_DEVICE_FUNCTIONS_H__ #define __CLANG_CUDA_DEVICE_FUNCTIONS_H__ -#ifndef _OPENMP +#ifndef __OPENMP_NVPTX__ #if CUDA_VERSION < 9000 #error This file is intended to be used with CUDA-9+ only. #endif @@ -20,7 +20,7 @@ // we implement in this file. We need static in order to avoid emitting unused // functions and __forceinline__ helps inlining these wrappers at -O1. #pragma push_macro("__DEVICE__") -#ifdef _OPENMP +#ifdef __OPENMP_NVPTX__ #define __DEVICE__ static __attribute__((always_inline, nothrow)) #else #define __DEVICE__ static __device__ __forceinline__ @@ -1466,14 +1466,14 @@ __DEVICE__ unsigned int __vsubus4(unsigned int __a, unsigned int __b) { // For OpenMP we require the user to include as we need to know what // clock_t is on the system. -#ifndef _OPENMP +#ifndef __OPENMP_NVPTX__ __DEVICE__ /* clock_t= */ int clock() { return __nvvm_read_ptx_sreg_clock(); } #endif __DEVICE__ long long clock64() { return __nvvm_read_ptx_sreg_clock64(); } // These functions shouldn't be declared when including this header // for math function resolution purposes. -#ifndef _OPENMP +#ifndef __OPENMP_NVPTX__ __DEVICE__ void *memcpy(void *__a, const void *__b, size_t __c) { return __builtin_memcpy(__a, __b, __c); } diff --git a/clang/lib/Headers/__clang_cuda_libdevice_declares.h b/clang/lib/Headers/__clang_cuda_libdevice_declares.h index 4d70353394c8f..6173b589e3eff 100644 --- a/clang/lib/Headers/__clang_cuda_libdevice_declares.h +++ b/clang/lib/Headers/__clang_cuda_libdevice_declares.h @@ -14,7 +14,7 @@ extern "C" { #endif -#if defined(_OPENMP) +#if defined(__OPENMP_NVPTX__) #define __DEVICE__ #elif defined(__CUDA__) #define __DEVICE__ __device__ diff --git a/clang/lib/Headers/__clang_cuda_math.h b/clang/lib/Headers/__clang_cuda_math.h index 01db2f29af45b..332e616702acf 100644 --- a/clang/lib/Headers/__clang_cuda_math.h +++ b/clang/lib/Headers/__clang_cuda_math.h @@ -12,7 +12,7 @@ #error "This file is for CUDA compilation only." #endif -#ifndef _OPENMP +#ifndef __OPENMP_NVPTX__ #if CUDA_VERSION < 9000 #error This file is intended to be used with CUDA-9+ only. #endif @@ -22,7 +22,7 @@ // we implement in this file. We need static in order to avoid emitting unused // functions and __forceinline__ helps inlining these wrappers at -O1. #pragma push_macro("__DEVICE__") -#ifdef _OPENMP +#ifdef __OPENMP_NVPTX__ #if defined(__cplusplus) #define __DEVICE__ static constexpr __attribute__((always_inline, nothrow)) #else @@ -36,7 +36,7 @@ // because the OpenMP overlay requires constexpr functions here but prior to // c++14 void return functions could not be constexpr. #pragma push_macro("__DEVICE_VOID__") -#ifdef _OPENMP && defined(__cplusplus) && __cplusplus < 201402L +#ifdef __OPENMP_NVPTX__ && defined(__cplusplus) && __cplusplus < 201402L #define __DEVICE_VOID__ static __attribute__((always_inline, nothrow)) #else #define __DEVICE_VOID__ __DEVICE__ diff --git a/clang/lib/Headers/altivec.h b/clang/lib/Headers/altivec.h index 385828aceced2..9a4009216930a 100644 --- a/clang/lib/Headers/altivec.h +++ b/clang/lib/Headers/altivec.h @@ -16777,6 +16777,56 @@ vec_pext(vector unsigned long long __a, vector unsigned long long __b) { return __builtin_altivec_vpextd(__a, __b); } +/* vec_cfuge */ + +static __inline__ vector unsigned long long __ATTRS_o_ai +vec_cfuge(vector unsigned long long __a, vector unsigned long long __b) { + return __builtin_altivec_vcfuged(__a, __b); +} + +/* vec_gnb */ + +#define vec_gnb(__a, __b) __builtin_altivec_vgnb(__a, __b) + +/* vec_ternarylogic */ +#ifdef __VSX__ +#define vec_ternarylogic(__a, __b, __c, __imm) \ + _Generic((__a), vector unsigned char \ + : __builtin_vsx_xxeval((vector unsigned long long)(__a), \ + (vector unsigned long long)(__b), \ + (vector unsigned long long)(__c), (__imm)), \ + vector unsigned short \ + : __builtin_vsx_xxeval((vector unsigned long long)(__a), \ + (vector unsigned long long)(__b), \ + (vector unsigned long long)(__c), (__imm)), \ + vector unsigned int \ + : __builtin_vsx_xxeval((vector unsigned long long)(__a), \ + (vector unsigned long long)(__b), \ + (vector unsigned long long)(__c), (__imm)), \ + vector unsigned long long \ + : __builtin_vsx_xxeval((vector unsigned long long)(__a), \ + (vector unsigned long long)(__b), \ + (vector unsigned long long)(__c), (__imm)), \ + vector unsigned __int128 \ + : __builtin_vsx_xxeval((vector unsigned long long)(__a), \ + (vector unsigned long long)(__b), \ + (vector unsigned long long)(__c), (__imm))) +#endif /* __VSX__ */ + +/* vec_genpcvm */ + +#ifdef __VSX__ +#define vec_genpcvm(__a, __imm) \ + _Generic((__a), vector unsigned char \ + : __builtin_vsx_xxgenpcvbm((__a), (int)(__imm)), \ + vector unsigned short \ + : __builtin_vsx_xxgenpcvhm((__a), (int)(__imm)), \ + vector unsigned int \ + : __builtin_vsx_xxgenpcvwm((__a), (int)(__imm)), \ + vector unsigned long long \ + : __builtin_vsx_xxgenpcvdm((__a), (int)(__imm))) +#endif /* __VSX__ */ + /* vec_clrl */ static __inline__ vector signed char __ATTRS_o_ai @@ -16816,6 +16866,287 @@ vec_clrr(vector unsigned char __a, unsigned int __n) { return __builtin_altivec_vclrrb((vector signed char)__a, __n); #endif } + +/* vec_cntlzm */ + +static __inline__ vector unsigned long long __ATTRS_o_ai +vec_cntlzm(vector unsigned long long __a, vector unsigned long long __b) { + return __builtin_altivec_vclzdm(__a, __b); +} + +/* vec_cnttzm */ + +static __inline__ vector unsigned long long __ATTRS_o_ai +vec_cnttzm(vector unsigned long long __a, vector unsigned long long __b) { + return __builtin_altivec_vctzdm(__a, __b); +} + +/* vec_sldbi */ + +#define vec_sldb(__a, __b, __c) __builtin_altivec_vsldbi(__a, __b, (__c & 0x7)) + +/* vec_srdbi */ + +#define vec_srdb(__a, __b, __c) __builtin_altivec_vsrdbi(__a, __b, (__c & 0x7)) + +/* vec_insertl */ + +static __inline__ vector unsigned char __ATTRS_o_ai +vec_insertl(unsigned char __a, vector unsigned char __b, unsigned int __c) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vinsbrx(__b, __c, __a); +#else + return __builtin_altivec_vinsblx(__b, __c, __a); +#endif +} + +static __inline__ vector unsigned short __ATTRS_o_ai +vec_insertl(unsigned short __a, vector unsigned short __b, unsigned int __c) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vinshrx(__b, __c, __a); +#else + return __builtin_altivec_vinshlx(__b, __c, __a); +#endif +} + +static __inline__ vector unsigned int __ATTRS_o_ai +vec_insertl(unsigned int __a, vector unsigned int __b, unsigned int __c) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vinswrx(__b, __c, __a); +#else + return __builtin_altivec_vinswlx(__b, __c, __a); +#endif +} + +static __inline__ vector unsigned long long __ATTRS_o_ai +vec_insertl(unsigned long long __a, vector unsigned long long __b, + unsigned int __c) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vinsdrx(__b, __c, __a); +#else + return __builtin_altivec_vinsdlx(__b, __c, __a); +#endif +} + +static __inline__ vector unsigned char __ATTRS_o_ai +vec_insertl(vector unsigned char __a, vector unsigned char __b, + unsigned int __c) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vinsbvrx(__b, __c, __a); +#else + return __builtin_altivec_vinsbvlx(__b, __c, __a); +#endif +} + +static __inline__ vector unsigned short __ATTRS_o_ai +vec_insertl(vector unsigned short __a, vector unsigned short __b, + unsigned int __c) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vinshvrx(__b, __c, __a); +#else + return __builtin_altivec_vinshvlx(__b, __c, __a); +#endif +} + +static __inline__ vector unsigned int __ATTRS_o_ai +vec_insertl(vector unsigned int __a, vector unsigned int __b, + unsigned int __c) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vinswvrx(__b, __c, __a); +#else + return __builtin_altivec_vinswvlx(__b, __c, __a); +#endif +} + +/* vec_inserth */ + +static __inline__ vector unsigned char __ATTRS_o_ai +vec_inserth(unsigned char __a, vector unsigned char __b, unsigned int __c) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vinsblx(__b, __c, __a); +#else + return __builtin_altivec_vinsbrx(__b, __c, __a); +#endif +} + +static __inline__ vector unsigned short __ATTRS_o_ai +vec_inserth(unsigned short __a, vector unsigned short __b, unsigned int __c) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vinshlx(__b, __c, __a); +#else + return __builtin_altivec_vinshrx(__b, __c, __a); +#endif +} + +static __inline__ vector unsigned int __ATTRS_o_ai +vec_inserth(unsigned int __a, vector unsigned int __b, unsigned int __c) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vinswlx(__b, __c, __a); +#else + return __builtin_altivec_vinswrx(__b, __c, __a); +#endif +} + +static __inline__ vector unsigned long long __ATTRS_o_ai +vec_inserth(unsigned long long __a, vector unsigned long long __b, + unsigned int __c) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vinsdlx(__b, __c, __a); +#else + return __builtin_altivec_vinsdrx(__b, __c, __a); +#endif +} + +static __inline__ vector unsigned char __ATTRS_o_ai +vec_inserth(vector unsigned char __a, vector unsigned char __b, + unsigned int __c) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vinsbvlx(__b, __c, __a); +#else + return __builtin_altivec_vinsbvrx(__b, __c, __a); +#endif +} + +static __inline__ vector unsigned short __ATTRS_o_ai +vec_inserth(vector unsigned short __a, vector unsigned short __b, + unsigned int __c) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vinshvlx(__b, __c, __a); +#else + return __builtin_altivec_vinshvrx(__b, __c, __a); +#endif +} + +static __inline__ vector unsigned int __ATTRS_o_ai +vec_inserth(vector unsigned int __a, vector unsigned int __b, + unsigned int __c) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vinswvlx(__b, __c, __a); +#else + return __builtin_altivec_vinswvrx(__b, __c, __a); +#endif +} + +#ifdef __VSX__ + +/* vec_permx */ + +#define vec_permx(__a, __b, __c, __d) \ + __builtin_vsx_xxpermx((__a), (__b), (__c), (__d)) + +/* vec_blendv */ + +static __inline__ vector signed char __ATTRS_o_ai +vec_blendv(vector signed char __a, vector signed char __b, + vector unsigned char __c) { + return __builtin_vsx_xxblendvb(__a, __b, __c); +} + +static __inline__ vector unsigned char __ATTRS_o_ai +vec_blendv(vector unsigned char __a, vector unsigned char __b, + vector unsigned char __c) { + return __builtin_vsx_xxblendvb(__a, __b, __c); +} + +static __inline__ vector signed short __ATTRS_o_ai +vec_blendv(vector signed short __a, vector signed short __b, + vector unsigned short __c) { + return __builtin_vsx_xxblendvh(__a, __b, __c); +} + +static __inline__ vector unsigned short __ATTRS_o_ai +vec_blendv(vector unsigned short __a, vector unsigned short __b, + vector unsigned short __c) { + return __builtin_vsx_xxblendvh(__a, __b, __c); +} + +static __inline__ vector signed int __ATTRS_o_ai +vec_blendv(vector signed int __a, vector signed int __b, + vector unsigned int __c) { + return __builtin_vsx_xxblendvw(__a, __b, __c); +} + +static __inline__ vector unsigned int __ATTRS_o_ai +vec_blendv(vector unsigned int __a, vector unsigned int __b, + vector unsigned int __c) { + return __builtin_vsx_xxblendvw(__a, __b, __c); +} + +static __inline__ vector signed long long __ATTRS_o_ai +vec_blendv(vector signed long long __a, vector signed long long __b, + vector unsigned long long __c) { + return __builtin_vsx_xxblendvd(__a, __b, __c); +} + +static __inline__ vector unsigned long long __ATTRS_o_ai +vec_blendv(vector unsigned long long __a, vector unsigned long long __b, + vector unsigned long long __c) { + return __builtin_vsx_xxblendvd(__a, __b, __c); +} + +static __inline__ vector float __ATTRS_o_ai +vec_blendv(vector float __a, vector float __b, vector unsigned int __c) { + return __builtin_vsx_xxblendvw(__a, __b, __c); +} + +static __inline__ vector double __ATTRS_o_ai +vec_blendv(vector double __a, vector double __b, + vector unsigned long long __c) { + return __builtin_vsx_xxblendvd(__a, __b, __c); +} + +/* vec_splati */ + +#define vec_splati(__a) \ + _Generic((__a), signed int \ + : ((vector signed int)__a), unsigned int \ + : ((vector unsigned int)__a), float \ + : ((vector float)__a)) + +/* vec_spatid */ + +static __inline__ vector double __ATTRS_o_ai vec_splatid(const float __a) { + return ((vector double)((double)__a)); +} + +/* vec_splati_ins */ + +static __inline__ vector signed int __ATTRS_o_ai vec_splati_ins( + vector signed int __a, const unsigned int __b, const signed int __c) { +#ifdef __LITTLE_ENDIAN__ + __a[1 - __b] = __c; + __a[3 - __b] = __c; +#else + __a[__b] = __c; + __a[2 + __b] = __c; +#endif + return __a; +} + +static __inline__ vector unsigned int __ATTRS_o_ai vec_splati_ins( + vector unsigned int __a, const unsigned int __b, const unsigned int __c) { +#ifdef __LITTLE_ENDIAN__ + __a[1 - __b] = __c; + __a[3 - __b] = __c; +#else + __a[__b] = __c; + __a[2 + __b] = __c; +#endif + return __a; +} + +static __inline__ vector float __ATTRS_o_ai +vec_splati_ins(vector float __a, const unsigned int __b, const float __c) { +#ifdef __LITTLE_ENDIAN__ + __a[1 - __b] = __c; + __a[3 - __b] = __c; +#else + __a[__b] = __c; + __a[2 + __b] = __c; +#endif + return __a; +} +#endif /* __VSX__ */ #endif /* __POWER10_VECTOR__ */ #undef __ATTRS_o_ai diff --git a/clang/lib/Headers/amxintrin.h b/clang/lib/Headers/amxintrin.h new file mode 100644 index 0000000000000..58254e21c81a6 --- /dev/null +++ b/clang/lib/Headers/amxintrin.h @@ -0,0 +1,225 @@ +/*===--------------- amxintrin.h - AMX intrinsics -*- C/C++ -*---------------=== + * + * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + * See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * + *===------------------------------------------------------------------------=== + */ + +#ifndef __IMMINTRIN_H +#error "Never use directly; include instead." +#endif /* __IMMINTRIN_H */ + +#ifndef __AMXINTRIN_H +#define __AMXINTRIN_H +#ifdef __x86_64__ + +#define __DEFAULT_FN_ATTRS \ + __attribute__((__always_inline__, __nodebug__, __target__("amx-tile"))) + +/// Load tile configuration from a 64-byte memory location specified by +/// "mem_addr". The tile configuration includes the tile type palette, the +/// number of bytes per row, and the number of rows. If the specified +/// palette_id is zero, that signifies the init state for both the tile +/// config and the tile data, and the tiles are zeroed. Any invalid +/// configurations will result in #GP fault. +/// +/// \headerfile +/// +/// This intrinsic corresponds to the LDTILECFG instruction. +/// +/// \param __config +/// A pointer to 512-bits configuration +static __inline__ void __DEFAULT_FN_ATTRS +_tile_loadconfig(const void *__config) +{ + __builtin_ia32_tile_loadconfig(__config); +} + +/// Stores the current tile configuration to a 64-byte memory location +/// specified by "mem_addr". The tile configuration includes the tile type +/// palette, the number of bytes per row, and the number of rows. If tiles +/// are not configured, all zeroes will be stored to memory. +/// +/// \headerfile +/// +/// This intrinsic corresponds to the STTILECFG instruction. +/// +/// \param __config +/// A pointer to 512-bits configuration +static __inline__ void __DEFAULT_FN_ATTRS +_tile_storeconfig(void *__config) +{ + __builtin_ia32_tile_storeconfig(__config); +} + +/// Release the tile configuration to return to the init state, which +/// releases all storage it currently holds. +/// +/// \headerfile +/// +/// This intrinsic corresponds to the TILERELEASE instruction. +static __inline__ void __DEFAULT_FN_ATTRS +_tile_release(void) +{ + __builtin_ia32_tilerelease(); +} + +/// Load tile rows from memory specifieid by "base" address and "stride" into +/// destination tile "dst" using the tile configuration previously configured +/// via "_tile_loadconfig". +/// +/// \headerfile +/// +/// This intrinsic corresponds to the TILELOADD instruction. +/// +/// \param dst +/// A destination tile. Max size is 1024 Bytes. +/// \param base +/// A pointer to base address. +/// \param stride +/// The stride between the rows' data to be loaded in memory. +#define _tile_loadd(dst, base, stride) \ + __builtin_ia32_tileloadd64((dst), ((const void *)(base)), (__SIZE_TYPE__)(stride)) + +/// Load tile rows from memory specifieid by "base" address and "stride" into +/// destination tile "dst" using the tile configuration previously configured +/// via "_tile_loadconfig". This intrinsic provides a hint to the implementation +/// that the data will likely not be reused in the near future and the data +/// caching can be optimized accordingly. +/// +/// \headerfile +/// +/// This intrinsic corresponds to the TILELOADDT1 instruction. +/// +/// \param dst +/// A destination tile. Max size is 1024 Bytes. +/// \param base +/// A pointer to base address. +/// \param stride +/// The stride between the rows' data to be loaded in memory. +#define _tile_stream_loadd(dst, base, stride) \ + __builtin_ia32_tileloaddt164((dst), ((const void *)(base)), (__SIZE_TYPE__)(stride)) + +/// Store the tile specified by "src" to memory specifieid by "base" address and +/// "stride" using the tile configuration previously configured via +/// "_tile_loadconfig". +/// +/// \headerfile +/// +/// This intrinsic corresponds to the TILESTORED instruction. +/// +/// \param dst +/// A destination tile. Max size is 1024 Bytes. +/// \param base +/// A pointer to base address. +/// \param stride +/// The stride between the rows' data to be stored in memory. +#define _tile_stored(dst, base, stride) \ + __builtin_ia32_tilestored64((dst), ((void *)(base)), (__SIZE_TYPE__)(stride)) + +/// Zero the tile specified by "tdest". +/// +/// \headerfile +/// +/// This intrinsic corresponds to the TILEZERO instruction. +/// +/// \param tile +/// The destination tile to be zero. Max size is 1024 Bytes. +#define _tile_zero(tile) __builtin_ia32_tilezero((tile)) + +/// Compute dot-product of bytes in tiles with a source/destination accumulator. +/// Multiply groups of 4 adjacent pairs of signed 8-bit integers in src0 with +/// corresponding signed 8-bit integers in src1, producing 4 intermediate 32-bit +/// results. Sum these 4 results with the corresponding 32-bit integer in "dst", +/// and store the 32-bit result back to tile "dst". +/// +/// \headerfile +/// +/// This intrinsic corresponds to the TDPBSSD instruction. +/// +/// \param dst +/// The destination tile. Max size is 1024 Bytes. +/// \param src0 +/// The 1st source tile. Max size is 1024 Bytes. +/// \param src1 +/// The 2nd source tile. Max size is 1024 Bytes. +#define _tile_dpbssd(dst, src0, src1) __builtin_ia32_tdpbssd((dst), (src0), (src1)) + +/// Compute dot-product of bytes in tiles with a source/destination accumulator. +/// Multiply groups of 4 adjacent pairs of signed 8-bit integers in src0 with +/// corresponding unsigned 8-bit integers in src1, producing 4 intermediate +/// 32-bit results. Sum these 4 results with the corresponding 32-bit integer +/// in "dst", and store the 32-bit result back to tile "dst". +/// +/// \headerfile +/// +/// This intrinsic corresponds to the TDPBSUD instruction. +/// +/// \param dst +/// The destination tile. Max size is 1024 Bytes. +/// \param src0 +/// The 1st source tile. Max size is 1024 Bytes. +/// \param src1 +/// The 2nd source tile. Max size is 1024 Bytes. +#define _tile_dpbsud(dst, src0, src1) __builtin_ia32_tdpbsud((dst), (src0), (src1)) + +/// Compute dot-product of bytes in tiles with a source/destination accumulator. +/// Multiply groups of 4 adjacent pairs of unsigned 8-bit integers in src0 with +/// corresponding signed 8-bit integers in src1, producing 4 intermediate 32-bit +/// results. Sum these 4 results with the corresponding 32-bit integer in "dst", +/// and store the 32-bit result back to tile "dst". +/// +/// \headerfile +/// +/// This intrinsic corresponds to the TDPBUSD instruction. +/// +/// \param dst +/// The destination tile. Max size is 1024 Bytes. +/// \param src0 +/// The 1st source tile. Max size is 1024 Bytes. +/// \param src1 +/// The 2nd source tile. Max size is 1024 Bytes. +#define _tile_dpbusd(dst, src0, src1) __builtin_ia32_tdpbusd((dst), (src0), (src1)) + +/// Compute dot-product of bytes in tiles with a source/destination accumulator. +/// Multiply groups of 4 adjacent pairs of unsigned 8-bit integers in src0 with +/// corresponding unsigned 8-bit integers in src1, producing 4 intermediate +/// 32-bit results. Sum these 4 results with the corresponding 32-bit integer in +/// "dst", and store the 32-bit result back to tile "dst". +/// +/// \headerfile +/// +/// This intrinsic corresponds to the TDPBUUD instruction. +/// +/// \param dst +/// The destination tile. Max size is 1024 Bytes. +/// \param src0 +/// The 1st source tile. Max size is 1024 Bytes. +/// \param src1 +/// The 2nd source tile. Max size is 1024 Bytes. +#define _tile_dpbuud(dst, src0, src1) __builtin_ia32_tdpbuud((dst), (src0), (src1)) + +/// Compute dot-product of BF16 (16-bit) floating-point pairs in tiles src0 and +/// src1, accumulating the intermediate single-precision (32-bit) floating-point +/// elements with elements in "dst", and store the 32-bit result back to tile +/// "dst". +/// +/// \headerfile +/// +/// This intrinsic corresponds to the TDPBF16PS instruction. +/// +/// \param dst +/// The destination tile. Max size is 1024 Bytes. +/// \param src0 +/// The 1st source tile. Max size is 1024 Bytes. +/// \param src1 +/// The 2nd source tile. Max size is 1024 Bytes. +#define _tile_dpbf16ps(dst, src0, src1) \ + __builtin_ia32_tdpbf16ps((dst), (src0), (src1)) + +#undef __DEFAULT_FN_ATTRS + +#endif /* __x86_64__ */ +#endif /* __AMXINTRIN_H */ diff --git a/clang/lib/Headers/cpuid.h b/clang/lib/Headers/cpuid.h index 6c38b578b30e5..2a88c042d0468 100644 --- a/clang/lib/Headers/cpuid.h +++ b/clang/lib/Headers/cpuid.h @@ -190,6 +190,9 @@ #define bit_TSXLDTRK 0x00010000 #define bit_PCONFIG 0x00040000 #define bit_IBT 0x00100000 +#define bit_AMXBF16 0x00400000 +#define bit_AMXTILE 0x01000000 +#define bit_AMXINT8 0x02000000 /* Features in %eax for leaf 7 sub-leaf 1 */ #define bit_AVX512BF16 0x00000020 diff --git a/clang/lib/Headers/immintrin.h b/clang/lib/Headers/immintrin.h index dd27ca2f6605b..e9dff2310fdf7 100644 --- a/clang/lib/Headers/immintrin.h +++ b/clang/lib/Headers/immintrin.h @@ -471,6 +471,11 @@ _storebe_i64(void * __P, long long __D) { #include #endif +#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ + defined(__AMXTILE__) || defined(__AMXINT8__) || defined(__AMXBF16__) +#include +#endif + #if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ defined(__AVX512VP2INTERSECT__) #include diff --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h index f85f7a2beb495..871b47ca82674 100644 --- a/clang/lib/Headers/intrin.h +++ b/clang/lib/Headers/intrin.h @@ -289,6 +289,9 @@ unsigned char _BitScanForward64(unsigned long *_Index, unsigned __int64 _Mask); static __inline__ unsigned char _BitScanReverse64(unsigned long *_Index, unsigned __int64 _Mask); +#endif + +#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) static __inline__ __int64 _InterlockedDecrement64(__int64 volatile *_Addend); static __inline__ diff --git a/clang/lib/Headers/openmp_wrappers/__clang_openmp_device_functions.h b/clang/lib/Headers/openmp_wrappers/__clang_openmp_device_functions.h index 9ff0a186273ae..406c9748e286e 100644 --- a/clang/lib/Headers/openmp_wrappers/__clang_openmp_device_functions.h +++ b/clang/lib/Headers/openmp_wrappers/__clang_openmp_device_functions.h @@ -22,11 +22,15 @@ extern "C" { #endif #define __CUDA__ +#define __OPENMP_NVPTX__ + /// Include declarations for libdevice functions. #include <__clang_cuda_libdevice_declares.h> /// Provide definitions for these functions. #include <__clang_cuda_device_functions.h> + +#undef __OPENMP_NVPTX__ #undef __CUDA__ #ifdef __cplusplus diff --git a/clang/lib/Headers/openmp_wrappers/cmath b/clang/lib/Headers/openmp_wrappers/cmath index 05be252fa9fbf..bd6011eb6f6d5 100644 --- a/clang/lib/Headers/openmp_wrappers/cmath +++ b/clang/lib/Headers/openmp_wrappers/cmath @@ -28,7 +28,9 @@ device = {arch(nvptx, nvptx64)}, implementation = {extension(match_any)}) #define __CUDA__ +#define __OPENMP_NVPTX__ #include <__clang_cuda_cmath.h> +#undef __OPENMP_NVPTX__ #undef __CUDA__ // Overloads not provided by the CUDA wrappers but by the CUDA system headers. diff --git a/clang/lib/Headers/openmp_wrappers/complex b/clang/lib/Headers/openmp_wrappers/complex new file mode 100644 index 0000000000000..1ed0b14879efb --- /dev/null +++ b/clang/lib/Headers/openmp_wrappers/complex @@ -0,0 +1,25 @@ +/*===-- complex --- OpenMP complex wrapper for target regions --------- c++ -=== + * + * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + * See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __CLANG_OPENMP_COMPLEX__ +#define __CLANG_OPENMP_COMPLEX__ + +#ifndef _OPENMP +#error "This file is for OpenMP compilation only." +#endif + +// We require std::math functions in the complex builtins below. +#include + +#define __CUDA__ +#include <__clang_cuda_complex_builtins.h> +#endif + +// Grab the host header too. +#include_next diff --git a/clang/lib/Headers/openmp_wrappers/complex.h b/clang/lib/Headers/openmp_wrappers/complex.h new file mode 100644 index 0000000000000..829c7a7857253 --- /dev/null +++ b/clang/lib/Headers/openmp_wrappers/complex.h @@ -0,0 +1,25 @@ +/*===-- complex --- OpenMP complex wrapper for target regions --------- c++ -=== + * + * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + * See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __CLANG_OPENMP_COMPLEX_H__ +#define __CLANG_OPENMP_COMPLEX_H__ + +#ifndef _OPENMP +#error "This file is for OpenMP compilation only." +#endif + +// We require math functions in the complex builtins below. +#include + +#define __CUDA__ +#include <__clang_cuda_complex_builtins.h> +#endif + +// Grab the host header too. +#include_next diff --git a/clang/lib/Headers/openmp_wrappers/math.h b/clang/lib/Headers/openmp_wrappers/math.h index e917a149b5c9a..c64af8b13ece4 100644 --- a/clang/lib/Headers/openmp_wrappers/math.h +++ b/clang/lib/Headers/openmp_wrappers/math.h @@ -41,7 +41,9 @@ device = {arch(nvptx, nvptx64)}, implementation = {extension(match_any)}) #define __CUDA__ +#define __OPENMP_NVPTX__ #include <__clang_cuda_math.h> +#undef __OPENMP_NVPTX__ #undef __CUDA__ #pragma omp end declare variant diff --git a/clang/lib/Index/CMakeLists.txt b/clang/lib/Index/CMakeLists.txt index e4ea7ea1660c9..68ebb5b7ede30 100644 --- a/clang/lib/Index/CMakeLists.txt +++ b/clang/lib/Index/CMakeLists.txt @@ -27,4 +27,7 @@ add_clang_library(clangIndex clangRewrite clangSerialization clangToolingCore + + DEPENDS + omp_gen ) diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index f44614b4bec46..eb16bc8c7da2d 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -525,8 +525,12 @@ static void EncodeUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf, /// NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, SourceLocation TokLoc, - Preprocessor &PP) - : PP(PP), ThisTokBegin(TokSpelling.begin()), ThisTokEnd(TokSpelling.end()) { + const SourceManager &SM, + const LangOptions &LangOpts, + const TargetInfo &Target, + DiagnosticsEngine &Diags) + : SM(SM), LangOpts(LangOpts), Diags(Diags), + ThisTokBegin(TokSpelling.begin()), ThisTokEnd(TokSpelling.end()) { // This routine assumes that the range begin/end matches the regex for integer // and FP constants (specifically, the 'pp-number' regex), and assumes that @@ -572,7 +576,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, checkSeparator(TokLoc, s, CSK_AfterDigits); // Initial scan to lookahead for fixed point suffix. - if (PP.getLangOpts().FixedPoint) { + if (LangOpts.FixedPoint) { for (const char *c = s; c != ThisTokEnd; ++c) { if (*c == 'r' || *c == 'k' || *c == 'R' || *c == 'K') { saw_fixed_point_suffix = true; @@ -592,14 +596,16 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, switch (*s) { case 'R': case 'r': - if (!PP.getLangOpts().FixedPoint) break; + if (!LangOpts.FixedPoint) + break; if (isFract || isAccum) break; if (!(saw_period || saw_exponent)) break; isFract = true; continue; case 'K': case 'k': - if (!PP.getLangOpts().FixedPoint) break; + if (!LangOpts.FixedPoint) + break; if (isFract || isAccum) break; if (!(saw_period || saw_exponent)) break; isAccum = true; @@ -607,7 +613,8 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, case 'h': // FP Suffix for "half". case 'H': // OpenCL Extension v1.2 s9.5 - h or H suffix for half type. - if (!(PP.getLangOpts().Half || PP.getLangOpts().FixedPoint)) break; + if (!(LangOpts.Half || LangOpts.FixedPoint)) + break; if (isIntegerLiteral()) break; // Error for integer constant. if (isHalf || isFloat || isLong) break; // HH, FH, LH invalid. isHalf = true; @@ -621,8 +628,8 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, // CUDA host and device may have different _Float16 support, therefore // allows f16 literals to avoid false alarm. // ToDo: more precise check for CUDA. - if ((PP.getTargetInfo().hasFloat16Type() || PP.getLangOpts().CUDA) && - s + 2 < ThisTokEnd && s[1] == '1' && s[2] == '6') { + if ((Target.hasFloat16Type() || LangOpts.CUDA) && s + 2 < ThisTokEnd && + s[1] == '1' && s[2] == '6') { s += 2; // success, eat up 2 characters. isFloat16 = true; continue; @@ -657,10 +664,10 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, } else { isLong = true; } - continue; // Success. + continue; // Success. case 'i': case 'I': - if (PP.getLangOpts().MicrosoftExt) { + if (LangOpts.MicrosoftExt) { if (isLong || isLongLong || MicrosoftInteger) break; @@ -713,7 +720,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, if (s != ThisTokEnd || isImaginary) { // FIXME: Don't bother expanding UCNs if !tok.hasUCN(). expandUCNs(UDSuffixBuf, StringRef(SuffixBegin, ThisTokEnd - SuffixBegin)); - if (isValidUDSuffix(PP.getLangOpts(), UDSuffixBuf)) { + if (isValidUDSuffix(LangOpts, UDSuffixBuf)) { if (!isImaginary) { // Any suffix pieces we might have parsed are actually part of the // ud-suffix. @@ -736,8 +743,9 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, if (s != ThisTokEnd) { // Report an error if there are any. - PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, SuffixBegin - ThisTokBegin), - diag::err_invalid_suffix_constant) + Diags.Report(Lexer::AdvanceToTokenCharacter( + TokLoc, SuffixBegin - ThisTokBegin, SM, LangOpts), + diag::err_invalid_suffix_constant) << StringRef(SuffixBegin, ThisTokEnd - SuffixBegin) << (isFixedPointConstant ? 2 : isFPConstant); hadError = true; @@ -758,9 +766,11 @@ void NumericLiteralParser::ParseDecimalOrOctalCommon(SourceLocation TokLoc){ // If we have a hex digit other than 'e' (which denotes a FP exponent) then // the code is using an incorrect base. if (isHexDigit(*s) && *s != 'e' && *s != 'E' && - !isValidUDSuffix(PP.getLangOpts(), StringRef(s, ThisTokEnd - s))) { - PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s-ThisTokBegin), - diag::err_invalid_digit) << StringRef(s, 1) << (radix == 8 ? 1 : 0); + !isValidUDSuffix(LangOpts, StringRef(s, ThisTokEnd - s))) { + Diags.Report( + Lexer::AdvanceToTokenCharacter(TokLoc, s - ThisTokBegin, SM, LangOpts), + diag::err_invalid_digit) + << StringRef(s, 1) << (radix == 8 ? 1 : 0); hadError = true; return; } @@ -786,8 +796,9 @@ void NumericLiteralParser::ParseDecimalOrOctalCommon(SourceLocation TokLoc){ s = first_non_digit; } else { if (!hadError) { - PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-ThisTokBegin), - diag::err_exponent_has_no_digits); + Diags.Report(Lexer::AdvanceToTokenCharacter( + TokLoc, Exponent - ThisTokBegin, SM, LangOpts), + diag::err_exponent_has_no_digits); hadError = true; } return; @@ -833,9 +844,10 @@ void NumericLiteralParser::checkSeparator(SourceLocation TokLoc, return; if (isDigitSeparator(*Pos)) { - PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Pos - ThisTokBegin), - diag::err_digit_separator_not_between_digits) - << IsAfterDigits; + Diags.Report(Lexer::AdvanceToTokenCharacter(TokLoc, Pos - ThisTokBegin, SM, + LangOpts), + diag::err_digit_separator_not_between_digits) + << IsAfterDigits; hadError = true; } } @@ -873,9 +885,10 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) { } if (!HasSignificandDigits) { - PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s - ThisTokBegin), - diag::err_hex_constant_requires) - << PP.getLangOpts().CPlusPlus << 1; + Diags.Report(Lexer::AdvanceToTokenCharacter(TokLoc, s - ThisTokBegin, SM, + LangOpts), + diag::err_hex_constant_requires) + << LangOpts.CPlusPlus << 1; hadError = true; return; } @@ -891,8 +904,9 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) { const char *first_non_digit = SkipDigits(s); if (!containsDigits(s, first_non_digit)) { if (!hadError) { - PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-ThisTokBegin), - diag::err_exponent_has_no_digits); + Diags.Report(Lexer::AdvanceToTokenCharacter( + TokLoc, Exponent - ThisTokBegin, SM, LangOpts), + diag::err_exponent_has_no_digits); hadError = true; } return; @@ -900,16 +914,17 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) { checkSeparator(TokLoc, s, CSK_BeforeDigits); s = first_non_digit; - if (!PP.getLangOpts().HexFloats) - PP.Diag(TokLoc, PP.getLangOpts().CPlusPlus - ? diag::ext_hex_literal_invalid - : diag::ext_hex_constant_invalid); - else if (PP.getLangOpts().CPlusPlus17) - PP.Diag(TokLoc, diag::warn_cxx17_hex_literal); + if (!LangOpts.HexFloats) + Diags.Report(TokLoc, LangOpts.CPlusPlus + ? diag::ext_hex_literal_invalid + : diag::ext_hex_constant_invalid); + else if (LangOpts.CPlusPlus17) + Diags.Report(TokLoc, diag::warn_cxx17_hex_literal); } else if (saw_period) { - PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s - ThisTokBegin), - diag::err_hex_constant_requires) - << PP.getLangOpts().CPlusPlus << 0; + Diags.Report(Lexer::AdvanceToTokenCharacter(TokLoc, s - ThisTokBegin, SM, + LangOpts), + diag::err_hex_constant_requires) + << LangOpts.CPlusPlus << 0; hadError = true; } return; @@ -918,12 +933,10 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) { // Handle simple binary numbers 0b01010 if ((c1 == 'b' || c1 == 'B') && (s[1] == '0' || s[1] == '1')) { // 0b101010 is a C++1y / GCC extension. - PP.Diag(TokLoc, - PP.getLangOpts().CPlusPlus14 - ? diag::warn_cxx11_compat_binary_literal - : PP.getLangOpts().CPlusPlus - ? diag::ext_binary_literal_cxx14 - : diag::ext_binary_literal); + Diags.Report(TokLoc, LangOpts.CPlusPlus14 + ? diag::warn_cxx11_compat_binary_literal + : LangOpts.CPlusPlus ? diag::ext_binary_literal_cxx14 + : diag::ext_binary_literal); ++s; assert(s < ThisTokEnd && "didn't maximally munch?"); radix = 2; @@ -932,10 +945,11 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) { if (s == ThisTokEnd) { // Done. } else if (isHexDigit(*s) && - !isValidUDSuffix(PP.getLangOpts(), - StringRef(s, ThisTokEnd - s))) { - PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s-ThisTokBegin), - diag::err_invalid_digit) << StringRef(s, 1) << 2; + !isValidUDSuffix(LangOpts, StringRef(s, ThisTokEnd - s))) { + Diags.Report(Lexer::AdvanceToTokenCharacter(TokLoc, s - ThisTokBegin, SM, + LangOpts), + diag::err_invalid_digit) + << StringRef(s, 1) << 2; hadError = true; } // Other suffixes will be diagnosed by the caller. diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index 396ba529fc9a1..053ef1d2dd180 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -432,6 +432,7 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc, // Skip to the next '#endif' / '#else' / '#elif'. CurLexer->skipOver(*SkipLength); } + SourceLocation endLoc; while (true) { CurLexer->Lex(Tok); @@ -538,7 +539,7 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc, // Restore the value of LexingRawMode so that trailing comments // are handled correctly, if we've reached the outermost block. CurPPLexer->LexingRawMode = false; - CheckEndOfDirective("endif"); + endLoc = CheckEndOfDirective("endif"); CurPPLexer->LexingRawMode = true; if (Callbacks) Callbacks->Endif(Tok.getLocation(), CondInfo.IfLoc); @@ -565,7 +566,7 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc, // Restore the value of LexingRawMode so that trailing comments // are handled correctly. CurPPLexer->LexingRawMode = false; - CheckEndOfDirective("else"); + endLoc = CheckEndOfDirective("else"); CurPPLexer->LexingRawMode = true; if (Callbacks) Callbacks->Else(Tok.getLocation(), CondInfo.IfLoc); @@ -621,7 +622,9 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc, // by the end of the preamble; we'll resume parsing after the preamble. if (Callbacks && (Tok.isNot(tok::eof) || !isRecordingPreamble())) Callbacks->SourceRangeSkipped( - SourceRange(HashTokenLoc, CurPPLexer->getSourceLocation()), + SourceRange(HashTokenLoc, endLoc.isValid() + ? endLoc + : CurPPLexer->getSourceLocation()), Tok.getLocation()); } diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp index e5ec2b99f5074..8c120c13d7d26 100644 --- a/clang/lib/Lex/PPExpressions.cpp +++ b/clang/lib/Lex/PPExpressions.cpp @@ -15,7 +15,6 @@ // //===----------------------------------------------------------------------===// -#include "clang/Lex/Preprocessor.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" @@ -26,9 +25,12 @@ #include "clang/Lex/LiteralSupport.h" #include "clang/Lex/MacroInfo.h" #include "clang/Lex/PPCallbacks.h" +#include "clang/Lex/Preprocessor.h" #include "clang/Lex/Token.h" #include "llvm/ADT/APSInt.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/SaveAndRestore.h" @@ -251,8 +253,24 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, // If this identifier isn't 'defined' or one of the special // preprocessor keywords and it wasn't macro expanded, it turns // into a simple 0 - if (ValueLive) + if (ValueLive) { PP.Diag(PeekTok, diag::warn_pp_undef_identifier) << II; + + const DiagnosticsEngine &DiagEngine = PP.getDiagnostics(); + // If 'Wundef' is enabled, do not emit 'undef-prefix' diagnostics. + if (DiagEngine.isIgnored(diag::warn_pp_undef_identifier, + PeekTok.getLocation())) { + const std::vector UndefPrefixes = + DiagEngine.getDiagnosticOptions().UndefPrefixes; + const StringRef IdentifierName = II->getName(); + if (llvm::any_of(UndefPrefixes, + [&IdentifierName](const std::string &Prefix) { + return IdentifierName.startswith(Prefix); + })) + PP.Diag(PeekTok, diag::warn_pp_undef_prefix) + << AddFlagValue{llvm::join(UndefPrefixes, ",")} << II; + } + } Result.Val = 0; Result.Val.setIsUnsigned(false); // "0" is signed intmax_t 0. Result.setIdentifier(II); @@ -277,7 +295,9 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, if (NumberInvalid) return true; // a diagnostic was already reported - NumericLiteralParser Literal(Spelling, PeekTok.getLocation(), PP); + NumericLiteralParser Literal(Spelling, PeekTok.getLocation(), + PP.getSourceManager(), PP.getLangOpts(), + PP.getTargetInfo(), PP.getDiagnostics()); if (Literal.hadError) return true; // a diagnostic was already reported. diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index 105aa6683c8b5..160e2b6ed8846 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -1370,7 +1370,9 @@ bool Preprocessor::parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value) { StringRef Spelling = getSpelling(Tok, IntegerBuffer, &NumberInvalid); if (NumberInvalid) return false; - NumericLiteralParser Literal(Spelling, Tok.getLocation(), *this); + NumericLiteralParser Literal(Spelling, Tok.getLocation(), getSourceManager(), + getLangOpts(), getTargetInfo(), + getDiagnostics()); if (Literal.hadError || !Literal.isIntegerLiteral() || Literal.hasUDSuffix()) return false; llvm::APInt APVal(64, 0); diff --git a/clang/lib/Parse/CMakeLists.txt b/clang/lib/Parse/CMakeLists.txt index 3f7ab2a74af27..43cd8f6e12a24 100644 --- a/clang/lib/Parse/CMakeLists.txt +++ b/clang/lib/Parse/CMakeLists.txt @@ -27,4 +27,7 @@ add_clang_library(clangParse clangBasic clangLex clangSema + + DEPENDS + omp_gen ) diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index 06e02ed0e11c6..d05332b5ac5a7 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -133,9 +133,6 @@ NamedDecl *Parser::ParseCXXInlineMethodDef( LexedMethod* LM = new LexedMethod(this, FnD); getCurrentClass().LateParsedDeclarations.push_back(LM); - LM->TemplateScope = getCurScope()->isTemplateParamScope() || - (FnD && isa(FnD) && - cast(FnD)->isAbbreviated()); CachedTokens &Toks = LM->Toks; tok::TokenKind kind = Tok.getKind(); @@ -225,6 +222,7 @@ Parser::LateParsedDeclaration::~LateParsedDeclaration() {} void Parser::LateParsedDeclaration::ParseLexedMethodDeclarations() {} void Parser::LateParsedDeclaration::ParseLexedMemberInitializers() {} void Parser::LateParsedDeclaration::ParseLexedMethodDefs() {} +void Parser::LateParsedDeclaration::ParseLexedAttributes() {} void Parser::LateParsedDeclaration::ParseLexedPragmas() {} Parser::LateParsedClass::LateParsedClass(Parser *P, ParsingClass *C) @@ -246,6 +244,10 @@ void Parser::LateParsedClass::ParseLexedMethodDefs() { Self->ParseLexedMethodDefs(*Class); } +void Parser::LateParsedClass::ParseLexedAttributes() { + Self->ParseLexedAttributes(*Class); +} + void Parser::LateParsedClass::ParseLexedPragmas() { Self->ParseLexedPragmas(*Class); } @@ -262,57 +264,79 @@ void Parser::LateParsedMemberInitializer::ParseLexedMemberInitializers() { Self->ParseLexedMemberInitializer(*this); } +void Parser::LateParsedAttribute::ParseLexedAttributes() { + Self->ParseLexedAttribute(*this, true, false); +} + void Parser::LateParsedPragma::ParseLexedPragmas() { Self->ParseLexedPragma(*this); } +/// Utility to re-enter a possibly-templated scope while parsing its +/// late-parsed components. +struct Parser::ReenterTemplateScopeRAII { + Parser &P; + MultiParseScope Scopes; + TemplateParameterDepthRAII CurTemplateDepthTracker; + + ReenterTemplateScopeRAII(Parser &P, Decl *MaybeTemplated, bool Enter = true) + : P(P), Scopes(P), CurTemplateDepthTracker(P.TemplateParameterDepth) { + if (Enter) { + CurTemplateDepthTracker.addDepth( + P.ReenterTemplateScopes(Scopes, MaybeTemplated)); + } + } +}; + +/// Utility to re-enter a class scope while parsing its late-parsed components. +struct Parser::ReenterClassScopeRAII : ReenterTemplateScopeRAII { + ParsingClass &Class; + + ReenterClassScopeRAII(Parser &P, ParsingClass &Class) + : ReenterTemplateScopeRAII(P, Class.TagOrTemplate, + /*Enter=*/!Class.TopLevelClass), + Class(Class) { + // If this is the top-level class, we're still within its scope. + if (Class.TopLevelClass) + return; + + // Re-enter the class scope itself. + Scopes.Enter(Scope::ClassScope|Scope::DeclScope); + P.Actions.ActOnStartDelayedMemberDeclarations(P.getCurScope(), + Class.TagOrTemplate); + } + ~ReenterClassScopeRAII() { + if (Class.TopLevelClass) + return; + + P.Actions.ActOnFinishDelayedMemberDeclarations(P.getCurScope(), + Class.TagOrTemplate); + } +}; + /// ParseLexedMethodDeclarations - We finished parsing the member /// specification of a top (non-nested) C++ class. Now go over the /// stack of method declarations with some parts for which parsing was /// delayed (such as default arguments) and parse them. void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) { - bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; - ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, - HasTemplateScope); - TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); - if (HasTemplateScope) { - Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); - ++CurTemplateDepthTracker; - } - - // The current scope is still active if we're the top-level class. - // Otherwise we'll need to push and enter a new scope. - bool HasClassScope = !Class.TopLevelClass; - ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope, - HasClassScope); - if (HasClassScope) - Actions.ActOnStartDelayedMemberDeclarations(getCurScope(), - Class.TagOrTemplate); - - for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) { - Class.LateParsedDeclarations[i]->ParseLexedMethodDeclarations(); - } + ReenterClassScopeRAII InClassScope(*this, Class); - if (HasClassScope) - Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(), - Class.TagOrTemplate); + for (LateParsedDeclaration *LateD : Class.LateParsedDeclarations) + LateD->ParseLexedMethodDeclarations(); } void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { // If this is a member template, introduce the template parameter scope. - ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope); - TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); - if (LM.TemplateScope) { - Actions.ActOnReenterTemplateScope(getCurScope(), LM.Method); - ++CurTemplateDepthTracker; - } + ReenterTemplateScopeRAII InFunctionTemplateScope(*this, LM.Method); + // Start the delayed C++ method declaration Actions.ActOnStartDelayedCXXMethodDeclaration(getCurScope(), LM.Method); // Introduce the parameters into scope and parse their default // arguments. - ParseScope PrototypeScope(this, Scope::FunctionPrototypeScope | - Scope::FunctionDeclarationScope | Scope::DeclScope); + InFunctionTemplateScope.Scopes.Enter(Scope::FunctionPrototypeScope | + Scope::FunctionDeclarationScope | + Scope::DeclScope); for (unsigned I = 0, N = LM.DefaultArgs.size(); I != N; ++I) { auto Param = cast(LM.DefaultArgs[I].Param); // Introduce the parameter into scope. @@ -466,7 +490,7 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { LM.ExceptionSpecTokens = nullptr; } - PrototypeScope.Exit(); + InFunctionTemplateScope.Scopes.Exit(); // Finish the delayed C++ method declaration. Actions.ActOnFinishDelayedCXXMethodDeclaration(getCurScope(), LM.Method); @@ -476,30 +500,15 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { /// (non-nested) C++ class. Now go over the stack of lexed methods that were /// collected during its parsing and parse them all. void Parser::ParseLexedMethodDefs(ParsingClass &Class) { - bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; - ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, HasTemplateScope); - TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); - if (HasTemplateScope) { - Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); - ++CurTemplateDepthTracker; - } - bool HasClassScope = !Class.TopLevelClass; - ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope, - HasClassScope); + ReenterClassScopeRAII InClassScope(*this, Class); - for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) { - Class.LateParsedDeclarations[i]->ParseLexedMethodDefs(); - } + for (LateParsedDeclaration *D : Class.LateParsedDeclarations) + D->ParseLexedMethodDefs(); } void Parser::ParseLexedMethodDef(LexedMethod &LM) { // If this is a member template, introduce the template parameter scope. - ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope); - TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); - if (LM.TemplateScope) { - Actions.ActOnReenterTemplateScope(getCurScope(), LM.D); - ++CurTemplateDepthTracker; - } + ReenterTemplateScopeRAII InFunctionTemplateScope(*this, LM.D); ParenBraceBracketBalancer BalancerRAIIObj(*this); @@ -580,23 +589,7 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) { /// of a top (non-nested) C++ class. Now go over the stack of lexed data member /// initializers that were collected during its parsing and parse them all. void Parser::ParseLexedMemberInitializers(ParsingClass &Class) { - bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; - ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, - HasTemplateScope); - TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); - if (HasTemplateScope) { - Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); - ++CurTemplateDepthTracker; - } - // Set or update the scope flags. - bool AlreadyHasClassScope = Class.TopLevelClass; - unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope; - ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope); - ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope); - - if (!AlreadyHasClassScope) - Actions.ActOnStartDelayedMemberDeclarations(getCurScope(), - Class.TagOrTemplate); + ReenterClassScopeRAII InClassScope(*this, Class); if (!Class.LateParsedDeclarations.empty()) { // C++11 [expr.prim.general]p4: @@ -604,18 +597,14 @@ void Parser::ParseLexedMemberInitializers(ParsingClass &Class) { // (9.2) of a class X, the expression this is a prvalue of type "pointer // to X" within the optional brace-or-equal-initializer. It shall not // appear elsewhere in the member-declarator. + // FIXME: This should be done in ParseLexedMemberInitializer, not here. Sema::CXXThisScopeRAII ThisScope(Actions, Class.TagOrTemplate, Qualifiers()); - for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) { - Class.LateParsedDeclarations[i]->ParseLexedMemberInitializers(); - } + for (LateParsedDeclaration *D : Class.LateParsedDeclarations) + D->ParseLexedMemberInitializers(); } - if (!AlreadyHasClassScope) - Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(), - Class.TagOrTemplate); - Actions.ActOnFinishDelayedMemberInitializers(Class.TagOrTemplate); } @@ -662,21 +651,115 @@ void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) { ConsumeAnyToken(); } -void Parser::ParseLexedPragmas(ParsingClass &Class) { - bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; - ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, - HasTemplateScope); - TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); - if (HasTemplateScope) { - Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); - ++CurTemplateDepthTracker; +/// Wrapper class which calls ParseLexedAttribute, after setting up the +/// scope appropriately. +void Parser::ParseLexedAttributes(ParsingClass &Class) { + ReenterClassScopeRAII InClassScope(*this, Class); + + for (LateParsedDeclaration *LateD : Class.LateParsedDeclarations) + LateD->ParseLexedAttributes(); +} + +/// Parse all attributes in LAs, and attach them to Decl D. +void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D, + bool EnterScope, bool OnDefinition) { + assert(LAs.parseSoon() && + "Attribute list should be marked for immediate parsing."); + for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) { + if (D) + LAs[i]->addDecl(D); + ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition); + delete LAs[i]; } - bool HasClassScope = !Class.TopLevelClass; - ParseScope ClassScope(this, Scope::ClassScope | Scope::DeclScope, - HasClassScope); + LAs.clear(); +} + +/// Finish parsing an attribute for which parsing was delayed. +/// This will be called at the end of parsing a class declaration +/// for each LateParsedAttribute. We consume the saved tokens and +/// create an attribute with the arguments filled in. We add this +/// to the Attribute list for the decl. +void Parser::ParseLexedAttribute(LateParsedAttribute &LA, + bool EnterScope, bool OnDefinition) { + // Create a fake EOF so that attribute parsing won't go off the end of the + // attribute. + Token AttrEnd; + AttrEnd.startToken(); + AttrEnd.setKind(tok::eof); + AttrEnd.setLocation(Tok.getLocation()); + AttrEnd.setEofData(LA.Toks.data()); + LA.Toks.push_back(AttrEnd); + + // Append the current token at the end of the new token stream so that it + // doesn't get lost. + LA.Toks.push_back(Tok); + PP.EnterTokenStream(LA.Toks, true, /*IsReinject=*/true); + // Consume the previously pushed token. + ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); + + ParsedAttributes Attrs(AttrFactory); + SourceLocation endLoc; + + if (LA.Decls.size() > 0) { + Decl *D = LA.Decls[0]; + NamedDecl *ND = dyn_cast(D); + RecordDecl *RD = dyn_cast_or_null(D->getDeclContext()); + + // Allow 'this' within late-parsed attributes. + Sema::CXXThisScopeRAII ThisScope(Actions, RD, Qualifiers(), + ND && ND->isCXXInstanceMember()); + + if (LA.Decls.size() == 1) { + // If the Decl is templatized, add template parameters to scope. + ReenterTemplateScopeRAII InDeclScope(*this, D, EnterScope); + + // If the Decl is on a function, add function parameters to the scope. + bool HasFunScope = EnterScope && D->isFunctionOrFunctionTemplate(); + if (HasFunScope) { + InDeclScope.Scopes.Enter(Scope::FnScope | Scope::DeclScope | + Scope::CompoundStmtScope); + Actions.ActOnReenterFunctionContext(Actions.CurScope, D); + } + + ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc, + nullptr, SourceLocation(), ParsedAttr::AS_GNU, + nullptr); + + if (HasFunScope) + Actions.ActOnExitFunctionContext(); + } else { + // If there are multiple decls, then the decl cannot be within the + // function scope. + ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc, + nullptr, SourceLocation(), ParsedAttr::AS_GNU, + nullptr); + } + } else { + Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName(); + } + + if (OnDefinition && !Attrs.empty() && !Attrs.begin()->isCXX11Attribute() && + Attrs.begin()->isKnownToGCC()) + Diag(Tok, diag::warn_attribute_on_function_definition) + << &LA.AttrName; + + for (unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i) + Actions.ActOnFinishDelayedAttribute(getCurScope(), LA.Decls[i], Attrs); + + // Due to a parsing error, we either went over the cached tokens or + // there are still cached tokens left, so we skip the leftover tokens. + while (Tok.isNot(tok::eof)) + ConsumeAnyToken(); + + if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData()) + ConsumeAnyToken(); +} + +void Parser::ParseLexedPragmas(ParsingClass &Class) { + ReenterClassScopeRAII InClassScope(*this, Class); - for (LateParsedDeclaration *LPD : Class.LateParsedDeclarations) - LPD->ParseLexedPragmas(); + for (LateParsedDeclaration *D : Class.LateParsedDeclarations) + D->ParseLexedPragmas(); } void Parser::ParseLexedPragma(LateParsedPragma &LP) { diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 79a3b19bac576..c87d240a8206a 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -1409,154 +1409,6 @@ void Parser::ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated, Syntax); } -// Late Parsed Attributes: -// See other examples of late parsing in lib/Parse/ParseCXXInlineMethods - -void Parser::LateParsedDeclaration::ParseLexedAttributes() {} - -void Parser::LateParsedClass::ParseLexedAttributes() { - Self->ParseLexedAttributes(*Class); -} - -void Parser::LateParsedAttribute::ParseLexedAttributes() { - Self->ParseLexedAttribute(*this, true, false); -} - -/// Wrapper class which calls ParseLexedAttribute, after setting up the -/// scope appropriately. -void Parser::ParseLexedAttributes(ParsingClass &Class) { - // Deal with templates - // FIXME: Test cases to make sure this does the right thing for templates. - bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; - ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, - HasTemplateScope); - if (HasTemplateScope) - Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); - - // Set or update the scope flags. - bool AlreadyHasClassScope = Class.TopLevelClass; - unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope; - ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope); - ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope); - - // Enter the scope of nested classes - if (!AlreadyHasClassScope) - Actions.ActOnStartDelayedMemberDeclarations(getCurScope(), - Class.TagOrTemplate); - if (!Class.LateParsedDeclarations.empty()) { - for (unsigned i = 0, ni = Class.LateParsedDeclarations.size(); i < ni; ++i){ - Class.LateParsedDeclarations[i]->ParseLexedAttributes(); - } - } - - if (!AlreadyHasClassScope) - Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(), - Class.TagOrTemplate); -} - -/// Parse all attributes in LAs, and attach them to Decl D. -void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D, - bool EnterScope, bool OnDefinition) { - assert(LAs.parseSoon() && - "Attribute list should be marked for immediate parsing."); - for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) { - if (D) - LAs[i]->addDecl(D); - ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition); - delete LAs[i]; - } - LAs.clear(); -} - -/// Finish parsing an attribute for which parsing was delayed. -/// This will be called at the end of parsing a class declaration -/// for each LateParsedAttribute. We consume the saved tokens and -/// create an attribute with the arguments filled in. We add this -/// to the Attribute list for the decl. -void Parser::ParseLexedAttribute(LateParsedAttribute &LA, - bool EnterScope, bool OnDefinition) { - // Create a fake EOF so that attribute parsing won't go off the end of the - // attribute. - Token AttrEnd; - AttrEnd.startToken(); - AttrEnd.setKind(tok::eof); - AttrEnd.setLocation(Tok.getLocation()); - AttrEnd.setEofData(LA.Toks.data()); - LA.Toks.push_back(AttrEnd); - - // Append the current token at the end of the new token stream so that it - // doesn't get lost. - LA.Toks.push_back(Tok); - PP.EnterTokenStream(LA.Toks, true, /*IsReinject=*/true); - // Consume the previously pushed token. - ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); - - ParsedAttributes Attrs(AttrFactory); - SourceLocation endLoc; - - if (LA.Decls.size() > 0) { - Decl *D = LA.Decls[0]; - NamedDecl *ND = dyn_cast(D); - RecordDecl *RD = dyn_cast_or_null(D->getDeclContext()); - - // Allow 'this' within late-parsed attributes. - Sema::CXXThisScopeRAII ThisScope(Actions, RD, Qualifiers(), - ND && ND->isCXXInstanceMember()); - - if (LA.Decls.size() == 1) { - // If the Decl is templatized, add template parameters to scope. - bool HasTemplateScope = EnterScope && D->isTemplateDecl(); - ParseScope TempScope(this, Scope::TemplateParamScope, HasTemplateScope); - if (HasTemplateScope) - Actions.ActOnReenterTemplateScope(Actions.CurScope, D); - - // If the Decl is on a function, add function parameters to the scope. - bool HasFunScope = EnterScope && D->isFunctionOrFunctionTemplate(); - ParseScope FnScope( - this, Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope, - HasFunScope); - if (HasFunScope) - Actions.ActOnReenterFunctionContext(Actions.CurScope, D); - - ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc, - nullptr, SourceLocation(), ParsedAttr::AS_GNU, - nullptr); - - if (HasFunScope) { - Actions.ActOnExitFunctionContext(); - FnScope.Exit(); // Pop scope, and remove Decls from IdResolver - } - if (HasTemplateScope) { - TempScope.Exit(); - } - } else { - // If there are multiple decls, then the decl cannot be within the - // function scope. - ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc, - nullptr, SourceLocation(), ParsedAttr::AS_GNU, - nullptr); - } - } else { - Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName(); - } - - if (OnDefinition && !Attrs.empty() && !Attrs.begin()->isCXX11Attribute() && - Attrs.begin()->isKnownToGCC()) - Diag(Tok, diag::warn_attribute_on_function_definition) - << &LA.AttrName; - - for (unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i) - Actions.ActOnFinishDelayedAttribute(getCurScope(), LA.Decls[i], Attrs); - - // Due to a parsing error, we either went over the cached tokens or - // there are still cached tokens left, so we skip the leftover tokens. - while (Tok.isNot(tok::eof)) - ConsumeAnyToken(); - - if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData()) - ConsumeAnyToken(); -} - void Parser::ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName, SourceLocation AttrNameLoc, ParsedAttributes &Attrs, @@ -2046,46 +1898,52 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS, } // Check to see if we have a function *definition* which must have a body. - if (D.isFunctionDeclarator() && - // Look at the next token to make sure that this isn't a function - // declaration. We have to check this because __attribute__ might be the - // start of a function definition in GCC-extended K&R C. - !isDeclarationAfterDeclarator()) { - - // Function definitions are only allowed at file scope and in C++ classes. - // The C++ inline method definition case is handled elsewhere, so we only - // need to handle the file scope definition case. - if (Context == DeclaratorContext::FileContext) { - if (isStartOfFunctionDefinition(D)) { - if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { - Diag(Tok, diag::err_function_declared_typedef); - - // Recover by treating the 'typedef' as spurious. - DS.ClearStorageClassSpecs(); - } + if (D.isFunctionDeclarator()) { + if (Tok.is(tok::equal) && NextToken().is(tok::code_completion)) { + Actions.CodeCompleteAfterFunctionEquals(D); + cutOffParsing(); + return nullptr; + } + // Look at the next token to make sure that this isn't a function + // declaration. We have to check this because __attribute__ might be the + // start of a function definition in GCC-extended K&R C. + if (!isDeclarationAfterDeclarator()) { + + // Function definitions are only allowed at file scope and in C++ classes. + // The C++ inline method definition case is handled elsewhere, so we only + // need to handle the file scope definition case. + if (Context == DeclaratorContext::FileContext) { + if (isStartOfFunctionDefinition(D)) { + if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { + Diag(Tok, diag::err_function_declared_typedef); + + // Recover by treating the 'typedef' as spurious. + DS.ClearStorageClassSpecs(); + } - Decl *TheDecl = - ParseFunctionDefinition(D, ParsedTemplateInfo(), &LateParsedAttrs); - return Actions.ConvertDeclToDeclGroup(TheDecl); - } + Decl *TheDecl = ParseFunctionDefinition(D, ParsedTemplateInfo(), + &LateParsedAttrs); + return Actions.ConvertDeclToDeclGroup(TheDecl); + } - if (isDeclarationSpecifier()) { - // If there is an invalid declaration specifier right after the - // function prototype, then we must be in a missing semicolon case - // where this isn't actually a body. Just fall through into the code - // that handles it as a prototype, and let the top-level code handle - // the erroneous declspec where it would otherwise expect a comma or - // semicolon. + if (isDeclarationSpecifier()) { + // If there is an invalid declaration specifier right after the + // function prototype, then we must be in a missing semicolon case + // where this isn't actually a body. Just fall through into the code + // that handles it as a prototype, and let the top-level code handle + // the erroneous declspec where it would otherwise expect a comma or + // semicolon. + } else { + Diag(Tok, diag::err_expected_fn_body); + SkipUntil(tok::semi); + return nullptr; + } } else { - Diag(Tok, diag::err_expected_fn_body); - SkipUntil(tok::semi); - return nullptr; - } - } else { - if (Tok.is(tok::l_brace)) { - Diag(Tok, diag::err_function_definition_not_allowed); - SkipMalformedDecl(); - return nullptr; + if (Tok.is(tok::l_brace)) { + Diag(Tok, diag::err_function_definition_not_allowed); + SkipMalformedDecl(); + return nullptr; + } } } } diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index a236a82213fb9..ddcbb5615feea 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -2185,7 +2185,6 @@ void Parser::HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo, // declarations. auto LateMethod = new LateParsedMethodDeclaration(this, ThisDecl); getCurrentClass().LateParsedDeclarations.push_back(LateMethod); - LateMethod->TemplateScope = getCurScope()->isTemplateParamScope(); // Stash the exception-specification tokens in the late-pased method. LateMethod->ExceptionSpecTokens = FTI.ExceptionSpecTokens; @@ -2714,6 +2713,11 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, DefinitionKind = FDK_Defaulted; else if (KW.is(tok::kw_delete)) DefinitionKind = FDK_Deleted; + else if (KW.is(tok::code_completion)) { + Actions.CodeCompleteAfterFunctionEquals(DeclaratorInfo); + cutOffParsing(); + return nullptr; + } } } DeclaratorInfo.setFunctionDefinitionKind(DefinitionKind); @@ -3372,8 +3376,10 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, // to the levels specified on the command line. Previous level // will be restored when the RAII object is destroyed. Sema::FPFeaturesStateRAII SaveFPFeaturesState(Actions); - FPOptions fpOptions(getLangOpts()); - Actions.CurFPFeatures.getFromOpaqueInt(fpOptions.getAsOpaqueInt()); + FPOptionsOverride NewOverrides; + Actions.CurFPFeatures = NewOverrides.applyOverrides(getLangOpts()); + Actions.FpPragmaStack.Act(Tok.getLocation(), Sema::PSK_Reset, StringRef(), + 0 /*unused*/); SourceLocation SavedPrevTokLocation = PrevTokLocation; ParseLexedPragmas(getCurrentClass()); @@ -3931,8 +3937,8 @@ void Parser::PopParsingClass(Sema::ParsingClassState state) { // after the top-level class is completely defined. Therefore, add // it to the list of nested classes within its parent. assert(getCurScope()->isClassScope() && "Nested class outside of class scope?"); - ClassStack.top()->LateParsedDeclarations.push_back(new LateParsedClass(this, Victim)); - Victim->TemplateScope = getCurScope()->getParent()->isTemplateParamScope(); + ClassStack.top()->LateParsedDeclarations.push_back( + new LateParsedClass(this, Victim)); } /// Try to parse an 'identifier' which appears within an attribute-token. diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index bd003204a97ca..81e87582c6ade 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -920,6 +920,11 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, auto SavedType = PreferredType; NotCastExpr = false; + // Are postfix-expression suffix operators permitted after this + // cast-expression? If not, and we find some, we'll parse them anyway and + // diagnose them. + bool AllowSuffix = true; + // This handles all of cast-expression, unary-expression, postfix-expression, // and primary-expression. We handle them together like this for efficiency // and to simplify handling of an expression starting with a '(' token: which @@ -929,8 +934,7 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, // If the parsed tokens consist of a primary-expression, the cases below // break out of the switch; at the end we call ParsePostfixExpressionSuffix // to handle the postfix expression suffixes. Cases that cannot be followed - // by postfix exprs should return without invoking - // ParsePostfixExpressionSuffix. + // by postfix exprs should set AllowSuffix to false. switch (SavedKind) { case tok::l_paren: { // If this expression is limited to being a unary-expression, the paren can @@ -953,8 +957,11 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/, isTypeCast == IsTypeCast, CastTy, RParenLoc); + // FIXME: What should we do if a vector literal is followed by a + // postfix-expression suffix? Usually postfix operators are permitted on + // literals. if (isVectorLiteral) - return Res; + return Res; switch (ParenExprType) { case SimpleExpr: break; // Nothing else to do. @@ -992,11 +999,13 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, case tok::kw___objc_yes: case tok::kw___objc_no: - return ParseObjCBoolLiteral(); + Res = ParseObjCBoolLiteral(); + break; case tok::kw_nullptr: Diag(Tok, diag::warn_cxx98_compat_nullptr); - return Actions.ActOnCXXNullPtrLiteral(ConsumeToken()); + Res = Actions.ActOnCXXNullPtrLiteral(ConsumeToken()); + break; case tok::annot_uneval_primary_expr: case tok::annot_primary_expr: @@ -1295,7 +1304,8 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, Res = ParseGenericSelectionExpression(); break; case tok::kw___builtin_available: - return ParseAvailabilityCheckExpr(Tok.getLocation()); + Res = ParseAvailabilityCheckExpr(Tok.getLocation()); + break; case tok::kw___builtin_va_arg: case tok::kw___builtin_offsetof: case tok::kw___builtin_choose_expr: @@ -1307,9 +1317,11 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, case tok::kw___builtin_LINE: if (NotPrimaryExpression) *NotPrimaryExpression = true; + // This parses the complete suffix; we can return early. return ParseBuiltinPrimaryExpression(); case tok::kw___null: - return Actions.ActOnGNUNullExpr(ConsumeToken()); + Res = Actions.ActOnGNUNullExpr(ConsumeToken()); + break; case tok::plusplus: // unary-expression: '++' unary-expression [C99] case tok::minusminus: { // unary-expression: '--' unary-expression [C99] @@ -1421,7 +1433,9 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, case tok::kw___builtin_omp_required_simd_align: if (NotPrimaryExpression) *NotPrimaryExpression = true; - return ParseUnaryExprOrTypeTraitExpression(); + AllowSuffix = false; + Res = ParseUnaryExprOrTypeTraitExpression(); + break; case tok::ampamp: { // unary-expression: '&&' identifier if (NotPrimaryExpression) *NotPrimaryExpression = true; @@ -1437,7 +1451,8 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, Tok.getLocation()); Res = Actions.ActOnAddrLabel(AmpAmpLoc, Tok.getLocation(), LD); ConsumeToken(); - return Res; + AllowSuffix = false; + break; } case tok::kw_const_cast: case tok::kw_dynamic_cast: @@ -1632,12 +1647,16 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, if (Tok.is(tok::kw_new)) { if (NotPrimaryExpression) *NotPrimaryExpression = true; - return ParseCXXNewExpression(true, CCLoc); + Res = ParseCXXNewExpression(true, CCLoc); + AllowSuffix = false; + break; } if (Tok.is(tok::kw_delete)) { if (NotPrimaryExpression) *NotPrimaryExpression = true; - return ParseCXXDeleteExpression(true, CCLoc); + Res = ParseCXXDeleteExpression(true, CCLoc); + AllowSuffix = false; + break; } // This is not a type name or scope specifier, it is an invalid expression. @@ -1648,15 +1667,21 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, case tok::kw_new: // [C++] new-expression if (NotPrimaryExpression) *NotPrimaryExpression = true; - return ParseCXXNewExpression(false, Tok.getLocation()); + Res = ParseCXXNewExpression(false, Tok.getLocation()); + AllowSuffix = false; + break; case tok::kw_delete: // [C++] delete-expression if (NotPrimaryExpression) *NotPrimaryExpression = true; - return ParseCXXDeleteExpression(false, Tok.getLocation()); + Res = ParseCXXDeleteExpression(false, Tok.getLocation()); + AllowSuffix = false; + break; case tok::kw_requires: // [C++2a] requires-expression - return ParseRequiresExpression(); + Res = ParseRequiresExpression(); + AllowSuffix = false; + break; case tok::kw_noexcept: { // [C++0x] 'noexcept' '(' expression ')' if (NotPrimaryExpression) @@ -1672,32 +1697,36 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, // which is an unevaluated operand, can throw an exception. EnterExpressionEvaluationContext Unevaluated( Actions, Sema::ExpressionEvaluationContext::Unevaluated); - ExprResult Result = ParseExpression(); + Res = ParseExpression(); T.consumeClose(); - if (!Result.isInvalid()) - Result = Actions.ActOnNoexceptExpr(KeyLoc, T.getOpenLocation(), - Result.get(), T.getCloseLocation()); - return Result; + if (!Res.isInvalid()) + Res = Actions.ActOnNoexceptExpr(KeyLoc, T.getOpenLocation(), Res.get(), + T.getCloseLocation()); + AllowSuffix = false; + break; } #define TYPE_TRAIT(N,Spelling,K) \ case tok::kw_##Spelling: #include "clang/Basic/TokenKinds.def" - return ParseTypeTrait(); + Res = ParseTypeTrait(); + break; case tok::kw___array_rank: case tok::kw___array_extent: if (NotPrimaryExpression) *NotPrimaryExpression = true; - return ParseArrayTypeTrait(); + Res = ParseArrayTypeTrait(); + break; case tok::kw___is_lvalue_expr: case tok::kw___is_rvalue_expr: if (NotPrimaryExpression) *NotPrimaryExpression = true; - return ParseExpressionTrait(); + Res = ParseExpressionTrait(); + break; case tok::at: { if (NotPrimaryExpression) @@ -1754,6 +1783,41 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, // parsed. return Res; + if (!AllowSuffix) { + // FIXME: Don't parse a primary-expression suffix if we encountered a parse + // error already. + if (Res.isInvalid()) + return Res; + + switch (Tok.getKind()) { + case tok::l_square: + case tok::l_paren: + case tok::plusplus: + case tok::minusminus: + // "expected ';'" or similar is probably the right diagnostic here. Let + // the caller decide what to do. + if (Tok.isAtStartOfLine()) + return Res; + + LLVM_FALLTHROUGH; + case tok::period: + case tok::arrow: + break; + + default: + return Res; + } + + // This was a unary-expression for which a postfix-expression suffix is + // not permitted by the grammar (eg, a sizeof expression or + // new-expression or similar). Diagnose but parse the suffix anyway. + Diag(Tok.getLocation(), diag::err_postfix_after_unary_requires_parens) + << Tok.getKind() << Res.get()->getSourceRange() + << FixItHint::CreateInsertion(Res.get()->getBeginLoc(), "(") + << FixItHint::CreateInsertion(PP.getLocForEndOfToken(PrevTokLocation), + ")"); + } + // These can be followed by postfix-expr pieces. PreferredType = SavedType; Res = ParsePostfixExpressionSuffix(Res); @@ -1845,8 +1909,8 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { BalancedDelimiterTracker T(*this, tok::l_square); T.consumeOpen(); Loc = T.getOpenLocation(); - ExprResult Idx, Length; - SourceLocation ColonLoc; + ExprResult Idx, Length, Stride; + SourceLocation ColonLocFirst, ColonLocSecond; PreferredType.enterSubscript(Actions, Tok.getLocation(), LHS.get()); if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); @@ -1860,10 +1924,22 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { } if (Tok.is(tok::colon)) { // Consume ':' - ColonLoc = ConsumeToken(); - if (Tok.isNot(tok::r_square)) + ColonLocFirst = ConsumeToken(); + if (Tok.isNot(tok::r_square) && + (getLangOpts().OpenMP < 50 || + ((Tok.isNot(tok::colon) && getLangOpts().OpenMP >= 50)))) Length = ParseExpression(); } + if (getLangOpts().OpenMP >= 50 && + (OMPClauseKind == llvm::omp::Clause::OMPC_to || + OMPClauseKind == llvm::omp::Clause::OMPC_from) && + Tok.is(tok::colon)) { + // Consume ':' + ColonLocSecond = ConsumeToken(); + if (Tok.isNot(tok::r_square)) { + Stride = ParseExpression(); + } + } } else Idx = ParseExpression(); @@ -1873,10 +1949,11 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { Idx = Actions.CorrectDelayedTyposInExpr(Idx); Length = Actions.CorrectDelayedTyposInExpr(Length); if (!LHS.isInvalid() && !Idx.isInvalid() && !Length.isInvalid() && - Tok.is(tok::r_square)) { - if (ColonLoc.isValid()) { - LHS = Actions.ActOnOMPArraySectionExpr(LHS.get(), Loc, Idx.get(), - ColonLoc, Length.get(), RLoc); + !Stride.isInvalid() && Tok.is(tok::r_square)) { + if (ColonLocFirst.isValid() || ColonLocSecond.isValid()) { + LHS = Actions.ActOnOMPArraySectionExpr( + LHS.get(), Loc, Idx.get(), ColonLocFirst, ColonLocSecond, + Length.get(), Stride.get(), RLoc); } else { LHS = Actions.ActOnArraySubscriptExpr(getCurScope(), LHS.get(), Loc, Idx.get(), RLoc); diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 48277dc854663..aa35200c33b66 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -1258,17 +1258,16 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( }; // FIXME: Consider allowing this as an extension for GCC compatibiblity. - const bool HasExplicitTemplateParams = Tok.is(tok::less); - ParseScope TemplateParamScope(this, Scope::TemplateParamScope, - /*EnteredScope=*/HasExplicitTemplateParams); - if (HasExplicitTemplateParams) { + MultiParseScope TemplateParamScope(*this); + if (Tok.is(tok::less)) { Diag(Tok, getLangOpts().CPlusPlus20 ? diag::warn_cxx17_compat_lambda_template_parameter_list : diag::ext_lambda_template_parameter_list); SmallVector TemplateParams; SourceLocation LAngleLoc, RAngleLoc; - if (ParseTemplateParameters(CurTemplateDepthTracker.getDepth(), + if (ParseTemplateParameters(TemplateParamScope, + CurTemplateDepthTracker.getDepth(), TemplateParams, LAngleLoc, RAngleLoc)) { Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope()); return ExprError(); diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 6cf50a5794f79..5223755c8fdf1 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -33,7 +33,7 @@ using namespace llvm::omp; namespace { enum OpenMPDirectiveKindEx { - OMPD_cancellation = unsigned(OMPD_unknown) + 1, + OMPD_cancellation = llvm::omp::Directive_enumSize + 1, OMPD_data, OMPD_declare, OMPD_end, @@ -194,8 +194,9 @@ static OpenMPDirectiveKindExWrapper parseOpenMPDirectiveKind(Parser &P) { DKind = F[I][2]; } } - return DKind < OMPD_unknown ? static_cast(DKind) - : OMPD_unknown; + return unsigned(DKind) < llvm::omp::Directive_enumSize + ? static_cast(DKind) + : OMPD_unknown; } static DeclarationName parseOpenMPReductionId(Parser &P) { @@ -647,16 +648,14 @@ namespace { class FNContextRAII final { Parser &P; Sema::CXXThisScopeRAII *ThisScope; - Parser::ParseScope *TempScope; - Parser::ParseScope *FnScope; - bool HasTemplateScope = false; + Parser::MultiParseScope Scopes; bool HasFunScope = false; FNContextRAII() = delete; FNContextRAII(const FNContextRAII &) = delete; FNContextRAII &operator=(const FNContextRAII &) = delete; public: - FNContextRAII(Parser &P, Parser::DeclGroupPtrTy Ptr) : P(P) { + FNContextRAII(Parser &P, Parser::DeclGroupPtrTy Ptr) : P(P), Scopes(P) { Decl *D = *Ptr.get().begin(); NamedDecl *ND = dyn_cast(D); RecordDecl *RD = dyn_cast_or_null(D->getDeclContext()); @@ -667,29 +666,20 @@ class FNContextRAII final { ND && ND->isCXXInstanceMember()); // If the Decl is templatized, add template parameters to scope. - HasTemplateScope = D->isTemplateDecl(); - TempScope = - new Parser::ParseScope(&P, Scope::TemplateParamScope, HasTemplateScope); - if (HasTemplateScope) - Actions.ActOnReenterTemplateScope(Actions.getCurScope(), D); + // FIXME: Track CurTemplateDepth? + P.ReenterTemplateScopes(Scopes, D); // If the Decl is on a function, add function parameters to the scope. - HasFunScope = D->isFunctionOrFunctionTemplate(); - FnScope = new Parser::ParseScope( - &P, Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope, - HasFunScope); - if (HasFunScope) + if (D->isFunctionOrFunctionTemplate()) { + HasFunScope = true; + Scopes.Enter(Scope::FnScope | Scope::DeclScope | + Scope::CompoundStmtScope); Actions.ActOnReenterFunctionContext(Actions.getCurScope(), D); + } } ~FNContextRAII() { - if (HasFunScope) { + if (HasFunScope) P.getActions().ActOnExitFunctionContext(); - FnScope->Exit(); // Pop scope, and remove Decls from IdResolver - } - if (HasTemplateScope) - TempScope->Exit(); - delete FnScope; - delete TempScope; delete ThisScope; } }; @@ -1451,7 +1441,7 @@ bool Parser::parseOMPDeclareVariantMatchClause(SourceLocation Loc, /// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'. /// /// default-clause: -/// 'default' '(' 'none' | 'shared' ') +/// 'default' '(' 'none' | 'shared' | 'firstprivate' ') /// /// proc_bind-clause: /// 'proc_bind' '(' 'master' | 'close' | 'spread' ') @@ -1718,8 +1708,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( SmallVector Clauses; if (Tok.isNot(tok::annot_pragma_openmp_end)) { SmallVector, - unsigned(OMPC_unknown) + 1> - FirstClauses(unsigned(OMPC_unknown) + 1); + llvm::omp::Clause_enumSize + 1> + FirstClauses(llvm::omp::Clause_enumSize + 1); while (Tok.isNot(tok::annot_pragma_openmp_end)) { OpenMPClauseKind CKind = Tok.isAnnotation() ? OMPC_unknown @@ -1754,8 +1744,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( SourceLocation StartLoc = ConsumeToken(); SmallVector Clauses; SmallVector, - unsigned(OMPC_unknown) + 1> - FirstClauses(unsigned(OMPC_unknown) + 1); + llvm::omp::Clause_enumSize + 1> + FirstClauses(llvm::omp::Clause_enumSize + 1); if (Tok.is(tok::annot_pragma_openmp_end)) { Diag(Tok, diag::err_omp_expected_clause) << getOpenMPDirectiveName(OMPD_requires); @@ -2019,6 +2009,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( Diag(Tok, diag::err_omp_unexpected_directive) << 1 << getOpenMPDirectiveName(DKind); break; + default: + break; } while (Tok.isNot(tok::annot_pragma_openmp_end)) ConsumeAnyToken(); @@ -2073,8 +2065,8 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { ParenBraceBracketBalancer BalancerRAIIObj(*this); SmallVector Clauses; SmallVector, - unsigned(OMPC_unknown) + 1> - FirstClauses(unsigned(OMPC_unknown) + 1); + llvm::omp::Clause_enumSize + 1> + FirstClauses(llvm::omp::Clause_enumSize + 1); unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope; SourceLocation Loc = ConsumeAnnotationToken(), EndLoc; @@ -2119,8 +2111,8 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { SmallVector Clauses; if (Tok.isNot(tok::annot_pragma_openmp_end)) { SmallVector, - unsigned(OMPC_unknown) + 1> - FirstClauses(unsigned(OMPC_unknown) + 1); + llvm::omp::Clause_enumSize + 1> + FirstClauses(llvm::omp::Clause_enumSize + 1); while (Tok.isNot(tok::annot_pragma_openmp_end)) { OpenMPClauseKind CKind = Tok.isAnnotation() ? OMPC_unknown @@ -2368,6 +2360,7 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { SkipUntil(tok::annot_pragma_openmp_end); break; case OMPD_unknown: + default: Diag(Tok, diag::err_omp_unknown_directive); SkipUntil(tok::annot_pragma_openmp_end); break; @@ -2505,6 +2498,7 @@ OMPClause *Parser::ParseOpenMPUsesAllocatorClause(OpenMPDirectiveKind DKind) { /// OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, bool FirstClause) { + OMPClauseKind = CKind; OMPClause *Clause = nullptr; bool ErrorFound = false; bool WrongDirective = false; @@ -2691,6 +2685,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind); SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch); break; + default: + break; } return ErrorFound ? nullptr : Clause; } @@ -2776,7 +2772,7 @@ OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind, /// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'. /// /// default-clause: -/// 'default' '(' 'none' | 'shared' ')' +/// 'default' '(' 'none' | 'shared' | 'firstprivate' ')' /// /// proc_bind-clause: /// 'proc_bind' '(' 'master' | 'close' | 'spread' ')' @@ -2789,6 +2785,14 @@ OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind, llvm::Optional Val = parseOpenMPSimpleClause(*this, Kind); if (!Val || ParseOnly) return nullptr; + if (getLangOpts().OpenMP < 51 && Kind == OMPC_default && + static_cast(Val.getValue().Type) == + OMP_DEFAULT_firstprivate) { + Diag(Val.getValue().LOpen, diag::err_omp_invalid_dsa) + << getOpenMPClauseName(OMPC_firstprivate) + << getOpenMPClauseName(OMPC_default) << "5.1"; + return nullptr; + } return Actions.ActOnOpenMPSimpleClause( Kind, Val.getValue().Type, Val.getValue().TypeLoc, Val.getValue().LOpen, Val.getValue().Loc, Val.getValue().RLoc); diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index eacb54e81ae60..6402b31d00b29 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -654,8 +654,8 @@ void Parser::HandlePragmaFPContract() { break; } - Actions.ActOnPragmaFPContract(FPC); - ConsumeAnnotationToken(); + SourceLocation PragmaLoc = ConsumeAnnotationToken(); + Actions.ActOnPragmaFPContract(PragmaLoc, FPC); } void Parser::HandlePragmaFloatControl() { @@ -2935,8 +2935,8 @@ void Parser::HandlePragmaFP() { reinterpret_cast(Tok.getAnnotationValue()); if (AnnotValue->FlagKind == TokFPAnnotValue::Reassociate) - Actions.ActOnPragmaFPReassociate(AnnotValue->FlagValue == - TokFPAnnotValue::On); + Actions.ActOnPragmaFPReassociate( + Tok.getLocation(), AnnotValue->FlagValue == TokFPAnnotValue::On); else { LangOptions::FPModeKind FPC; switch (AnnotValue->FlagValue) { @@ -2950,7 +2950,7 @@ void Parser::HandlePragmaFP() { FPC = LangOptions::FPM_Fast; break; } - Actions.ActOnPragmaFPContract(FPC); + Actions.ActOnPragmaFPContract(Tok.getLocation(), FPC); } ConsumeAnnotationToken(); } diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 773c31ff3aec1..89a6a2b829ae1 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -1156,10 +1156,14 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { /// should try to recover harder. It returns false if the condition is /// successfully parsed. Note that a successful parse can still have semantic /// errors in the condition. +/// Additionally, if LParenLoc and RParenLoc are non-null, it will assign +/// the location of the outer-most '(' and ')', respectively, to them. bool Parser::ParseParenExprOrCondition(StmtResult *InitStmt, Sema::ConditionResult &Cond, SourceLocation Loc, - Sema::ConditionKind CK) { + Sema::ConditionKind CK, + SourceLocation *LParenLoc, + SourceLocation *RParenLoc) { BalancedDelimiterTracker T(*this, tok::l_paren); T.consumeOpen(); @@ -1189,6 +1193,13 @@ bool Parser::ParseParenExprOrCondition(StmtResult *InitStmt, // Otherwise the condition is valid or the rparen is present. T.consumeClose(); + if (LParenLoc != nullptr) { + *LParenLoc = T.getOpenLocation(); + } + if (RParenLoc != nullptr) { + *RParenLoc = T.getCloseLocation(); + } + // Check for extraneous ')'s to catch things like "if (foo())) {". We know // that all callers are looking for a statement after the condition, so ")" // isn't valid. @@ -1348,6 +1359,8 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) { if (IsConstexpr) ConstexprCondition = Cond.getKnownValue(); + bool IsBracedThen = Tok.is(tok::l_brace); + // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if // there is no compound stmt. C90 does not have this clause. We only do this // if the body isn't a compound statement to avoid push/pop in common cases. @@ -1366,7 +1379,7 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) { // would have to notify ParseStatement not to create a new scope. It's // simpler to let it create a new scope. // - ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace)); + ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, IsBracedThen); MisleadingIndentationChecker MIChecker(*this, MSK_if, IfLoc); @@ -1427,7 +1440,7 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) { // Pop the 'else' scope if needed. InnerScope.Exit(); } else if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteAfterIf(getCurScope()); + Actions.CodeCompleteAfterIf(getCurScope(), IsBracedThen); cutOffParsing(); return StmtError(); } else if (InnerStatementTrailingElseLoc.isValid()) { @@ -1580,8 +1593,10 @@ StmtResult Parser::ParseWhileStatement(SourceLocation *TrailingElseLoc) { // Parse the condition. Sema::ConditionResult Cond; + SourceLocation LParen; + SourceLocation RParen; if (ParseParenExprOrCondition(nullptr, Cond, WhileLoc, - Sema::ConditionKind::Boolean)) + Sema::ConditionKind::Boolean, &LParen, &RParen)) return StmtError(); // C99 6.8.5p5 - In C99, the body of the while statement is a scope, even if @@ -1611,7 +1626,7 @@ StmtResult Parser::ParseWhileStatement(SourceLocation *TrailingElseLoc) { if (Cond.isInvalid() || Body.isInvalid()) return StmtError(); - return Actions.ActOnWhileStmt(WhileLoc, Cond, Body.get()); + return Actions.ActOnWhileStmt(WhileLoc, LParen, Cond, RParen, Body.get()); } /// ParseDoStatement diff --git a/clang/lib/Parse/ParseStmtAsm.cpp b/clang/lib/Parse/ParseStmtAsm.cpp index 0f21037b61000..7d0818840a4fc 100644 --- a/clang/lib/Parse/ParseStmtAsm.cpp +++ b/clang/lib/Parse/ParseStmtAsm.cpp @@ -941,7 +941,7 @@ const char *Parser::GNUAsmQualifiers::getQualifierName(AQ Qualifier) { case AQ_goto: return "goto"; case AQ_unspecified: return "unspecified"; } - llvm_unreachable("Unkown GNUAsmQualifier"); + llvm_unreachable("Unknown GNUAsmQualifier"); } Parser::GNUAsmQualifiers::AQ diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index 16aecffa494ad..3ef73f5791239 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -22,6 +22,16 @@ #include "llvm/Support/TimeProfiler.h" using namespace clang; +/// Re-enter a possible template scope, creating as many template parameter +/// scopes as necessary. +/// \return The number of template parameter scopes entered. +unsigned Parser::ReenterTemplateScopes(MultiParseScope &S, Decl *D) { + return Actions.ActOnReenterTemplateScope(D, [&] { + S.Enter(Scope::TemplateParamScope); + return Actions.getCurScope(); + }); +} + /// Parse a template declaration, explicit instantiation, or /// explicit specialization. Decl *Parser::ParseDeclarationStartingWithTemplate( @@ -67,8 +77,7 @@ Decl *Parser::ParseTemplateDeclarationOrSpecialization( assert(Tok.isOneOf(tok::kw_export, tok::kw_template) && "Token does not start a template declaration."); - // Enter template-parameter scope. - ParseScope TemplateParmScope(this, Scope::TemplateParamScope); + MultiParseScope TemplateParamScopes(*this); // Tell the action that names should be checked in the context of // the declaration to come. @@ -116,7 +125,8 @@ Decl *Parser::ParseTemplateDeclarationOrSpecialization( // Parse the '<' template-parameter-list '>' SourceLocation LAngleLoc, RAngleLoc; SmallVector TemplateParams; - if (ParseTemplateParameters(CurTemplateDepthTracker.getDepth(), + if (ParseTemplateParameters(TemplateParamScopes, + CurTemplateDepthTracker.getDepth(), TemplateParams, LAngleLoc, RAngleLoc)) { // Skip until the semi-colon or a '}'. SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); @@ -150,9 +160,6 @@ Decl *Parser::ParseTemplateDeclarationOrSpecialization( TemplateParams, RAngleLoc, OptionalRequiresClauseConstraintER.get())); } while (Tok.isOneOf(tok::kw_export, tok::kw_template)); - unsigned NewFlags = getCurScope()->getFlags() & ~Scope::TemplateParamScope; - ParseScopeFlags TemplateScopeFlags(this, NewFlags, isSpecialization); - // Parse the actual template declaration. if (Tok.is(tok::kw_concept)) return ParseConceptDefinition( @@ -430,8 +437,9 @@ Parser::ParseConceptDefinition(const ParsedTemplateInfo &TemplateInfo, /// /// \returns true if an error occurred, false otherwise. bool Parser::ParseTemplateParameters( - unsigned Depth, SmallVectorImpl &TemplateParams, - SourceLocation &LAngleLoc, SourceLocation &RAngleLoc) { + MultiParseScope &TemplateScopes, unsigned Depth, + SmallVectorImpl &TemplateParams, SourceLocation &LAngleLoc, + SourceLocation &RAngleLoc) { // Get the template parameter list. if (!TryConsumeToken(tok::less, LAngleLoc)) { Diag(Tok.getLocation(), diag::err_expected_less_after) << "template"; @@ -440,8 +448,11 @@ bool Parser::ParseTemplateParameters( // Try to parse the template parameter list. bool Failed = false; - if (!Tok.is(tok::greater) && !Tok.is(tok::greatergreater)) + // FIXME: Missing greatergreatergreater support. + if (!Tok.is(tok::greater) && !Tok.is(tok::greatergreater)) { + TemplateScopes.Enter(Scope::TemplateParamScope); Failed = ParseTemplateParameterList(Depth, TemplateParams); + } if (Tok.is(tok::greatergreater)) { // No diagnostic required here: a template-parameter-list can only be @@ -850,9 +861,9 @@ Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) { SmallVector TemplateParams; SourceLocation LAngleLoc, RAngleLoc; { - ParseScope TemplateParmScope(this, Scope::TemplateParamScope); - if (ParseTemplateParameters(Depth + 1, TemplateParams, LAngleLoc, - RAngleLoc)) { + MultiParseScope TemplateParmScope(*this); + if (ParseTemplateParameters(TemplateParmScope, Depth + 1, TemplateParams, + LAngleLoc, RAngleLoc)) { return nullptr; } } @@ -1630,40 +1641,22 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) { Sema::ContextRAII GlobalSavedContext( Actions, Actions.Context.getTranslationUnitDecl()); - SmallVector TemplateParamScopeStack; - - // Get the list of DeclContexts to reenter. For inline methods, we only want - // to push the DeclContext of the outermost class. This matches the way the - // parser normally parses bodies of inline methods when the outermost class is - // complete. - struct ContainingDC { - ContainingDC(DeclContext *DC, bool ShouldPush) : Pair(DC, ShouldPush) {} - llvm::PointerIntPair Pair; - DeclContext *getDC() { return Pair.getPointer(); } - bool shouldPushDC() { return Pair.getInt(); } - }; - SmallVector DeclContextsToReenter; - DeclContext *DD = FunD; - DeclContext *NextContaining = Actions.getContainingDC(DD); - while (DD && !DD->isTranslationUnit()) { - bool ShouldPush = DD == NextContaining; - DeclContextsToReenter.push_back({DD, ShouldPush}); - if (ShouldPush) - NextContaining = Actions.getContainingDC(DD); - DD = DD->getLexicalParent(); - } - - // Reenter template scopes from outermost to innermost. - for (ContainingDC CDC : reverse(DeclContextsToReenter)) { - TemplateParamScopeStack.push_back( - new ParseScope(this, Scope::TemplateParamScope)); - unsigned NumParamLists = Actions.ActOnReenterTemplateScope( - getCurScope(), cast(CDC.getDC())); - CurTemplateDepthTracker.addDepth(NumParamLists); - if (CDC.shouldPushDC()) { - TemplateParamScopeStack.push_back(new ParseScope(this, Scope::DeclScope)); - Actions.PushDeclContext(Actions.getCurScope(), CDC.getDC()); - } + MultiParseScope Scopes(*this); + + // Get the list of DeclContexts to reenter. + SmallVector DeclContextsToReenter; + for (DeclContext *DC = FunD; DC && !DC->isTranslationUnit(); + DC = DC->getLexicalParent()) + DeclContextsToReenter.push_back(DC); + + // Reenter scopes from outermost to innermost. + for (DeclContext *DC : reverse(DeclContextsToReenter)) { + CurTemplateDepthTracker.addDepth( + ReenterTemplateScopes(Scopes, cast(DC))); + Scopes.Enter(Scope::DeclScope); + // We'll reenter the function context itself below. + if (DC != FunD) + Actions.PushDeclContext(Actions.getCurScope(), DC); } assert(!LPT.Toks.empty() && "Empty body!"); @@ -1684,8 +1677,7 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) { Scope::CompoundStmtScope); // Recreate the containing function DeclContext. - Sema::ContextRAII FunctionSavedContext(Actions, - Actions.getContainingDC(FunD)); + Sema::ContextRAII FunctionSavedContext(Actions, FunD->getLexicalParent()); Actions.ActOnStartOfFunctionDef(getCurScope(), FunD); @@ -1709,13 +1701,6 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) { } else Actions.ActOnFinishFunctionBody(LPT.D, nullptr); } - - // Exit scopes. - FnScope.Exit(); - SmallVectorImpl::reverse_iterator I = - TemplateParamScopeStack.rbegin(); - for (; I != TemplateParamScopeStack.rend(); ++I) - delete *I; } /// Lex a delayed template function for late parsing. diff --git a/clang/lib/Sema/CMakeLists.txt b/clang/lib/Sema/CMakeLists.txt index b59fc30882f96..adadc06e209c3 100644 --- a/clang/lib/Sema/CMakeLists.txt +++ b/clang/lib/Sema/CMakeLists.txt @@ -72,6 +72,7 @@ add_clang_library(clangSema DEPENDS ClangOpenCLBuiltinsImpl + omp_gen LINK_LIBS clangAST diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp index 6ad50e18cd528..f4c30c90ad271 100644 --- a/clang/lib/Sema/DeclSpec.cpp +++ b/clang/lib/Sema/DeclSpec.cpp @@ -1150,14 +1150,20 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { S.Diag(TSSLoc, diag::err_invalid_vector_bool_decl_spec) << getSpecifierName((TSS)TypeSpecSign); } - - // Only char/int are valid with vector bool. (PIM 2.1) + // Only char/int are valid with vector bool prior to Power10. + // Power10 adds instructions that produce vector bool data + // for quadwords as well so allow vector bool __int128. if (((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) && - (TypeSpecType != TST_int)) || TypeAltiVecPixel) { + (TypeSpecType != TST_int) && (TypeSpecType != TST_int128)) || + TypeAltiVecPixel) { S.Diag(TSTLoc, diag::err_invalid_vector_bool_decl_spec) << (TypeAltiVecPixel ? "__pixel" : getSpecifierName((TST)TypeSpecType, Policy)); } + // vector bool __int128 requires Power10. + if ((TypeSpecType == TST_int128) && + (!S.Context.getTargetInfo().hasFeature("power10-vector"))) + S.Diag(TSTLoc, diag::err_invalid_vector_bool_int128_decl_spec); // Only 'short' and 'long long' are valid with vector bool. (PIM 2.1) if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short) && @@ -1174,7 +1180,7 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { // Elements of vector bool are interpreted as unsigned. (PIM 2.1) if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) || - (TypeSpecWidth != TSW_unspecified)) + (TypeSpecType == TST_int128) || (TypeSpecWidth != TSW_unspecified)) TypeSpecSign = TSS_unsigned; } else if (TypeSpecType == TST_double) { // vector long double and vector long long double are never allowed. diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index fc3fb524c8f42..2f2b52106f3d4 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -159,9 +159,8 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, LangOpts.getMSPointerToMemberRepresentationMethod()), VtorDispStack(LangOpts.getVtorDispMode()), PackStack(0), DataSegStack(nullptr), BSSSegStack(nullptr), ConstSegStack(nullptr), - CodeSegStack(nullptr), FpPragmaStack(CurFPFeatures.getAsOpaqueInt()), - CurInitSeg(nullptr), VisContext(nullptr), - PragmaAttributeCurrentTargetDecl(nullptr), + CodeSegStack(nullptr), FpPragmaStack(0xffffffff), CurInitSeg(nullptr), + VisContext(nullptr), PragmaAttributeCurrentTargetDecl(nullptr), IsBuildingRecoveryCallExpr(false), Cleanup{}, LateTemplateParser(nullptr), LateTemplateParserCleanup(nullptr), OpaqueParser(nullptr), IdResolver(pp), StdExperimentalNamespaceCache(nullptr), StdInitializerList(nullptr), diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index 977e92475182d..b354e810974c4 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -417,8 +417,10 @@ void Sema::ActOnPragmaDetectMismatch(SourceLocation Loc, StringRef Name, void Sema::ActOnPragmaFloatControl(SourceLocation Loc, PragmaMsStackAction Action, PragmaFloatControlKind Value) { - auto NewValue = FpPragmaStack.CurrentValue; - FPOptions NewFPFeatures(NewValue); + unsigned NewValue = FpPragmaStack.hasValue() + ? FpPragmaStack.CurrentValue + : CurFPFeatureOverrides().getAsOpaqueInt(); + FPOptionsOverride NewFPFeatures(NewValue); if ((Action == PSK_Push_Set || Action == PSK_Push || Action == PSK_Pop) && !(CurContext->isTranslationUnit()) && !CurContext->isNamespace()) { // Push and pop can only occur at file or namespace scope. @@ -429,38 +431,34 @@ void Sema::ActOnPragmaFloatControl(SourceLocation Loc, default: llvm_unreachable("invalid pragma float_control kind"); case PFC_Precise: - CurFPFeatures.setFPPreciseEnabled(true); - NewValue = CurFPFeatures.getAsOpaqueInt(); + NewFPFeatures.setFPPreciseEnabled(true); + NewValue = NewFPFeatures.getAsOpaqueInt(); FpPragmaStack.Act(Loc, Action, StringRef(), NewValue); break; case PFC_NoPrecise: - if (CurFPFeatures.getExceptionMode() == LangOptions::FPE_Strict) + if (CurFPFeatures.getFPExceptionMode() == LangOptions::FPE_Strict) Diag(Loc, diag::err_pragma_fc_noprecise_requires_noexcept); - else if (CurFPFeatures.allowFEnvAccess()) + else if (CurFPFeatures.getAllowFEnvAccess()) Diag(Loc, diag::err_pragma_fc_noprecise_requires_nofenv); else - CurFPFeatures.setFPPreciseEnabled(false); - NewValue = CurFPFeatures.getAsOpaqueInt(); + NewFPFeatures.setFPPreciseEnabled(false); + NewValue = NewFPFeatures.getAsOpaqueInt(); FpPragmaStack.Act(Loc, Action, StringRef(), NewValue); break; case PFC_Except: if (!isPreciseFPEnabled()) Diag(Loc, diag::err_pragma_fc_except_requires_precise); else - CurFPFeatures.setExceptionMode(LangOptions::FPE_Strict); - NewValue = CurFPFeatures.getAsOpaqueInt(); + NewFPFeatures.setFPExceptionModeOverride(LangOptions::FPE_Strict); + NewValue = NewFPFeatures.getAsOpaqueInt(); FpPragmaStack.Act(Loc, Action, StringRef(), NewValue); break; case PFC_NoExcept: - CurFPFeatures.setExceptionMode(LangOptions::FPE_Ignore); - NewValue = CurFPFeatures.getAsOpaqueInt(); + NewFPFeatures.setFPExceptionModeOverride(LangOptions::FPE_Ignore); + NewValue = NewFPFeatures.getAsOpaqueInt(); FpPragmaStack.Act(Loc, Action, StringRef(), NewValue); break; case PFC_Push: - if (FpPragmaStack.Stack.empty()) { - FpPragmaStack.Act(Loc, Sema::PSK_Set, StringRef(), - CurFPFeatures.getAsOpaqueInt()); - } FpPragmaStack.Act(Loc, Sema::PSK_Push_Set, StringRef(), NewFPFeatures.getAsOpaqueInt()); break; @@ -472,9 +470,12 @@ void Sema::ActOnPragmaFloatControl(SourceLocation Loc, } FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures.getAsOpaqueInt()); NewValue = FpPragmaStack.CurrentValue; - CurFPFeatures.getFromOpaqueInt(NewValue); break; } + FPOptionsOverride NewOverrides; + if (NewValue != FpPragmaStack.DefaultValue) + NewOverrides.getFromOpaqueInt(NewValue); + CurFPFeatures = NewOverrides.applyOverrides(getLangOpts()); } void Sema::ActOnPragmaMSPointersToMembers( @@ -493,44 +494,6 @@ void Sema::ActOnPragmaMSVtorDisp(PragmaMsStackAction Action, VtorDispStack.Act(PragmaLoc, Action, StringRef(), Mode); } -template -void Sema::PragmaStack::Act(SourceLocation PragmaLocation, - PragmaMsStackAction Action, - llvm::StringRef StackSlotLabel, - ValueType Value) { - if (Action == PSK_Reset) { - CurrentValue = DefaultValue; - CurrentPragmaLocation = PragmaLocation; - return; - } - if (Action & PSK_Push) - Stack.emplace_back(StackSlotLabel, CurrentValue, CurrentPragmaLocation, - PragmaLocation); - else if (Action & PSK_Pop) { - if (!StackSlotLabel.empty()) { - // If we've got a label, try to find it and jump there. - auto I = llvm::find_if(llvm::reverse(Stack), [&](const Slot &x) { - return x.StackSlotLabel == StackSlotLabel; - }); - // If we found the label so pop from there. - if (I != Stack.rend()) { - CurrentValue = I->Value; - CurrentPragmaLocation = I->PragmaLocation; - Stack.erase(std::prev(I.base()), Stack.end()); - } - } else if (!Stack.empty()) { - // We do not have a label, just pop the last entry. - CurrentValue = Stack.back().Value; - CurrentPragmaLocation = Stack.back().PragmaLocation; - Stack.pop_back(); - } - } - if (Action & PSK_Set) { - CurrentValue = Value; - CurrentPragmaLocation = PragmaLocation; - } -} - bool Sema::UnifySection(StringRef SectionName, int SectionFlags, DeclaratorDecl *Decl) { @@ -1003,33 +966,70 @@ void Sema::ActOnPragmaVisibility(const IdentifierInfo* VisType, } } -void Sema::ActOnPragmaFPContract(LangOptions::FPModeKind FPC) { +void Sema::ActOnPragmaFPContract(SourceLocation Loc, + LangOptions::FPModeKind FPC) { + unsigned NewValue = FpPragmaStack.hasValue() + ? FpPragmaStack.CurrentValue + : CurFPFeatureOverrides().getAsOpaqueInt(); + FPOptionsOverride NewFPFeatures(NewValue); switch (FPC) { case LangOptions::FPM_On: - CurFPFeatures.setAllowFPContractWithinStatement(); + NewFPFeatures.setAllowFPContractWithinStatement(); break; case LangOptions::FPM_Fast: - CurFPFeatures.setAllowFPContractAcrossStatement(); + NewFPFeatures.setAllowFPContractAcrossStatement(); break; case LangOptions::FPM_Off: - CurFPFeatures.setDisallowFPContract(); + NewFPFeatures.setDisallowFPContract(); break; } + CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts()); + FpPragmaStack.Act(Loc, Sema::PSK_Set, StringRef(), + NewFPFeatures.getAsOpaqueInt()); } -void Sema::ActOnPragmaFPReassociate(bool IsEnabled) { - CurFPFeatures.setAllowAssociativeMath(IsEnabled); +void Sema::ActOnPragmaFPReassociate(SourceLocation Loc, bool IsEnabled) { + unsigned NewValue = FpPragmaStack.hasValue() + ? FpPragmaStack.CurrentValue + : CurFPFeatureOverrides().getAsOpaqueInt(); + FPOptionsOverride NewFPFeatures(NewValue); + NewFPFeatures.setAllowFPReassociateOverride(IsEnabled); + NewValue = NewFPFeatures.getAsOpaqueInt(); + FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewValue); + FPOptionsOverride NewOverrides(NewValue); + CurFPFeatures = NewOverrides.applyOverrides(getLangOpts()); } -void Sema::setRoundingMode(llvm::RoundingMode FPR) { - CurFPFeatures.setRoundingMode(FPR); +void Sema::setRoundingMode(SourceLocation Loc, llvm::RoundingMode FPR) { + unsigned NewValue = FpPragmaStack.hasValue() + ? FpPragmaStack.CurrentValue + : CurFPFeatureOverrides().getAsOpaqueInt(); + FPOptionsOverride NewFPFeatures(NewValue); + NewFPFeatures.setRoundingModeOverride(FPR); + NewValue = NewFPFeatures.getAsOpaqueInt(); + FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewValue); + FPOptionsOverride NewOverrides(NewValue); + CurFPFeatures = NewOverrides.applyOverrides(getLangOpts()); } -void Sema::setExceptionMode(LangOptions::FPExceptionModeKind FPE) { - CurFPFeatures.setExceptionMode(FPE); +void Sema::setExceptionMode(SourceLocation Loc, + LangOptions::FPExceptionModeKind FPE) { + unsigned NewValue = FpPragmaStack.hasValue() + ? FpPragmaStack.CurrentValue + : CurFPFeatureOverrides().getAsOpaqueInt(); + FPOptionsOverride NewFPFeatures(NewValue); + NewFPFeatures.setFPExceptionModeOverride(FPE); + NewValue = NewFPFeatures.getAsOpaqueInt(); + FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewValue); + FPOptionsOverride NewOverrides(NewValue); + CurFPFeatures = NewOverrides.applyOverrides(getLangOpts()); } void Sema::ActOnPragmaFEnvAccess(SourceLocation Loc, bool IsEnabled) { + unsigned NewValue = FpPragmaStack.hasValue() + ? FpPragmaStack.CurrentValue + : CurFPFeatureOverrides().getAsOpaqueInt(); + FPOptionsOverride NewFPFeatures(NewValue); if (IsEnabled) { // Verify Microsoft restriction: // You can't enable fenv_access unless precise semantics are enabled. @@ -1037,9 +1037,13 @@ void Sema::ActOnPragmaFEnvAccess(SourceLocation Loc, bool IsEnabled) { // pragma, or by using the /fp:precise or /fp:strict compiler options if (!isPreciseFPEnabled()) Diag(Loc, diag::err_pragma_fenv_requires_precise); - CurFPFeatures.setAllowFEnvAccess(); + NewFPFeatures.setAllowFEnvAccessOverride(true); } else - CurFPFeatures.setDisallowFEnvAccess(); + NewFPFeatures.setAllowFEnvAccessOverride(false); + NewValue = NewFPFeatures.getAsOpaqueInt(); + FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewValue); + FPOptionsOverride NewOverrides(NewValue); + CurFPFeatures = NewOverrides.applyOverrides(getLangOpts()); } void Sema::PushNamespaceVisibilityAttr(const VisibilityAttr *Attr, diff --git a/clang/lib/Sema/SemaCUDA.cpp b/clang/lib/Sema/SemaCUDA.cpp index f54d97a2a3195..283a04683a32a 100644 --- a/clang/lib/Sema/SemaCUDA.cpp +++ b/clang/lib/Sema/SemaCUDA.cpp @@ -17,6 +17,7 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Lex/Preprocessor.h" #include "clang/Sema/Lookup.h" +#include "clang/Sema/ScopeInfo.h" #include "clang/Sema/Sema.h" #include "clang/Sema/SemaDiagnostic.h" #include "clang/Sema/SemaInternal.h" @@ -746,20 +747,58 @@ bool Sema::CheckCUDACall(SourceLocation Loc, FunctionDecl *Callee) { DiagKind != DeviceDiagBuilder::K_ImmediateWithCallStack; } +// Check the wrong-sided reference capture of lambda for CUDA/HIP. +// A lambda function may capture a stack variable by reference when it is +// defined and uses the capture by reference when the lambda is called. When +// the capture and use happen on different sides, the capture is invalid and +// should be diagnosed. +void Sema::CUDACheckLambdaCapture(CXXMethodDecl *Callee, + const sema::Capture &Capture) { + // In host compilation we only need to check lambda functions emitted on host + // side. In such lambda functions, a reference capture is invalid only + // if the lambda structure is populated by a device function or kernel then + // is passed to and called by a host function. However that is impossible, + // since a device function or kernel can only call a device function, also a + // kernel cannot pass a lambda back to a host function since we cannot + // define a kernel argument type which can hold the lambda before the lambda + // itself is defined. + if (!LangOpts.CUDAIsDevice) + return; + + // File-scope lambda can only do init captures for global variables, which + // results in passing by value for these global variables. + FunctionDecl *Caller = dyn_cast(CurContext); + if (!Caller) + return; + + // In device compilation, we only need to check lambda functions which are + // emitted on device side. For such lambdas, a reference capture is invalid + // only if the lambda structure is populated by a host function then passed + // to and called in a device function or kernel. + bool CalleeIsDevice = Callee->hasAttr(); + bool CallerIsHost = + !Caller->hasAttr() && !Caller->hasAttr(); + bool ShouldCheck = CalleeIsDevice && CallerIsHost; + if (!ShouldCheck || !Capture.isReferenceCapture()) + return; + auto DiagKind = DeviceDiagBuilder::K_Deferred; + if (Capture.isVariableCapture()) { + DeviceDiagBuilder(DiagKind, Capture.getLocation(), + diag::err_capture_bad_target, Callee, *this) + << Capture.getVariable(); + } else if (Capture.isThisCapture()) { + DeviceDiagBuilder(DiagKind, Capture.getLocation(), + diag::err_capture_bad_target_this_ptr, Callee, *this); + } + return; +} + void Sema::CUDASetLambdaAttrs(CXXMethodDecl *Method) { assert(getLangOpts().CUDA && "Should only be called during CUDA compilation"); if (Method->hasAttr() || Method->hasAttr()) return; - FunctionDecl *CurFn = dyn_cast(CurContext); - if (!CurFn) - return; - CUDAFunctionTarget Target = IdentifyCUDATarget(CurFn); - if (Target == CFT_Global || Target == CFT_Device) { - Method->addAttr(CUDADeviceAttr::CreateImplicit(Context)); - } else if (Target == CFT_HostDevice) { - Method->addAttr(CUDADeviceAttr::CreateImplicit(Context)); - Method->addAttr(CUDAHostAttr::CreateImplicit(Context)); - } + Method->addAttr(CUDADeviceAttr::CreateImplicit(Context)); + Method->addAttr(CUDAHostAttr::CreateImplicit(Context)); } void Sema::checkCUDATargetOverload(FunctionDecl *NewFD, diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 883ff17eb279b..efaf36a693061 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -88,6 +88,7 @@ #include "llvm/Support/SaveAndRestore.h" #include "llvm/Support/raw_ostream.h" #include +#include #include #include #include @@ -237,8 +238,8 @@ static bool SemaBuiltinAlignment(Sema &S, CallExpr *TheCall, unsigned ID) { } Expr::EvalResult AlignResult; unsigned MaxAlignmentBits = S.Context.getIntWidth(SrcTy) - 1; - // We can't check validity of alignment if it is type dependent. - if (!AlignOp->isInstantiationDependent() && + // We can't check validity of alignment if it is value dependent. + if (!AlignOp->isValueDependent() && AlignOp->EvaluateAsInt(AlignResult, S.Context, Expr::SE_AllowSideEffects)) { llvm::APSInt AlignValue = AlignResult.Val.getInt(); @@ -1808,6 +1809,36 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, TheCall->setType(Context.IntTy); break; } + case Builtin::BI__builtin_expect_with_probability: { + // We first want to ensure we are called with 3 arguments + if (checkArgCount(*this, TheCall, 3)) + return ExprError(); + // then check probability is constant float in range [0.0, 1.0] + const Expr *ProbArg = TheCall->getArg(2); + SmallVector Notes; + Expr::EvalResult Eval; + Eval.Diag = &Notes; + if ((!ProbArg->EvaluateAsConstantExpr(Eval, Expr::EvaluateForCodeGen, + Context)) || + !Eval.Val.isFloat()) { + Diag(ProbArg->getBeginLoc(), diag::err_probability_not_constant_float) + << ProbArg->getSourceRange(); + for (const PartialDiagnosticAt &PDiag : Notes) + Diag(PDiag.first, PDiag.second); + return ExprError(); + } + llvm::APFloat Probability = Eval.Val.getFloat(); + bool LoseInfo = false; + Probability.convert(llvm::APFloat::IEEEdouble(), + llvm::RoundingMode::Dynamic, &LoseInfo); + if (!(Probability >= llvm::APFloat(0.0) && + Probability <= llvm::APFloat(1.0))) { + Diag(ProbArg->getBeginLoc(), diag::err_probability_out_of_range) + << ProbArg->getSourceRange(); + return ExprError(); + } + break; + } case Builtin::BI__builtin_preserve_access_index: if (SemaBuiltinPreserveAI(*this, TheCall)) return ExprError(); @@ -3094,6 +3125,16 @@ bool Sema::CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, SemaBuiltinConstantArgRange(TheCall, 1, 0, 1); case PPC::BI__builtin_pack_vector_int128: return SemaVSXCheck(TheCall); + case PPC::BI__builtin_altivec_vgnb: + return SemaBuiltinConstantArgRange(TheCall, 1, 2, 7); + case PPC::BI__builtin_vsx_xxeval: + return SemaBuiltinConstantArgRange(TheCall, 3, 0, 255); + case PPC::BI__builtin_altivec_vsldbi: + return SemaBuiltinConstantArgRange(TheCall, 2, 0, 7); + case PPC::BI__builtin_altivec_vsrdbi: + return SemaBuiltinConstantArgRange(TheCall, 2, 0, 7); + case PPC::BI__builtin_vsx_xxpermx: + return SemaBuiltinConstantArgRange(TheCall, 3, 0, 7); } return SemaBuiltinConstantArgRange(TheCall, i, l, u); } @@ -3567,6 +3608,64 @@ bool Sema::CheckX86BuiltinGatherScatterScale(unsigned BuiltinID, << Arg->getSourceRange(); } +enum { TileRegLow = 0, TileRegHigh = 7 }; + +bool Sema::CheckX86BuiltinTileArgumentsRange(CallExpr *TheCall, + ArrayRef ArgNums) { + for (int ArgNum : ArgNums) { + if (SemaBuiltinConstantArgRange(TheCall, ArgNum, TileRegLow, TileRegHigh)) + return true; + } + return false; +} + +bool Sema::CheckX86BuiltinTileArgumentsRange(CallExpr *TheCall, int ArgNum) { + return SemaBuiltinConstantArgRange(TheCall, ArgNum, TileRegLow, TileRegHigh); +} + +bool Sema::CheckX86BuiltinTileDuplicate(CallExpr *TheCall, + ArrayRef ArgNums) { + // Because the max number of tile register is TileRegHigh + 1, so here we use + // each bit to represent the usage of them in bitset. + std::bitset ArgValues; + for (int ArgNum : ArgNums) { + llvm::APSInt Arg; + SemaBuiltinConstantArg(TheCall, ArgNum, Arg); + int ArgExtValue = Arg.getExtValue(); + assert((ArgExtValue >= TileRegLow || ArgExtValue <= TileRegHigh) && + "Incorrect tile register num."); + if (ArgValues.test(ArgExtValue)) + return Diag(TheCall->getBeginLoc(), + diag::err_x86_builtin_tile_arg_duplicate) + << TheCall->getArg(ArgNum)->getSourceRange(); + ArgValues.set(ArgExtValue); + } + return false; +} + +bool Sema::CheckX86BuiltinTileRangeAndDuplicate(CallExpr *TheCall, + ArrayRef ArgNums) { + return CheckX86BuiltinTileArgumentsRange(TheCall, ArgNums) || + CheckX86BuiltinTileDuplicate(TheCall, ArgNums); +} + +bool Sema::CheckX86BuiltinTileArguments(unsigned BuiltinID, CallExpr *TheCall) { + switch (BuiltinID) { + default: + return false; + case X86::BI__builtin_ia32_tileloadd64: + case X86::BI__builtin_ia32_tileloaddt164: + case X86::BI__builtin_ia32_tilestored64: + case X86::BI__builtin_ia32_tilezero: + return CheckX86BuiltinTileArgumentsRange(TheCall, 0); + case X86::BI__builtin_ia32_tdpbssd: + case X86::BI__builtin_ia32_tdpbsud: + case X86::BI__builtin_ia32_tdpbusd: + case X86::BI__builtin_ia32_tdpbuud: + case X86::BI__builtin_ia32_tdpbf16ps: + return CheckX86BuiltinTileRangeAndDuplicate(TheCall, {0, 1, 2}); + } +} static bool isX86_32Builtin(unsigned BuiltinID) { // These builtins only work on x86-32 targets. switch (BuiltinID) { @@ -3600,6 +3699,10 @@ bool Sema::CheckX86BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, if (CheckX86BuiltinGatherScatterScale(BuiltinID, TheCall)) return true; + // If the intrinsic has a tile arguments, make sure they are valid. + if (CheckX86BuiltinTileArguments(BuiltinID, TheCall)) + return true; + // For intrinsics which take an immediate value as part of the instruction, // range check them here. int i = 0, l = 0, u = 0; @@ -11833,27 +11936,31 @@ static void CheckImplicitConversion(Sema &S, Expr *E, QualType T, } } -static void CheckConditionalOperator(Sema &S, ConditionalOperator *E, +static void CheckConditionalOperator(Sema &S, AbstractConditionalOperator *E, SourceLocation CC, QualType T); static void CheckConditionalOperand(Sema &S, Expr *E, QualType T, SourceLocation CC, bool &ICContext) { E = E->IgnoreParenImpCasts(); - if (isa(E)) - return CheckConditionalOperator(S, cast(E), CC, T); + if (auto *CO = dyn_cast(E)) + return CheckConditionalOperator(S, CO, CC, T); AnalyzeImplicitConversions(S, E, CC); if (E->getType() != T) return CheckImplicitConversion(S, E, T, CC, &ICContext); } -static void CheckConditionalOperator(Sema &S, ConditionalOperator *E, +static void CheckConditionalOperator(Sema &S, AbstractConditionalOperator *E, SourceLocation CC, QualType T) { AnalyzeImplicitConversions(S, E->getCond(), E->getQuestionLoc()); + Expr *TrueExpr = E->getTrueExpr(); + if (auto *BCO = dyn_cast(E)) + TrueExpr = BCO->getCommon(); + bool Suspicious = false; - CheckConditionalOperand(S, E->getTrueExpr(), T, CC, Suspicious); + CheckConditionalOperand(S, TrueExpr, T, CC, Suspicious); CheckConditionalOperand(S, E->getFalseExpr(), T, CC, Suspicious); if (T->isBooleanType()) @@ -11872,7 +11979,7 @@ static void CheckConditionalOperator(Sema &S, ConditionalOperator *E, if (E->getType() == T) return; Suspicious = false; - CheckImplicitConversion(S, E->getTrueExpr()->IgnoreParenImpCasts(), + CheckImplicitConversion(S, TrueExpr->IgnoreParenImpCasts(), E->getType(), CC, &Suspicious); if (!Suspicious) CheckImplicitConversion(S, E->getFalseExpr()->IgnoreParenImpCasts(), @@ -11935,7 +12042,7 @@ static void AnalyzeImplicitConversions( // For conditional operators, we analyze the arguments as if they // were being fed directly into the output. - if (auto *CO = dyn_cast(SourceExpr)) { + if (auto *CO = dyn_cast(SourceExpr)) { CheckConditionalOperator(S, CO, CC, T); return; } @@ -13453,12 +13560,14 @@ static getBaseAlignmentAndOffsetFromLValue(const Expr *E, ASTContext &Ctx) { } case Stmt::MemberExprClass: { auto *ME = cast(E); - if (ME->isArrow()) - break; auto *FD = dyn_cast(ME->getMemberDecl()); if (!FD || FD->getType()->isReferenceType()) break; - auto P = getBaseAlignmentAndOffsetFromLValue(ME->getBase(), Ctx); + Optional> P; + if (ME->isArrow()) + P = getBaseAlignmentAndOffsetFromPtr(ME->getBase(), Ctx); + else + P = getBaseAlignmentAndOffsetFromLValue(ME->getBase(), Ctx); if (!P) break; const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(FD->getParent()); @@ -13522,6 +13631,11 @@ static getBaseAlignmentAndOffsetFromPtr(const Expr *E, ASTContext &Ctx) { } break; } + case Stmt::CXXThisExprClass: { + auto *RD = E->getType()->getPointeeType()->getAsCXXRecordDecl(); + CharUnits Alignment = Ctx.getASTRecordLayout(RD).getNonVirtualAlignment(); + return std::make_pair(Alignment, CharUnits::Zero()); + } case Stmt::UnaryOperatorClass: { auto *UO = cast(E); if (UO->getOpcode() == UO_AddrOf) @@ -15265,7 +15379,8 @@ ExprResult Sema::SemaBuiltinMatrixColumnMajorLoad(CallExpr *TheCall, if (checkArgCount(*this, TheCall, 4)) return ExprError(); - Expr *PtrExpr = TheCall->getArg(0); + unsigned PtrArgIdx = 0; + Expr *PtrExpr = TheCall->getArg(PtrArgIdx); Expr *RowsExpr = TheCall->getArg(1); Expr *ColumnsExpr = TheCall->getArg(2); Expr *StrideExpr = TheCall->getArg(3); @@ -15289,14 +15404,14 @@ ExprResult Sema::SemaBuiltinMatrixColumnMajorLoad(CallExpr *TheCall, QualType ElementTy; if (!PtrTy) { Diag(PtrExpr->getBeginLoc(), diag::err_builtin_matrix_pointer_arg) - << "first"; + << PtrArgIdx + 1; ArgError = true; } else { ElementTy = PtrTy->getPointeeType().getUnqualifiedType(); if (!ConstantMatrixType::isValidElementType(ElementTy)) { Diag(PtrExpr->getBeginLoc(), diag::err_builtin_matrix_pointer_arg) - << "first"; + << PtrArgIdx + 1; ArgError = true; } } @@ -15372,8 +15487,9 @@ ExprResult Sema::SemaBuiltinMatrixColumnMajorStore(CallExpr *TheCall, if (checkArgCount(*this, TheCall, 3)) return ExprError(); + unsigned PtrArgIdx = 1; Expr *MatrixExpr = TheCall->getArg(0); - Expr *PtrExpr = TheCall->getArg(1); + Expr *PtrExpr = TheCall->getArg(PtrArgIdx); Expr *StrideExpr = TheCall->getArg(2); bool ArgError = false; @@ -15412,7 +15528,7 @@ ExprResult Sema::SemaBuiltinMatrixColumnMajorStore(CallExpr *TheCall, auto *PtrTy = PtrExpr->getType()->getAs(); if (!PtrTy) { Diag(PtrExpr->getBeginLoc(), diag::err_builtin_matrix_pointer_arg) - << "second"; + << PtrArgIdx + 1; ArgError = true; } else { QualType ElementTy = PtrTy->getPointeeType(); diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 5539aef917d09..0a8a27068ebfd 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -24,11 +24,13 @@ #include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/Type.h" #include "clang/Basic/CharInfo.h" +#include "clang/Basic/OperatorKinds.h" #include "clang/Basic/Specifiers.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/MacroInfo.h" #include "clang/Lex/Preprocessor.h" #include "clang/Sema/CodeCompleteConsumer.h" +#include "clang/Sema/DeclSpec.h" #include "clang/Sema/Designator.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/Overload.h" @@ -1687,11 +1689,9 @@ static void AddTypeSpecifierResults(const LangOptions &LangOpts, Results.AddResult(Result("class", CCP_Type)); Results.AddResult(Result("wchar_t", CCP_Type)); - // typename qualified-id + // typename name Builder.AddTypedTextChunk("typename"); Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); - Builder.AddPlaceholderChunk("qualifier"); - Builder.AddTextChunk("::"); Builder.AddPlaceholderChunk("name"); Results.AddResult(Result(Builder.TakeString())); @@ -1818,6 +1818,18 @@ static void AddTypedefResult(ResultBuilder &Results) { Results.AddResult(CodeCompletionResult(Builder.TakeString())); } +// using name = type +static void AddUsingAliasResult(CodeCompletionBuilder &Builder, + ResultBuilder &Results) { + Builder.AddTypedTextChunk("using"); + Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); + Builder.AddPlaceholderChunk("name"); + Builder.AddChunk(CodeCompletionString::CK_Equal); + Builder.AddPlaceholderChunk("type"); + Builder.AddChunk(CodeCompletionString::CK_SemiColon); + Results.AddResult(CodeCompletionResult(Builder.TakeString())); +} + static bool WantTypesInContext(Sema::ParserCompletionContext CCC, const LangOptions &LangOpts) { switch (CCC) { @@ -2061,6 +2073,9 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, Scope *S, Builder.AddChunk(CodeCompletionString::CK_SemiColon); Results.AddResult(Result(Builder.TakeString())); + if (SemaRef.getLangOpts().CPlusPlus11) + AddUsingAliasResult(Builder, Results); + // using typename qualifier::name (only in a dependent context) if (SemaRef.CurContext->isDependentContext()) { Builder.AddTypedTextChunk("using typename"); @@ -2141,6 +2156,9 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, Scope *S, case Sema::PCC_RecoveryInFunction: case Sema::PCC_Statement: { + if (SemaRef.getLangOpts().CPlusPlus11) + AddUsingAliasResult(Builder, Results); + AddTypedefResult(Results); if (SemaRef.getLangOpts().CPlusPlus && Results.includeCodePatterns() && @@ -5743,7 +5761,7 @@ void Sema::CodeCompleteInitializer(Scope *S, Decl *D) { CodeCompleteExpression(S, Data); } -void Sema::CodeCompleteAfterIf(Scope *S) { +void Sema::CodeCompleteAfterIf(Scope *S, bool IsBracedThen) { ResultBuilder Results(*this, CodeCompleter->getAllocator(), CodeCompleter->getCodeCompletionTUInfo(), mapCodeCompletionContext(*this, PCC_Statement)); @@ -5760,15 +5778,25 @@ void Sema::CodeCompleteAfterIf(Scope *S) { // "else" block CodeCompletionBuilder Builder(Results.getAllocator(), Results.getCodeCompletionTUInfo()); + + auto AddElseBodyPattern = [&] { + if (IsBracedThen) { + Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); + Builder.AddChunk(CodeCompletionString::CK_LeftBrace); + Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); + Builder.AddPlaceholderChunk("statements"); + Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); + Builder.AddChunk(CodeCompletionString::CK_RightBrace); + } else { + Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); + Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); + Builder.AddPlaceholderChunk("statement"); + Builder.AddChunk(CodeCompletionString::CK_SemiColon); + } + }; Builder.AddTypedTextChunk("else"); - if (Results.includeCodePatterns()) { - Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); - Builder.AddChunk(CodeCompletionString::CK_LeftBrace); - Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); - Builder.AddPlaceholderChunk("statements"); - Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); - Builder.AddChunk(CodeCompletionString::CK_RightBrace); - } + if (Results.includeCodePatterns()) + AddElseBodyPattern(); Results.AddResult(Builder.TakeString()); // "else if" block @@ -5781,12 +5809,7 @@ void Sema::CodeCompleteAfterIf(Scope *S) { Builder.AddPlaceholderChunk("expression"); Builder.AddChunk(CodeCompletionString::CK_RightParen); if (Results.includeCodePatterns()) { - Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); - Builder.AddChunk(CodeCompletionString::CK_LeftBrace); - Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); - Builder.AddPlaceholderChunk("statements"); - Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); - Builder.AddChunk(CodeCompletionString::CK_RightBrace); + AddElseBodyPattern(); } Results.AddResult(Builder.TakeString()); @@ -6245,6 +6268,53 @@ void Sema::CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro, Results.data(), Results.size()); } +void Sema::CodeCompleteAfterFunctionEquals(Declarator &D) { + if (!LangOpts.CPlusPlus11) + return; + ResultBuilder Results(*this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), + CodeCompletionContext::CCC_Other); + auto ShouldAddDefault = [&D, this]() { + if (!D.isFunctionDeclarator()) + return false; + auto &Id = D.getName(); + if (Id.getKind() == UnqualifiedIdKind::IK_DestructorName) + return true; + // FIXME(liuhui): Ideally, we should check the constructor parameter list to + // verify that it is the default, copy or move constructor? + if (Id.getKind() == UnqualifiedIdKind::IK_ConstructorName && + D.getFunctionTypeInfo().NumParams <= 1) + return true; + if (Id.getKind() == UnqualifiedIdKind::IK_OperatorFunctionId) { + auto Op = Id.OperatorFunctionId.Operator; + // FIXME(liuhui): Ideally, we should check the function parameter list to + // verify that it is the copy or move assignment? + if (Op == OverloadedOperatorKind::OO_Equal) + return true; + if (LangOpts.CPlusPlus20 && + (Op == OverloadedOperatorKind::OO_EqualEqual || + Op == OverloadedOperatorKind::OO_ExclaimEqual || + Op == OverloadedOperatorKind::OO_Less || + Op == OverloadedOperatorKind::OO_LessEqual || + Op == OverloadedOperatorKind::OO_Greater || + Op == OverloadedOperatorKind::OO_GreaterEqual || + Op == OverloadedOperatorKind::OO_Spaceship)) + return true; + } + return false; + }; + + Results.EnterNewScope(); + if (ShouldAddDefault()) + Results.AddResult("default"); + // FIXME(liuhui): Ideally, we should only provide `delete` completion for the + // first function declaration. + Results.AddResult("delete"); + Results.ExitScope(); + HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), + Results.data(), Results.size()); +} + /// Macro that optionally prepends an "@" to the string literal passed in via /// Keyword, depending on whether NeedAt is true or false. #define OBJC_AT_KEYWORD_NAME(NeedAt, Keyword) ((NeedAt) ? "@" Keyword : Keyword) @@ -8133,8 +8203,8 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, Builder.AddChunk(CodeCompletionString::CK_RightParen); } - Builder.AddTypedTextChunk(Allocator.CopyString(SelectorId->getName())); - Builder.AddTypedTextChunk(":"); + Builder.AddTypedTextChunk( + Allocator.CopyString(SelectorId->getName() + ":")); AddObjCPassingTypeChunk(Property->getType(), /*Quals=*/0, Context, Policy, Builder); Builder.AddTextChunk(Key); @@ -8722,39 +8792,43 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S, Optional IsInstanceMethod, Selector Sel = Method->getSelector(); - // Add the first part of the selector to the pattern. - Builder.AddTypedTextChunk( - Builder.getAllocator().CopyString(Sel.getNameForSlot(0))); - - // Add parameters to the pattern. - unsigned I = 0; - for (ObjCMethodDecl::param_iterator P = Method->param_begin(), - PEnd = Method->param_end(); - P != PEnd; (void)++P, ++I) { - // Add the part of the selector name. - if (I == 0) - Builder.AddTypedTextChunk(":"); - else if (I < Sel.getNumArgs()) { - Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); - Builder.AddTypedTextChunk( - Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":")); - } else - break; - - // Add the parameter type. - QualType ParamType; - if ((*P)->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability) - ParamType = (*P)->getType(); - else - ParamType = (*P)->getOriginalType(); - ParamType = ParamType.substObjCTypeArgs( - Context, {}, ObjCSubstitutionContext::Parameter); - AttributedType::stripOuterNullability(ParamType); - AddObjCPassingTypeChunk(ParamType, (*P)->getObjCDeclQualifier(), Context, - Policy, Builder); + if (Sel.isUnarySelector()) { + // Unary selectors have no arguments. + Builder.AddTypedTextChunk( + Builder.getAllocator().CopyString(Sel.getNameForSlot(0))); + } else { + // Add all parameters to the pattern. + unsigned I = 0; + for (ObjCMethodDecl::param_iterator P = Method->param_begin(), + PEnd = Method->param_end(); + P != PEnd; (void)++P, ++I) { + // Add the part of the selector name. + if (I == 0) + Builder.AddTypedTextChunk( + Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":")); + else if (I < Sel.getNumArgs()) { + Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); + Builder.AddTypedTextChunk( + Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":")); + } else + break; - if (IdentifierInfo *Id = (*P)->getIdentifier()) - Builder.AddTextChunk(Builder.getAllocator().CopyString(Id->getName())); + // Add the parameter type. + QualType ParamType; + if ((*P)->getObjCDeclQualifier() & Decl::OBJC_TQ_CSNullability) + ParamType = (*P)->getType(); + else + ParamType = (*P)->getOriginalType(); + ParamType = ParamType.substObjCTypeArgs( + Context, {}, ObjCSubstitutionContext::Parameter); + AttributedType::stripOuterNullability(ParamType); + AddObjCPassingTypeChunk(ParamType, (*P)->getObjCDeclQualifier(), + Context, Policy, Builder); + + if (IdentifierInfo *Id = (*P)->getIdentifier()) + Builder.AddTextChunk( + Builder.getAllocator().CopyString(Id->getName())); + } } if (Method->isVariadic()) { diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp index 5ed0bbd6041d1..992cccac64050 100644 --- a/clang/lib/Sema/SemaCoroutine.cpp +++ b/clang/lib/Sema/SemaCoroutine.cpp @@ -24,6 +24,7 @@ #include "clang/Sema/Overload.h" #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/SemaInternal.h" +#include "llvm/ADT/SmallSet.h" using namespace clang; using namespace sema; @@ -390,7 +391,13 @@ static Expr *maybeTailCall(Sema &S, QualType RetType, Expr *E, return nullptr; Expr *JustAddress = AddressExpr.get(); - // FIXME: Check that the type of AddressExpr is void* + + // Check that the type of AddressExpr is void* + if (!JustAddress->getType().getTypePtr()->isVoidPointerType()) + S.Diag(cast(JustAddress)->getCalleeDecl()->getLocation(), + diag::warn_coroutine_handle_address_invalid_return_type) + << JustAddress->getType(); + return buildBuiltinCall(S, Loc, Builtin::BI__builtin_coro_resume, JustAddress); } @@ -604,6 +611,80 @@ static FunctionScopeInfo *checkCoroutineContext(Sema &S, SourceLocation Loc, return ScopeInfo; } +/// Recursively check \p E and all its children to see if any call target +/// (including constructor call) is declared noexcept. Also any value returned +/// from the call has a noexcept destructor. +static void checkNoThrow(Sema &S, const Stmt *E, + llvm::SmallPtrSetImpl &ThrowingDecls) { + auto checkDeclNoexcept = [&](const Decl *D, bool IsDtor = false) { + // In the case of dtor, the call to dtor is implicit and hence we should + // pass nullptr to canCalleeThrow. + if (Sema::canCalleeThrow(S, IsDtor ? nullptr : cast(E), D)) { + if (const auto *FD = dyn_cast(D)) { + // co_await promise.final_suspend() could end up calling + // __builtin_coro_resume for symmetric transfer if await_suspend() + // returns a handle. In that case, even __builtin_coro_resume is not + // declared as noexcept and may throw, it does not throw _into_ the + // coroutine that just suspended, but rather throws back out from + // whoever called coroutine_handle::resume(), hence we claim that + // logically it does not throw. + if (FD->getBuiltinID() == Builtin::BI__builtin_coro_resume) + return; + } + if (ThrowingDecls.empty()) { + // First time seeing an error, emit the error message. + S.Diag(cast(S.CurContext)->getLocation(), + diag::err_coroutine_promise_final_suspend_requires_nothrow); + } + ThrowingDecls.insert(D); + } + }; + auto SC = E->getStmtClass(); + if (SC == Expr::CXXConstructExprClass) { + auto const *Ctor = cast(E)->getConstructor(); + checkDeclNoexcept(Ctor); + // Check the corresponding destructor of the constructor. + checkDeclNoexcept(Ctor->getParent()->getDestructor(), true); + } else if (SC == Expr::CallExprClass || SC == Expr::CXXMemberCallExprClass || + SC == Expr::CXXOperatorCallExprClass) { + if (!cast(E)->isTypeDependent()) { + checkDeclNoexcept(cast(E)->getCalleeDecl()); + auto ReturnType = cast(E)->getCallReturnType(S.getASTContext()); + // Check the destructor of the call return type, if any. + if (ReturnType.isDestructedType() == + QualType::DestructionKind::DK_cxx_destructor) { + const auto *T = + cast(ReturnType.getCanonicalType().getTypePtr()); + checkDeclNoexcept( + dyn_cast(T->getDecl())->getDestructor(), true); + } + } + } + for (const auto *Child : E->children()) { + if (!Child) + continue; + checkNoThrow(S, Child, ThrowingDecls); + } +} + +bool Sema::checkFinalSuspendNoThrow(const Stmt *FinalSuspend) { + llvm::SmallPtrSet ThrowingDecls; + // We first collect all declarations that should not throw but not declared + // with noexcept. We then sort them based on the location before printing. + // This is to avoid emitting the same note multiple times on the same + // declaration, and also provide a deterministic order for the messages. + checkNoThrow(*this, FinalSuspend, ThrowingDecls); + auto SortedDecls = llvm::SmallVector{ThrowingDecls.begin(), + ThrowingDecls.end()}; + sort(SortedDecls, [](const Decl *A, const Decl *B) { + return A->getEndLoc() < B->getEndLoc(); + }); + for (const auto *D : SortedDecls) { + Diag(D->getEndLoc(), diag::note_coroutine_function_declare_noexcept); + } + return ThrowingDecls.empty(); +} + bool Sema::ActOnCoroutineBodyStart(Scope *SC, SourceLocation KWLoc, StringRef Keyword) { if (!checkCoroutineContext(*this, KWLoc, Keyword)) @@ -646,7 +727,7 @@ bool Sema::ActOnCoroutineBodyStart(Scope *SC, SourceLocation KWLoc, return true; StmtResult FinalSuspend = buildSuspends("final_suspend"); - if (FinalSuspend.isInvalid()) + if (FinalSuspend.isInvalid() || !checkFinalSuspendNoThrow(FinalSuspend.get())) return true; ScopeInfo->setCoroutineSuspends(InitSuspend.get(), FinalSuspend.get()); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 5eebfb7dc1f0c..f5e375134c293 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -750,7 +750,10 @@ void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II, Diag(IILoc, IsTemplateName ? diag::err_no_member_template : diag::err_typename_nested_not_found) << II << DC << SS->getRange(); - else if (isDependentScopeSpecifier(*SS)) { + else if (SS->isValid() && SS->getScopeRep()->containsErrors()) { + SuggestedType = + ActOnTypenameType(S, SourceLocation(), *SS, *II, IILoc).get(); + } else if (isDependentScopeSpecifier(*SS)) { unsigned DiagID = diag::err_typename_missing; if (getLangOpts().MSVCCompat && isMicrosoftMissingTypename(SS, S)) DiagID = diag::ext_typename_missing; @@ -1257,47 +1260,8 @@ Sema::getTemplateNameKindForDiagnostics(TemplateName Name) { return TemplateNameKindForDiagnostics::DependentTemplate; } -// Determines the context to return to after temporarily entering a -// context. This depends in an unnecessarily complicated way on the -// exact ordering of callbacks from the parser. -DeclContext *Sema::getContainingDC(DeclContext *DC) { - - // Functions defined inline within classes aren't parsed until we've - // finished parsing the top-level class, so the top-level class is - // the context we'll need to return to. - // A Lambda call operator whose parent is a class must not be treated - // as an inline member function. A Lambda can be used legally - // either as an in-class member initializer or a default argument. These - // are parsed once the class has been marked complete and so the containing - // context would be the nested class (when the lambda is defined in one); - // If the class is not complete, then the lambda is being used in an - // ill-formed fashion (such as to specify the width of a bit-field, or - // in an array-bound) - in which case we still want to return the - // lexically containing DC (which could be a nested class). - if (isa(DC) && !isLambdaCallOperator(DC)) { - DC = DC->getLexicalParent(); - - // A function not defined within a class will always return to its - // lexical context. - if (!isa(DC)) - return DC; - - // A C++ inline method/friend is parsed *after* the topmost class - // it was declared in is fully parsed ("complete"); the topmost - // class is the context we need to return to. - while (CXXRecordDecl *RD = dyn_cast(DC->getLexicalParent())) - DC = RD; - - // Return the declaration context of the topmost class the inline method is - // declared in. - return DC; - } - - return DC->getLexicalParent(); -} - void Sema::PushDeclContext(Scope *S, DeclContext *DC) { - assert(getContainingDC(DC) == CurContext && + assert(DC->getLexicalParent() == CurContext && "The next DeclContext should be lexically contained in the current one."); CurContext = DC; S->setEntity(DC); @@ -1306,7 +1270,7 @@ void Sema::PushDeclContext(Scope *S, DeclContext *DC) { void Sema::PopDeclContext() { assert(CurContext && "DeclContext imbalance!"); - CurContext = getContainingDC(CurContext); + CurContext = CurContext->getLexicalParent(); assert(CurContext && "Popped translation unit!"); } @@ -1358,6 +1322,12 @@ void Sema::EnterDeclaratorContext(Scope *S, DeclContext *DC) { CurContext = DC; S->setEntity(DC); + + if (S->getParent()->isTemplateParamScope()) { + // Also set the corresponding entities for all immediately-enclosing + // template parameter scopes. + EnterTemplatedContext(S->getParent(), DC); + } } void Sema::ExitDeclaratorContext(Scope *S) { @@ -1373,6 +1343,49 @@ void Sema::ExitDeclaratorContext(Scope *S) { // disappear. } +void Sema::EnterTemplatedContext(Scope *S, DeclContext *DC) { + assert(S->isTemplateParamScope() && + "expected to be initializing a template parameter scope"); + + // C++20 [temp.local]p7: + // In the definition of a member of a class template that appears outside + // of the class template definition, the name of a member of the class + // template hides the name of a template-parameter of any enclosing class + // templates (but not a template-parameter of the member if the member is a + // class or function template). + // C++20 [temp.local]p9: + // In the definition of a class template or in the definition of a member + // of such a template that appears outside of the template definition, for + // each non-dependent base class (13.8.2.1), if the name of the base class + // or the name of a member of the base class is the same as the name of a + // template-parameter, the base class name or member name hides the + // template-parameter name (6.4.10). + // + // This means that a template parameter scope should be searched immediately + // after searching the DeclContext for which it is a template parameter + // scope. For example, for + // template template template + // void N::A::B::f(...) + // we search V then B (and base classes) then U then A (and base + // classes) then T then N then ::. + unsigned ScopeDepth = getTemplateDepth(S); + for (; S && S->isTemplateParamScope(); S = S->getParent(), --ScopeDepth) { + DeclContext *SearchDCAfterScope = DC; + for (; DC; DC = DC->getLookupParent()) { + if (const TemplateParameterList *TPL = + cast(DC)->getDescribedTemplateParams()) { + unsigned DCDepth = TPL->getDepth() + 1; + if (DCDepth > ScopeDepth) + continue; + if (ScopeDepth == DCDepth) + SearchDCAfterScope = DC = DC->getLookupParent(); + break; + } + } + S->setLookupEntity(SearchDCAfterScope); + } +} + void Sema::ActOnReenterFunctionContext(Scope* S, Decl *D) { // We assume that the caller has already called // ActOnReenterTemplateScope so getTemplatedDecl() works. @@ -16152,7 +16165,7 @@ Decl *Sema::ActOnObjCContainerStartDefinition(Decl *IDecl) { assert(isa(IDecl) && "ActOnObjCContainerStartDefinition - Not ObjCContainerDecl"); DeclContext *OCD = cast(IDecl); - assert(getContainingDC(OCD) == CurContext && + assert(OCD->getLexicalParent() == CurContext && "The next DeclContext should be lexically contained in the current one."); CurContext = OCD; return IDecl; @@ -17171,10 +17184,10 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, I.setAccess((*I)->getAccess()); } - if (!CXXRecord->isDependentType()) { - // Add any implicitly-declared members to this class. - AddImplicitlyDeclaredMembersToClass(CXXRecord); + // Add any implicitly-declared members to this class. + AddImplicitlyDeclaredMembersToClass(CXXRecord); + if (!CXXRecord->isDependentType()) { if (!CXXRecord->isInvalidDecl()) { // If we have virtual base classes, we may end up finding multiple // final overriders for a given virtual function. Check for this diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index a2b669c991258..515a2e9690ed1 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -2426,7 +2426,10 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class, TypeSourceInfo *TInfo, SourceLocation EllipsisLoc) { QualType BaseType = TInfo->getType(); - + if (BaseType->containsErrors()) { + // Already emitted a diagnostic when parsing the error type. + return nullptr; + } // C++ [class.union]p1: // A union shall not have base classes. if (Class->isUnion()) { @@ -3042,7 +3045,7 @@ void Sema::CheckOverrideControl(NamedDecl *D) { << MD->getDeclName(); } -void Sema::DiagnoseAbsenceOfOverrideControl(NamedDecl *D) { +void Sema::DiagnoseAbsenceOfOverrideControl(NamedDecl *D, bool Inconsistent) { if (D->isInvalidDecl() || D->hasAttr()) return; CXXMethodDecl *MD = dyn_cast(D); @@ -3058,12 +3061,22 @@ void Sema::DiagnoseAbsenceOfOverrideControl(NamedDecl *D) { return; if (MD->size_overridden_methods() > 0) { - unsigned DiagID = isa(MD) - ? diag::warn_destructor_marked_not_override_overriding - : diag::warn_function_marked_not_override_overriding; - Diag(MD->getLocation(), DiagID) << MD->getDeclName(); - const CXXMethodDecl *OMD = *MD->begin_overridden_methods(); - Diag(OMD->getLocation(), diag::note_overridden_virtual_function); + auto EmitDiag = [&](unsigned DiagInconsistent, unsigned DiagSuggest) { + unsigned DiagID = + Inconsistent && !Diags.isIgnored(DiagInconsistent, MD->getLocation()) + ? DiagInconsistent + : DiagSuggest; + Diag(MD->getLocation(), DiagID) << MD->getDeclName(); + const CXXMethodDecl *OMD = *MD->begin_overridden_methods(); + Diag(OMD->getLocation(), diag::note_overridden_virtual_function); + }; + if (isa(MD)) + EmitDiag( + diag::warn_inconsistent_destructor_marked_not_override_overriding, + diag::warn_suggest_destructor_marked_not_override_overriding); + else + EmitDiag(diag::warn_inconsistent_function_marked_not_override_overriding, + diag::warn_suggest_function_marked_not_override_overriding); } } @@ -6746,13 +6759,10 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) { } } - if (HasMethodWithOverrideControl && - HasOverridingMethodWithoutOverrideControl) { - // At least one method has the 'override' control declared. - // Diagnose all other overridden methods which do not have 'override' - // specified on them. + if (HasOverridingMethodWithoutOverrideControl) { + bool HasInconsistentOverrideControl = HasMethodWithOverrideControl; for (auto *M : Record->methods()) - DiagnoseAbsenceOfOverrideControl(M); + DiagnoseAbsenceOfOverrideControl(M, HasInconsistentOverrideControl); } // Check the defaulted secondary comparisons after any other member functions. @@ -9716,6 +9726,10 @@ void Sema::checkIllFormedTrivialABIStruct(CXXRecordDecl &RD) { // Ill-formed if the copy and move constructors are deleted. auto HasNonDeletedCopyOrMoveConstructor = [&]() { + // If the type is dependent, then assume it might have + // implicit copy or move ctor because we won't know yet at this point. + if (RD.isDependentType()) + return true; if (RD.needsImplicitCopyConstructor() && !RD.defaultedCopyConstructorIsDeleted()) return true; @@ -9839,86 +9853,95 @@ static void findImplicitlyDeclaredEqualityComparisons( /// [special]p1). This routine can only be executed just before the /// definition of the class is complete. void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) { - if (ClassDecl->needsImplicitDefaultConstructor()) { - ++getASTContext().NumImplicitDefaultConstructors; + // Don't add implicit special members to templated classes. + // FIXME: This means unqualified lookups for 'operator=' within a class + // template don't work properly. + if (!ClassDecl->isDependentType()) { + if (ClassDecl->needsImplicitDefaultConstructor()) { + ++getASTContext().NumImplicitDefaultConstructors; - if (ClassDecl->hasInheritedConstructor()) - DeclareImplicitDefaultConstructor(ClassDecl); - } + if (ClassDecl->hasInheritedConstructor()) + DeclareImplicitDefaultConstructor(ClassDecl); + } - if (ClassDecl->needsImplicitCopyConstructor()) { - ++getASTContext().NumImplicitCopyConstructors; + if (ClassDecl->needsImplicitCopyConstructor()) { + ++getASTContext().NumImplicitCopyConstructors; - // If the properties or semantics of the copy constructor couldn't be - // determined while the class was being declared, force a declaration - // of it now. - if (ClassDecl->needsOverloadResolutionForCopyConstructor() || - ClassDecl->hasInheritedConstructor()) - DeclareImplicitCopyConstructor(ClassDecl); - // For the MS ABI we need to know whether the copy ctor is deleted. A - // prerequisite for deleting the implicit copy ctor is that the class has a - // move ctor or move assignment that is either user-declared or whose - // semantics are inherited from a subobject. FIXME: We should provide a more - // direct way for CodeGen to ask whether the constructor was deleted. - else if (Context.getTargetInfo().getCXXABI().isMicrosoft() && - (ClassDecl->hasUserDeclaredMoveConstructor() || - ClassDecl->needsOverloadResolutionForMoveConstructor() || - ClassDecl->hasUserDeclaredMoveAssignment() || - ClassDecl->needsOverloadResolutionForMoveAssignment())) - DeclareImplicitCopyConstructor(ClassDecl); - } + // If the properties or semantics of the copy constructor couldn't be + // determined while the class was being declared, force a declaration + // of it now. + if (ClassDecl->needsOverloadResolutionForCopyConstructor() || + ClassDecl->hasInheritedConstructor()) + DeclareImplicitCopyConstructor(ClassDecl); + // For the MS ABI we need to know whether the copy ctor is deleted. A + // prerequisite for deleting the implicit copy ctor is that the class has + // a move ctor or move assignment that is either user-declared or whose + // semantics are inherited from a subobject. FIXME: We should provide a + // more direct way for CodeGen to ask whether the constructor was deleted. + else if (Context.getTargetInfo().getCXXABI().isMicrosoft() && + (ClassDecl->hasUserDeclaredMoveConstructor() || + ClassDecl->needsOverloadResolutionForMoveConstructor() || + ClassDecl->hasUserDeclaredMoveAssignment() || + ClassDecl->needsOverloadResolutionForMoveAssignment())) + DeclareImplicitCopyConstructor(ClassDecl); + } - if (getLangOpts().CPlusPlus11 && ClassDecl->needsImplicitMoveConstructor()) { - ++getASTContext().NumImplicitMoveConstructors; + if (getLangOpts().CPlusPlus11 && + ClassDecl->needsImplicitMoveConstructor()) { + ++getASTContext().NumImplicitMoveConstructors; - if (ClassDecl->needsOverloadResolutionForMoveConstructor() || - ClassDecl->hasInheritedConstructor()) - DeclareImplicitMoveConstructor(ClassDecl); - } + if (ClassDecl->needsOverloadResolutionForMoveConstructor() || + ClassDecl->hasInheritedConstructor()) + DeclareImplicitMoveConstructor(ClassDecl); + } - if (ClassDecl->needsImplicitCopyAssignment()) { - ++getASTContext().NumImplicitCopyAssignmentOperators; + if (ClassDecl->needsImplicitCopyAssignment()) { + ++getASTContext().NumImplicitCopyAssignmentOperators; - // If we have a dynamic class, then the copy assignment operator may be - // virtual, so we have to declare it immediately. This ensures that, e.g., - // it shows up in the right place in the vtable and that we diagnose - // problems with the implicit exception specification. - if (ClassDecl->isDynamicClass() || - ClassDecl->needsOverloadResolutionForCopyAssignment() || - ClassDecl->hasInheritedAssignment()) - DeclareImplicitCopyAssignment(ClassDecl); - } + // If we have a dynamic class, then the copy assignment operator may be + // virtual, so we have to declare it immediately. This ensures that, e.g., + // it shows up in the right place in the vtable and that we diagnose + // problems with the implicit exception specification. + if (ClassDecl->isDynamicClass() || + ClassDecl->needsOverloadResolutionForCopyAssignment() || + ClassDecl->hasInheritedAssignment()) + DeclareImplicitCopyAssignment(ClassDecl); + } - if (getLangOpts().CPlusPlus11 && ClassDecl->needsImplicitMoveAssignment()) { - ++getASTContext().NumImplicitMoveAssignmentOperators; + if (getLangOpts().CPlusPlus11 && ClassDecl->needsImplicitMoveAssignment()) { + ++getASTContext().NumImplicitMoveAssignmentOperators; - // Likewise for the move assignment operator. - if (ClassDecl->isDynamicClass() || - ClassDecl->needsOverloadResolutionForMoveAssignment() || - ClassDecl->hasInheritedAssignment()) - DeclareImplicitMoveAssignment(ClassDecl); - } + // Likewise for the move assignment operator. + if (ClassDecl->isDynamicClass() || + ClassDecl->needsOverloadResolutionForMoveAssignment() || + ClassDecl->hasInheritedAssignment()) + DeclareImplicitMoveAssignment(ClassDecl); + } - if (ClassDecl->needsImplicitDestructor()) { - ++getASTContext().NumImplicitDestructors; + if (ClassDecl->needsImplicitDestructor()) { + ++getASTContext().NumImplicitDestructors; - // If we have a dynamic class, then the destructor may be virtual, so we - // have to declare the destructor immediately. This ensures that, e.g., it - // shows up in the right place in the vtable and that we diagnose problems - // with the implicit exception specification. - if (ClassDecl->isDynamicClass() || - ClassDecl->needsOverloadResolutionForDestructor()) - DeclareImplicitDestructor(ClassDecl); + // If we have a dynamic class, then the destructor may be virtual, so we + // have to declare the destructor immediately. This ensures that, e.g., it + // shows up in the right place in the vtable and that we diagnose problems + // with the implicit exception specification. + if (ClassDecl->isDynamicClass() || + ClassDecl->needsOverloadResolutionForDestructor()) + DeclareImplicitDestructor(ClassDecl); + } } // C++2a [class.compare.default]p3: // If the member-specification does not explicitly declare any member or // friend named operator==, an == operator function is declared implicitly - // for each defaulted three-way comparison operator function defined in the - // member-specification + // for each defaulted three-way comparison operator function defined in + // the member-specification // FIXME: Consider doing this lazily. - if (getLangOpts().CPlusPlus20) { - llvm::SmallVector DefaultedSpaceships; + // We do this during the initial parse for a class template, not during + // instantiation, so that we can handle unqualified lookups for 'operator==' + // when parsing the template. + if (getLangOpts().CPlusPlus20 && !inTemplateInstantiation()) { + llvm::SmallVector DefaultedSpaceships; findImplicitlyDeclaredEqualityComparisons(Context, ClassDecl, DefaultedSpaceships); for (auto *FD : DefaultedSpaceships) @@ -9926,19 +9949,17 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) { } } -unsigned Sema::ActOnReenterTemplateScope(Scope *S, Decl *D) { +unsigned +Sema::ActOnReenterTemplateScope(Decl *D, + llvm::function_ref EnterScope) { if (!D) return 0; + AdjustDeclIfTemplate(D); - // The order of template parameters is not important here. All names - // get added to the same scope. + // In order to get name lookup right, reenter template scopes in order from + // outermost to innermost. SmallVector ParameterLists; - - if (TemplateDecl *TD = dyn_cast(D)) - D = TD->getTemplatedDecl(); - - if (auto *PSD = dyn_cast(D)) - ParameterLists.push_back(PSD->getTemplateParameters()); + DeclContext *LookupDC = dyn_cast(D); if (DeclaratorDecl *DD = dyn_cast(D)) { for (unsigned i = 0; i < DD->getNumTemplateParameterLists(); ++i) @@ -9947,31 +9968,49 @@ unsigned Sema::ActOnReenterTemplateScope(Scope *S, Decl *D) { if (FunctionDecl *FD = dyn_cast(D)) { if (FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate()) ParameterLists.push_back(FTD->getTemplateParameters()); - } - } + } else if (VarDecl *VD = dyn_cast(D)) { + LookupDC = VD->getDeclContext(); - if (TagDecl *TD = dyn_cast(D)) { + if (VarTemplateDecl *VTD = VD->getDescribedVarTemplate()) + ParameterLists.push_back(VTD->getTemplateParameters()); + else if (auto *PSD = dyn_cast(D)) + ParameterLists.push_back(PSD->getTemplateParameters()); + } + } else if (TagDecl *TD = dyn_cast(D)) { for (unsigned i = 0; i < TD->getNumTemplateParameterLists(); ++i) ParameterLists.push_back(TD->getTemplateParameterList(i)); if (CXXRecordDecl *RD = dyn_cast(TD)) { if (ClassTemplateDecl *CTD = RD->getDescribedClassTemplate()) ParameterLists.push_back(CTD->getTemplateParameters()); + else if (auto *PSD = dyn_cast(D)) + ParameterLists.push_back(PSD->getTemplateParameters()); } } + // FIXME: Alias declarations and concepts. unsigned Count = 0; + Scope *InnermostTemplateScope = nullptr; for (TemplateParameterList *Params : ParameterLists) { - if (Params->size() > 0) - // Ignore explicit specializations; they don't contribute to the template - // depth. - ++Count; + // Ignore explicit specializations; they don't contribute to the template + // depth. + if (Params->size() == 0) + continue; + + InnermostTemplateScope = EnterScope(); for (NamedDecl *Param : *Params) { if (Param->getDeclName()) { - S->AddDecl(Param); + InnermostTemplateScope->AddDecl(Param); IdResolver.AddDecl(Param); } } + ++Count; + } + + // Associate the new template scopes with the corresponding entities. + if (InnermostTemplateScope) { + assert(LookupDC && "no enclosing DeclContext for template lookup"); + EnterTemplatedContext(InnermostTemplateScope, LookupDC); } return Count; @@ -13498,11 +13537,11 @@ buildMemcpyForAssignmentOp(Sema &S, SourceLocation Loc, QualType T, Expr *From = FromB.build(S, Loc); From = UnaryOperator::Create( S.Context, From, UO_AddrOf, S.Context.getPointerType(From->getType()), - VK_RValue, OK_Ordinary, Loc, false, S.CurFPFeatures); + VK_RValue, OK_Ordinary, Loc, false, S.CurFPFeatureOverrides()); Expr *To = ToB.build(S, Loc); - To = UnaryOperator::Create(S.Context, To, UO_AddrOf, - S.Context.getPointerType(To->getType()), VK_RValue, - OK_Ordinary, Loc, false, S.CurFPFeatures); + To = UnaryOperator::Create( + S.Context, To, UO_AddrOf, S.Context.getPointerType(To->getType()), + VK_RValue, OK_Ordinary, Loc, false, S.CurFPFeatureOverrides()); const Type *E = T->getBaseElementTypeUnsafe(); bool NeedsCollectableMemCpy = @@ -13739,14 +13778,14 @@ buildSingleCopyAssignRecursively(Sema &S, SourceLocation Loc, QualType T, Expr *Comparison = BinaryOperator::Create( S.Context, IterationVarRefRVal.build(S, Loc), IntegerLiteral::Create(S.Context, Upper, SizeType, Loc), BO_NE, - S.Context.BoolTy, VK_RValue, OK_Ordinary, Loc, S.CurFPFeatures); + S.Context.BoolTy, VK_RValue, OK_Ordinary, Loc, S.CurFPFeatureOverrides()); // Create the pre-increment of the iteration variable. We can determine // whether the increment will overflow based on the value of the array // bound. Expr *Increment = UnaryOperator::Create( S.Context, IterationVarRef.build(S, Loc), UO_PreInc, SizeType, VK_LValue, - OK_Ordinary, Loc, Upper.isMaxValue(), S.CurFPFeatures); + OK_Ordinary, Loc, Upper.isMaxValue(), S.CurFPFeatureOverrides()); // Construct the loop that copies all elements of this array. return S.ActOnForStmt( @@ -15184,12 +15223,6 @@ CheckOperatorNewDeleteTypes(Sema &SemaRef, const FunctionDecl *FnDecl, QualType ResultType = FnDecl->getType()->castAs()->getReturnType(); - // Check that the result type is not dependent. - if (ResultType->isDependentType()) - return SemaRef.Diag(FnDecl->getLocation(), - diag::err_operator_new_delete_dependent_result_type) - << FnDecl->getDeclName() << ExpectedResultType; - // The operator is valid on any address space for OpenCL. if (SemaRef.getLangOpts().OpenCLCPlusPlus) { if (auto *PtrTy = ResultType->getAs()) { @@ -15198,10 +15231,16 @@ CheckOperatorNewDeleteTypes(Sema &SemaRef, const FunctionDecl *FnDecl, } // Check that the result type is what we expect. - if (SemaRef.Context.getCanonicalType(ResultType) != ExpectedResultType) - return SemaRef.Diag(FnDecl->getLocation(), - diag::err_operator_new_delete_invalid_result_type) - << FnDecl->getDeclName() << ExpectedResultType; + if (SemaRef.Context.getCanonicalType(ResultType) != ExpectedResultType) { + // Reject even if the type is dependent; an operator delete function is + // required to have a non-dependent result type. + return SemaRef.Diag( + FnDecl->getLocation(), + ResultType->isDependentType() + ? diag::err_operator_new_delete_dependent_result_type + : diag::err_operator_new_delete_invalid_result_type) + << FnDecl->getDeclName() << ExpectedResultType; + } // A function template must have at least 2 parameters. if (FnDecl->getDescribedFunctionTemplate() && FnDecl->getNumParams() < 2) @@ -15215,13 +15254,7 @@ CheckOperatorNewDeleteTypes(Sema &SemaRef, const FunctionDecl *FnDecl, diag::err_operator_new_delete_too_few_parameters) << FnDecl->getDeclName(); - // Check the first parameter type is not dependent. QualType FirstParamType = FnDecl->getParamDecl(0)->getType(); - if (FirstParamType->isDependentType()) - return SemaRef.Diag(FnDecl->getLocation(), DependentParamTypeDiag) - << FnDecl->getDeclName() << ExpectedFirstParamType; - - // Check that the first parameter type is what we expect. if (SemaRef.getLangOpts().OpenCLCPlusPlus) { // The operator is valid on any address space for OpenCL. if (auto *PtrTy = @@ -15229,10 +15262,18 @@ CheckOperatorNewDeleteTypes(Sema &SemaRef, const FunctionDecl *FnDecl, FirstParamType = RemoveAddressSpaceFromPtr(SemaRef, PtrTy); } } + + // Check that the first parameter type is what we expect. if (SemaRef.Context.getCanonicalType(FirstParamType).getUnqualifiedType() != - ExpectedFirstParamType) - return SemaRef.Diag(FnDecl->getLocation(), InvalidParamTypeDiag) - << FnDecl->getDeclName() << ExpectedFirstParamType; + ExpectedFirstParamType) { + // The first parameter type is not allowed to be dependent. As a tentative + // DR resolution, we allow a dependent parameter type if it is the right + // type anyway, to allow destroying operator delete in class templates. + return SemaRef.Diag(FnDecl->getLocation(), FirstParamType->isDependentType() + ? DependentParamTypeDiag + : InvalidParamTypeDiag) + << FnDecl->getDeclName() << ExpectedFirstParamType; + } return false; } diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index 504a48b56639f..d7695f9d7d7a6 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -999,10 +999,8 @@ static CanThrowResult canSubStmtsThrow(Sema &Self, const Stmt *S) { return R; } -/// Determine whether the callee of a particular function call can throw. -/// E and D are both optional, but at least one of E and Loc must be specified. -static CanThrowResult canCalleeThrow(Sema &S, const Expr *E, const Decl *D, - SourceLocation Loc = SourceLocation()) { +CanThrowResult Sema::canCalleeThrow(Sema &S, const Expr *E, const Decl *D, + SourceLocation Loc) { // As an extension, we assume that __attribute__((nothrow)) functions don't // throw. if (D && isa(D) && D->hasAttr()) @@ -1048,7 +1046,8 @@ static CanThrowResult canCalleeThrow(Sema &S, const Expr *E, const Decl *D, if (!FT) return CT_Can; - FT = S.ResolveExceptionSpec(Loc.isInvalid() ? E->getBeginLoc() : Loc, FT); + if (Loc.isValid() || (Loc.isInvalid() && E)) + FT = S.ResolveExceptionSpec(Loc.isInvalid() ? E->getBeginLoc() : Loc, FT); if (!FT) return CT_Can; @@ -1069,7 +1068,7 @@ static CanThrowResult canVarDeclThrow(Sema &Self, const VarDecl *VD) { VD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl()) { if (auto *Dtor = RD->getDestructor()) { CT = mergeCanThrow( - CT, canCalleeThrow(Self, nullptr, Dtor, VD->getLocation())); + CT, Sema::canCalleeThrow(Self, nullptr, Dtor, VD->getLocation())); } } } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index ec595ae7d723d..24b9c6777be17 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -964,6 +964,11 @@ ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, ExprResult ExprRes = DefaultArgumentPromotion(E); if (ExprRes.isInvalid()) return ExprError(); + + // Copy blocks to the heap. + if (ExprRes.get()->getType()->isBlockPointerType()) + maybeExtendBlockObject(ExprRes); + E = ExprRes.get(); // Diagnostics regarding non-POD argument types are @@ -3629,7 +3634,9 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { if (Invalid) return ExprError(); - NumericLiteralParser Literal(TokSpelling, Tok.getLocation(), PP); + NumericLiteralParser Literal(TokSpelling, Tok.getLocation(), + PP.getSourceManager(), PP.getLangOpts(), + PP.getTargetInfo(), PP.getDiagnostics()); if (Literal.hadError) return ExprError(); @@ -4555,7 +4562,8 @@ Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, SourceLocation lbLoc, if (base && !base->getType().isNull() && base->getType()->isSpecificPlaceholderType(BuiltinType::OMPArraySection)) return ActOnOMPArraySectionExpr(base, lbLoc, idx, SourceLocation(), - /*Length=*/nullptr, rbLoc); + SourceLocation(), /*Length*/ nullptr, + /*Stride=*/nullptr, rbLoc); // Since this might be a postfix expression, get rid of ParenListExprs. if (isa(base)) { @@ -4805,7 +4813,9 @@ void Sema::CheckSubscriptAccessOfNoDeref(const ArraySubscriptExpr *E) { ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, Expr *LowerBound, - SourceLocation ColonLoc, Expr *Length, + SourceLocation ColonLocFirst, + SourceLocation ColonLocSecond, + Expr *Length, Expr *Stride, SourceLocation RBLoc) { if (Base->getType()->isPlaceholderType() && !Base->getType()->isSpecificPlaceholderType( @@ -4833,15 +4843,25 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, return ExprError(); Length = Result.get(); } + if (Stride && Stride->getType()->isNonOverloadPlaceholderType()) { + ExprResult Result = CheckPlaceholderExpr(Stride); + if (Result.isInvalid()) + return ExprError(); + Result = DefaultLvalueConversion(Result.get()); + if (Result.isInvalid()) + return ExprError(); + Stride = Result.get(); + } // Build an unanalyzed expression if either operand is type-dependent. if (Base->isTypeDependent() || (LowerBound && (LowerBound->isTypeDependent() || LowerBound->isValueDependent())) || - (Length && (Length->isTypeDependent() || Length->isValueDependent()))) { - return new (Context) - OMPArraySectionExpr(Base, LowerBound, Length, Context.DependentTy, - VK_LValue, OK_Ordinary, ColonLoc, RBLoc); + (Length && (Length->isTypeDependent() || Length->isValueDependent())) || + (Stride && (Stride->isTypeDependent() || Stride->isValueDependent()))) { + return new (Context) OMPArraySectionExpr( + Base, LowerBound, Length, Stride, Context.DependentTy, VK_LValue, + OK_Ordinary, ColonLocFirst, ColonLocSecond, RBLoc); } // Perform default conversions. @@ -4885,6 +4905,20 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, Diag(Length->getExprLoc(), diag::warn_omp_section_is_char) << 1 << Length->getSourceRange(); } + if (Stride) { + ExprResult Res = + PerformOpenMPImplicitIntegerConversion(Stride->getExprLoc(), Stride); + if (Res.isInvalid()) + return ExprError(Diag(Stride->getExprLoc(), + diag::err_omp_typecheck_section_not_integer) + << 1 << Stride->getSourceRange()); + Stride = Res.get(); + + if (Stride->getType()->isSpecificBuiltinType(BuiltinType::Char_S) || + Stride->getType()->isSpecificBuiltinType(BuiltinType::Char_U)) + Diag(Stride->getExprLoc(), diag::warn_omp_section_is_char) + << 1 << Stride->getSourceRange(); + } // C99 6.5.2.1p1: "shall have type "pointer to *object* type". Similarly, // C++ [expr.sub]p1: The type "T" shall be a completely-defined object @@ -4903,7 +4937,7 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, if (LowerBound && !OriginalTy->isAnyPointerType()) { Expr::EvalResult Result; if (LowerBound->EvaluateAsInt(Result, Context)) { - // OpenMP 4.5, [2.4 Array Sections] + // OpenMP 5.0, [2.1.5 Array Sections] // The array section must be a subset of the original array. llvm::APSInt LowerBoundValue = Result.Val.getInt(); if (LowerBoundValue.isNegative()) { @@ -4917,7 +4951,7 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, if (Length) { Expr::EvalResult Result; if (Length->EvaluateAsInt(Result, Context)) { - // OpenMP 4.5, [2.4 Array Sections] + // OpenMP 5.0, [2.1.5 Array Sections] // The length must evaluate to non-negative integers. llvm::APSInt LengthValue = Result.Val.getInt(); if (LengthValue.isNegative()) { @@ -4927,17 +4961,32 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, return ExprError(); } } - } else if (ColonLoc.isValid() && + } else if (ColonLocFirst.isValid() && (OriginalTy.isNull() || (!OriginalTy->isConstantArrayType() && !OriginalTy->isVariableArrayType()))) { - // OpenMP 4.5, [2.4 Array Sections] + // OpenMP 5.0, [2.1.5 Array Sections] // When the size of the array dimension is not known, the length must be // specified explicitly. - Diag(ColonLoc, diag::err_omp_section_length_undefined) + Diag(ColonLocFirst, diag::err_omp_section_length_undefined) << (!OriginalTy.isNull() && OriginalTy->isArrayType()); return ExprError(); } + if (Stride) { + Expr::EvalResult Result; + if (Stride->EvaluateAsInt(Result, Context)) { + // OpenMP 5.0, [2.1.5 Array Sections] + // The stride must evaluate to a positive integer. + llvm::APSInt StrideValue = Result.Val.getInt(); + if (!StrideValue.isStrictlyPositive()) { + Diag(Stride->getExprLoc(), diag::err_omp_section_stride_non_positive) + << StrideValue.toString(/*Radix=*/10, /*Signed=*/true) + << Stride->getSourceRange(); + return ExprError(); + } + } + } + if (!Base->getType()->isSpecificPlaceholderType( BuiltinType::OMPArraySection)) { ExprResult Result = DefaultFunctionArrayLvalueConversion(Base); @@ -4945,9 +4994,9 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, return ExprError(); Base = Result.get(); } - return new (Context) - OMPArraySectionExpr(Base, LowerBound, Length, Context.OMPArraySectionTy, - VK_LValue, OK_Ordinary, ColonLoc, RBLoc); + return new (Context) OMPArraySectionExpr( + Base, LowerBound, Length, Stride, Context.OMPArraySectionTy, VK_LValue, + OK_Ordinary, ColonLocFirst, ColonLocSecond, RBLoc); } ExprResult Sema::ActOnOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc, @@ -5526,83 +5575,9 @@ bool Sema::CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD, return true; } - if (Param->hasUninstantiatedDefaultArg()) { - Expr *UninstExpr = Param->getUninstantiatedDefaultArg(); - - EnterExpressionEvaluationContext EvalContext( - *this, ExpressionEvaluationContext::PotentiallyEvaluated, Param); - - // Instantiate the expression. - // - // FIXME: Pass in a correct Pattern argument, otherwise - // getTemplateInstantiationArgs uses the lexical context of FD, e.g. - // - // template - // struct A { - // static int FooImpl(); - // - // template - // // bug: default argument A::FooImpl() is evaluated with 2-level - // // template argument list [[T], [Tp]], should be [[Tp]]. - // friend A Foo(int a); - // }; - // - // template - // A Foo(int a = A::FooImpl()); - MultiLevelTemplateArgumentList MutiLevelArgList - = getTemplateInstantiationArgs(FD, nullptr, /*RelativeToPrimary=*/true); - - InstantiatingTemplate Inst(*this, CallLoc, Param, - MutiLevelArgList.getInnermost()); - if (Inst.isInvalid()) - return true; - if (Inst.isAlreadyInstantiating()) { - Diag(Param->getBeginLoc(), diag::err_recursive_default_argument) << FD; - Param->setInvalidDecl(); - return true; - } - - ExprResult Result; - { - // C++ [dcl.fct.default]p5: - // The names in the [default argument] expression are bound, and - // the semantic constraints are checked, at the point where the - // default argument expression appears. - ContextRAII SavedContext(*this, FD); - LocalInstantiationScope Local(*this); - runWithSufficientStackSpace(CallLoc, [&] { - Result = SubstInitializer(UninstExpr, MutiLevelArgList, - /*DirectInit*/false); - }); - } - if (Result.isInvalid()) - return true; - - // Check the expression as an initializer for the parameter. - InitializedEntity Entity - = InitializedEntity::InitializeParameter(Context, Param); - InitializationKind Kind = InitializationKind::CreateCopy( - Param->getLocation(), - /*FIXME:EqualLoc*/ UninstExpr->getBeginLoc()); - Expr *ResultE = Result.getAs(); - - InitializationSequence InitSeq(*this, Entity, Kind, ResultE); - Result = InitSeq.Perform(*this, Entity, Kind, ResultE); - if (Result.isInvalid()) - return true; - - Result = - ActOnFinishFullExpr(Result.getAs(), Param->getOuterLocStart(), - /*DiscardedValue*/ false); - if (Result.isInvalid()) - return true; - - // Remember the instantiated default argument. - Param->setDefaultArg(Result.getAs()); - if (ASTMutationListener *L = getASTMutationListener()) { - L->DefaultArgumentInstantiated(Param); - } - } + if (Param->hasUninstantiatedDefaultArg() && + InstantiateDefaultArgument(CallLoc, FD, Param)) + return true; assert(Param->hasInit() && "default argument but no initializer?"); @@ -5941,9 +5916,6 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, FunctionDecl *FDecl, for (Expr *A : Args.slice(ArgIx)) { ExprResult Arg = DefaultVariadicArgumentPromotion(A, CallType, FDecl); Invalid |= Arg.isInvalid(); - // Copy blocks to the heap. - if (A->getType()->isBlockPointerType()) - maybeExtendBlockObject(Arg); AllArgs.push_back(Arg.get()); } } @@ -13628,7 +13600,7 @@ static ExprResult convertHalfVecBinOp(Sema &S, ExprResult LHS, ExprResult RHS, BinaryOperatorKind Opc, QualType ResultTy, ExprValueKind VK, ExprObjectKind OK, bool IsCompAssign, SourceLocation OpLoc, - FPOptions FPFeatures) { + FPOptionsOverride FPFeatures) { auto &Context = S.getASTContext(); assert((isVector(ResultTy, Context.HalfTy) || isVector(ResultTy, Context.ShortTy)) && @@ -13951,9 +13923,9 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, if (CompResultTy.isNull()) { if (ConvertHalfVec) return convertHalfVecBinOp(*this, LHS, RHS, Opc, ResultTy, VK, OK, false, - OpLoc, CurFPFeatures); + OpLoc, CurFPFeatureOverrides()); return BinaryOperator::Create(Context, LHS.get(), RHS.get(), Opc, ResultTy, - VK, OK, OpLoc, CurFPFeatures); + VK, OK, OpLoc, CurFPFeatureOverrides()); } // Handle compound assignments. @@ -13971,11 +13943,11 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, if (ConvertHalfVec) return convertHalfVecBinOp(*this, LHS, RHS, Opc, ResultTy, VK, OK, true, - OpLoc, CurFPFeatures); + OpLoc, CurFPFeatureOverrides()); - return CompoundAssignOperator::Create(Context, LHS.get(), RHS.get(), Opc, - ResultTy, VK, OK, OpLoc, CurFPFeatures, - CompLHSTy, CompResultTy); + return CompoundAssignOperator::Create( + Context, LHS.get(), RHS.get(), Opc, ResultTy, VK, OK, OpLoc, + CurFPFeatureOverrides(), CompLHSTy, CompResultTy); } /// DiagnoseBitwisePrecedence - Emit a warning when bitwise and comparison @@ -14563,8 +14535,9 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, if (Opc != UO_AddrOf && Opc != UO_Deref) CheckArrayAccess(Input.get()); - auto *UO = UnaryOperator::Create(Context, Input.get(), Opc, resultType, VK, - OK, OpLoc, CanOverflow, CurFPFeatures); + auto *UO = + UnaryOperator::Create(Context, Input.get(), Opc, resultType, VK, OK, + OpLoc, CanOverflow, CurFPFeatureOverrides()); if (Opc == UO_Deref && UO->getType()->hasAttr(attr::NoDeref) && !isa(UO->getType().getDesugaredType(Context))) diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 0a0bb3952cd89..d885920b6c14e 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -4203,8 +4203,8 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, break; case ICK_Compatible_Conversion: - From = ImpCastExprToType(From, ToType, CK_NoOp, - VK_RValue, /*BasePath=*/nullptr, CCK).get(); + From = ImpCastExprToType(From, ToType, CK_NoOp, From->getValueKind(), + /*BasePath=*/nullptr, CCK).get(); break; case ICK_Writeback_Conversion: @@ -4441,11 +4441,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, break; case ICK_Qualification: { - // The qualification keeps the category of the inner expression, unless the - // target type isn't a reference. - ExprValueKind VK = - ToType->isReferenceType() ? From->getValueKind() : VK_RValue; - + ExprValueKind VK = From->getValueKind(); CastKind CK = CK_NoOp; if (ToType->isReferenceType() && diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 474aba6a0d446..228a1ec3ba1f9 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -1228,33 +1228,66 @@ static void DiagnoseMismatchedSelectors(Sema &S, SourceLocation AtLoc, } } -static void HelperToDiagnoseDirectSelectorsExpr(Sema &S, SourceLocation AtLoc, - Selector Sel, - ObjCMethodList &MethList, - bool &onlyDirect) { +static ObjCMethodDecl *LookupDirectMethodInMethodList(Sema &S, Selector Sel, + ObjCMethodList &MethList, + bool &onlyDirect, + bool &anyDirect) { + (void)Sel; ObjCMethodList *M = &MethList; - for (M = M->getNext(); M; M = M->getNext()) { + ObjCMethodDecl *DirectMethod = nullptr; + for (; M; M = M->getNext()) { ObjCMethodDecl *Method = M->getMethod(); - if (Method->getSelector() != Sel) + if (!Method) continue; - if (!Method->isDirectMethod()) + assert(Method->getSelector() == Sel && "Method with wrong selector in method list"); + if (Method->isDirectMethod()) { + anyDirect = true; + DirectMethod = Method; + } else onlyDirect = false; } + + return DirectMethod; } -static void DiagnoseDirectSelectorsExpr(Sema &S, SourceLocation AtLoc, - Selector Sel, bool &onlyDirect) { - for (Sema::GlobalMethodPool::iterator b = S.MethodPool.begin(), - e = S.MethodPool.end(); b != e; b++) { - // first, instance methods - ObjCMethodList &InstMethList = b->second.first; - HelperToDiagnoseDirectSelectorsExpr(S, AtLoc, Sel, InstMethList, - onlyDirect); +// Search the global pool for (potentially) direct methods matching the given +// selector. If a non-direct method is found, set \param onlyDirect to false. If +// a direct method is found, set \param anyDirect to true. Returns a direct +// method, if any. +static ObjCMethodDecl *LookupDirectMethodInGlobalPool(Sema &S, Selector Sel, + bool &onlyDirect, + bool &anyDirect) { + auto Iter = S.MethodPool.find(Sel); + if (Iter == S.MethodPool.end()) + return nullptr; - // second, class methods - ObjCMethodList &ClsMethList = b->second.second; - HelperToDiagnoseDirectSelectorsExpr(S, AtLoc, Sel, ClsMethList, onlyDirect); - } + ObjCMethodDecl *DirectInstance = LookupDirectMethodInMethodList( + S, Sel, Iter->second.first, onlyDirect, anyDirect); + ObjCMethodDecl *DirectClass = LookupDirectMethodInMethodList( + S, Sel, Iter->second.second, onlyDirect, anyDirect); + + return DirectInstance ? DirectInstance : DirectClass; +} + +static ObjCMethodDecl *findMethodInCurrentClass(Sema &S, Selector Sel) { + auto *CurMD = S.getCurMethodDecl(); + if (!CurMD) + return nullptr; + ObjCInterfaceDecl *IFace = CurMD->getClassInterface(); + + // The language enforce that only one direct method is present in a given + // class, so we just need to find one method in the current class to know + // whether Sel is potentially direct in this context. + if (ObjCMethodDecl *MD = IFace->lookupMethod(Sel, /*isInstance=*/true)) + return MD; + if (ObjCMethodDecl *MD = IFace->lookupPrivateMethod(Sel, /*isInstance=*/true)) + return MD; + if (ObjCMethodDecl *MD = IFace->lookupMethod(Sel, /*isInstance=*/false)) + return MD; + if (ObjCMethodDecl *MD = IFace->lookupPrivateMethod(Sel, /*isInstance=*/false)) + return MD; + + return nullptr; } ExprResult Sema::ParseObjCSelectorExpression(Selector Sel, @@ -1280,15 +1313,38 @@ ExprResult Sema::ParseObjCSelectorExpression(Selector Sel, } else Diag(SelLoc, diag::warn_undeclared_selector) << Sel; } else { - bool onlyDirect = Method->isDirectMethod(); - DiagnoseDirectSelectorsExpr(*this, AtLoc, Sel, onlyDirect); DiagnoseMismatchedSelectors(*this, AtLoc, Method, LParenLoc, RParenLoc, WarnMultipleSelectors); + + bool onlyDirect = true; + bool anyDirect = false; + ObjCMethodDecl *GlobalDirectMethod = + LookupDirectMethodInGlobalPool(*this, Sel, onlyDirect, anyDirect); + if (onlyDirect) { Diag(AtLoc, diag::err_direct_selector_expression) << Method->getSelector(); Diag(Method->getLocation(), diag::note_direct_method_declared_at) << Method->getDeclName(); + } else if (anyDirect) { + // If we saw any direct methods, see if we see a direct member of the + // current class. If so, the @selector will likely be used to refer to + // this direct method. + ObjCMethodDecl *LikelyTargetMethod = findMethodInCurrentClass(*this, Sel); + if (LikelyTargetMethod && LikelyTargetMethod->isDirectMethod()) { + Diag(AtLoc, diag::warn_potentially_direct_selector_expression) << Sel; + Diag(LikelyTargetMethod->getLocation(), + diag::note_direct_method_declared_at) + << LikelyTargetMethod->getDeclName(); + } else if (!LikelyTargetMethod) { + // Otherwise, emit the "strict" variant of this diagnostic, unless + // LikelyTargetMethod is non-direct. + Diag(AtLoc, diag::warn_strict_potentially_direct_selector_expression) + << Sel; + Diag(GlobalDirectMethod->getLocation(), + diag::note_direct_method_declared_at) + << GlobalDirectMethod->getDeclName(); + } } } @@ -4487,7 +4543,8 @@ Expr *Sema::stripARCUnbridgedCast(Expr *e) { Expr *sub = stripARCUnbridgedCast(uo->getSubExpr()); return UnaryOperator::Create(Context, sub, UO_Extension, sub->getType(), sub->getValueKind(), sub->getObjectKind(), - uo->getOperatorLoc(), false, CurFPFeatures); + uo->getOperatorLoc(), false, + CurFPFeatureOverrides()); } else if (GenericSelectionExpr *gse = dyn_cast(e)) { assert(!gse->isResultDependent()); diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index d46e7f86d6b33..eb07de65d2668 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -4693,6 +4693,9 @@ static bool isNonReferenceableGLValue(Expr *E) { } /// Reference initialization without resolving overloaded functions. +/// +/// We also can get here in C if we call a builtin which is declared as +/// a function with a parameter of reference type (such as __builtin_va_end()). static void TryReferenceInitializationCore(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, @@ -4769,15 +4772,20 @@ static void TryReferenceInitializationCore(Sema &S, // an rvalue. DR1287 removed the "implicitly" here. if (RefRelationship == Sema::Ref_Incompatible && T2->isRecordType() && (isLValueRef || InitCategory.isRValue())) { - ConvOvlResult = TryRefInitWithConversionFunction( - S, Entity, Kind, Initializer, /*AllowRValues*/ isRValueRef, - /*IsLValueRef*/ isLValueRef, Sequence); - if (ConvOvlResult == OR_Success) - return; - if (ConvOvlResult != OR_No_Viable_Function) - Sequence.SetOverloadFailure( - InitializationSequence::FK_ReferenceInitOverloadFailed, - ConvOvlResult); + if (S.getLangOpts().CPlusPlus) { + // Try conversion functions only for C++. + ConvOvlResult = TryRefInitWithConversionFunction( + S, Entity, Kind, Initializer, /*AllowRValues*/ isRValueRef, + /*IsLValueRef*/ isLValueRef, Sequence); + if (ConvOvlResult == OR_Success) + return; + if (ConvOvlResult != OR_No_Viable_Function) + Sequence.SetOverloadFailure( + InitializationSequence::FK_ReferenceInitOverloadFailed, + ConvOvlResult); + } else { + ConvOvlResult = OR_No_Viable_Function; + } } } diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index e751a73957d0d..657ed13f207ad 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -990,8 +990,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, // Attributes on the lambda apply to the method. ProcessDeclAttributes(CurScope, Method, ParamInfo); - // CUDA lambdas get implicit attributes based on the scope in which they're - // declared. + // CUDA lambdas get implicit host and device attributes. if (getLangOpts().CUDA) CUDASetLambdaAttrs(Method); @@ -1780,6 +1779,9 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc, BuildCaptureField(Class, From); Captures.push_back(Capture); CaptureInits.push_back(Init.get()); + + if (LangOpts.CUDA) + CUDACheckLambdaCapture(CallOperator, From); } Class->setCaptures(Captures); diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 06a4dfa0a636f..5757eaf3fac08 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -1153,73 +1153,14 @@ static bool isNamespaceOrTranslationUnitScope(Scope *S) { return false; } -// Find the next outer declaration context from this scope. This -// routine actually returns the semantic outer context, which may -// differ from the lexical context (encoded directly in the Scope -// stack) when we are parsing a member of a class template. In this -// case, the second element of the pair will be true, to indicate that -// name lookup should continue searching in this semantic context when -// it leaves the current template parameter scope. -static std::pair findOuterContext(Scope *S) { - DeclContext *DC = S->getEntity(); - DeclContext *Lexical = nullptr; - for (Scope *OuterS = S->getParent(); OuterS; - OuterS = OuterS->getParent()) { - if (OuterS->getEntity()) { - Lexical = OuterS->getEntity(); - break; - } - } - - // C++ [temp.local]p8: - // In the definition of a member of a class template that appears - // outside of the namespace containing the class template - // definition, the name of a template-parameter hides the name of - // a member of this namespace. - // - // Example: - // - // namespace N { - // class C { }; - // - // template class B { - // void f(T); - // }; - // } - // - // template void N::B::f(C) { - // C b; // C is the template parameter, not N::C - // } - // - // In this example, the lexical context we return is the - // TranslationUnit, while the semantic context is the namespace N. - if (!Lexical || !DC || !S->getParent() || - !S->getParent()->isTemplateParamScope()) - return std::make_pair(Lexical, false); - - // Find the outermost template parameter scope. - // For the example, this is the scope for the template parameters of - // template. - Scope *OutermostTemplateScope = S->getParent(); - while (OutermostTemplateScope->getParent() && - OutermostTemplateScope->getParent()->isTemplateParamScope()) - OutermostTemplateScope = OutermostTemplateScope->getParent(); - - // Find the namespace context in which the original scope occurs. In - // the example, this is namespace N. - DeclContext *Semantic = DC; - while (!Semantic->isFileContext()) - Semantic = Semantic->getParent(); - - // Find the declaration context just outside of the template - // parameter scope. This is the context in which the template is - // being lexically declaration (a namespace context). In the - // example, this is the global scope. - if (Lexical->isFileContext() && !Lexical->Equals(Semantic) && - Lexical->Encloses(Semantic)) - return std::make_pair(Semantic, true); - - return std::make_pair(Lexical, false); +/// Find the outer declaration context from this scope. This indicates the +/// context that we should search up to (exclusive) before considering the +/// parent of the specified scope. +static DeclContext *findOuterContext(Scope *S) { + for (Scope *OuterS = S->getParent(); OuterS; OuterS = OuterS->getParent()) + if (DeclContext *DC = OuterS->getLookupEntity()) + return DC; + return nullptr; } namespace { @@ -1286,13 +1227,11 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) { UnqualUsingDirectiveSet UDirs(*this); bool VisitedUsingDirectives = false; bool LeftStartingScope = false; - DeclContext *OutsideOfTemplateParamDC = nullptr; // When performing a scope lookup, we want to find local extern decls. FindLocalExternScope FindLocals(R); for (; S && !isNamespaceOrTranslationUnitScope(S); S = S->getParent()) { - DeclContext *Ctx = S->getEntity(); bool SearchNamespaceScope = true; // Check whether the IdResolver has anything in this scope. for (; I != IEnd && S->isDeclScope(*I); ++I) { @@ -1324,7 +1263,8 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) { if (!SearchNamespaceScope) { R.resolveKind(); if (S->isClassScope()) - if (CXXRecordDecl *Record = dyn_cast_or_null(Ctx)) + if (CXXRecordDecl *Record = + dyn_cast_or_null(S->getEntity())) R.setNamingClass(Record); return true; } @@ -1338,24 +1278,8 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) { return false; } - if (!Ctx && S->isTemplateParamScope() && OutsideOfTemplateParamDC && - S->getParent() && !S->getParent()->isTemplateParamScope()) { - // We've just searched the last template parameter scope and - // found nothing, so look into the contexts between the - // lexical and semantic declaration contexts returned by - // findOuterContext(). This implements the name lookup behavior - // of C++ [temp.local]p8. - Ctx = OutsideOfTemplateParamDC; - OutsideOfTemplateParamDC = nullptr; - } - - if (Ctx) { - DeclContext *OuterCtx; - bool SearchAfterTemplateScope; - std::tie(OuterCtx, SearchAfterTemplateScope) = findOuterContext(S); - if (SearchAfterTemplateScope) - OutsideOfTemplateParamDC = OuterCtx; - + if (DeclContext *Ctx = S->getLookupEntity()) { + DeclContext *OuterCtx = findOuterContext(S); for (; Ctx && !Ctx->Equals(OuterCtx); Ctx = Ctx->getLookupParent()) { // We do not directly look into transparent contexts, since // those entities will be found in the nearest enclosing @@ -1480,25 +1404,9 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) { return true; } - DeclContext *Ctx = S->getEntity(); - if (!Ctx && S->isTemplateParamScope() && OutsideOfTemplateParamDC && - S->getParent() && !S->getParent()->isTemplateParamScope()) { - // We've just searched the last template parameter scope and - // found nothing, so look into the contexts between the - // lexical and semantic declaration contexts returned by - // findOuterContext(). This implements the name lookup behavior - // of C++ [temp.local]p8. - Ctx = OutsideOfTemplateParamDC; - OutsideOfTemplateParamDC = nullptr; - } - + DeclContext *Ctx = S->getLookupEntity(); if (Ctx) { - DeclContext *OuterCtx; - bool SearchAfterTemplateScope; - std::tie(OuterCtx, SearchAfterTemplateScope) = findOuterContext(S); - if (SearchAfterTemplateScope) - OutsideOfTemplateParamDC = OuterCtx; - + DeclContext *OuterCtx = findOuterContext(S); for (; Ctx && !Ctx->Equals(OuterCtx); Ctx = Ctx->getLookupParent()) { // We do not directly look into transparent contexts, since // those entities will be found in the nearest enclosing @@ -3995,14 +3903,12 @@ class LookupVisibleHelper { } } - // FIXME: C++ [temp.local]p8 - DeclContext *Entity = nullptr; - if (S->getEntity()) { + DeclContext *Entity = S->getLookupEntity(); + if (Entity) { // Look into this scope's declaration context, along with any of its // parent lookup contexts (e.g., enclosing classes), up to the point // where we hit the context stored in the next outer scope. - Entity = S->getEntity(); - DeclContext *OuterCtx = findOuterContext(S).first; // FIXME + DeclContext *OuterCtx = findOuterContext(S); for (DeclContext *Ctx = Entity; Ctx && !Ctx->Equals(OuterCtx); Ctx = Ctx->getLookupParent()) { diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index e005072da0aff..920463da40277 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -53,9 +53,10 @@ static const Expr *checkMapClauseExpressionBase( namespace { /// Default data sharing attributes, which can be applied to directive. enum DefaultDataSharingAttributes { - DSA_unspecified = 0, /// Data sharing attribute not specified. - DSA_none = 1 << 0, /// Default data sharing attribute 'none'. - DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. + DSA_unspecified = 0, /// Data sharing attribute not specified. + DSA_none = 1 << 0, /// Default data sharing attribute 'none'. + DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. + DSA_firstprivate = 1 << 2, /// Default data sharing attribute 'firstprivate'. }; /// Stack for tracking declarations used in OpenMP directives and @@ -684,6 +685,11 @@ class DSAStackTy { getTopOfStack().DefaultAttr = DSA_shared; getTopOfStack().DefaultAttrLoc = Loc; } + /// Set default data sharing attribute to firstprivate. + void setDefaultDSAFirstPrivate(SourceLocation Loc) { + getTopOfStack().DefaultAttr = DSA_firstprivate; + getTopOfStack().DefaultAttrLoc = Loc; + } /// Set default data mapping attribute to Modifier:Kind void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, @@ -1183,6 +1189,15 @@ DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, return DVar; case DSA_none: return DVar; + case DSA_firstprivate: + if (VD->getStorageDuration() == SD_Static && + VD->getDeclContext()->isFileContext()) { + DVar.CKind = OMPC_unknown; + } else { + DVar.CKind = OMPC_firstprivate; + } + DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; + return DVar; case DSA_unspecified: // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced // in a Construct, implicitly determined, p.2] @@ -2058,7 +2073,13 @@ bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, // If the variable is artificial and must be captured by value - try to // capture by value. !(isa(D) && !D->hasAttr() && - !cast(D)->getInit()->isGLValue()); + !cast(D)->getInit()->isGLValue()) && + // If the variable is implicitly firstprivate and scalar - capture by + // copy + !(DSAStack->getDefaultDSA() == DSA_firstprivate && + !DSAStack->hasExplicitDSA( + D, [](OpenMPClauseKind K) { return K != OMPC_unknown; }, Level) && + !DSAStack->isLoopControlVariable(D, Level).first); } // When passing data by copy, we need to make sure it fits the uintptr size @@ -2185,10 +2206,13 @@ VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, DSAStack->isClauseParsingMode()); // Global shared must not be captured. if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown && - (DSAStack->getDefaultDSA() != DSA_none || DVarTop.CKind == OMPC_shared)) + ((DSAStack->getDefaultDSA() != DSA_none && + DSAStack->getDefaultDSA() != DSA_firstprivate) || + DVarTop.CKind == OMPC_shared)) return nullptr; if (DVarPrivate.CKind != OMPC_unknown || - (VD && DSAStack->getDefaultDSA() == DSA_none)) + (VD && (DSAStack->getDefaultDSA() == DSA_none || + DSAStack->getDefaultDSA() == DSA_firstprivate))) return VD ? VD : cast(DVarPrivate.PrivateCopy->getDecl()); } return nullptr; @@ -3333,10 +3357,19 @@ class DSAAttrChecker final : public StmtVisitor { // in the construct, and does not have a predetermined data-sharing // attribute, must have its data-sharing attribute explicitly determined // by being listed in a data-sharing attribute clause. - if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && + if (DVar.CKind == OMPC_unknown && + (Stack->getDefaultDSA() == DSA_none || + Stack->getDefaultDSA() == DSA_firstprivate) && isImplicitOrExplicitTaskingRegion(DKind) && VarsWithInheritedDSA.count(VD) == 0) { - VarsWithInheritedDSA[VD] = E; + bool InheritedDSA = Stack->getDefaultDSA() == DSA_none; + if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) { + DSAStackTy::DSAVarData DVar = + Stack->getImplicitDSA(VD, /*FromParent=*/false); + InheritedDSA = DVar.CKind == OMPC_unknown; + } + if (InheritedDSA) + VarsWithInheritedDSA[VD] = E; return; } @@ -3438,7 +3471,9 @@ class DSAAttrChecker final : public StmtVisitor { // Define implicit data-sharing attributes for task. DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); - if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && + if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) || + (Stack->getDefaultDSA() == DSA_firstprivate && + DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) && !Stack->isLoopControlVariable(VD).first) { ImplicitFirstprivate.push_back(E); return; @@ -4050,6 +4085,7 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { case OMPD_end_declare_variant: llvm_unreachable("OpenMP Directive is not allowed"); case OMPD_unknown: + default: llvm_unreachable("Unknown OpenMP directive"); } } @@ -4644,7 +4680,7 @@ static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, bool ErrorFound = false; unsigned NamedModifiersNumber = 0; llvm::IndexedMap FoundNameModifiers; - FoundNameModifiers.resize(unsigned(OMPD_unknown) + 1); + FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1); SmallVector NameModifierLoc; for (const OMPClause *C : Clauses) { if (const auto *IC = dyn_cast_or_null(C)) { @@ -5335,13 +5371,16 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( case OMPD_end_declare_variant: llvm_unreachable("OpenMP Directive is not allowed"); case OMPD_unknown: + default: llvm_unreachable("Unknown OpenMP directive"); } ErrorFound = Res.isInvalid() || ErrorFound; - // Check variables in the clauses if default(none) was specified. - if (DSAStack->getDefaultDSA() == DSA_none) { + // Check variables in the clauses if default(none) or + // default(firstprivate) was specified. + if (DSAStack->getDefaultDSA() == DSA_none || + DSAStack->getDefaultDSA() == DSA_firstprivate) { DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); for (OMPClause *C : Clauses) { switch (C->getClauseKind()) { @@ -5437,6 +5476,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( case OMPC_atomic_default_mem_order: case OMPC_device_type: case OMPC_match: + default: llvm_unreachable("Unexpected clause"); } for (Stmt *CC : C->children()) { @@ -5451,7 +5491,8 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( if (P.getFirst()->isImplicit() || isa(P.getFirst())) continue; ErrorFound = true; - if (DSAStack->getDefaultDSA() == DSA_none) { + if (DSAStack->getDefaultDSA() == DSA_none || + DSAStack->getDefaultDSA() == DSA_firstprivate) { Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) << P.first << P.second->getSourceRange(); Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); @@ -11683,6 +11724,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, case OMPC_exclusive: case OMPC_uses_allocators: case OMPC_affinity: + default: llvm_unreachable("Clause is not allowed."); } return Res; @@ -11837,6 +11879,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_requires: llvm_unreachable("Unexpected OpenMP directive with if-clause"); case OMPD_unknown: + default: llvm_unreachable("Unknown OpenMP directive"); } break; @@ -11915,6 +11958,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_requires: llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); case OMPD_unknown: + default: llvm_unreachable("Unknown OpenMP directive"); } break; @@ -11991,6 +12035,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_requires: llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); case OMPD_unknown: + default: llvm_unreachable("Unknown OpenMP directive"); } break; @@ -12067,6 +12112,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_requires: llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); case OMPD_unknown: + default: llvm_unreachable("Unknown OpenMP directive"); } break; @@ -12143,6 +12189,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_requires: llvm_unreachable("Unexpected OpenMP directive with schedule clause"); case OMPD_unknown: + default: llvm_unreachable("Unknown OpenMP directive"); } break; @@ -12219,6 +12266,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_requires: llvm_unreachable("Unexpected OpenMP directive with schedule clause"); case OMPD_unknown: + default: llvm_unreachable("Unknown OpenMP directive"); } break; @@ -12295,6 +12343,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_requires: llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); case OMPD_unknown: + default: llvm_unreachable("Unknown OpenMP directive"); } break; @@ -12373,6 +12422,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPD_requires: llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); case OMPD_unknown: + default: llvm_unreachable("Unknown OpenMP directive"); } break; @@ -12439,6 +12489,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPC_exclusive: case OMPC_uses_allocators: case OMPC_affinity: + default: llvm_unreachable("Unexpected OpenMP clause."); } return CaptureRegion; @@ -12880,6 +12931,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause( case OMPC_exclusive: case OMPC_uses_allocators: case OMPC_affinity: + default: llvm_unreachable("Clause is not allowed."); } return Res; @@ -12918,10 +12970,20 @@ OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, << getOpenMPClauseName(OMPC_default); return nullptr; } - if (Kind == OMP_DEFAULT_none) + + switch (Kind) { + case OMP_DEFAULT_none: DSAStack->setDefaultDSANone(KindKwLoc); - else if (Kind == OMP_DEFAULT_shared) + break; + case OMP_DEFAULT_shared: DSAStack->setDefaultDSAShared(KindKwLoc); + break; + case OMP_DEFAULT_firstprivate: + DSAStack->setDefaultDSAFirstPrivate(KindKwLoc); + break; + default: + llvm_unreachable("DSA unexpected in OpenMP default clause"); + } return new (Context) OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); @@ -13108,6 +13170,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( case OMPC_exclusive: case OMPC_uses_allocators: case OMPC_affinity: + default: llvm_unreachable("Clause is not allowed."); } return Res; @@ -13345,6 +13408,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, case OMPC_exclusive: case OMPC_uses_allocators: case OMPC_affinity: + default: llvm_unreachable("Clause is not allowed."); } return Res; @@ -13618,6 +13682,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause( case OMPC_destroy: case OMPC_detach: case OMPC_uses_allocators: + default: llvm_unreachable("Clause is not allowed."); } return Res; @@ -14675,7 +14740,7 @@ static bool checkOMPArraySectionConstantForReduction( if (Length == nullptr) { // For array sections of the form [1:] or [:], we would need to analyze // the lower bound... - if (OASE->getColonLoc().isValid()) + if (OASE->getColonLocFirst().isValid()) return false; // This is an array subscript which has implicit length 1! @@ -14701,7 +14766,7 @@ static bool checkOMPArraySectionConstantForReduction( if (Length == nullptr) { // For array sections of the form [1:] or [:], we would need to analyze // the lower bound... - if (OASE->getColonLoc().isValid()) + if (OASE->getColonLocFirst().isValid()) return false; // This is an array subscript which has implicit length 1! @@ -16458,7 +16523,8 @@ static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, // If this is an array subscript, it refers to the whole size if the size of // the dimension is constant and equals 1. Also, an array section assumes the // format of an array subscript if no colon is used. - if (isa(E) || (OASE && OASE->getColonLoc().isInvalid())) { + if (isa(E) || + (OASE && OASE->getColonLocFirst().isInvalid())) { if (const auto *ATy = dyn_cast(BaseQTy.getTypePtr())) return ATy->getSize().getSExtValue() != 1; // Size can't be evaluated statically. @@ -16514,7 +16580,8 @@ static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, // An array subscript always refer to a single element. Also, an array section // assumes the format of an array subscript if no colon is used. - if (isa(E) || (OASE && OASE->getColonLoc().isInvalid())) + if (isa(E) || + (OASE && OASE->getColonLocFirst().isInvalid())) return false; assert(OASE && "Expecting array section if not an array subscript."); @@ -16558,7 +16625,7 @@ static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, // // We want to retrieve the member expression 'this->S'; -// OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] +// OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2] // If a list item is an array section, it must specify contiguous storage. // // For this restriction it is sufficient that we make sure only references diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index e57264dec9a09..8635397f48067 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -4709,7 +4709,7 @@ TryReferenceInit(Sema &S, Expr *Init, QualType DeclType, Sema::ReferenceConversions::NestedQualification) ? ICK_Qualification : ICK_Identity; - ICS.Standard.FromTypePtr = T2.getAsOpaquePtr(); + ICS.Standard.setFromType(T2); ICS.Standard.setToType(0, T2); ICS.Standard.setToType(1, T1); ICS.Standard.setToType(2, T1); @@ -12818,7 +12818,7 @@ static QualType chooseRecoveryType(OverloadCandidateSet &CS, auto ConsiderCandidate = [&](const OverloadCandidate &Candidate) { if (!Candidate.Function) return; - QualType T = Candidate.Function->getCallResultType(); + QualType T = Candidate.Function->getReturnType(); if (T.isNull()) return; if (!Result) @@ -13041,7 +13041,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, if (Fns.empty()) return UnaryOperator::Create(Context, Input, Opc, Context.DependentTy, VK_RValue, OK_Ordinary, OpLoc, false, - CurFPFeatures); + CurFPFeatureOverrides()); CXXRecordDecl *NamingClass = nullptr; // lookup ignores member operators UnresolvedLookupExpr *Fn = UnresolvedLookupExpr::Create( @@ -13049,7 +13049,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, /*ADL*/ true, IsOverloaded(Fns), Fns.begin(), Fns.end()); return CXXOperatorCallExpr::Create(Context, Op, Fn, ArgsArray, Context.DependentTy, VK_RValue, OpLoc, - CurFPFeatures); + CurFPFeatureOverrides()); } // Build an empty overload set. @@ -13123,7 +13123,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, Args[0] = Input; CallExpr *TheCall = CXXOperatorCallExpr::Create( Context, Op, FnExpr.get(), ArgsArray, ResultTy, VK, OpLoc, - CurFPFeatures, Best->IsADLCandidate); + CurFPFeatureOverrides(), Best->IsADLCandidate); if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall, FnDecl)) return ExprError(); @@ -13292,12 +13292,12 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc, // If there are no functions to store, just build a dependent // BinaryOperator or CompoundAssignment. if (Opc <= BO_Assign || Opc > BO_OrAssign) - return BinaryOperator::Create(Context, Args[0], Args[1], Opc, - Context.DependentTy, VK_RValue, - OK_Ordinary, OpLoc, CurFPFeatures); + return BinaryOperator::Create( + Context, Args[0], Args[1], Opc, Context.DependentTy, VK_RValue, + OK_Ordinary, OpLoc, CurFPFeatureOverrides()); return CompoundAssignOperator::Create( Context, Args[0], Args[1], Opc, Context.DependentTy, VK_LValue, - OK_Ordinary, OpLoc, CurFPFeatures, Context.DependentTy, + OK_Ordinary, OpLoc, CurFPFeatureOverrides(), Context.DependentTy, Context.DependentTy); } @@ -13311,7 +13311,7 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc, /*ADL*/ PerformADL, IsOverloaded(Fns), Fns.begin(), Fns.end()); return CXXOperatorCallExpr::Create(Context, Op, Fn, Args, Context.DependentTy, VK_RValue, OpLoc, - CurFPFeatures); + CurFPFeatureOverrides()); } // Always do placeholder-like conversions on the RHS. @@ -13480,7 +13480,7 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc, CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create( Context, ChosenOp, FnExpr.get(), Args, ResultTy, VK, OpLoc, - CurFPFeatures, Best->IsADLCandidate); + CurFPFeatureOverrides(), Best->IsADLCandidate); if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall, FnDecl)) @@ -13506,6 +13506,10 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc, if (R.isInvalid()) return ExprError(); + R = CheckForImmediateInvocation(R, FnDecl); + if (R.isInvalid()) + return ExprError(); + // For a rewritten candidate, we've already reversed the arguments // if needed. Perform the rest of the rewrite now. if ((Best->RewriteKind & CRK_DifferentOperator) || @@ -13541,7 +13545,7 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc, if (Best->RewriteKind != CRK_None) R = new (Context) CXXRewrittenBinaryOperator(R.get(), IsReversed); - return CheckForImmediateInvocation(R, FnDecl); + return R; } else { // We matched a built-in operator. Convert the arguments, then // break out so that we will build the appropriate built-in @@ -13748,7 +13752,7 @@ ExprResult Sema::BuildSynthesizedThreeWayComparison( Expr *SyntacticForm = BinaryOperator::Create( Context, OrigLHS, OrigRHS, BO_Cmp, Result.get()->getType(), Result.get()->getValueKind(), Result.get()->getObjectKind(), OpLoc, - CurFPFeatures); + CurFPFeatureOverrides()); Expr *SemanticForm[] = {LHS, RHS, Result.get()}; return PseudoObjectExpr::Create(Context, SyntacticForm, SemanticForm, 2); } @@ -13779,7 +13783,7 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, return CXXOperatorCallExpr::Create(Context, OO_Subscript, Fn, Args, Context.DependentTy, VK_RValue, RLoc, - CurFPFeatures); + CurFPFeatureOverrides()); } // Handle placeholders on both operands. @@ -13852,9 +13856,9 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, ExprValueKind VK = Expr::getValueKindForType(ResultTy); ResultTy = ResultTy.getNonLValueExprType(Context); - CXXOperatorCallExpr *TheCall = - CXXOperatorCallExpr::Create(Context, OO_Subscript, FnExpr.get(), - Args, ResultTy, VK, RLoc, CurFPFeatures); + CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create( + Context, OO_Subscript, FnExpr.get(), Args, ResultTy, VK, RLoc, + CurFPFeatureOverrides()); if (CheckCallReturnType(FnDecl->getReturnType(), LLoc, TheCall, FnDecl)) return ExprError(); @@ -14476,9 +14480,9 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, ExprValueKind VK = Expr::getValueKindForType(ResultTy); ResultTy = ResultTy.getNonLValueExprType(Context); - CXXOperatorCallExpr *TheCall = - CXXOperatorCallExpr::Create(Context, OO_Call, NewFn.get(), MethodArgs, - ResultTy, VK, RParenLoc, CurFPFeatures); + CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create( + Context, OO_Call, NewFn.get(), MethodArgs, ResultTy, VK, RParenLoc, + CurFPFeatureOverrides()); if (CheckCallReturnType(Method->getReturnType(), LParenLoc, TheCall, Method)) return true; @@ -14594,8 +14598,9 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc, QualType ResultTy = Method->getReturnType(); ExprValueKind VK = Expr::getValueKindForType(ResultTy); ResultTy = ResultTy.getNonLValueExprType(Context); - CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create( - Context, OO_Arrow, FnExpr.get(), Base, ResultTy, VK, OpLoc, CurFPFeatures); + CXXOperatorCallExpr *TheCall = + CXXOperatorCallExpr::Create(Context, OO_Arrow, FnExpr.get(), Base, + ResultTy, VK, OpLoc, CurFPFeatureOverrides()); if (CheckCallReturnType(Method->getReturnType(), OpLoc, TheCall, Method)) return ExprError(); @@ -14844,7 +14849,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, return UnaryOperator::Create( Context, SubExpr, UO_AddrOf, MemPtrType, VK_RValue, OK_Ordinary, - UnOp->getOperatorLoc(), false, CurFPFeatures); + UnOp->getOperatorLoc(), false, CurFPFeatureOverrides()); } } Expr *SubExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(), @@ -14852,9 +14857,10 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, if (SubExpr == UnOp->getSubExpr()) return UnOp; - return UnaryOperator::Create( - Context, SubExpr, UO_AddrOf, Context.getPointerType(SubExpr->getType()), - VK_RValue, OK_Ordinary, UnOp->getOperatorLoc(), false, CurFPFeatures); + return UnaryOperator::Create(Context, SubExpr, UO_AddrOf, + Context.getPointerType(SubExpr->getType()), + VK_RValue, OK_Ordinary, UnOp->getOperatorLoc(), + false, CurFPFeatureOverrides()); } if (UnresolvedLookupExpr *ULE = dyn_cast(E)) { diff --git a/clang/lib/Sema/SemaPseudoObject.cpp b/clang/lib/Sema/SemaPseudoObject.cpp index da777201af882..d17599a6ed149 100644 --- a/clang/lib/Sema/SemaPseudoObject.cpp +++ b/clang/lib/Sema/SemaPseudoObject.cpp @@ -130,7 +130,7 @@ namespace { return UnaryOperator::Create( S.Context, e, uop->getOpcode(), uop->getType(), uop->getValueKind(), uop->getObjectKind(), uop->getOperatorLoc(), uop->canOverflow(), - S.CurFPFeatures); + S.CurFPFeatureOverrides()); } if (GenericSelectionExpr *gse = dyn_cast(e)) { @@ -446,9 +446,10 @@ PseudoOpBuilder::buildAssignmentOperation(Scope *Sc, SourceLocation opcLoc, ExprResult result; if (opcode == BO_Assign) { result = semanticRHS; - syntactic = BinaryOperator::Create( - S.Context, syntacticLHS, capturedRHS, opcode, capturedRHS->getType(), - capturedRHS->getValueKind(), OK_Ordinary, opcLoc, S.CurFPFeatures); + syntactic = BinaryOperator::Create(S.Context, syntacticLHS, capturedRHS, + opcode, capturedRHS->getType(), + capturedRHS->getValueKind(), OK_Ordinary, + opcLoc, S.CurFPFeatureOverrides()); } else { ExprResult opLHS = buildGet(); @@ -462,8 +463,9 @@ PseudoOpBuilder::buildAssignmentOperation(Scope *Sc, SourceLocation opcLoc, syntactic = CompoundAssignOperator::Create( S.Context, syntacticLHS, capturedRHS, opcode, result.get()->getType(), - result.get()->getValueKind(), OK_Ordinary, opcLoc, S.CurFPFeatures, - opLHS.get()->getType(), result.get()->getType()); + result.get()->getValueKind(), OK_Ordinary, opcLoc, + S.CurFPFeatureOverrides(), opLHS.get()->getType(), + result.get()->getType()); } // The result of the assignment, if not void, is the value set into @@ -531,7 +533,7 @@ PseudoOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc, ? S.Context.getTypeSize(resultType) >= S.Context.getTypeSize(S.Context.IntTy) : false, - S.CurFPFeatures); + S.CurFPFeatureOverrides()); return complete(syntactic); } @@ -1553,7 +1555,7 @@ ExprResult Sema::checkPseudoObjectIncDec(Scope *Sc, SourceLocation opcLoc, if (op->isTypeDependent()) return UnaryOperator::Create(Context, op, opcode, Context.DependentTy, VK_RValue, OK_Ordinary, opcLoc, false, - CurFPFeatures); + CurFPFeatureOverrides()); assert(UnaryOperator::isIncrementDecrementOp(opcode)); Expr *opaqueRef = op->IgnoreParens(); @@ -1584,7 +1586,7 @@ ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc, if (LHS->isTypeDependent() || RHS->isTypeDependent()) return BinaryOperator::Create(Context, LHS, RHS, opcode, Context.DependentTy, VK_RValue, OK_Ordinary, - opcLoc, CurFPFeatures); + opcLoc, CurFPFeatureOverrides()); // Filter out non-overload placeholder types in the RHS. if (RHS->getType()->isNonOverloadPlaceholderType()) { @@ -1640,7 +1642,7 @@ Expr *Sema::recreateSyntacticForm(PseudoObjectExpr *E) { return UnaryOperator::Create(Context, op, uop->getOpcode(), uop->getType(), uop->getValueKind(), uop->getObjectKind(), uop->getOperatorLoc(), uop->canOverflow(), - CurFPFeatures); + CurFPFeatureOverrides()); } else if (CompoundAssignOperator *cop = dyn_cast(syntax)) { Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, cop->getLHS()); @@ -1648,7 +1650,7 @@ Expr *Sema::recreateSyntacticForm(PseudoObjectExpr *E) { return CompoundAssignOperator::Create( Context, lhs, rhs, cop->getOpcode(), cop->getType(), cop->getValueKind(), cop->getObjectKind(), cop->getOperatorLoc(), - CurFPFeatures, cop->getComputationLHSType(), + CurFPFeatureOverrides(), cop->getComputationLHSType(), cop->getComputationResultType()); } else if (BinaryOperator *bop = dyn_cast(syntax)) { @@ -1657,7 +1659,7 @@ Expr *Sema::recreateSyntacticForm(PseudoObjectExpr *E) { return BinaryOperator::Create(Context, lhs, rhs, bop->getOpcode(), bop->getType(), bop->getValueKind(), bop->getObjectKind(), bop->getOperatorLoc(), - CurFPFeatures); + CurFPFeatureOverrides()); } else if (isa(syntax)) { return syntax; diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index a22a1116eb0bb..73f3183c163f3 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -1328,8 +1328,9 @@ Sema::DiagnoseAssignmentEnum(QualType DstType, QualType SrcType, } } -StmtResult Sema::ActOnWhileStmt(SourceLocation WhileLoc, ConditionResult Cond, - Stmt *Body) { +StmtResult Sema::ActOnWhileStmt(SourceLocation WhileLoc, + SourceLocation LParenLoc, ConditionResult Cond, + SourceLocation RParenLoc, Stmt *Body) { if (Cond.isInvalid()) return StmtError(); @@ -1344,7 +1345,7 @@ StmtResult Sema::ActOnWhileStmt(SourceLocation WhileLoc, ConditionResult Cond, getCurCompoundScope().setHasEmptyLoopBodies(); return WhileStmt::Create(Context, CondVal.first, CondVal.second, Body, - WhileLoc); + WhileLoc, LParenLoc, RParenLoc); } StmtResult diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 073b4e818a249..c05ed0b14e3eb 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -51,8 +51,7 @@ unsigned Sema::getTemplateDepth(Scope *S) const { // Each template parameter scope represents one level of template parameter // depth. - for (Scope *TempParamScope = S->getTemplateParamParent(); - TempParamScope && !Depth; + for (Scope *TempParamScope = S->getTemplateParamParent(); TempParamScope; TempParamScope = TempParamScope->getParent()->getTemplateParamParent()) { ++Depth; } @@ -2038,6 +2037,7 @@ struct ConvertConstructorToDeductionGuideTransform { // a list of substituted template arguments as we go. for (NamedDecl *Param : *InnerParams) { MultiLevelTemplateArgumentList Args; + Args.setKind(TemplateSubstitutionKind::Rewrite); Args.addOuterTemplateArguments(SubstArgs); Args.addOuterRetainedLevel(); NamedDecl *NewParam = transformTemplateParameter(Param, Args); @@ -2057,6 +2057,7 @@ struct ConvertConstructorToDeductionGuideTransform { // substitute references to the old parameters into references to the // new ones. MultiLevelTemplateArgumentList Args; + Args.setKind(TemplateSubstitutionKind::Rewrite); if (FTD) { Args.addOuterTemplateArguments(SubstArgs); Args.addOuterRetainedLevel(); @@ -3558,9 +3559,8 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, // Only substitute for the innermost template argument list. MultiLevelTemplateArgumentList TemplateArgLists; TemplateArgLists.addOuterTemplateArguments(&StackTemplateArgs); - unsigned Depth = AliasTemplate->getTemplateParameters()->getDepth(); - for (unsigned I = 0; I < Depth; ++I) - TemplateArgLists.addOuterTemplateArguments(None); + TemplateArgLists.addOuterRetainedLevels( + AliasTemplate->getTemplateParameters()->getDepth()); LocalInstantiationScope Scope(*this); InstantiatingTemplate Inst(*this, TemplateLoc, Template); @@ -4844,10 +4844,7 @@ bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param, CXXScopeSpec SS; DeclarationNameInfo NameInfo; - if (DeclRefExpr *ArgExpr = dyn_cast(Arg.getAsExpr())) { - SS.Adopt(ArgExpr->getQualifierLoc()); - NameInfo = ArgExpr->getNameInfo(); - } else if (DependentScopeDeclRefExpr *ArgExpr = + if (DependentScopeDeclRefExpr *ArgExpr = dyn_cast(Arg.getAsExpr())) { SS.Adopt(ArgExpr->getQualifierLoc()); NameInfo = ArgExpr->getNameInfo(); @@ -4866,6 +4863,7 @@ bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param, if (Result.getAsSingle() || Result.getResultKind() == LookupResult::NotFoundInCurrentInstantiation) { + assert(SS.getScopeRep() && "dependent scope expr must has a scope!"); // Suggest that the user add 'typename' before the NNS. SourceLocation Loc = AL.getSourceRange().getBegin(); Diag(Loc, getLangOpts().MSVCCompat diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 877020ed4dcf9..f3641afbbf8a0 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -738,8 +738,9 @@ class PackDeductionScope { // type, so we need to collect the pending deduced values for those packs. if (auto *NTTP = dyn_cast( TemplateParams->getParam(Index))) { - if (auto *Expansion = dyn_cast(NTTP->getType())) - ExtraDeductions.push_back(Expansion->getPattern()); + if (!NTTP->isExpandedParameterPack()) + if (auto *Expansion = dyn_cast(NTTP->getType())) + ExtraDeductions.push_back(Expansion->getPattern()); } // FIXME: Also collect the unexpanded packs in any type and template // parameter packs that are pack expansions. @@ -3040,8 +3041,13 @@ Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, if (Trap.hasErrorOccurred()) return Sema::TDK_SubstitutionFailure; - return ::FinishTemplateArgumentDeduction( - *this, Partial, /*IsPartialOrdering=*/false, TemplateArgs, Deduced, Info); + TemplateDeductionResult Result; + runWithSufficientStackSpace(Info.getLocation(), [&] { + Result = ::FinishTemplateArgumentDeduction(*this, Partial, + /*IsPartialOrdering=*/false, + TemplateArgs, Deduced, Info); + }); + return Result; } /// Perform template argument deduction to determine whether @@ -3081,8 +3087,13 @@ Sema::DeduceTemplateArguments(VarTemplatePartialSpecializationDecl *Partial, if (Trap.hasErrorOccurred()) return Sema::TDK_SubstitutionFailure; - return ::FinishTemplateArgumentDeduction( - *this, Partial, /*IsPartialOrdering=*/false, TemplateArgs, Deduced, Info); + TemplateDeductionResult Result; + runWithSufficientStackSpace(Info.getLocation(), [&] { + Result = ::FinishTemplateArgumentDeduction(*this, Partial, + /*IsPartialOrdering=*/false, + TemplateArgs, Deduced, Info); + }); + return Result; } /// Determine whether the given type T is a simple-template-id type. @@ -4031,13 +4042,12 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( SmallVector ParamTypes; unsigned NumExplicitlySpecified = 0; if (ExplicitTemplateArgs) { - TemplateDeductionResult Result = - SubstituteExplicitTemplateArguments(FunctionTemplate, - *ExplicitTemplateArgs, - Deduced, - ParamTypes, - nullptr, - Info); + TemplateDeductionResult Result; + runWithSufficientStackSpace(Info.getLocation(), [&] { + Result = SubstituteExplicitTemplateArguments( + FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes, nullptr, + Info); + }); if (Result) return Result; @@ -4139,12 +4149,16 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( // that is needed when the accessibility of template arguments is checked. DeclContext *CallingCtx = CurContext; - return FinishTemplateArgumentDeduction( - FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info, - &OriginalCallArgs, PartialOverloading, [&, CallingCtx]() { - ContextRAII SavedContext(*this, CallingCtx); - return CheckNonDependent(ParamTypesForArgChecking); - }); + TemplateDeductionResult Result; + runWithSufficientStackSpace(Info.getLocation(), [&] { + Result = FinishTemplateArgumentDeduction( + FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info, + &OriginalCallArgs, PartialOverloading, [&, CallingCtx]() { + ContextRAII SavedContext(*this, CallingCtx); + return CheckNonDependent(ParamTypesForArgChecking); + }); + }); + return Result; } QualType Sema::adjustCCAndNoReturn(QualType ArgFunctionType, @@ -4230,11 +4244,13 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( unsigned NumExplicitlySpecified = 0; SmallVector ParamTypes; if (ExplicitTemplateArgs) { - if (TemplateDeductionResult Result - = SubstituteExplicitTemplateArguments(FunctionTemplate, - *ExplicitTemplateArgs, - Deduced, ParamTypes, - &FunctionType, Info)) + TemplateDeductionResult Result; + runWithSufficientStackSpace(Info.getLocation(), [&] { + Result = SubstituteExplicitTemplateArguments( + FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes, + &FunctionType, Info); + }); + if (Result) return Result; NumExplicitlySpecified = Deduced.size(); @@ -4276,10 +4292,13 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( return Result; } - if (TemplateDeductionResult Result - = FinishTemplateArgumentDeduction(FunctionTemplate, Deduced, - NumExplicitlySpecified, - Specialization, Info)) + TemplateDeductionResult Result; + runWithSufficientStackSpace(Info.getLocation(), [&] { + Result = FinishTemplateArgumentDeduction(FunctionTemplate, Deduced, + NumExplicitlySpecified, + Specialization, Info); + }); + if (Result) return Result; // If the function has a deduced return type, deduce it now, so we can check @@ -4436,9 +4455,11 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *ConversionTemplate, LocalInstantiationScope InstScope(*this); // Finish template argument deduction. FunctionDecl *ConversionSpecialized = nullptr; - TemplateDeductionResult Result - = FinishTemplateArgumentDeduction(ConversionTemplate, Deduced, 0, - ConversionSpecialized, Info); + TemplateDeductionResult Result; + runWithSufficientStackSpace(Info.getLocation(), [&] { + Result = FinishTemplateArgumentDeduction(ConversionTemplate, Deduced, 0, + ConversionSpecialized, Info); + }); Specialization = cast_or_null(ConversionSpecialized); return Result; } @@ -5378,14 +5399,15 @@ static bool isAtLeastAsSpecializedAs(Sema &S, QualType T1, QualType T2, Sema::InstantiatingTemplate Inst(S, Info.getLocation(), P2, DeducedArgs, Info); auto *TST1 = T1->castAs(); - if (FinishTemplateArgumentDeduction( - S, P2, /*IsPartialOrdering=*/true, - TemplateArgumentList(TemplateArgumentList::OnStack, - TST1->template_arguments()), - Deduced, Info)) - return false; - - return true; + bool AtLeastAsSpecialized; + S.runWithSufficientStackSpace(Info.getLocation(), [&] { + AtLeastAsSpecialized = !FinishTemplateArgumentDeduction( + S, P2, /*IsPartialOrdering=*/true, + TemplateArgumentList(TemplateArgumentList::OnStack, + TST1->template_arguments()), + Deduced, Info); + }); + return AtLeastAsSpecialized; } /// Returns the more specialized class template partial specialization diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index bfda59d40c2a2..11e03c517d015 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1362,6 +1362,19 @@ TemplateName TemplateInstantiator::TransformTemplateName( TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getPosition()); + if (TemplateArgs.isRewrite()) { + // We're rewriting the template parameter as a reference to another + // template parameter. + if (Arg.getKind() == TemplateArgument::Pack) { + assert(Arg.pack_size() == 1 && Arg.pack_begin()->isPackExpansion() && + "unexpected pack arguments in template rewrite"); + Arg = Arg.pack_begin()->getPackExpansionPattern(); + } + assert(Arg.getKind() == TemplateArgument::Template && + "unexpected nontype template argument kind in template rewrite"); + return Arg.getAsTemplate(); + } + if (TTP->isParameterPack()) { assert(Arg.getKind() == TemplateArgument::Pack && "Missing argument pack"); @@ -1458,19 +1471,18 @@ TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E, TemplateArgument Arg = TemplateArgs(NTTP->getDepth(), NTTP->getPosition()); - if (TemplateArgs.getNumLevels() != TemplateArgs.getNumSubstitutedLevels()) { - // We're performing a partial substitution, so the substituted argument - // could be dependent. As a result we can't create a SubstNonType*Expr - // node now, since that represents a fully-substituted argument. - // FIXME: We should have some AST representation for this. + if (TemplateArgs.isRewrite()) { + // We're rewriting the template parameter as a reference to another + // template parameter. if (Arg.getKind() == TemplateArgument::Pack) { - // FIXME: This won't work for alias templates. assert(Arg.pack_size() == 1 && Arg.pack_begin()->isPackExpansion() && - "unexpected pack arguments in partial substitution"); + "unexpected pack arguments in template rewrite"); Arg = Arg.pack_begin()->getPackExpansionPattern(); } assert(Arg.getKind() == TemplateArgument::Expression && - "unexpected nontype template argument kind in partial substitution"); + "unexpected nontype template argument kind in template rewrite"); + // FIXME: This can lead to the same subexpression appearing multiple times + // in a complete expression. return Arg.getAsExpr(); } @@ -1782,6 +1794,24 @@ TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB, TemplateArgument Arg = TemplateArgs(T->getDepth(), T->getIndex()); + if (TemplateArgs.isRewrite()) { + // We're rewriting the template parameter as a reference to another + // template parameter. + if (Arg.getKind() == TemplateArgument::Pack) { + assert(Arg.pack_size() == 1 && Arg.pack_begin()->isPackExpansion() && + "unexpected pack arguments in template rewrite"); + Arg = Arg.pack_begin()->getPackExpansionPattern(); + } + assert(Arg.getKind() == TemplateArgument::Type && + "unexpected nontype template argument kind in template rewrite"); + QualType NewT = Arg.getAsType(); + assert(isa(NewT) && + "type parm not rewritten to type parm"); + auto NewTL = TLB.push(NewT); + NewTL.setNameLoc(TL.getNameLoc()); + return NewT; + } + if (T->isParameterPack()) { assert(Arg.getKind() == TemplateArgument::Pack && "Missing argument pack"); @@ -2396,7 +2426,7 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm, UnparsedDefaultArgInstantiations[OldParm].push_back(NewParm); } else if (Expr *Arg = OldParm->getDefaultArg()) { FunctionDecl *OwningFunc = cast(OldParm->getDeclContext()); - if (OwningFunc->isInLocalScope()) { + if (OwningFunc->isInLocalScopeForInstantiation()) { // Instantiate default arguments for methods of local classes (DR1484) // and non-defining declarations. Sema::ContextRAII SavedContext(*this, OwningFunc); diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 1fff6b8b951e7..85adc4ef2dbde 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -3719,6 +3719,8 @@ FunctionDecl *Sema::SubstSpaceshipAsEqualEqual(CXXRecordDecl *RD, // access and function-definition and in the same class scope as the // three-way comparison operator function MultiLevelTemplateArgumentList NoTemplateArgs; + NoTemplateArgs.setKind(TemplateSubstitutionKind::Rewrite); + NoTemplateArgs.addOuterRetainedLevels(RD->getTemplateDepth()); TemplateDeclInstantiator Instantiator(*this, RD, NoTemplateArgs); Decl *R; if (auto *MD = dyn_cast(Spaceship)) { @@ -4225,6 +4227,94 @@ static bool addInstantiatedParametersToScope(Sema &S, FunctionDecl *Function, return false; } +bool Sema::InstantiateDefaultArgument(SourceLocation CallLoc, FunctionDecl *FD, + ParmVarDecl *Param) { + assert(Param->hasUninstantiatedDefaultArg()); + Expr *UninstExpr = Param->getUninstantiatedDefaultArg(); + + EnterExpressionEvaluationContext EvalContext( + *this, ExpressionEvaluationContext::PotentiallyEvaluated, Param); + + // Instantiate the expression. + // + // FIXME: Pass in a correct Pattern argument, otherwise + // getTemplateInstantiationArgs uses the lexical context of FD, e.g. + // + // template + // struct A { + // static int FooImpl(); + // + // template + // // bug: default argument A::FooImpl() is evaluated with 2-level + // // template argument list [[T], [Tp]], should be [[Tp]]. + // friend A Foo(int a); + // }; + // + // template + // A Foo(int a = A::FooImpl()); + MultiLevelTemplateArgumentList TemplateArgs + = getTemplateInstantiationArgs(FD, nullptr, /*RelativeToPrimary=*/true); + + InstantiatingTemplate Inst(*this, CallLoc, Param, + TemplateArgs.getInnermost()); + if (Inst.isInvalid()) + return true; + if (Inst.isAlreadyInstantiating()) { + Diag(Param->getBeginLoc(), diag::err_recursive_default_argument) << FD; + Param->setInvalidDecl(); + return true; + } + + ExprResult Result; + { + // C++ [dcl.fct.default]p5: + // The names in the [default argument] expression are bound, and + // the semantic constraints are checked, at the point where the + // default argument expression appears. + ContextRAII SavedContext(*this, FD); + LocalInstantiationScope Local(*this); + + FunctionDecl *Pattern = FD->getTemplateInstantiationPattern( + /*ForDefinition*/ false); + if (addInstantiatedParametersToScope(*this, FD, Pattern, Local, + TemplateArgs)) + return true; + + runWithSufficientStackSpace(CallLoc, [&] { + Result = SubstInitializer(UninstExpr, TemplateArgs, + /*DirectInit*/false); + }); + } + if (Result.isInvalid()) + return true; + + // Check the expression as an initializer for the parameter. + InitializedEntity Entity + = InitializedEntity::InitializeParameter(Context, Param); + InitializationKind Kind = InitializationKind::CreateCopy( + Param->getLocation(), + /*FIXME:EqualLoc*/ UninstExpr->getBeginLoc()); + Expr *ResultE = Result.getAs(); + + InitializationSequence InitSeq(*this, Entity, Kind, ResultE); + Result = InitSeq.Perform(*this, Entity, Kind, ResultE); + if (Result.isInvalid()) + return true; + + Result = + ActOnFinishFullExpr(Result.getAs(), Param->getOuterLocStart(), + /*DiscardedValue*/ false); + if (Result.isInvalid()) + return true; + + // Remember the instantiated default argument. + Param->setDefaultArg(Result.getAs()); + if (ASTMutationListener *L = getASTMutationListener()) + L->DefaultArgumentInstantiated(Param); + + return false; +} + void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation, FunctionDecl *Decl) { const FunctionProtoType *Proto = Decl->getType()->castAs(); @@ -4255,6 +4345,10 @@ void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation, MultiLevelTemplateArgumentList TemplateArgs = getTemplateInstantiationArgs(Decl, nullptr, /*RelativeToPrimary*/true); + // FIXME: We can't use getTemplateInstantiationPattern(false) in general + // here, because for a non-defining friend declaration in a class template, + // we don't store enough information to map back to the friend declaration in + // the template. FunctionDecl *Template = Proto->getExceptionSpecTemplate(); if (addInstantiatedParametersToScope(*this, Decl, Template, Scope, TemplateArgs)) { @@ -4364,7 +4458,7 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, EPI.ExceptionSpec.Type != EST_None && EPI.ExceptionSpec.Type != EST_DynamicNone && EPI.ExceptionSpec.Type != EST_BasicNoexcept && - !Tmpl->isInLocalScope()) { + !Tmpl->isInLocalScopeForInstantiation()) { FunctionDecl *ExceptionSpecTemplate = Tmpl; if (EPI.ExceptionSpec.Type == EST_Uninstantiated) ExceptionSpecTemplate = EPI.ExceptionSpec.SourceTemplate; @@ -5605,6 +5699,20 @@ DeclContext *Sema::FindInstantiatedContext(SourceLocation Loc, DeclContext* DC, } else return DC; } +/// Determine whether the given context is dependent on template parameters at +/// level \p Level or below. +/// +/// Sometimes we only substitute an inner set of template arguments and leave +/// the outer templates alone. In such cases, contexts dependent only on the +/// outer levels are not effectively dependent. +static bool isDependentContextAtLevel(DeclContext *DC, unsigned Level) { + if (!DC->isDependentContext()) + return false; + if (!Level) + return true; + return cast(DC)->getTemplateDepth() > Level; +} + /// Find the instantiation of the given declaration within the /// current instantiation. /// @@ -5635,6 +5743,10 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, const MultiLevelTemplateArgumentList &TemplateArgs, bool FindingInstantiatedContext) { DeclContext *ParentDC = D->getDeclContext(); + // Determine whether our parent context depends on any of the tempalte + // arguments we're currently substituting. + bool ParentDependsOnArgs = isDependentContextAtLevel( + ParentDC, TemplateArgs.getNumRetainedOuterLevels()); // FIXME: Parmeters of pointer to functions (y below) that are themselves // parameters (p below) can have their ParentDC set to the translation-unit // - thus we can not consistently check if the ParentDC of such a parameter @@ -5651,15 +5763,14 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, // - as long as we have a ParmVarDecl whose parent is non-dependent and // whose type is not instantiation dependent, do nothing to the decl // - otherwise find its instantiated decl. - if (isa(D) && !ParentDC->isDependentContext() && + if (isa(D) && !ParentDependsOnArgs && !cast(D)->getType()->isInstantiationDependentType()) return D; if (isa(D) || isa(D) || isa(D) || isa(D) || - ((ParentDC->isFunctionOrMethod() || - isa(ParentDC) || - isa(ParentDC)) && - ParentDC->isDependentContext()) || + (ParentDependsOnArgs && (ParentDC->isFunctionOrMethod() || + isa(ParentDC) || + isa(ParentDC))) || (isa(D) && cast(D)->isLambda())) { // D is a local of some kind. Look into the map of local // declarations to their instantiations. @@ -5813,7 +5924,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, // anonymous unions in class templates). } - if (!ParentDC->isDependentContext()) + if (!ParentDependsOnArgs) return D; ParentDC = FindInstantiatedContext(Loc, ParentDC, TemplateArgs); diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 46fa8bc0608bd..b8f7f1a581590 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1759,7 +1759,7 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { // The effect of a cv-qualifier-seq in a function declarator is not the // same as adding cv-qualification on top of the function type. In the // latter case, the cv-qualifiers are ignored. - if (TypeQuals && Result->isFunctionType()) { + if (Result->isFunctionType()) { diagnoseAndRemoveTypeQualifiers( S, DS, TypeQuals, Result, DeclSpec::TQ_const | DeclSpec::TQ_volatile, S.getLangOpts().CPlusPlus @@ -2393,13 +2393,6 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM, ? diag::err_typecheck_zero_array_size : diag::ext_typecheck_zero_array_size) << ArraySize->getSourceRange(); - - if (ASM == ArrayType::Static) { - Diag(ArraySize->getBeginLoc(), - diag::warn_typecheck_zero_static_array_size) - << ArraySize->getSourceRange(); - ASM = ArrayType::Normal; - } } else if (!T->isDependentType() && !T->isVariablyModifiedType() && !T->isIncompleteType() && !T->isUndeducedType()) { // Is the array too large? @@ -3301,12 +3294,16 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state, D.isFunctionDeclarator()) break; bool Cxx = SemaRef.getLangOpts().CPlusPlus; - switch (cast(SemaRef.CurContext)->getTagKind()) { - case TTK_Enum: llvm_unreachable("unhandled tag kind"); - case TTK_Struct: Error = Cxx ? 1 : 2; /* Struct member */ break; - case TTK_Union: Error = Cxx ? 3 : 4; /* Union member */ break; - case TTK_Class: Error = 5; /* Class member */ break; - case TTK_Interface: Error = 6; /* Interface member */ break; + if (isa(SemaRef.CurContext)) { + Error = 6; // Interface member. + } else { + switch (cast(SemaRef.CurContext)->getTagKind()) { + case TTK_Enum: llvm_unreachable("unhandled tag kind"); + case TTK_Struct: Error = Cxx ? 1 : 2; /* Struct member */ break; + case TTK_Union: Error = Cxx ? 3 : 4; /* Union member */ break; + case TTK_Class: Error = 5; /* Class member */ break; + case TTK_Interface: Error = 6; /* Interface member */ break; + } } if (D.getDeclSpec().isFriendSpecified()) Error = 20; // Friend type @@ -5135,8 +5132,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, // FIXME: This really should be in BuildFunctionType. if (S.getLangOpts().OpenCL) { if (!S.getOpenCLOptions().isEnabled("cl_khr_fp16")) { - S.Diag(Param->getLocation(), - diag::err_opencl_half_param) << ParamTy; + S.Diag(Param->getLocation(), diag::err_opencl_invalid_param) + << ParamTy << 0; D.setInvalidType(); Param->setInvalidDecl(); } @@ -5155,6 +5152,11 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, Param->setKNRPromoted(true); } } + } else if (S.getLangOpts().OpenCL && ParamTy->isBlockPointerType()) { + // OpenCL 2.0 s6.12.5: A block cannot be a parameter of a function. + S.Diag(Param->getLocation(), diag::err_opencl_invalid_param) + << ParamTy << 1 /*hint off*/; + D.setInvalidType(); } if (LangOpts.ObjCAutoRefCount && Param->hasAttr()) { @@ -7031,15 +7033,15 @@ static bool checkNullabilityTypeSpecifier(TypeProcessingState &state, // attributes, require that the type be a single-level pointer. if (isContextSensitive) { // Make sure that the pointee isn't itself a pointer type. - const Type *pointeeType; + const Type *pointeeType = nullptr; if (desugared->isArrayType()) pointeeType = desugared->getArrayElementTypeNoTypeQual(); - else + else if (desugared->isAnyPointerType()) pointeeType = desugared->getPointeeType().getTypePtr(); - if (pointeeType->isAnyPointerType() || - pointeeType->isObjCObjectPointerType() || - pointeeType->isMemberPointerType()) { + if (pointeeType && (pointeeType->isAnyPointerType() || + pointeeType->isObjCObjectPointerType() || + pointeeType->isMemberPointerType())) { S.Diag(nullabilityLoc, diag::err_nullability_cs_multilevel) << DiagNullabilityKind(nullability, true) << type; @@ -8106,6 +8108,15 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type, case ParsedAttr::AT_AcquireHandle: { if (!type->isFunctionType()) return; + + if (attr.getNumArgs() != 1) { + state.getSema().Diag(attr.getLoc(), + diag::err_attribute_wrong_number_arguments) + << attr << 1; + attr.setInvalid(); + return; + } + StringRef HandleType; if (!state.getSema().checkStringLiteralArgumentAttr(attr, 0, HandleType)) return; diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index ff9d4d610660a..ae0e9f1119b43 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -1347,9 +1347,10 @@ class TreeTransform { /// /// By default, performs semantic analysis to build the new statement. /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildWhileStmt(SourceLocation WhileLoc, - Sema::ConditionResult Cond, Stmt *Body) { - return getSema().ActOnWhileStmt(WhileLoc, Cond, Body); + StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc, + Sema::ConditionResult Cond, + SourceLocation RParenLoc, Stmt *Body) { + return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body); } /// Build a new do-while statement. @@ -2436,10 +2437,13 @@ class TreeTransform { /// Subclasses may override this routine to provide different behavior. ExprResult RebuildOMPArraySectionExpr(Expr *Base, SourceLocation LBracketLoc, Expr *LowerBound, - SourceLocation ColonLoc, Expr *Length, + SourceLocation ColonLocFirst, + SourceLocation ColonLocSecond, + Expr *Length, Expr *Stride, SourceLocation RBracketLoc) { return getSema().ActOnOMPArraySectionExpr(Base, LBracketLoc, LowerBound, - ColonLoc, Length, RBracketLoc); + ColonLocFirst, ColonLocSecond, + Length, Stride, RBracketLoc); } /// Build a new array shaping expression. @@ -7332,7 +7336,8 @@ TreeTransform::TransformWhileStmt(WhileStmt *S) { Body.get() == S->getBody()) return Owned(S); - return getDerived().RebuildWhileStmt(S->getWhileLoc(), Cond, Body.get()); + return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(), + Cond, S->getRParenLoc(), Body.get()); } template @@ -7630,7 +7635,8 @@ TreeTransform::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) { return StmtError(); StmtResult FinalSuspend = getDerived().TransformStmt(S->getFinalSuspendStmt()); - if (FinalSuspend.isInvalid()) + if (FinalSuspend.isInvalid() || + !SemaRef.checkFinalSuspendNoThrow(FinalSuspend.get())) return StmtError(); ScopeInfo->setCoroutineSuspends(InitSuspend.get(), FinalSuspend.get()); assert(isa(InitSuspend.get()) && isa(FinalSuspend.get())); @@ -10336,13 +10342,21 @@ TreeTransform::TransformOMPArraySectionExpr(OMPArraySectionExpr *E) { return ExprError(); } + ExprResult Stride; + if (Expr *Str = E->getStride()) { + Stride = getDerived().TransformExpr(Str); + if (Stride.isInvalid()) + return ExprError(); + } + if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() && LowerBound.get() == E->getLowerBound() && Length.get() == E->getLength()) return E; return getDerived().RebuildOMPArraySectionExpr( - Base.get(), E->getBase()->getEndLoc(), LowerBound.get(), E->getColonLoc(), - Length.get(), E->getRBracketLoc()); + Base.get(), E->getBase()->getEndLoc(), LowerBound.get(), + E->getColonLocFirst(), E->getColonLocSecond(), Length.get(), Stride.get(), + E->getRBracketLoc()); } template @@ -10563,8 +10577,10 @@ TreeTransform::TransformBinaryOperator(BinaryOperator *E) { return getDerived().RebuildBinaryOperator( E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get()); Sema::FPFeaturesStateRAII FPFeaturesState(getSema()); - getSema().CurFPFeatures = E->getFPFeatures(getSema().getLangOpts()); - + FPOptionsOverride NewOverrides(E->getFPFeatures(getSema().getLangOpts())); + getSema().CurFPFeatures = + NewOverrides.applyOverrides(getSema().getLangOpts()); + getSema().FpPragmaStack.CurrentValue = NewOverrides.getAsOpaqueInt(); return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get()); } @@ -10618,7 +10634,10 @@ ExprResult TreeTransform::TransformCompoundAssignOperator( CompoundAssignOperator *E) { Sema::FPFeaturesStateRAII FPFeaturesState(getSema()); - getSema().CurFPFeatures = E->getFPFeatures(getSema().getLangOpts()); + FPOptionsOverride NewOverrides(E->getFPFeatures(getSema().getLangOpts())); + getSema().CurFPFeatures = + NewOverrides.applyOverrides(getSema().getLangOpts()); + getSema().FpPragmaStack.CurrentValue = NewOverrides.getAsOpaqueInt(); return getDerived().TransformBinaryOperator(E); } @@ -11093,7 +11112,10 @@ TreeTransform::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) { return SemaRef.MaybeBindToTemporary(E); Sema::FPFeaturesStateRAII FPFeaturesState(getSema()); - getSema().CurFPFeatures = E->getFPFeatures(); + FPOptionsOverride NewOverrides(E->getFPFeatures()); + getSema().CurFPFeatures = + NewOverrides.applyOverrides(getSema().getLangOpts()); + getSema().FpPragmaStack.CurrentValue = NewOverrides.getAsOpaqueInt(); return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(), E->getOperatorLoc(), diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 4dd2054d4b079..4a1a995204e59 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -3234,7 +3234,8 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { case MODULAR_CODEGEN_DECLS: // FIXME: Skip reading this record if our ASTConsumer doesn't care about // them (ie: if we're not codegenerating this module). - if (F.Kind == MK_MainFile) + if (F.Kind == MK_MainFile || + getContext().getLangOpts().BuildingPCHWithObjectFile) for (unsigned I = 0, N = Record.size(); I != N; ++I) EagerlyDeserializedDecls.push_back(getGlobalDeclID(F, Record[I])); break; @@ -7843,7 +7844,9 @@ void ASTReader::InitializeSema(Sema &S) { // FIXME: What happens if these are changed by a module import? if (!FPPragmaOptions.empty()) { assert(FPPragmaOptions.size() == 1 && "Wrong number of FP_PRAGMA_OPTIONS"); - SemaObj->CurFPFeatures = FPOptions(FPPragmaOptions[0]); + FPOptionsOverride NewOverrides(FPPragmaOptions[0]); + SemaObj->CurFPFeatures = + NewOverrides.applyOverrides(SemaObj->getLangOpts()); } SemaObj->OpenCLFeatures.copy(OpenCLExtensions); @@ -11992,6 +11995,8 @@ OMPClause *OMPClauseReader::readClause() { case llvm::omp::Enum: \ break; #include "llvm/Frontend/OpenMP/OMPKinds.def" + default: + break; } assert(C && "Unknown OMPClause type"); diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 359d5e567e672..eef4ab16ec15e 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -503,8 +503,12 @@ uint64_t ASTDeclReader::GetCurrentCursorOffset() { } void ASTDeclReader::ReadFunctionDefinition(FunctionDecl *FD) { - if (Record.readInt()) + if (Record.readInt()) { Reader.DefinitionSource[FD] = Loc.F->Kind == ModuleKind::MK_MainFile; + if (Reader.getContext().getLangOpts().BuildingPCHWithObjectFile && + Reader.DeclIsFromPCHWithObjectFile(FD)) + Reader.DefinitionSource[FD] = true; + } if (auto *CD = dyn_cast(FD)) { CD->setNumCtorInitializers(Record.readInt()); if (CD->getNumCtorInitializers()) @@ -1431,8 +1435,12 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) { Reader.getContext().setBlockVarCopyInit(VD, CopyExpr, Record.readInt()); } - if (VD->getStorageDuration() == SD_Static && Record.readInt()) + if (VD->getStorageDuration() == SD_Static && Record.readInt()) { Reader.DefinitionSource[VD] = Loc.F->Kind == ModuleKind::MK_MainFile; + if (Reader.getContext().getLangOpts().BuildingPCHWithObjectFile && + Reader.DeclIsFromPCHWithObjectFile(VD)) + Reader.DefinitionSource[VD] = true; + } enum VarKind { VarNotTemplate = 0, VarTemplate, StaticDataMemberSpecialization @@ -1691,8 +1699,12 @@ void ASTDeclReader::ReadCXXDefinitionData( Data.ODRHash = Record.readInt(); Data.HasODRHash = true; - if (Record.readInt()) + if (Record.readInt()) { Reader.DefinitionSource[D] = Loc.F->Kind == ModuleKind::MK_MainFile; + if (Reader.getContext().getLangOpts().BuildingPCHWithObjectFile && + Reader.DeclIsFromPCHWithObjectFile(D)) + Reader.DefinitionSource[D] = true; + } Data.NumBases = Record.readInt(); if (Data.NumBases) diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 0c379839ba839..a40c5499a6d77 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -271,6 +271,8 @@ void ASTStmtReader::VisitWhileStmt(WhileStmt *S) { S->setConditionVariable(Record.getContext(), readDeclAs()); S->setWhileLoc(readSourceLocation()); + S->setLParenLoc(readSourceLocation()); + S->setRParenLoc(readSourceLocation()); } void ASTStmtReader::VisitDoStmt(DoStmt *S) { @@ -706,7 +708,7 @@ void ASTStmtReader::VisitUnaryOperator(UnaryOperator *E) { E->setOperatorLoc(readSourceLocation()); E->setCanOverflow(Record.readInt()); if (hasFP_Features) - E->setStoredFPFeatures(FPOptions(Record.readInt())); + E->setStoredFPFeatures(FPOptionsOverride(Record.readInt())); } void ASTStmtReader::VisitOffsetOfExpr(OffsetOfExpr *E) { @@ -937,7 +939,9 @@ void ASTStmtReader::VisitOMPArraySectionExpr(OMPArraySectionExpr *E) { E->setBase(Record.readSubExpr()); E->setLowerBound(Record.readSubExpr()); E->setLength(Record.readSubExpr()); - E->setColonLoc(readSourceLocation()); + E->setStride(Record.readSubExpr()); + E->setColonLocFirst(readSourceLocation()); + E->setColonLocSecond(readSourceLocation()); E->setRBracketLoc(readSourceLocation()); } @@ -1089,7 +1093,7 @@ void ASTStmtReader::VisitBinaryOperator(BinaryOperator *E) { E->setRHS(Record.readSubExpr()); E->setOperatorLoc(readSourceLocation()); if (hasFP_Features) - E->setStoredFPFeatures(FPOptions(Record.readInt())); + E->setStoredFPFeatures(FPOptionsOverride(Record.readInt())); } void ASTStmtReader::VisitCompoundAssignOperator(CompoundAssignOperator *E) { @@ -1657,8 +1661,8 @@ void ASTStmtReader::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) { void ASTStmtReader::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) { VisitCallExpr(E); E->CXXOperatorCallExprBits.OperatorKind = Record.readInt(); - E->CXXOperatorCallExprBits.FPFeatures = Record.readInt(); E->Range = Record.readSourceRange(); + E->setFPFeatures(FPOptionsOverride(Record.readInt())); } void ASTStmtReader::VisitCXXRewrittenBinaryOperator( @@ -1715,12 +1719,12 @@ void ASTStmtReader::VisitLambdaExpr(LambdaExpr *E) { // Read capture initializers. for (LambdaExpr::capture_init_iterator C = E->capture_init_begin(), - CEnd = E->capture_init_end(); + CEnd = E->capture_init_end(); C != CEnd; ++C) *C = Record.readSubExpr(); - // Ok, not one past the end. - E->getStoredStmts()[NumCaptures] = Record.readSubStmt(); + // The body will be lazily deserialized when needed from the call operator + // declaration. } void diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 2a17360a67bc4..2345a12caeb2e 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -3960,7 +3960,7 @@ void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) { } /// Write an FP_PRAGMA_OPTIONS block for the given FPOptions. -void ASTWriter::WriteFPPragmaOptions(const FPOptions &Opts) { +void ASTWriter::WriteFPPragmaOptions(const FPOptionsOverride &Opts) { RecordData::value_type Record[] = {Opts.getAsOpaqueInt()}; Stream.EmitRecord(FP_PRAGMA_OPTIONS, Record); } @@ -4790,7 +4790,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, WriteReferencedSelectorsPool(SemaRef); WriteLateParsedTemplates(SemaRef); WriteIdentifierTable(PP, SemaRef.IdResolver, isModule); - WriteFPPragmaOptions(SemaRef.getCurFPFeatures()); + WriteFPPragmaOptions(SemaRef.CurFPFeatureOverrides()); WriteOpenCLExtensions(SemaRef); WriteOpenCLExtensionTypes(SemaRef); WriteCUDAPragmas(SemaRef); @@ -5688,8 +5688,8 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) { // getODRHash will compute the ODRHash if it has not been previously computed. Record->push_back(D->getODRHash()); - bool ModulesDebugInfo = Writer->Context->getLangOpts().ModulesDebugInfo && - Writer->WritingModule && !D->isDependentType(); + bool ModulesDebugInfo = + Writer->Context->getLangOpts().ModulesDebugInfo && !D->isDependentType(); Record->push_back(ModulesDebugInfo); if (ModulesDebugInfo) Writer->ModularCodegenDecls.push_back(Writer->GetDeclRef(D)); diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 19608c869613d..eecdf89c791ad 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -2458,9 +2458,10 @@ void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) { assert(FD->doesThisDeclarationHaveABody()); bool ModulesCodegen = false; - if (Writer->WritingModule && !FD->isDependentContext()) { + if (!FD->isDependentContext()) { Optional Linkage; - if (Writer->WritingModule->Kind == Module::ModuleInterfaceUnit) { + if (Writer->WritingModule && + Writer->WritingModule->Kind == Module::ModuleInterfaceUnit) { // When building a C++ Modules TS module interface unit, a strong // definition in the module interface is provided by the compilation of // that module interface unit, not by its users. (Inline functions are diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index b13d0df9c3761..0767b3a24bf2f 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -194,6 +194,8 @@ void ASTStmtWriter::VisitWhileStmt(WhileStmt *S) { Record.AddDeclRef(S->getConditionVariable()); Record.AddSourceLocation(S->getWhileLoc()); + Record.AddSourceLocation(S->getLParenLoc()); + Record.AddSourceLocation(S->getRParenLoc()); Code = serialization::STMT_WHILE; } @@ -797,7 +799,9 @@ void ASTStmtWriter::VisitOMPArraySectionExpr(OMPArraySectionExpr *E) { Record.AddStmt(E->getBase()); Record.AddStmt(E->getLowerBound()); Record.AddStmt(E->getLength()); - Record.AddSourceLocation(E->getColonLoc()); + Record.AddStmt(E->getStride()); + Record.AddSourceLocation(E->getColonLocFirst()); + Record.AddSourceLocation(E->getColonLocSecond()); Record.AddSourceLocation(E->getRBracketLoc()); Code = serialization::EXPR_OMP_ARRAY_SECTION; } @@ -1545,8 +1549,8 @@ void ASTStmtWriter::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) { void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) { VisitCallExpr(E); Record.push_back(E->getOperator()); - Record.push_back(E->getFPFeatures().getAsOpaqueInt()); Record.AddSourceRange(E->Range); + Record.push_back(E->getFPFeatures().getAsOpaqueInt()); Code = serialization::EXPR_CXX_OPERATOR_CALL; } @@ -1615,7 +1619,8 @@ void ASTStmtWriter::VisitLambdaExpr(LambdaExpr *E) { Record.AddStmt(*C); } - Record.AddStmt(E->getBody()); + // Don't serialize the body. It belongs to the call operator declaration. + // LambdaExpr only stores a copy of the Stmt *. Code = serialization::EXPR_LAMBDA; } diff --git a/clang/lib/Serialization/CMakeLists.txt b/clang/lib/Serialization/CMakeLists.txt index 1f05117bb5fd4..a7c5b5e4ffa41 100644 --- a/clang/lib/Serialization/CMakeLists.txt +++ b/clang/lib/Serialization/CMakeLists.txt @@ -30,4 +30,7 @@ add_clang_library(clangSerialization clangBasic clangLex clangSema + + DEPENDS + omp_gen ) diff --git a/clang/lib/Serialization/GlobalModuleIndex.cpp b/clang/lib/Serialization/GlobalModuleIndex.cpp index 958cca7345722..9192b3b476bbc 100644 --- a/clang/lib/Serialization/GlobalModuleIndex.cpp +++ b/clang/lib/Serialization/GlobalModuleIndex.cpp @@ -321,7 +321,7 @@ bool GlobalModuleIndex::lookupIdentifier(StringRef Name, HitSet &Hits) { = *static_cast(IdentifierIndex); IdentifierIndexTable::iterator Known = Table.find(Name); if (Known == Table.end()) { - return true; + return false; } SmallVector ModuleIDs = *Known; diff --git a/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp index 479e50b80867e..0e8cbc60689a7 100644 --- a/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp @@ -38,7 +38,7 @@ class AnalysisOrderChecker check::PostStmt, check::PreCall, check::PostCall, check::EndFunction, check::EndAnalysis, check::NewAllocator, check::Bind, check::PointerEscape, check::RegionChanges, - check::LiveSymbols> { + check::LiveSymbols, eval::Call> { bool isCallbackEnabled(const AnalyzerOptions &Opts, StringRef CallbackName) const { @@ -122,6 +122,19 @@ class AnalysisOrderChecker llvm::errs() << "PostStmt\n"; } + bool evalCall(const CallEvent &Call, CheckerContext &C) const { + if (isCallbackEnabled(C, "EvalCall")) { + llvm::errs() << "EvalCall"; + if (const NamedDecl *ND = dyn_cast_or_null(Call.getDecl())) + llvm::errs() << " (" << ND->getQualifiedNameAsString() << ')'; + llvm::errs() << " {argno: " << Call.getNumArgs() << '}'; + llvm::errs() << " [" << Call.getKindAsString() << ']'; + llvm::errs() << '\n'; + return true; + } + return false; + } + void checkPreCall(const CallEvent &Call, CheckerContext &C) const { if (isCallbackEnabled(C, "PreCall")) { llvm::errs() << "PreCall"; diff --git a/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp index 3eeb1e9a3502e..233ce57c3ac9f 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp @@ -64,10 +64,12 @@ bool BuiltinFunctionChecker::evalCall(const CallEvent &Call, case Builtin::BI__builtin_unpredictable: case Builtin::BI__builtin_expect: + case Builtin::BI__builtin_expect_with_probability: case Builtin::BI__builtin_assume_aligned: case Builtin::BI__builtin_addressof: { - // For __builtin_unpredictable, __builtin_expect, and - // __builtin_assume_aligned, just return the value of the subexpression. + // For __builtin_unpredictable, __builtin_expect, + // __builtin_expect_with_probability and __builtin_assume_aligned, + // just return the value of the subexpression. // __builtin_addressof is going from a reference to a pointer, but those // are represented the same way in the analyzer. assert (Call.getNumArgs() > 0); diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt index 40f520d522fe0..9be1fdeb3ebfa 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt +++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt @@ -98,6 +98,7 @@ add_clang_library(clangStaticAnalyzerCheckers ReturnValueChecker.cpp RunLoopAutoreleaseLeakChecker.cpp SimpleStreamChecker.cpp + SmartPtrChecker.cpp SmartPtrModeling.cpp StackAddrEscapeChecker.cpp StdLibraryFunctionsChecker.cpp @@ -134,4 +135,7 @@ add_clang_library(clangStaticAnalyzerCheckers clangBasic clangLex clangStaticAnalyzerCore + + DEPENDS + omp_gen ) diff --git a/clang/lib/StaticAnalyzer/Checkers/InvalidatedIteratorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/InvalidatedIteratorChecker.cpp index c6cd11b09a4ca..6955ba11a28ff 100644 --- a/clang/lib/StaticAnalyzer/Checkers/InvalidatedIteratorChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/InvalidatedIteratorChecker.cpp @@ -26,7 +26,10 @@ using namespace iterator; namespace { class InvalidatedIteratorChecker - : public Checker { + : public Checker, + check::PreStmt, + check::PreStmt, + check::PreStmt> { std::unique_ptr InvalidatedBugType; @@ -37,6 +40,10 @@ class InvalidatedIteratorChecker InvalidatedIteratorChecker(); void checkPreCall(const CallEvent &Call, CheckerContext &C) const; + void checkPreStmt(const UnaryOperator *UO, CheckerContext &C) const; + void checkPreStmt(const BinaryOperator *BO, CheckerContext &C) const; + void checkPreStmt(const ArraySubscriptExpr *ASE, CheckerContext &C) const; + void checkPreStmt(const MemberExpr *ME, CheckerContext &C) const; }; @@ -65,6 +72,48 @@ void InvalidatedIteratorChecker::checkPreCall(const CallEvent &Call, } } +void InvalidatedIteratorChecker::checkPreStmt(const UnaryOperator *UO, + CheckerContext &C) const { + if (isa(UO->getSubExpr())) + return; + + ProgramStateRef State = C.getState(); + UnaryOperatorKind OK = UO->getOpcode(); + SVal SubVal = State->getSVal(UO->getSubExpr(), C.getLocationContext()); + + if (isAccessOperator(OK)) { + verifyAccess(C, SubVal); + } +} + +void InvalidatedIteratorChecker::checkPreStmt(const BinaryOperator *BO, + CheckerContext &C) const { + ProgramStateRef State = C.getState(); + BinaryOperatorKind OK = BO->getOpcode(); + SVal LVal = State->getSVal(BO->getLHS(), C.getLocationContext()); + + if (isAccessOperator(OK)) { + verifyAccess(C, LVal); + } +} + +void InvalidatedIteratorChecker::checkPreStmt(const ArraySubscriptExpr *ASE, + CheckerContext &C) const { + ProgramStateRef State = C.getState(); + SVal LVal = State->getSVal(ASE->getLHS(), C.getLocationContext()); + verifyAccess(C, LVal); +} + +void InvalidatedIteratorChecker::checkPreStmt(const MemberExpr *ME, + CheckerContext &C) const { + if (!ME->isArrow() || ME->isImplicitAccess()) + return; + + ProgramStateRef State = C.getState(); + SVal BaseVal = State->getSVal(ME->getBase(), C.getLocationContext()); + verifyAccess(C, BaseVal); +} + void InvalidatedIteratorChecker::verifyAccess(CheckerContext &C, const SVal &Val) const { auto State = C.getState(); const auto *Pos = getIteratorPosition(State, Val); diff --git a/clang/lib/StaticAnalyzer/Checkers/Iterator.cpp b/clang/lib/StaticAnalyzer/Checkers/Iterator.cpp index e80d8bc32deca..ac0f24603dd90 100644 --- a/clang/lib/StaticAnalyzer/Checkers/Iterator.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/Iterator.cpp @@ -128,24 +128,54 @@ bool isAccessOperator(OverloadedOperatorKind OK) { isDecrementOperator(OK) || isRandomIncrOrDecrOperator(OK); } +bool isAccessOperator(UnaryOperatorKind OK) { + return isDereferenceOperator(OK) || isIncrementOperator(OK) || + isDecrementOperator(OK); +} + +bool isAccessOperator(BinaryOperatorKind OK) { + return isDereferenceOperator(OK) || isRandomIncrOrDecrOperator(OK); +} + bool isDereferenceOperator(OverloadedOperatorKind OK) { return OK == OO_Star || OK == OO_Arrow || OK == OO_ArrowStar || OK == OO_Subscript; } +bool isDereferenceOperator(UnaryOperatorKind OK) { + return OK == UO_Deref; +} + +bool isDereferenceOperator(BinaryOperatorKind OK) { + return OK == BO_PtrMemI; +} + bool isIncrementOperator(OverloadedOperatorKind OK) { return OK == OO_PlusPlus; } +bool isIncrementOperator(UnaryOperatorKind OK) { + return OK == UO_PreInc || OK == UO_PostInc; +} + bool isDecrementOperator(OverloadedOperatorKind OK) { return OK == OO_MinusMinus; } +bool isDecrementOperator(UnaryOperatorKind OK) { + return OK == UO_PreDec || OK == UO_PostDec; +} + bool isRandomIncrOrDecrOperator(OverloadedOperatorKind OK) { return OK == OO_Plus || OK == OO_PlusEqual || OK == OO_Minus || OK == OO_MinusEqual; } +bool isRandomIncrOrDecrOperator(BinaryOperatorKind OK) { + return OK == BO_Add || OK == BO_AddAssign || + OK == BO_Sub || OK == BO_SubAssign; +} + const ContainerData *getContainerData(ProgramStateRef State, const MemRegion *Cont) { return State->get(Cont); diff --git a/clang/lib/StaticAnalyzer/Checkers/Iterator.h b/clang/lib/StaticAnalyzer/Checkers/Iterator.h index d5c6cb96ebc64..37157492fe3e9 100644 --- a/clang/lib/StaticAnalyzer/Checkers/Iterator.h +++ b/clang/lib/StaticAnalyzer/Checkers/Iterator.h @@ -115,9 +115,12 @@ class IteratorSymbolMap {}; class IteratorRegionMap {}; class ContainerMap {}; -using IteratorSymbolMapTy = CLANG_ENTO_PROGRAMSTATE_MAP(SymbolRef, IteratorPosition); -using IteratorRegionMapTy = CLANG_ENTO_PROGRAMSTATE_MAP(const MemRegion *, IteratorPosition); -using ContainerMapTy = CLANG_ENTO_PROGRAMSTATE_MAP(const MemRegion *, ContainerData); +using IteratorSymbolMapTy = + CLANG_ENTO_PROGRAMSTATE_MAP(SymbolRef, IteratorPosition); +using IteratorRegionMapTy = + CLANG_ENTO_PROGRAMSTATE_MAP(const MemRegion *, IteratorPosition); +using ContainerMapTy = + CLANG_ENTO_PROGRAMSTATE_MAP(const MemRegion *, ContainerData); } // namespace iterator @@ -149,10 +152,17 @@ bool isEraseCall(const FunctionDecl *Func); bool isEraseAfterCall(const FunctionDecl *Func); bool isEmplaceCall(const FunctionDecl *Func); bool isAccessOperator(OverloadedOperatorKind OK); +bool isAccessOperator(UnaryOperatorKind OK); +bool isAccessOperator(BinaryOperatorKind OK); bool isDereferenceOperator(OverloadedOperatorKind OK); +bool isDereferenceOperator(UnaryOperatorKind OK); +bool isDereferenceOperator(BinaryOperatorKind OK); bool isIncrementOperator(OverloadedOperatorKind OK); +bool isIncrementOperator(UnaryOperatorKind OK); bool isDecrementOperator(OverloadedOperatorKind OK); +bool isDecrementOperator(UnaryOperatorKind OK); bool isRandomIncrOrDecrOperator(OverloadedOperatorKind OK); +bool isRandomIncrOrDecrOperator(BinaryOperatorKind OK); const ContainerData *getContainerData(ProgramStateRef State, const MemRegion *Cont); const IteratorPosition *getIteratorPosition(ProgramStateRef State, diff --git a/clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp index e35918edbf89c..fd8cbd694b240 100644 --- a/clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp @@ -83,7 +83,9 @@ using namespace iterator; namespace { class IteratorModeling - : public Checker, + : public Checker, + check::PostStmt, + check::PostStmt, check::Bind, check::LiveSymbols, check::DeadSymbols> { using AdvanceFn = void (IteratorModeling::*)(CheckerContext &, const Expr *, @@ -108,6 +110,8 @@ class IteratorModeling void handleRandomIncrOrDecr(CheckerContext &C, const Expr *CE, OverloadedOperatorKind Op, const SVal &RetVal, const SVal &LHS, const SVal &RHS) const; + void handlePtrIncrOrDecr(CheckerContext &C, const Expr *Iterator, + OverloadedOperatorKind OK, SVal Offset) const; void handleAdvance(CheckerContext &C, const Expr *CE, SVal RetVal, SVal Iter, SVal Amount) const; void handlePrev(CheckerContext &C, const Expr *CE, SVal RetVal, SVal Iter, @@ -144,6 +148,8 @@ class IteratorModeling void checkPostCall(const CallEvent &Call, CheckerContext &C) const; void checkBind(SVal Loc, SVal Val, const Stmt *S, CheckerContext &C) const; + void checkPostStmt(const UnaryOperator *UO, CheckerContext &C) const; + void checkPostStmt(const BinaryOperator *BO, CheckerContext &C) const; void checkPostStmt(const CXXConstructExpr *CCE, CheckerContext &C) const; void checkPostStmt(const DeclStmt *DS, CheckerContext &C) const; void checkPostStmt(const MaterializeTemporaryExpr *MTE, @@ -153,6 +159,7 @@ class IteratorModeling }; bool isSimpleComparisonOperator(OverloadedOperatorKind OK); +bool isSimpleComparisonOperator(BinaryOperatorKind OK); ProgramStateRef removeIteratorPosition(ProgramStateRef State, const SVal &Val); ProgramStateRef relateSymbols(ProgramStateRef State, SymbolRef Sym1, SymbolRef Sym2, bool Equal); @@ -207,12 +214,15 @@ void IteratorModeling::checkPostCall(const CallEvent &Call, } // Assumption: if return value is an iterator which is not yet bound to a - // container, then look for the first iterator argument, and - // bind the return value to the same container. This approach - // works for STL algorithms. + // container, then look for the first iterator argument of the + // same type as the return value and bind the return value to + // the same container. This approach works for STL algorithms. // FIXME: Add a more conservative mode for (unsigned i = 0; i < Call.getNumArgs(); ++i) { - if (isIteratorType(Call.getArgExpr(i)->getType())) { + if (isIteratorType(Call.getArgExpr(i)->getType()) && + Call.getArgExpr(i)->getType().getNonReferenceType().getDesugaredType( + C.getASTContext()).getTypePtr() == + Call.getResultType().getDesugaredType(C.getASTContext()).getTypePtr()) { if (const auto *Pos = getIteratorPosition(State, Call.getArgSVal(i))) { assignToContainer(C, OrigExpr, Call.getReturnValue(), Pos->getContainer()); @@ -238,6 +248,35 @@ void IteratorModeling::checkBind(SVal Loc, SVal Val, const Stmt *S, } } +void IteratorModeling::checkPostStmt(const UnaryOperator *UO, + CheckerContext &C) const { + UnaryOperatorKind OK = UO->getOpcode(); + if (!isIncrementOperator(OK) && !isDecrementOperator(OK)) + return; + + auto &SVB = C.getSValBuilder(); + handlePtrIncrOrDecr(C, UO->getSubExpr(), + isIncrementOperator(OK) ? OO_Plus : OO_Minus, + SVB.makeArrayIndex(1)); +} + +void IteratorModeling::checkPostStmt(const BinaryOperator *BO, + CheckerContext &C) const { + ProgramStateRef State = C.getState(); + BinaryOperatorKind OK = BO->getOpcode(); + SVal RVal = State->getSVal(BO->getRHS(), C.getLocationContext()); + + if (isSimpleComparisonOperator(BO->getOpcode())) { + SVal LVal = State->getSVal(BO->getLHS(), C.getLocationContext()); + SVal Result = State->getSVal(BO, C.getLocationContext()); + handleComparison(C, BO, Result, LVal, RVal, + BinaryOperator::getOverloadedOperator(OK)); + } else if (isRandomIncrOrDecrOperator(OK)) { + handlePtrIncrOrDecr(C, BO->getLHS(), + BinaryOperator::getOverloadedOperator(OK), RVal); + } +} + void IteratorModeling::checkPostStmt(const MaterializeTemporaryExpr *MTE, CheckerContext &C) const { /* Transfer iterator state to temporary objects */ @@ -458,7 +497,7 @@ void IteratorModeling::processComparison(CheckerContext &C, StateTrue = StateTrue->assume(*ConditionVal, true); C.addTransition(StateTrue); } - + if (auto StateFalse = relateSymbols(State, Sym1, Sym2, Op != OO_EqualEqual)) { StateFalse = StateFalse->assume(*ConditionVal, false); C.addTransition(StateFalse); @@ -540,20 +579,65 @@ void IteratorModeling::handleRandomIncrOrDecr(CheckerContext &C, auto &TgtVal = (Op == OO_PlusEqual || Op == OO_MinusEqual) ? LHS : RetVal; - auto NewState = - advancePosition(State, LHS, Op, *value); - if (NewState) { - const auto *NewPos = getIteratorPosition(NewState, LHS); + // `AdvancedState` is a state where the position of `LHS` is advanced. We + // only need this state to retrieve the new position, but we do not want + // to change the position of `LHS` (in every case). + auto AdvancedState = advancePosition(State, LHS, Op, *value); + if (AdvancedState) { + const auto *NewPos = getIteratorPosition(AdvancedState, LHS); assert(NewPos && "Iterator should have position after successful advancement"); - State = setIteratorPosition(NewState, TgtVal, *NewPos); + State = setIteratorPosition(State, TgtVal, *NewPos); C.addTransition(State); } else { assignToContainer(C, CE, TgtVal, Pos->getContainer()); } } +void IteratorModeling::handlePtrIncrOrDecr(CheckerContext &C, + const Expr *Iterator, + OverloadedOperatorKind OK, + SVal Offset) const { + QualType PtrType = Iterator->getType(); + if (!PtrType->isPointerType()) + return; + QualType ElementType = PtrType->getPointeeType(); + + ProgramStateRef State = C.getState(); + SVal OldVal = State->getSVal(Iterator, C.getLocationContext()); + + const IteratorPosition *OldPos = getIteratorPosition(State, OldVal); + if (!OldPos) + return; + + SVal NewVal; + if (OK == OO_Plus || OK == OO_PlusEqual) + NewVal = State->getLValue(ElementType, Offset, OldVal); + else { + const llvm::APSInt &OffsetInt = + Offset.castAs().getValue(); + auto &BVF = C.getSymbolManager().getBasicVals(); + SVal NegatedOffset = nonloc::ConcreteInt(BVF.getValue(-OffsetInt)); + NewVal = State->getLValue(ElementType, NegatedOffset, OldVal); + } + + // `AdvancedState` is a state where the position of `Old` is advanced. We + // only need this state to retrieve the new position, but we do not want + // ever to change the position of `OldVal`. + auto AdvancedState = advancePosition(State, OldVal, OK, Offset); + if (AdvancedState) { + const IteratorPosition *NewPos = getIteratorPosition(AdvancedState, OldVal); + assert(NewPos && + "Iterator should have position after successful advancement"); + + ProgramStateRef NewState = setIteratorPosition(State, NewVal, *NewPos); + C.addTransition(NewState); + } else { + assignToContainer(C, Iterator, NewVal, OldPos->getContainer()); + } +} + void IteratorModeling::handleAdvance(CheckerContext &C, const Expr *CE, SVal RetVal, SVal Iter, SVal Amount) const { @@ -611,10 +695,15 @@ void IteratorModeling::printState(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep) const { auto SymbolMap = State->get(); auto RegionMap = State->get(); + // Use a counter to add newlines before every line except the first one. + unsigned Count = 0; if (!SymbolMap.isEmpty() || !RegionMap.isEmpty()) { Out << Sep << "Iterator Positions :" << NL; for (const auto &Sym : SymbolMap) { + if (Count++) + Out << NL; + Sym.first->dumpToStream(Out); Out << " : "; const auto Pos = Sym.second; @@ -625,6 +714,9 @@ void IteratorModeling::printState(raw_ostream &Out, ProgramStateRef State, } for (const auto &Reg : RegionMap) { + if (Count++) + Out << NL; + Reg.first->dumpToStream(Out); Out << " : "; const auto Pos = Reg.second; @@ -642,6 +734,10 @@ bool isSimpleComparisonOperator(OverloadedOperatorKind OK) { return OK == OO_EqualEqual || OK == OO_ExclaimEqual; } +bool isSimpleComparisonOperator(BinaryOperatorKind OK) { + return OK == BO_EQ || OK == BO_NE; +} + ProgramStateRef removeIteratorPosition(ProgramStateRef State, const SVal &Val) { if (auto Reg = Val.getAsRegion()) { Reg = Reg->getMostDerivedObjectRegion(); diff --git a/clang/lib/StaticAnalyzer/Checkers/IteratorRangeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IteratorRangeChecker.cpp index 6e86ef0c552a9..df8e379d1f20e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/IteratorRangeChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/IteratorRangeChecker.cpp @@ -27,7 +27,10 @@ using namespace iterator; namespace { class IteratorRangeChecker - : public Checker { + : public Checker, + check::PreStmt, + check::PreStmt, + check::PreStmt> { std::unique_ptr OutOfRangeBugType; @@ -46,6 +49,10 @@ class IteratorRangeChecker IteratorRangeChecker(); void checkPreCall(const CallEvent &Call, CheckerContext &C) const; + void checkPreStmt(const UnaryOperator *UO, CheckerContext &C) const; + void checkPreStmt(const BinaryOperator *BO, CheckerContext &C) const; + void checkPreStmt(const ArraySubscriptExpr *ASE, CheckerContext &C) const; + void checkPreStmt(const MemberExpr *ME, CheckerContext &C) const; using AdvanceFn = void (IteratorRangeChecker::*)(CheckerContext &, SVal, SVal) const; @@ -134,6 +141,56 @@ void IteratorRangeChecker::checkPreCall(const CallEvent &Call, } } +void IteratorRangeChecker::checkPreStmt(const UnaryOperator *UO, + CheckerContext &C) const { + if (isa(UO->getSubExpr())) + return; + + ProgramStateRef State = C.getState(); + UnaryOperatorKind OK = UO->getOpcode(); + SVal SubVal = State->getSVal(UO->getSubExpr(), C.getLocationContext()); + + if (isDereferenceOperator(OK)) { + verifyDereference(C, SubVal); + } else if (isIncrementOperator(OK)) { + verifyIncrement(C, SubVal); + } else if (isDecrementOperator(OK)) { + verifyDecrement(C, SubVal); + } +} + +void IteratorRangeChecker::checkPreStmt(const BinaryOperator *BO, + CheckerContext &C) const { + ProgramStateRef State = C.getState(); + BinaryOperatorKind OK = BO->getOpcode(); + SVal LVal = State->getSVal(BO->getLHS(), C.getLocationContext()); + + if (isDereferenceOperator(OK)) { + verifyDereference(C, LVal); + } else if (isRandomIncrOrDecrOperator(OK)) { + SVal RVal = State->getSVal(BO->getRHS(), C.getLocationContext()); + verifyRandomIncrOrDecr(C, BinaryOperator::getOverloadedOperator(OK), LVal, + RVal); + } +} + +void IteratorRangeChecker::checkPreStmt(const ArraySubscriptExpr *ASE, + CheckerContext &C) const { + ProgramStateRef State = C.getState(); + SVal LVal = State->getSVal(ASE->getLHS(), C.getLocationContext()); + verifyDereference(C, LVal); +} + +void IteratorRangeChecker::checkPreStmt(const MemberExpr *ME, + CheckerContext &C) const { + if (!ME->isArrow() || ME->isImplicitAccess()) + return; + + ProgramStateRef State = C.getState(); + SVal BaseVal = State->getSVal(ME->getBase(), C.getLocationContext()); + verifyDereference(C, BaseVal); +} + void IteratorRangeChecker::verifyDereference(CheckerContext &C, SVal Val) const { auto State = C.getState(); diff --git a/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp index d170b875856c2..1960873599f73 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp @@ -28,7 +28,7 @@ using namespace iterator; namespace { class MismatchedIteratorChecker - : public Checker { + : public Checker> { std::unique_ptr MismatchedBugType; @@ -47,6 +47,7 @@ class MismatchedIteratorChecker MismatchedIteratorChecker(); void checkPreCall(const CallEvent &Call, CheckerContext &C) const; + void checkPreStmt(const BinaryOperator *BO, CheckerContext &C) const; }; @@ -141,7 +142,7 @@ void MismatchedIteratorChecker::checkPreCall(const CallEvent &Call, // Example: // template // void f(I1 first1, I1 last1, I2 first2, I2 last2); - // + // // In this case the first two arguments to f() must be iterators must belong // to the same container and the last to also to the same container but // not necessarily to the same as the first two. @@ -188,6 +189,17 @@ void MismatchedIteratorChecker::checkPreCall(const CallEvent &Call, } } +void MismatchedIteratorChecker::checkPreStmt(const BinaryOperator *BO, + CheckerContext &C) const { + if (!BO->isComparisonOp()) + return; + + ProgramStateRef State = C.getState(); + SVal LVal = State->getSVal(BO->getLHS(), C.getLocationContext()); + SVal RVal = State->getSVal(BO->getRHS(), C.getLocationContext()); + verifyMatch(C, LVal, RVal); +} + void MismatchedIteratorChecker::verifyMatch(CheckerContext &C, const SVal &Iter, const MemRegion *Cont) const { // Verify match between a container and the container of an iterator diff --git a/clang/lib/StaticAnalyzer/Checkers/SmartPtr.h b/clang/lib/StaticAnalyzer/Checkers/SmartPtr.h new file mode 100644 index 0000000000000..89b8965e4c9ad --- /dev/null +++ b/clang/lib/StaticAnalyzer/Checkers/SmartPtr.h @@ -0,0 +1,40 @@ +//=== SmartPtr.h - Tracking smart pointer state. -------------------*- C++ -*-// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Defines inter-checker API for the smart pointer modeling. It allows +// dependent checkers to figure out if an smart pointer is null or not. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_SMARTPTR_H +#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_SMARTPTR_H + +#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" + +namespace clang { +namespace ento { +namespace smartptr { + +/// Set of STL smart pointer class which we are trying to model. +const llvm::StringSet<> StdSmartPtrs = { + "shared_ptr", + "unique_ptr", + "weak_ptr", +}; + +/// Returns true if the event call is on smart pointer. +bool isStdSmartPtrCall(const CallEvent &Call); + +/// Returns whether the smart pointer is null or not. +bool isNullSmartPtr(const ProgramStateRef State, const MemRegion *ThisRegion); + +} // namespace smartptr +} // namespace ento +} // namespace clang + +#endif // LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_SMARTPTR_H diff --git a/clang/lib/StaticAnalyzer/Checkers/SmartPtrChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/SmartPtrChecker.cpp new file mode 100644 index 0000000000000..7bb25f397d010 --- /dev/null +++ b/clang/lib/StaticAnalyzer/Checkers/SmartPtrChecker.cpp @@ -0,0 +1,80 @@ +// SmartPtrChecker.cpp - Check for smart pointer dereference - C++ --------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines a checker that check for null dereference of C++ smart +// pointer. +// +//===----------------------------------------------------------------------===// +#include "SmartPtr.h" + +#include "clang/AST/DeclCXX.h" +#include "clang/AST/ExprCXX.h" +#include "clang/AST/Type.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" +#include "clang/StaticAnalyzer/Core/Checker.h" +#include "clang/StaticAnalyzer/Core/CheckerManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h" + +using namespace clang; +using namespace ento; + +namespace { +class SmartPtrChecker : public Checker { + BugType NullDereferenceBugType{this, "Null SmartPtr dereference", + "C++ Smart Pointer"}; + +public: + void checkPreCall(const CallEvent &Call, CheckerContext &C) const; + +private: + void reportBug(CheckerContext &C, const CallEvent &Call) const; +}; +} // end of anonymous namespace + +void SmartPtrChecker::checkPreCall(const CallEvent &Call, + CheckerContext &C) const { + if (!smartptr::isStdSmartPtrCall(Call)) + return; + ProgramStateRef State = C.getState(); + const auto *OC = dyn_cast(&Call); + if (!OC) + return; + const MemRegion *ThisRegion = OC->getCXXThisVal().getAsRegion(); + if (!ThisRegion) + return; + + OverloadedOperatorKind OOK = OC->getOverloadedOperator(); + if (OOK == OO_Star || OOK == OO_Arrow) { + if (smartptr::isNullSmartPtr(State, ThisRegion)) + reportBug(C, Call); + } +} + +void SmartPtrChecker::reportBug(CheckerContext &C, + const CallEvent &Call) const { + ExplodedNode *ErrNode = C.generateErrorNode(); + if (!ErrNode) + return; + + auto R = std::make_unique( + NullDereferenceBugType, "Dereference of null smart pointer", ErrNode); + C.emitReport(std::move(R)); +} + +void ento::registerSmartPtrChecker(CheckerManager &Mgr) { + Mgr.registerChecker(); +} + +bool ento::shouldRegisterSmartPtrChecker(const CheckerManager &mgr) { + const LangOptions &LO = mgr.getLangOpts(); + return LO.CPlusPlus; +} diff --git a/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp index 8250fd46b9266..91f2890788141 100644 --- a/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp @@ -12,27 +12,80 @@ //===----------------------------------------------------------------------===// #include "Move.h" +#include "SmartPtr.h" +#include "clang/AST/DeclCXX.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/Type.h" #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h" using namespace clang; using namespace ento; namespace { -class SmartPtrModeling : public Checker { +class SmartPtrModeling : public Checker { + bool isNullAfterMoveMethod(const CallEvent &Call) const; public: + // Whether the checker should model for null dereferences of smart pointers. + DefaultBool ModelSmartPtrDereference; bool evalCall(const CallEvent &Call, CheckerContext &C) const; + void checkPreCall(const CallEvent &Call, CheckerContext &C) const; + void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const; + +private: + ProgramStateRef updateTrackedRegion(const CallEvent &Call, CheckerContext &C, + const MemRegion *ThisValRegion) const; + void handleReset(const CallEvent &Call, CheckerContext &C) const; + void handleRelease(const CallEvent &Call, CheckerContext &C) const; + void handleSwap(const CallEvent &Call, CheckerContext &C) const; + + using SmartPtrMethodHandlerFn = + void (SmartPtrModeling::*)(const CallEvent &Call, CheckerContext &) const; + CallDescriptionMap SmartPtrMethodHandlers{ + {{"reset"}, &SmartPtrModeling::handleReset}, + {{"release"}, &SmartPtrModeling::handleRelease}, + {{"swap", 1}, &SmartPtrModeling::handleSwap}}; }; } // end of anonymous namespace +REGISTER_MAP_WITH_PROGRAMSTATE(TrackedRegionMap, const MemRegion *, SVal) + +// Define the inter-checker API. +namespace clang { +namespace ento { +namespace smartptr { +bool isStdSmartPtrCall(const CallEvent &Call) { + const auto *MethodDecl = dyn_cast_or_null(Call.getDecl()); + if (!MethodDecl || !MethodDecl->getParent()) + return false; + + const auto *RecordDecl = MethodDecl->getParent(); + if (!RecordDecl || !RecordDecl->getDeclContext()->isStdNamespace()) + return false; + + if (RecordDecl->getDeclName().isIdentifier()) { + return smartptr::StdSmartPtrs.count(RecordDecl->getName().lower()); + } + return false; +} + +bool isNullSmartPtr(const ProgramStateRef State, const MemRegion *ThisRegion) { + const auto *InnerPointVal = State->get(ThisRegion); + return InnerPointVal && InnerPointVal->isZeroConstant(); +} +} // namespace smartptr +} // namespace ento +} // namespace clang + bool SmartPtrModeling::isNullAfterMoveMethod(const CallEvent &Call) const { // TODO: Update CallDescription to support anonymous calls? // TODO: Handle other methods, such as .get() or .release(). @@ -44,27 +97,133 @@ bool SmartPtrModeling::isNullAfterMoveMethod(const CallEvent &Call) const { bool SmartPtrModeling::evalCall(const CallEvent &Call, CheckerContext &C) const { - if (!isNullAfterMoveMethod(Call)) + + if (!smartptr::isStdSmartPtrCall(Call)) return false; - ProgramStateRef State = C.getState(); - const MemRegion *ThisR = - cast(&Call)->getCXXThisVal().getAsRegion(); + if (isNullAfterMoveMethod(Call)) { + ProgramStateRef State = C.getState(); + const MemRegion *ThisR = + cast(&Call)->getCXXThisVal().getAsRegion(); + + if (!move::isMovedFrom(State, ThisR)) { + // TODO: Model this case as well. At least, avoid invalidation of globals. + return false; + } + + // TODO: Add a note to bug reports describing this decision. + C.addTransition( + State->BindExpr(Call.getOriginExpr(), C.getLocationContext(), + C.getSValBuilder().makeZeroVal(Call.getResultType()))); + return true; + } - if (!move::isMovedFrom(State, ThisR)) { - // TODO: Model this case as well. At least, avoid invalidation of globals. + if (!ModelSmartPtrDereference) return false; + + if (const auto *CC = dyn_cast(&Call)) { + if (CC->getDecl()->isCopyOrMoveConstructor()) + return false; + + const MemRegion *ThisValRegion = CC->getCXXThisVal().getAsRegion(); + if (!ThisValRegion) + return false; + + auto State = updateTrackedRegion(Call, C, ThisValRegion); + C.addTransition(State); + return true; + } + + const SmartPtrMethodHandlerFn *Handler = SmartPtrMethodHandlers.lookup(Call); + if (!Handler) + return false; + (this->**Handler)(Call, C); + + return C.isDifferent(); +} + +void SmartPtrModeling::checkDeadSymbols(SymbolReaper &SymReaper, + CheckerContext &C) const { + ProgramStateRef State = C.getState(); + // Clean up dead regions from the region map. + TrackedRegionMapTy TrackedRegions = State->get(); + for (auto E : TrackedRegions) { + const MemRegion *Region = E.first; + bool IsRegDead = !SymReaper.isLiveRegion(Region); + + if (IsRegDead) + State = State->remove(Region); + } + C.addTransition(State); +} + +void SmartPtrModeling::handleReset(const CallEvent &Call, + CheckerContext &C) const { + const auto *IC = dyn_cast(&Call); + if (!IC) + return; + + const MemRegion *ThisValRegion = IC->getCXXThisVal().getAsRegion(); + if (!ThisValRegion) + return; + auto State = updateTrackedRegion(Call, C, ThisValRegion); + C.addTransition(State); + // TODO: Make sure to ivalidate the the region in the Store if we don't have + // time to model all methods. +} + +void SmartPtrModeling::handleRelease(const CallEvent &Call, + CheckerContext &C) const { + const auto *IC = dyn_cast(&Call); + if (!IC) + return; + + const MemRegion *ThisValRegion = IC->getCXXThisVal().getAsRegion(); + if (!ThisValRegion) + return; + + auto State = updateTrackedRegion(Call, C, ThisValRegion); + + const auto *InnerPointVal = State->get(ThisValRegion); + if (InnerPointVal) { + State = State->BindExpr(Call.getOriginExpr(), C.getLocationContext(), + *InnerPointVal); + } + C.addTransition(State); + // TODO: Add support to enable MallocChecker to start tracking the raw + // pointer. +} + +void SmartPtrModeling::handleSwap(const CallEvent &Call, + CheckerContext &C) const { + // TODO: Add support to handle swap method. +} + +ProgramStateRef +SmartPtrModeling::updateTrackedRegion(const CallEvent &Call, CheckerContext &C, + const MemRegion *ThisValRegion) const { + // TODO: Refactor and clean up handling too many things. + ProgramStateRef State = C.getState(); + auto NumArgs = Call.getNumArgs(); + + if (NumArgs == 0) { + auto NullSVal = C.getSValBuilder().makeNull(); + State = State->set(ThisValRegion, NullSVal); + } else if (NumArgs == 1) { + auto ArgVal = Call.getArgSVal(0); + assert(Call.getArgExpr(0)->getType()->isPointerType() && + "Adding a non pointer value to TrackedRegionMap"); + State = State->set(ThisValRegion, ArgVal); } - // TODO: Add a note to bug reports describing this decision. - C.addTransition( - State->BindExpr(Call.getOriginExpr(), C.getLocationContext(), - C.getSValBuilder().makeZeroVal(Call.getResultType()))); - return true; + return State; } void ento::registerSmartPtrModeling(CheckerManager &Mgr) { - Mgr.registerChecker(); + auto *Checker = Mgr.registerChecker(); + Checker->ModelSmartPtrDereference = + Mgr.getAnalyzerOptions().getCheckerBooleanOption( + Checker, "ModelSmartPtrDereference"); } bool ento::shouldRegisterSmartPtrModeling(const CheckerManager &mgr) { diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp index 6feae56502f1f..8b575f4f4759c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -461,6 +461,7 @@ class StdLibraryFunctionsChecker CheckerNameRef CheckNames[CK_NumCheckKinds]; bool DisplayLoadedSummaries = false; + bool ModelPOSIX = false; private: Optional findFunctionSummary(const FunctionDecl *FD, @@ -725,7 +726,8 @@ StdLibraryFunctionsChecker::findFunctionSummary(const CallEvent &Call, return findFunctionSummary(FD, C); } -llvm::Optional lookupType(StringRef Name, const ASTContext &ACtx) { +static llvm::Optional lookupType(StringRef Name, + const ASTContext &ACtx) { IdentifierInfo &II = ACtx.Idents.get(Name); auto LookupRes = ACtx.getTranslationUnitDecl()->lookup(&II); if (LookupRes.size() == 0) @@ -736,13 +738,18 @@ llvm::Optional lookupType(StringRef Name, const ASTContext &ACtx) { // typedef struct FILE FILE; // In this case, we have a RecordDecl 'struct FILE' with the name 'FILE' and // we have a TypedefDecl with the name 'FILE'. - for (Decl *D : LookupRes) { + for (Decl *D : LookupRes) if (auto *TD = dyn_cast(D)) return ACtx.getTypeDeclType(TD).getCanonicalType(); - } - assert(LookupRes.size() == 1 && "Type identifier should be unique"); - auto *D = cast(LookupRes.front()); - return ACtx.getTypeDeclType(D).getCanonicalType(); + + // Find the first TypeDecl. + // There maybe cases when a function has the same name as a struct. + // E.g. in POSIX: `struct stat` and the function `stat()`: + // int stat(const char *restrict path, struct stat *restrict buf); + for (Decl *D : LookupRes) + if (auto *TD = dyn_cast(D)) + return ACtx.getTypeDeclType(TD).getCanonicalType(); + return None; } void StdLibraryFunctionsChecker::initFunctionSummaries( @@ -761,26 +768,46 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( // of function summary for common cases (eg. ssize_t could be int or long // or long long, so three summary variants would be enough). // Of course, function variants are also useful for C++ overloads. + const QualType VoidTy = ACtx.VoidTy; const QualType IntTy = ACtx.IntTy; + const QualType UnsignedIntTy = ACtx.UnsignedIntTy; const QualType LongTy = ACtx.LongTy; const QualType LongLongTy = ACtx.LongLongTy; const QualType SizeTy = ACtx.getSizeType(); + const QualType VoidPtrTy = ACtx.VoidPtrTy; // void * + const QualType IntPtrTy = ACtx.getPointerType(IntTy); // int * + const QualType UnsignedIntPtrTy = + ACtx.getPointerType(UnsignedIntTy); // unsigned int * const QualType VoidPtrRestrictTy = ACtx.getLangOpts().C99 ? ACtx.getRestrictType(VoidPtrTy) // void *restrict : VoidPtrTy; const QualType ConstVoidPtrTy = ACtx.getPointerType(ACtx.VoidTy.withConst()); // const void * + const QualType CharPtrTy = ACtx.getPointerType(ACtx.CharTy); // char * + const QualType CharPtrRestrictTy = + ACtx.getLangOpts().C99 ? ACtx.getRestrictType(CharPtrTy) // char *restrict + : CharPtrTy; const QualType ConstCharPtrTy = ACtx.getPointerType(ACtx.CharTy.withConst()); // const char * + const QualType ConstCharPtrRestrictTy = + ACtx.getLangOpts().C99 + ? ACtx.getRestrictType(ConstCharPtrTy) // const char *restrict + : ConstCharPtrTy; + const QualType Wchar_tPtrTy = ACtx.getPointerType(ACtx.WCharTy); // wchar_t * + const QualType ConstWchar_tPtrTy = + ACtx.getPointerType(ACtx.WCharTy.withConst()); // const wchar_t * const QualType ConstVoidPtrRestrictTy = ACtx.getLangOpts().C99 ? ACtx.getRestrictType(ConstVoidPtrTy) // const void *restrict : ConstVoidPtrTy; const RangeInt IntMax = BVF.getMaxValue(IntTy).getLimitedValue(); + const RangeInt UnsignedIntMax = + BVF.getMaxValue(UnsignedIntTy).getLimitedValue(); const RangeInt LongMax = BVF.getMaxValue(LongTy).getLimitedValue(); const RangeInt LongLongMax = BVF.getMaxValue(LongLongTy).getLimitedValue(); + const RangeInt SizeMax = BVF.getMaxValue(SizeTy).getLimitedValue(); // Set UCharRangeMax to min of int or uchar maximum value. // The C standard states that the arguments of functions like isalpha must @@ -1110,6 +1137,573 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( {Getline(IntTy, IntMax), Getline(LongTy, LongMax), Getline(LongLongTy, LongLongMax)}); + if (ModelPOSIX) { + + // long a64l(const char *str64); + addToFunctionSummaryMap( + "a64l", Summary(ArgTypes{ConstCharPtrTy}, RetType{LongTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // char *l64a(long value); + addToFunctionSummaryMap( + "l64a", Summary(ArgTypes{LongTy}, RetType{CharPtrTy}, NoEvalCall) + .ArgConstraint( + ArgumentCondition(0, WithinRange, Range(0, LongMax)))); + + // int access(const char *pathname, int amode); + addToFunctionSummaryMap("access", Summary(ArgTypes{ConstCharPtrTy, IntTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // int faccessat(int dirfd, const char *pathname, int mode, int flags); + addToFunctionSummaryMap( + "faccessat", Summary(ArgTypes{IntTy, ConstCharPtrTy, IntTy, IntTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(1)))); + + // int dup(int fildes); + addToFunctionSummaryMap( + "dup", Summary(ArgTypes{IntTy}, RetType{IntTy}, NoEvalCall) + .ArgConstraint( + ArgumentCondition(0, WithinRange, Range(0, IntMax)))); + + // int dup2(int fildes1, int filedes2); + addToFunctionSummaryMap( + "dup2", + Summary(ArgTypes{IntTy, IntTy}, RetType{IntTy}, NoEvalCall) + .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax))) + .ArgConstraint( + ArgumentCondition(1, WithinRange, Range(0, IntMax)))); + + // int fdatasync(int fildes); + addToFunctionSummaryMap( + "fdatasync", Summary(ArgTypes{IntTy}, RetType{IntTy}, NoEvalCall) + .ArgConstraint(ArgumentCondition(0, WithinRange, + Range(0, IntMax)))); + + // int fnmatch(const char *pattern, const char *string, int flags); + addToFunctionSummaryMap( + "fnmatch", Summary(ArgTypes{ConstCharPtrTy, ConstCharPtrTy, IntTy}, + RetType{IntTy}, EvalCallAsPure) + .ArgConstraint(NotNull(ArgNo(0))) + .ArgConstraint(NotNull(ArgNo(1)))); + + // int fsync(int fildes); + addToFunctionSummaryMap( + "fsync", Summary(ArgTypes{IntTy}, RetType{IntTy}, NoEvalCall) + .ArgConstraint( + ArgumentCondition(0, WithinRange, Range(0, IntMax)))); + + Optional Off_tTy = lookupType("off_t", ACtx); + + if (Off_tTy) + // int truncate(const char *path, off_t length); + addToFunctionSummaryMap("truncate", + Summary(ArgTypes{ConstCharPtrTy, *Off_tTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // int symlink(const char *oldpath, const char *newpath); + addToFunctionSummaryMap("symlink", + Summary(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0))) + .ArgConstraint(NotNull(ArgNo(1)))); + + // int symlinkat(const char *oldpath, int newdirfd, const char *newpath); + addToFunctionSummaryMap( + "symlinkat", + Summary(ArgTypes{ConstCharPtrTy, IntTy, ConstCharPtrTy}, RetType{IntTy}, + NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0))) + .ArgConstraint(ArgumentCondition(1, WithinRange, Range(0, IntMax))) + .ArgConstraint(NotNull(ArgNo(2)))); + + if (Off_tTy) + // int lockf(int fd, int cmd, off_t len); + addToFunctionSummaryMap( + "lockf", + Summary(ArgTypes{IntTy, IntTy, *Off_tTy}, RetType{IntTy}, NoEvalCall) + .ArgConstraint( + ArgumentCondition(0, WithinRange, Range(0, IntMax)))); + + Optional Mode_tTy = lookupType("mode_t", ACtx); + + if (Mode_tTy) + // int creat(const char *pathname, mode_t mode); + addToFunctionSummaryMap("creat", + Summary(ArgTypes{ConstCharPtrTy, *Mode_tTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // unsigned int sleep(unsigned int seconds); + addToFunctionSummaryMap( + "sleep", + Summary(ArgTypes{UnsignedIntTy}, RetType{UnsignedIntTy}, NoEvalCall) + .ArgConstraint( + ArgumentCondition(0, WithinRange, Range(0, UnsignedIntMax)))); + + Optional DirTy = lookupType("DIR", ACtx); + Optional DirPtrTy; + if (DirTy) + DirPtrTy = ACtx.getPointerType(*DirTy); + + if (DirPtrTy) + // int dirfd(DIR *dirp); + addToFunctionSummaryMap( + "dirfd", Summary(ArgTypes{*DirPtrTy}, RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // unsigned int alarm(unsigned int seconds); + addToFunctionSummaryMap( + "alarm", + Summary(ArgTypes{UnsignedIntTy}, RetType{UnsignedIntTy}, NoEvalCall) + .ArgConstraint( + ArgumentCondition(0, WithinRange, Range(0, UnsignedIntMax)))); + + if (DirPtrTy) + // int closedir(DIR *dir); + addToFunctionSummaryMap( + "closedir", Summary(ArgTypes{*DirPtrTy}, RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // char *strdup(const char *s); + addToFunctionSummaryMap("strdup", Summary(ArgTypes{ConstCharPtrTy}, + RetType{CharPtrTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // char *strndup(const char *s, size_t n); + addToFunctionSummaryMap( + "strndup", Summary(ArgTypes{ConstCharPtrTy, SizeTy}, RetType{CharPtrTy}, + NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0))) + .ArgConstraint(ArgumentCondition(1, WithinRange, + Range(0, SizeMax)))); + + // wchar_t *wcsdup(const wchar_t *s); + addToFunctionSummaryMap("wcsdup", Summary(ArgTypes{ConstWchar_tPtrTy}, + RetType{Wchar_tPtrTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // int mkstemp(char *template); + addToFunctionSummaryMap( + "mkstemp", Summary(ArgTypes{CharPtrTy}, RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // char *mkdtemp(char *template); + addToFunctionSummaryMap( + "mkdtemp", Summary(ArgTypes{CharPtrTy}, RetType{CharPtrTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // char *getcwd(char *buf, size_t size); + addToFunctionSummaryMap( + "getcwd", + Summary(ArgTypes{CharPtrTy, SizeTy}, RetType{CharPtrTy}, NoEvalCall) + .ArgConstraint( + ArgumentCondition(1, WithinRange, Range(0, SizeMax)))); + + if (Mode_tTy) { + // int mkdir(const char *pathname, mode_t mode); + addToFunctionSummaryMap("mkdir", + Summary(ArgTypes{ConstCharPtrTy, *Mode_tTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // int mkdirat(int dirfd, const char *pathname, mode_t mode); + addToFunctionSummaryMap( + "mkdirat", Summary(ArgTypes{IntTy, ConstCharPtrTy, *Mode_tTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(1)))); + } + + Optional Dev_tTy = lookupType("dev_t", ACtx); + + if (Mode_tTy && Dev_tTy) { + // int mknod(const char *pathname, mode_t mode, dev_t dev); + addToFunctionSummaryMap( + "mknod", Summary(ArgTypes{ConstCharPtrTy, *Mode_tTy, *Dev_tTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // int mknodat(int dirfd, const char *pathname, mode_t mode, dev_t dev); + addToFunctionSummaryMap("mknodat", Summary(ArgTypes{IntTy, ConstCharPtrTy, + *Mode_tTy, *Dev_tTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(1)))); + } + + if (Mode_tTy) { + // int chmod(const char *path, mode_t mode); + addToFunctionSummaryMap("chmod", + Summary(ArgTypes{ConstCharPtrTy, *Mode_tTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // int fchmodat(int dirfd, const char *pathname, mode_t mode, int flags); + addToFunctionSummaryMap( + "fchmodat", Summary(ArgTypes{IntTy, ConstCharPtrTy, *Mode_tTy, IntTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(ArgumentCondition(0, WithinRange, + Range(0, IntMax))) + .ArgConstraint(NotNull(ArgNo(1)))); + + // int fchmod(int fildes, mode_t mode); + addToFunctionSummaryMap( + "fchmod", + Summary(ArgTypes{IntTy, *Mode_tTy}, RetType{IntTy}, NoEvalCall) + .ArgConstraint( + ArgumentCondition(0, WithinRange, Range(0, IntMax)))); + } + + Optional Uid_tTy = lookupType("uid_t", ACtx); + Optional Gid_tTy = lookupType("gid_t", ACtx); + + if (Uid_tTy && Gid_tTy) { + // int fchownat(int dirfd, const char *pathname, uid_t owner, gid_t group, + // int flags); + addToFunctionSummaryMap( + "fchownat", + Summary(ArgTypes{IntTy, ConstCharPtrTy, *Uid_tTy, *Gid_tTy, IntTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint( + ArgumentCondition(0, WithinRange, Range(0, IntMax))) + .ArgConstraint(NotNull(ArgNo(1)))); + + // int chown(const char *path, uid_t owner, gid_t group); + addToFunctionSummaryMap( + "chown", Summary(ArgTypes{ConstCharPtrTy, *Uid_tTy, *Gid_tTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // int lchown(const char *path, uid_t owner, gid_t group); + addToFunctionSummaryMap( + "lchown", Summary(ArgTypes{ConstCharPtrTy, *Uid_tTy, *Gid_tTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // int fchown(int fildes, uid_t owner, gid_t group); + addToFunctionSummaryMap( + "fchown", Summary(ArgTypes{IntTy, *Uid_tTy, *Gid_tTy}, RetType{IntTy}, + NoEvalCall) + .ArgConstraint(ArgumentCondition(0, WithinRange, + Range(0, IntMax)))); + } + + // int rmdir(const char *pathname); + addToFunctionSummaryMap( + "rmdir", Summary(ArgTypes{ConstCharPtrTy}, RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // int chdir(const char *path); + addToFunctionSummaryMap( + "chdir", Summary(ArgTypes{ConstCharPtrTy}, RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // int link(const char *oldpath, const char *newpath); + addToFunctionSummaryMap("link", + Summary(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0))) + .ArgConstraint(NotNull(ArgNo(1)))); + + // int linkat(int fd1, const char *path1, int fd2, const char *path2, + // int flag); + addToFunctionSummaryMap( + "linkat", + Summary(ArgTypes{IntTy, ConstCharPtrTy, IntTy, ConstCharPtrTy, IntTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax))) + .ArgConstraint(NotNull(ArgNo(1))) + .ArgConstraint(ArgumentCondition(2, WithinRange, Range(0, IntMax))) + .ArgConstraint(NotNull(ArgNo(3)))); + + // int unlink(const char *pathname); + addToFunctionSummaryMap( + "unlink", Summary(ArgTypes{ConstCharPtrTy}, RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // int unlinkat(int fd, const char *path, int flag); + addToFunctionSummaryMap( + "unlinkat", + Summary(ArgTypes{IntTy, ConstCharPtrTy, IntTy}, RetType{IntTy}, + NoEvalCall) + .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax))) + .ArgConstraint(NotNull(ArgNo(1)))); + + Optional StructStatTy = lookupType("stat", ACtx); + Optional StructStatPtrTy, StructStatPtrRestrictTy; + if (StructStatTy) { + StructStatPtrTy = ACtx.getPointerType(*StructStatTy); + StructStatPtrRestrictTy = ACtx.getLangOpts().C99 + ? ACtx.getRestrictType(*StructStatPtrTy) + : *StructStatPtrTy; + } + + if (StructStatPtrTy) + // int fstat(int fd, struct stat *statbuf); + addToFunctionSummaryMap( + "fstat", + Summary(ArgTypes{IntTy, *StructStatPtrTy}, RetType{IntTy}, NoEvalCall) + .ArgConstraint( + ArgumentCondition(0, WithinRange, Range(0, IntMax))) + .ArgConstraint(NotNull(ArgNo(1)))); + + if (StructStatPtrRestrictTy) { + // int stat(const char *restrict path, struct stat *restrict buf); + addToFunctionSummaryMap( + "stat", + Summary(ArgTypes{ConstCharPtrRestrictTy, *StructStatPtrRestrictTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0))) + .ArgConstraint(NotNull(ArgNo(1)))); + + // int lstat(const char *restrict path, struct stat *restrict buf); + addToFunctionSummaryMap( + "lstat", + Summary(ArgTypes{ConstCharPtrRestrictTy, *StructStatPtrRestrictTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0))) + .ArgConstraint(NotNull(ArgNo(1)))); + + // int fstatat(int fd, const char *restrict path, + // struct stat *restrict buf, int flag); + addToFunctionSummaryMap( + "fstatat", Summary(ArgTypes{IntTy, ConstCharPtrRestrictTy, + *StructStatPtrRestrictTy, IntTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(ArgumentCondition(0, WithinRange, + Range(0, IntMax))) + .ArgConstraint(NotNull(ArgNo(1))) + .ArgConstraint(NotNull(ArgNo(2)))); + } + + if (DirPtrTy) { + // DIR *opendir(const char *name); + addToFunctionSummaryMap("opendir", Summary(ArgTypes{ConstCharPtrTy}, + RetType{*DirPtrTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // DIR *fdopendir(int fd); + addToFunctionSummaryMap( + "fdopendir", Summary(ArgTypes{IntTy}, RetType{*DirPtrTy}, NoEvalCall) + .ArgConstraint(ArgumentCondition(0, WithinRange, + Range(0, IntMax)))); + } + + // int isatty(int fildes); + addToFunctionSummaryMap( + "isatty", Summary(ArgTypes{IntTy}, RetType{IntTy}, NoEvalCall) + .ArgConstraint( + ArgumentCondition(0, WithinRange, Range(0, IntMax)))); + + if (FilePtrTy) { + // FILE *popen(const char *command, const char *type); + addToFunctionSummaryMap("popen", + Summary(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, + RetType{*FilePtrTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0))) + .ArgConstraint(NotNull(ArgNo(1)))); + + // int pclose(FILE *stream); + addToFunctionSummaryMap( + "pclose", Summary(ArgTypes{*FilePtrTy}, RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + } + + // int close(int fildes); + addToFunctionSummaryMap( + "close", Summary(ArgTypes{IntTy}, RetType{IntTy}, NoEvalCall) + .ArgConstraint( + ArgumentCondition(0, WithinRange, Range(0, IntMax)))); + + // long fpathconf(int fildes, int name); + addToFunctionSummaryMap( + "fpathconf", + Summary(ArgTypes{IntTy, IntTy}, RetType{LongTy}, NoEvalCall) + .ArgConstraint( + ArgumentCondition(0, WithinRange, Range(0, IntMax)))); + + // long pathconf(const char *path, int name); + addToFunctionSummaryMap("pathconf", Summary(ArgTypes{ConstCharPtrTy, IntTy}, + RetType{LongTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + if (FilePtrTy) + // FILE *fdopen(int fd, const char *mode); + addToFunctionSummaryMap( + "fdopen", Summary(ArgTypes{IntTy, ConstCharPtrTy}, + RetType{*FilePtrTy}, NoEvalCall) + .ArgConstraint( + ArgumentCondition(0, WithinRange, Range(0, IntMax))) + .ArgConstraint(NotNull(ArgNo(1)))); + + if (DirPtrTy) { + // void rewinddir(DIR *dir); + addToFunctionSummaryMap( + "rewinddir", Summary(ArgTypes{*DirPtrTy}, RetType{VoidTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // void seekdir(DIR *dirp, long loc); + addToFunctionSummaryMap("seekdir", Summary(ArgTypes{*DirPtrTy, LongTy}, + RetType{VoidTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + } + + // int rand_r(unsigned int *seedp); + addToFunctionSummaryMap("rand_r", Summary(ArgTypes{UnsignedIntPtrTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // int strcasecmp(const char *s1, const char *s2); + addToFunctionSummaryMap("strcasecmp", + Summary(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, + RetType{IntTy}, EvalCallAsPure) + .ArgConstraint(NotNull(ArgNo(0))) + .ArgConstraint(NotNull(ArgNo(1)))); + + // int strncasecmp(const char *s1, const char *s2, size_t n); + addToFunctionSummaryMap( + "strncasecmp", Summary(ArgTypes{ConstCharPtrTy, ConstCharPtrTy, SizeTy}, + RetType{IntTy}, EvalCallAsPure) + .ArgConstraint(NotNull(ArgNo(0))) + .ArgConstraint(NotNull(ArgNo(1))) + .ArgConstraint(ArgumentCondition( + 2, WithinRange, Range(0, SizeMax)))); + + if (FilePtrTy && Off_tTy) { + + // int fileno(FILE *stream); + addToFunctionSummaryMap( + "fileno", Summary(ArgTypes{*FilePtrTy}, RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // int fseeko(FILE *stream, off_t offset, int whence); + addToFunctionSummaryMap("fseeko", + Summary(ArgTypes{*FilePtrTy, *Off_tTy, IntTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // off_t ftello(FILE *stream); + addToFunctionSummaryMap( + "ftello", Summary(ArgTypes{*FilePtrTy}, RetType{*Off_tTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + } + + if (Off_tTy) { + Optional Off_tMax = BVF.getMaxValue(*Off_tTy).getLimitedValue(); + + // void *mmap(void *addr, size_t length, int prot, int flags, int fd, + // off_t offset); + addToFunctionSummaryMap( + "mmap", + Summary(ArgTypes{VoidPtrTy, SizeTy, IntTy, IntTy, IntTy, *Off_tTy}, + RetType{VoidPtrTy}, NoEvalCall) + .ArgConstraint( + ArgumentCondition(1, WithinRange, Range(1, SizeMax))) + .ArgConstraint( + ArgumentCondition(4, WithinRange, Range(0, *Off_tMax)))); + } + + Optional Off64_tTy = lookupType("off64_t", ACtx); + Optional Off64_tMax; + if (Off64_tTy) { + Off64_tMax = BVF.getMaxValue(*Off_tTy).getLimitedValue(); + // void *mmap64(void *addr, size_t length, int prot, int flags, int fd, + // off64_t offset); + addToFunctionSummaryMap( + "mmap64", + Summary(ArgTypes{VoidPtrTy, SizeTy, IntTy, IntTy, IntTy, *Off64_tTy}, + RetType{VoidPtrTy}, NoEvalCall) + .ArgConstraint( + ArgumentCondition(1, WithinRange, Range(1, SizeMax))) + .ArgConstraint( + ArgumentCondition(4, WithinRange, Range(0, *Off64_tMax)))); + } + + // int pipe(int fildes[2]); + addToFunctionSummaryMap( + "pipe", Summary(ArgTypes{IntPtrTy}, RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + if (Off_tTy) + // off_t lseek(int fildes, off_t offset, int whence); + addToFunctionSummaryMap( + "lseek", Summary(ArgTypes{IntTy, *Off_tTy, IntTy}, RetType{*Off_tTy}, + NoEvalCall) + .ArgConstraint(ArgumentCondition(0, WithinRange, + Range(0, IntMax)))); + + Optional Ssize_tTy = lookupType("ssize_t", ACtx); + + if (Ssize_tTy) { + // ssize_t readlink(const char *restrict path, char *restrict buf, + // size_t bufsize); + addToFunctionSummaryMap( + "readlink", + Summary(ArgTypes{ConstCharPtrRestrictTy, CharPtrRestrictTy, SizeTy}, + RetType{*Ssize_tTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0))) + .ArgConstraint(NotNull(ArgNo(1))) + .ArgConstraint(BufferSize(/*Buffer=*/ArgNo(1), + /*BufSize=*/ArgNo(2))) + .ArgConstraint( + ArgumentCondition(2, WithinRange, Range(0, SizeMax)))); + + // ssize_t readlinkat(int fd, const char *restrict path, + // char *restrict buf, size_t bufsize); + addToFunctionSummaryMap( + "readlinkat", Summary(ArgTypes{IntTy, ConstCharPtrRestrictTy, + CharPtrRestrictTy, SizeTy}, + RetType{*Ssize_tTy}, NoEvalCall) + .ArgConstraint(ArgumentCondition(0, WithinRange, + Range(0, IntMax))) + .ArgConstraint(NotNull(ArgNo(1))) + .ArgConstraint(NotNull(ArgNo(2))) + .ArgConstraint(BufferSize(/*Buffer=*/ArgNo(2), + /*BufSize=*/ArgNo(3))) + .ArgConstraint(ArgumentCondition( + 3, WithinRange, Range(0, SizeMax)))); + } + + // int renameat(int olddirfd, const char *oldpath, int newdirfd, const char + // *newpath); + addToFunctionSummaryMap("renameat", Summary(ArgTypes{IntTy, ConstCharPtrTy, + IntTy, ConstCharPtrTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(1))) + .ArgConstraint(NotNull(ArgNo(3)))); + + // char *realpath(const char *restrict file_name, + // char *restrict resolved_name); + addToFunctionSummaryMap( + "realpath", Summary(ArgTypes{ConstCharPtrRestrictTy, CharPtrRestrictTy}, + RetType{CharPtrTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + QualType CharPtrConstPtr = ACtx.getPointerType(CharPtrTy.withConst()); + + // int execv(const char *path, char *const argv[]); + addToFunctionSummaryMap("execv", + Summary(ArgTypes{ConstCharPtrTy, CharPtrConstPtr}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // int execvp(const char *file, char *const argv[]); + addToFunctionSummaryMap("execvp", + Summary(ArgTypes{ConstCharPtrTy, CharPtrConstPtr}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(NotNull(ArgNo(0)))); + + // int getopt(int argc, char * const argv[], const char *optstring); + addToFunctionSummaryMap( + "getopt", + Summary(ArgTypes{IntTy, CharPtrConstPtr, ConstCharPtrTy}, + RetType{IntTy}, NoEvalCall) + .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax))) + .ArgConstraint(NotNull(ArgNo(1))) + .ArgConstraint(NotNull(ArgNo(2)))); + } + // Functions for testing. if (ChecksEnabled[CK_StdCLibraryFunctionsTesterChecker]) { addToFunctionSummaryMap( @@ -1151,6 +1745,8 @@ void ento::registerStdCLibraryFunctionsChecker(CheckerManager &mgr) { Checker->DisplayLoadedSummaries = mgr.getAnalyzerOptions().getCheckerBooleanOption( Checker, "DisplayLoadedSummaries"); + Checker->ModelPOSIX = + mgr.getAnalyzerOptions().getCheckerBooleanOption(Checker, "ModelPOSIX"); } bool ento::shouldRegisterStdCLibraryFunctionsChecker(const CheckerManager &mgr) { diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp index 7e10b2aa43568..f6abbe4f8f03b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp @@ -195,29 +195,16 @@ ProgramStateRef bindInt(uint64_t Value, ProgramStateRef State, class StreamChecker : public Checker { - BuiltinBug BT_FileNull{this, "NULL stream pointer", - "Stream pointer might be NULL."}; - BuiltinBug BT_UseAfterClose{ - this, "Closed stream", - "Stream might be already closed. Causes undefined behaviour."}; - BuiltinBug BT_UseAfterOpenFailed{this, "Invalid stream", - "Stream might be invalid after " - "(re-)opening it has failed. " - "Can cause undefined behaviour."}; - BuiltinBug BT_IndeterminatePosition{ - this, "Invalid stream state", - "File position of the stream might be 'indeterminate' " - "after a failed operation. " - "Can cause undefined behavior."}; - BuiltinBug BT_IllegalWhence{this, "Illegal whence argument", - "The whence argument to fseek() should be " - "SEEK_SET, SEEK_END, or SEEK_CUR."}; - BuiltinBug BT_StreamEof{this, "Stream already in EOF", - "Read function called when stream is in EOF state. " - "Function has no effect."}; - BuiltinBug BT_ResourceLeak{ - this, "Resource Leak", - "Opened File never closed. Potential Resource leak."}; + BugType BT_FileNull{this, "NULL stream pointer", "Stream handling error"}; + BugType BT_UseAfterClose{this, "Closed stream", "Stream handling error"}; + BugType BT_UseAfterOpenFailed{this, "Invalid stream", + "Stream handling error"}; + BugType BT_IndeterminatePosition{this, "Invalid stream state", + "Stream handling error"}; + BugType BT_IllegalWhence{this, "Illegal whence argument", + "Stream handling error"}; + BugType BT_StreamEof{this, "Stream already in EOF", "Stream handling error"}; + BugType BT_ResourceLeak{this, "Resource leak", "Stream handling error"}; public: void checkPreCall(const CallEvent &Call, CheckerContext &C) const; @@ -365,6 +352,33 @@ class StreamChecker : public CheckergetState(); + // When bug type is resource leak, exploded node N may not have state info + // for leaked file descriptor, but predecessor should have it. + if (!State->get(StreamSym)) + N = N->getFirstPred(); + + const ExplodedNode *Pred = N; + while (N) { + State = N->getState(); + if (!State->get(StreamSym)) + return Pred; + Pred = N; + N = N->getFirstPred(); + } + + return nullptr; +} + void StreamChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const { const FnDescription *Desc = lookupFn(Call); @@ -421,7 +456,8 @@ void StreamChecker::evalFopen(const FnDescription *Desc, const CallEvent &Call, StateNull = StateNull->set(RetSym, StreamState::getOpenFailed(Desc)); - C.addTransition(StateNotNull); + C.addTransition(StateNotNull, + constructNoteTag(C, RetSym, "Stream opened here")); C.addTransition(StateNull); } @@ -476,7 +512,8 @@ void StreamChecker::evalFreopen(const FnDescription *Desc, StateRetNull = StateRetNull->set(StreamSym, StreamState::getOpenFailed(Desc)); - C.addTransition(StateRetNotNull); + C.addTransition(StateRetNotNull, + constructNoteTag(C, StreamSym, "Stream reopened here")); C.addTransition(StateRetNull); } @@ -784,7 +821,7 @@ StreamChecker::ensureStreamNonNull(SVal StreamVal, CheckerContext &C, if (!StateNotNull && StateNull) { if (ExplodedNode *N = C.generateErrorNode(StateNull)) { C.emitReport(std::make_unique( - BT_FileNull, BT_FileNull.getDescription(), N)); + BT_FileNull, "Stream pointer might be NULL.", N)); } return nullptr; } @@ -809,7 +846,8 @@ ProgramStateRef StreamChecker::ensureStreamOpened(SVal StreamVal, ExplodedNode *N = C.generateErrorNode(); if (N) { C.emitReport(std::make_unique( - BT_UseAfterClose, BT_UseAfterClose.getDescription(), N)); + BT_UseAfterClose, + "Stream might be already closed. Causes undefined behaviour.", N)); return nullptr; } @@ -824,7 +862,11 @@ ProgramStateRef StreamChecker::ensureStreamOpened(SVal StreamVal, ExplodedNode *N = C.generateErrorNode(); if (N) { C.emitReport(std::make_unique( - BT_UseAfterOpenFailed, BT_UseAfterOpenFailed.getDescription(), N)); + BT_UseAfterOpenFailed, + "Stream might be invalid after " + "(re-)opening it has failed. " + "Can cause undefined behaviour.", + N)); return nullptr; } return State; @@ -835,6 +877,11 @@ ProgramStateRef StreamChecker::ensureStreamOpened(SVal StreamVal, ProgramStateRef StreamChecker::ensureNoFilePositionIndeterminate( SVal StreamVal, CheckerContext &C, ProgramStateRef State) const { + static const char *BugMessage = + "File position of the stream might be 'indeterminate' " + "after a failed operation. " + "Can cause undefined behavior."; + SymbolRef Sym = StreamVal.getAsSymbol(); if (!Sym) return State; @@ -855,8 +902,7 @@ ProgramStateRef StreamChecker::ensureNoFilePositionIndeterminate( return nullptr; C.emitReport(std::make_unique( - BT_IndeterminatePosition, BT_IndeterminatePosition.getDescription(), - N)); + BT_IndeterminatePosition, BugMessage, N)); return State->set( Sym, StreamState::getOpened(SS->LastOperation, ErrorFEof, false)); } @@ -866,8 +912,7 @@ ProgramStateRef StreamChecker::ensureNoFilePositionIndeterminate( ExplodedNode *N = C.generateErrorNode(State); if (N) C.emitReport(std::make_unique( - BT_IndeterminatePosition, BT_IndeterminatePosition.getDescription(), - N)); + BT_IndeterminatePosition, BugMessage, N)); return nullptr; } @@ -888,7 +933,10 @@ StreamChecker::ensureFseekWhenceCorrect(SVal WhenceVal, CheckerContext &C, if (ExplodedNode *N = C.generateNonFatalErrorNode(State)) { C.emitReport(std::make_unique( - BT_IllegalWhence, BT_IllegalWhence.getDescription(), N)); + BT_IllegalWhence, + "The whence argument to fseek() should be " + "SEEK_SET, SEEK_END, or SEEK_CUR.", + N)); return nullptr; } @@ -899,7 +947,10 @@ void StreamChecker::reportFEofWarning(CheckerContext &C, ProgramStateRef State) const { if (ExplodedNode *N = C.generateNonFatalErrorNode(State)) { C.emitReport(std::make_unique( - BT_StreamEof, BT_StreamEof.getDescription(), N)); + BT_StreamEof, + "Read function called when stream is in EOF state. " + "Function has no effect.", + N)); return; } C.addTransition(State); @@ -921,8 +972,39 @@ void StreamChecker::checkDeadSymbols(SymbolReaper &SymReaper, if (!N) continue; - C.emitReport(std::make_unique( - BT_ResourceLeak, BT_ResourceLeak.getDescription(), N)); + // Do not warn for non-closed stream at program exit. + ExplodedNode *Pred = C.getPredecessor(); + if (Pred && Pred->getCFGBlock() && + Pred->getCFGBlock()->hasNoReturnElement()) + continue; + + // Resource leaks can result in multiple warning that describe the same kind + // of programming error: + // void f() { + // FILE *F = fopen("a.txt"); + // if (rand()) // state split + // return; // warning + // } // warning + // While this isn't necessarily true (leaking the same stream could result + // from a different kinds of errors), the reduction in redundant reports + // makes this a worthwhile heuristic. + // FIXME: Add a checker option to turn this uniqueing feature off. + + const ExplodedNode *StreamOpenNode = getAcquisitionSite(N, Sym, C); + assert(StreamOpenNode && "Could not find place of stream opening."); + PathDiagnosticLocation LocUsedForUniqueing = + PathDiagnosticLocation::createBegin( + StreamOpenNode->getStmtForDiagnostics(), C.getSourceManager(), + StreamOpenNode->getLocationContext()); + + std::unique_ptr R = + std::make_unique( + BT_ResourceLeak, + "Opened stream never closed. Potential resource leak.", N, + LocUsedForUniqueing, + StreamOpenNode->getLocationContext()->getDecl()); + R->markInteresting(Sym); + C.emitReport(std::move(R)); } } diff --git a/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp index e0be718decb29..4182b51c02b08 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp @@ -541,14 +541,11 @@ static bool hasUnguardedAccess(const FieldDecl *FD, ProgramStateRef State) { auto FieldAccessM = memberExpr(hasDeclaration(equalsNode(FD))).bind("access"); auto AssertLikeM = callExpr(callee(functionDecl( - anyOf(hasName("exit"), hasName("panic"), hasName("error"), - hasName("Assert"), hasName("assert"), hasName("ziperr"), - hasName("assfail"), hasName("db_error"), hasName("__assert"), - hasName("__assert2"), hasName("_wassert"), hasName("__assert_rtn"), - hasName("__assert_fail"), hasName("dtrace_assfail"), - hasName("yy_fatal_error"), hasName("_XCAssertionFailureHandler"), - hasName("_DTAssertionFailureHandler"), - hasName("_TSAssertionFailureHandler"))))); + hasAnyName("exit", "panic", "error", "Assert", "assert", "ziperr", + "assfail", "db_error", "__assert", "__assert2", "_wassert", + "__assert_rtn", "__assert_fail", "dtrace_assfail", + "yy_fatal_error", "_XCAssertionFailureHandler", + "_DTAssertionFailureHandler", "_TSAssertionFailureHandler")))); auto NoReturnFuncM = callExpr(callee(functionDecl(isNoReturn()))); diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp index efae511da83b4..72be4e81c83d6 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -34,10 +34,12 @@ #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" +#include "clang/StaticAnalyzer/Core/CheckerRegistryData.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" #include "llvm/ADT/ArrayRef.h" @@ -2106,6 +2108,53 @@ void BuiltinBug::anchor() {} // Methods for BugReport and subclasses. //===----------------------------------------------------------------------===// +LLVM_ATTRIBUTE_USED static bool +isDependency(const CheckerRegistryData &Registry, StringRef CheckerName) { + for (const std::pair &Pair : Registry.Dependencies) { + if (Pair.second == CheckerName) + return true; + } + return false; +} + +LLVM_ATTRIBUTE_USED static bool isHidden(const CheckerRegistryData &Registry, + StringRef CheckerName) { + for (const CheckerInfo &Checker : Registry.Checkers) { + if (Checker.FullName == CheckerName) + return Checker.IsHidden; + } + llvm_unreachable( + "Checker name not found in CheckerRegistry -- did you retrieve it " + "correctly from CheckerManager::getCurrentCheckerName?"); +} + +PathSensitiveBugReport::PathSensitiveBugReport( + const BugType &bt, StringRef shortDesc, StringRef desc, + const ExplodedNode *errorNode, PathDiagnosticLocation LocationToUnique, + const Decl *DeclToUnique) + : BugReport(Kind::PathSensitive, bt, shortDesc, desc), ErrorNode(errorNode), + ErrorNodeRange(getStmt() ? getStmt()->getSourceRange() : SourceRange()), + UniqueingLocation(LocationToUnique), UniqueingDecl(DeclToUnique) { + assert(!isDependency(ErrorNode->getState() + ->getAnalysisManager() + .getCheckerManager() + ->getCheckerRegistryData(), + bt.getCheckerName()) && + "Some checkers depend on this one! We don't allow dependency " + "checkers to emit warnings, because checkers should depend on " + "*modeling*, not *diagnostics*."); + + assert( + (bt.getCheckerName().startswith("debug") || + !isHidden(ErrorNode->getState() + ->getAnalysisManager() + .getCheckerManager() + ->getCheckerRegistryData(), + bt.getCheckerName())) && + "Hidden checkers musn't emit diagnostics as they are by definition " + "non-user facing!"); +} + void PathSensitiveBugReport::addVisitor( std::unique_ptr visitor) { if (!visitor) @@ -2194,12 +2243,12 @@ static void insertToInterestingnessMap( return; case bugreporter::TrackingKind::Condition: return; - } + } - llvm_unreachable( - "BugReport::markInteresting currently can only handle 2 different " - "tracking kinds! Please define what tracking kind should this entitiy" - "have, if it was already marked as interesting with a different kind!"); + llvm_unreachable( + "BugReport::markInteresting currently can only handle 2 different " + "tracking kinds! Please define what tracking kind should this entitiy" + "have, if it was already marked as interesting with a different kind!"); } void PathSensitiveBugReport::markInteresting(SymbolRef sym, @@ -2783,7 +2832,7 @@ Optional PathDiagnosticBuilder::findValidReport( R->clearVisitors(); R->addVisitor(std::make_unique()); - // We don't overrite the notes inserted by other visitors because the + // We don't overwrite the notes inserted by other visitors because the // refutation manager does not add any new note to the path generateVisitorsDiagnostics(R, BugPath->ErrorNode, BRC); } diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index ad79f7cb9359f..ef4d38ff498ff 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -2819,7 +2819,7 @@ void FalsePositiveRefutationBRVisitor::finalizeVisitor( BugReporterContext &BRC, const ExplodedNode *EndPathNode, PathSensitiveBugReport &BR) { // Collect new constraints - VisitNode(EndPathNode, BRC, BR); + addConstraints(EndPathNode, /*OverwriteConstraintsOnExistingSyms=*/true); // Create a refutation manager llvm::SMTSolverRef RefutationSolver = llvm::CreateZ3Solver(); @@ -2830,30 +2830,30 @@ void FalsePositiveRefutationBRVisitor::finalizeVisitor( const SymbolRef Sym = I.first; auto RangeIt = I.second.begin(); - llvm::SMTExprRef Constraints = SMTConv::getRangeExpr( + llvm::SMTExprRef SMTConstraints = SMTConv::getRangeExpr( RefutationSolver, Ctx, Sym, RangeIt->From(), RangeIt->To(), /*InRange=*/true); while ((++RangeIt) != I.second.end()) { - Constraints = RefutationSolver->mkOr( - Constraints, SMTConv::getRangeExpr(RefutationSolver, Ctx, Sym, - RangeIt->From(), RangeIt->To(), - /*InRange=*/true)); + SMTConstraints = RefutationSolver->mkOr( + SMTConstraints, SMTConv::getRangeExpr(RefutationSolver, Ctx, Sym, + RangeIt->From(), RangeIt->To(), + /*InRange=*/true)); } - RefutationSolver->addConstraint(Constraints); + RefutationSolver->addConstraint(SMTConstraints); } // And check for satisfiability - Optional isSat = RefutationSolver->check(); - if (!isSat.hasValue()) + Optional IsSAT = RefutationSolver->check(); + if (!IsSAT.hasValue()) return; - if (!isSat.getValue()) + if (!IsSAT.getValue()) BR.markInvalid("Infeasible constraints", EndPathNode->getLocationContext()); } -PathDiagnosticPieceRef FalsePositiveRefutationBRVisitor::VisitNode( - const ExplodedNode *N, BugReporterContext &, PathSensitiveBugReport &) { +void FalsePositiveRefutationBRVisitor::addConstraints( + const ExplodedNode *N, bool OverwriteConstraintsOnExistingSyms) { // Collect new constraints const ConstraintRangeTy &NewCs = N->getState()->get(); ConstraintRangeTy::Factory &CF = @@ -2863,10 +2863,19 @@ PathDiagnosticPieceRef FalsePositiveRefutationBRVisitor::VisitNode( for (auto const &C : NewCs) { const SymbolRef &Sym = C.first; if (!Constraints.contains(Sym)) { + // This symbol is new, just add the constraint. + Constraints = CF.add(Constraints, Sym, C.second); + } else if (OverwriteConstraintsOnExistingSyms) { + // Overwrite the associated constraint of the Symbol. + Constraints = CF.remove(Constraints, Sym); Constraints = CF.add(Constraints, Sym, C.second); } } +} +PathDiagnosticPieceRef FalsePositiveRefutationBRVisitor::VisitNode( + const ExplodedNode *N, BugReporterContext &, PathSensitiveBugReport &) { + addConstraints(N, /*OverwriteConstraintsOnExistingSyms=*/false); return nullptr; } diff --git a/clang/lib/StaticAnalyzer/Core/CMakeLists.txt b/clang/lib/StaticAnalyzer/Core/CMakeLists.txt index 233ffaf799568..f2329ae6042ef 100644 --- a/clang/lib/StaticAnalyzer/Core/CMakeLists.txt +++ b/clang/lib/StaticAnalyzer/Core/CMakeLists.txt @@ -16,6 +16,7 @@ add_clang_library(clangStaticAnalyzerCore CheckerContext.cpp CheckerHelpers.cpp CheckerManager.cpp + CheckerRegistryData.cpp CommonBugCategories.cpp ConstraintManager.cpp CoreEngine.cpp @@ -60,5 +61,8 @@ add_clang_library(clangStaticAnalyzerCore clangLex clangRewrite clangToolingCore + + DEPENDS + omp_gen ) diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp index b8d8d467341d8..78d13ddfb773c 100644 --- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp +++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp @@ -523,7 +523,7 @@ CallEvent::getReturnValueUnderConstruction() const { if (!CC) return None; - ExprEngine::EvalCallOptions CallOpts; + EvalCallOptions CallOpts; ExprEngine &Engine = getState()->getStateManager().getOwningEngine(); SVal RetVal = Engine.computeObjectUnderConstruction(getOriginExpr(), getState(), diff --git a/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp b/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp index 98504006030a7..86cecf6524f03 100644 --- a/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp +++ b/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp @@ -653,7 +653,8 @@ CheckerManager::runCheckersForEvalAssume(ProgramStateRef state, void CheckerManager::runCheckersForEvalCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &Call, - ExprEngine &Eng) { + ExprEngine &Eng, + const EvalCallOptions &CallOpts) { for (auto *const Pred : Src) { bool anyEvaluated = false; @@ -665,10 +666,8 @@ void CheckerManager::runCheckersForEvalCall(ExplodedNodeSet &Dst, // TODO: Support the situation when the call doesn't correspond // to any Expr. ProgramPoint L = ProgramPoint::getProgramPoint( - cast(Call.getOriginExpr()), - ProgramPoint::PostStmtKind, - Pred->getLocationContext(), - EvalCallChecker.Checker); + Call.getOriginExpr(), ProgramPoint::PostStmtKind, + Pred->getLocationContext(), EvalCallChecker.Checker); bool evaluated = false; { // CheckerContext generates transitions(populates checkDest) on // destruction, so introduce the scope to make sure it gets properly @@ -690,7 +689,7 @@ void CheckerManager::runCheckersForEvalCall(ExplodedNodeSet &Dst, // If none of the checkers evaluated the call, ask ExprEngine to handle it. if (!anyEvaluated) { NodeBuilder B(Pred, Dst, Eng.getBuilderContext()); - Eng.defaultEvalCall(B, Pred, Call); + Eng.defaultEvalCall(B, Pred, Call, CallOpts); } } } diff --git a/clang/lib/StaticAnalyzer/Core/CheckerRegistryData.cpp b/clang/lib/StaticAnalyzer/Core/CheckerRegistryData.cpp new file mode 100644 index 0000000000000..1b3e8b11549dd --- /dev/null +++ b/clang/lib/StaticAnalyzer/Core/CheckerRegistryData.cpp @@ -0,0 +1,241 @@ +//===- CheckerRegistry.h - Maintains all available checkers -----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clang/StaticAnalyzer/Core/CheckerRegistryData.h" +#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" +#include "llvm/ADT/Twine.h" +#include + +using namespace clang; +using namespace ento; + +//===----------------------------------------------------------------------===// +// Methods of CmdLineOption, PackageInfo and CheckerInfo. +//===----------------------------------------------------------------------===// + +LLVM_DUMP_METHOD void CmdLineOption::dump() const { + dumpToStream(llvm::errs()); +} + +LLVM_DUMP_METHOD void +CmdLineOption::dumpToStream(llvm::raw_ostream &Out) const { + // The description can be just checked in Checkers.inc, the point here is to + // debug whether we succeeded in parsing it. + Out << OptionName << " (" << OptionType << ", " + << (IsHidden ? "hidden, " : "") << DevelopmentStatus << ") default: \"" + << DefaultValStr; +} + +static StringRef toString(StateFromCmdLine Kind) { + switch (Kind) { + case StateFromCmdLine::State_Disabled: + return "Disabled"; + case StateFromCmdLine::State_Enabled: + return "Enabled"; + case StateFromCmdLine::State_Unspecified: + return "Unspecified"; + } + llvm_unreachable("Unhandled StateFromCmdLine enum"); +} + +LLVM_DUMP_METHOD void CheckerInfo::dump() const { dumpToStream(llvm::errs()); } + +LLVM_DUMP_METHOD void CheckerInfo::dumpToStream(llvm::raw_ostream &Out) const { + // The description can be just checked in Checkers.inc, the point here is to + // debug whether we succeeded in parsing it. Same with documentation uri. + Out << FullName << " (" << toString(State) << (IsHidden ? ", hidden" : "") + << ")\n"; + Out << " Options:\n"; + for (const CmdLineOption &Option : CmdLineOptions) { + Out << " "; + Option.dumpToStream(Out); + Out << '\n'; + } + Out << " Dependencies:\n"; + for (const CheckerInfo *Dependency : Dependencies) { + Out << " " << Dependency->FullName << '\n'; + } + Out << " Weak dependencies:\n"; + for (const CheckerInfo *Dependency : WeakDependencies) { + Out << " " << Dependency->FullName << '\n'; + } +} + +LLVM_DUMP_METHOD void PackageInfo::dump() const { dumpToStream(llvm::errs()); } + +LLVM_DUMP_METHOD void PackageInfo::dumpToStream(llvm::raw_ostream &Out) const { + Out << FullName << "\n"; + Out << " Options:\n"; + for (const CmdLineOption &Option : CmdLineOptions) { + Out << " "; + Option.dumpToStream(Out); + Out << '\n'; + } +} + +static constexpr char PackageSeparator = '.'; + +static bool isInPackage(const CheckerInfo &Checker, StringRef PackageName) { + // Does the checker's full name have the package as a prefix? + if (!Checker.FullName.startswith(PackageName)) + return false; + + // Is the package actually just the name of a specific checker? + if (Checker.FullName.size() == PackageName.size()) + return true; + + // Is the checker in the package (or a subpackage)? + if (Checker.FullName[PackageName.size()] == PackageSeparator) + return true; + + return false; +} + +CheckerInfoListRange +CheckerRegistryData::getMutableCheckersForCmdLineArg(StringRef CmdLineArg) { + auto It = checker_registry::binaryFind(Checkers, CmdLineArg); + + if (!isInPackage(*It, CmdLineArg)) + return {Checkers.end(), Checkers.end()}; + + // See how large the package is. + // If the package doesn't exist, assume the option refers to a single + // checker. + size_t Size = 1; + llvm::StringMap::const_iterator PackageSize = + PackageSizes.find(CmdLineArg); + + if (PackageSize != PackageSizes.end()) + Size = PackageSize->getValue(); + + return {It, It + Size}; +} +//===----------------------------------------------------------------------===// +// Printing functions. +//===----------------------------------------------------------------------===// + +void CheckerRegistryData::printCheckerWithDescList( + const AnalyzerOptions &AnOpts, raw_ostream &Out, + size_t MaxNameChars) const { + // FIXME: Print available packages. + + Out << "CHECKERS:\n"; + + // Find the maximum option length. + size_t OptionFieldWidth = 0; + for (const auto &Checker : Checkers) { + // Limit the amount of padding we are willing to give up for alignment. + // Package.Name Description [Hidden] + size_t NameLength = Checker.FullName.size(); + if (NameLength <= MaxNameChars) + OptionFieldWidth = std::max(OptionFieldWidth, NameLength); + } + + const size_t InitialPad = 2; + + auto Print = [=](llvm::raw_ostream &Out, const CheckerInfo &Checker, + StringRef Description) { + AnalyzerOptions::printFormattedEntry(Out, {Checker.FullName, Description}, + InitialPad, OptionFieldWidth); + Out << '\n'; + }; + + for (const auto &Checker : Checkers) { + // The order of this if branches is significant, we wouldn't like to display + // developer checkers even in the alpha output. For example, + // alpha.cplusplus.IteratorModeling is a modeling checker, hence it's hidden + // by default, and users (even when the user is a developer of an alpha + // checker) shouldn't normally tinker with whether they should be enabled. + + if (Checker.IsHidden) { + if (AnOpts.ShowCheckerHelpDeveloper) + Print(Out, Checker, Checker.Desc); + continue; + } + + if (Checker.FullName.startswith("alpha")) { + if (AnOpts.ShowCheckerHelpAlpha) + Print(Out, Checker, + ("(Enable only for development!) " + Checker.Desc).str()); + continue; + } + + if (AnOpts.ShowCheckerHelp) + Print(Out, Checker, Checker.Desc); + } +} + +void CheckerRegistryData::printEnabledCheckerList(raw_ostream &Out) const { + for (const auto *i : EnabledCheckers) + Out << i->FullName << '\n'; +} + +void CheckerRegistryData::printCheckerOptionList(const AnalyzerOptions &AnOpts, + raw_ostream &Out) const { + Out << "OVERVIEW: Clang Static Analyzer Checker and Package Option List\n\n"; + Out << "USAGE: -analyzer-config \n\n"; + Out << " -analyzer-config OPTION1=VALUE, -analyzer-config " + "OPTION2=VALUE, ...\n\n"; + Out << "OPTIONS:\n\n"; + + // It's usually ill-advised to use multimap, but clang will terminate after + // this function. + std::multimap OptionMap; + + for (const CheckerInfo &Checker : Checkers) { + for (const CmdLineOption &Option : Checker.CmdLineOptions) { + OptionMap.insert({Checker.FullName, Option}); + } + } + + for (const PackageInfo &Package : Packages) { + for (const CmdLineOption &Option : Package.CmdLineOptions) { + OptionMap.insert({Package.FullName, Option}); + } + } + + auto Print = [](llvm::raw_ostream &Out, StringRef FullOption, + StringRef Desc) { + AnalyzerOptions::printFormattedEntry(Out, {FullOption, Desc}, + /*InitialPad*/ 2, + /*EntryWidth*/ 50, + /*MinLineWidth*/ 90); + Out << "\n\n"; + }; + for (const std::pair &Entry : + OptionMap) { + const CmdLineOption &Option = Entry.second; + std::string FullOption = (Entry.first + ":" + Option.OptionName).str(); + + std::string Desc = + ("(" + Option.OptionType + ") " + Option.Description + " (default: " + + (Option.DefaultValStr.empty() ? "\"\"" : Option.DefaultValStr) + ")") + .str(); + + // The list of these if branches is significant, we wouldn't like to + // display hidden alpha checker options for + // -analyzer-checker-option-help-alpha. + + if (Option.IsHidden) { + if (AnOpts.ShowCheckerOptionDeveloperList) + Print(Out, FullOption, Desc); + continue; + } + + if (Option.DevelopmentStatus == "alpha" || + Entry.first.startswith("alpha")) { + if (AnOpts.ShowCheckerOptionAlphaList) + Print(Out, FullOption, + llvm::Twine("(Enable only for development!) " + Desc).str()); + continue; + } + + if (AnOpts.ShowCheckerOptionList) + Print(Out, FullOption, Desc); + } +} diff --git a/clang/lib/StaticAnalyzer/Core/Environment.cpp b/clang/lib/StaticAnalyzer/Core/Environment.cpp index 1ccf4c6104a65..9e6d79bb7dcc9 100644 --- a/clang/lib/StaticAnalyzer/Core/Environment.cpp +++ b/clang/lib/StaticAnalyzer/Core/Environment.cpp @@ -183,12 +183,18 @@ EnvironmentManager::removeDeadBindings(Environment Env, F.getTreeFactory()); // Iterate over the block-expr bindings. - for (Environment::iterator I = Env.begin(), E = Env.end(); - I != E; ++I) { + for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) { const EnvironmentEntry &BlkExpr = I.getKey(); const SVal &X = I.getData(); - if (SymReaper.isLive(BlkExpr.getStmt(), BlkExpr.getLocationContext())) { + const bool IsBlkExprLive = + SymReaper.isLive(BlkExpr.getStmt(), BlkExpr.getLocationContext()); + + assert((isa(BlkExpr.getStmt()) || !IsBlkExprLive) && + "Only Exprs can be live, LivenessAnalysis argues about the liveness " + "of *values*!"); + + if (IsBlkExprLive) { // Copy the binding to the new map. EBMapRef = EBMapRef.add(BlkExpr, X); diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp index ba2875aab7543..38a680eb04c00 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -615,7 +615,8 @@ void ExprEngine::handleConstructor(const Expr *E, } else { for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); I != E; ++I) - defaultEvalCall(Bldr, *I, *Call, CallOpts); + getCheckerManager().runCheckersForEvalCall(DstEvaluated, *I, *Call, *this, + CallOpts); } // If the CFG was constructed without elements for temporary destructors diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp index da7b5d9efa471..52ba17d59ae07 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp @@ -584,7 +584,7 @@ void ExprEngine::evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred, // defaultEvalCall if all of them fail. ExplodedNodeSet dstCallEvaluated; getCheckerManager().runCheckersForEvalCall(dstCallEvaluated, dstPreVisit, - Call, *this); + Call, *this, EvalCallOptions()); // If there were other constructors called for object-type arguments // of this call, clean them up. @@ -717,7 +717,7 @@ void ExprEngine::conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr, ExprEngine::CallInlinePolicy ExprEngine::mayInlineCallKind(const CallEvent &Call, const ExplodedNode *Pred, AnalyzerOptions &Opts, - const ExprEngine::EvalCallOptions &CallOpts) { + const EvalCallOptions &CallOpts) { const LocationContext *CurLC = Pred->getLocationContext(); const StackFrameContext *CallerSFC = CurLC->getStackFrame(); switch (Call.getKind()) { diff --git a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp index 08413c080d41c..cb6f61e86ae3b 100644 --- a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp +++ b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp @@ -672,7 +672,7 @@ class SymbolicRangeInferrer if (!BinaryOperator::isComparisonOp(CurrentOP) || (CurrentOP == BO_Cmp)) return EmptyRangeSet; - static const OperatorRelationsTable CmpOpTable; + static const OperatorRelationsTable CmpOpTable{}; const SymExpr *LHS = SSE->getLHS(); const SymExpr *RHS = SSE->getRHS(); diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index 74c689730e58d..392049e21c6e5 100644 --- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -154,7 +154,7 @@ class AnalysisConsumer : public AnalysisASTConsumer, break; #include "clang/StaticAnalyzer/Core/Analyses.def" default: - llvm_unreachable("Unkown analyzer output type!"); + llvm_unreachable("Unknown analyzer output type!"); } // Create the analyzer component creators. diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalyzerHelpFlags.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalyzerHelpFlags.cpp index d589e69bdf347..eb6014a0629df 100644 --- a/clang/lib/StaticAnalyzer/Frontend/AnalyzerHelpFlags.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/AnalyzerHelpFlags.cpp @@ -33,7 +33,8 @@ void ento::printCheckerHelp(raw_ostream &out, CompilerInstance &CI) { *CI.getAnalyzerOpts(), CI.getLangOpts(), CI.getDiagnostics(), CI.getFrontendOpts().Plugins); - CheckerMgr->getCheckerRegistry().printCheckerWithDescList(out); + CheckerMgr->getCheckerRegistryData().printCheckerWithDescList( + *CI.getAnalyzerOpts(), out); } void ento::printEnabledCheckerList(raw_ostream &out, CompilerInstance &CI) { @@ -43,7 +44,7 @@ void ento::printEnabledCheckerList(raw_ostream &out, CompilerInstance &CI) { *CI.getAnalyzerOpts(), CI.getLangOpts(), CI.getDiagnostics(), CI.getFrontendOpts().Plugins); - CheckerMgr->getCheckerRegistry().printEnabledCheckerList(out); + CheckerMgr->getCheckerRegistryData().printEnabledCheckerList(out); } void ento::printCheckerConfigList(raw_ostream &out, CompilerInstance &CI) { @@ -52,7 +53,8 @@ void ento::printCheckerConfigList(raw_ostream &out, CompilerInstance &CI) { *CI.getAnalyzerOpts(), CI.getLangOpts(), CI.getDiagnostics(), CI.getFrontendOpts().Plugins); - CheckerMgr->getCheckerRegistry().printCheckerOptionList(out); + CheckerMgr->getCheckerRegistryData().printCheckerOptionList( + *CI.getAnalyzerOpts(), out); } void ento::printAnalyzerConfigList(raw_ostream &out) { diff --git a/clang/lib/StaticAnalyzer/Frontend/CMakeLists.txt b/clang/lib/StaticAnalyzer/Frontend/CMakeLists.txt index 0c100a121f777..5293f5e0a522d 100644 --- a/clang/lib/StaticAnalyzer/Frontend/CMakeLists.txt +++ b/clang/lib/StaticAnalyzer/Frontend/CMakeLists.txt @@ -23,4 +23,7 @@ add_clang_library(clangStaticAnalyzerFrontend clangLex clangStaticAnalyzerCheckers clangStaticAnalyzerCore + + DEPENDS + omp_gen ) diff --git a/clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp b/clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp index e690ed849e40d..528284ca89858 100644 --- a/clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp @@ -25,14 +25,13 @@ using namespace clang; using namespace ento; +using namespace checker_registry; using llvm::sys::DynamicLibrary; //===----------------------------------------------------------------------===// // Utilities. //===----------------------------------------------------------------------===// -using RegisterCheckersFn = void (*)(CheckerRegistry &); - static bool isCompatibleAPIVersion(const char *VersionString) { // If the version string is null, its not an analyzer plugin. if (!VersionString) @@ -43,140 +42,17 @@ static bool isCompatibleAPIVersion(const char *VersionString) { return strcmp(VersionString, CLANG_ANALYZER_API_VERSION_STRING) == 0; } -namespace { -template struct FullNameLT { - bool operator()(const T &Lhs, const T &Rhs) { - return Lhs.FullName < Rhs.FullName; - } -}; - -using PackageNameLT = FullNameLT; -using CheckerNameLT = FullNameLT; -} // end of anonymous namespace - -template -static std::conditional_t::value, - typename CheckerOrPackageInfoList::const_iterator, - typename CheckerOrPackageInfoList::iterator> -binaryFind(CheckerOrPackageInfoList &Collection, StringRef FullName) { - - using CheckerOrPackage = typename CheckerOrPackageInfoList::value_type; - using CheckerOrPackageFullNameLT = FullNameLT; - - assert(llvm::is_sorted(Collection, CheckerOrPackageFullNameLT{}) && - "In order to efficiently gather checkers/packages, this function " - "expects them to be already sorted!"); - - return llvm::lower_bound(Collection, CheckerOrPackage(FullName), - CheckerOrPackageFullNameLT{}); -} - static constexpr char PackageSeparator = '.'; -static bool isInPackage(const CheckerRegistry::CheckerInfo &Checker, - StringRef PackageName) { - // Does the checker's full name have the package as a prefix? - if (!Checker.FullName.startswith(PackageName)) - return false; - - // Is the package actually just the name of a specific checker? - if (Checker.FullName.size() == PackageName.size()) - return true; - - // Is the checker in the package (or a subpackage)? - if (Checker.FullName[PackageName.size()] == PackageSeparator) - return true; - - return false; -} - -//===----------------------------------------------------------------------===// -// Methods of CmdLineOption, PackageInfo and CheckerInfo. -//===----------------------------------------------------------------------===// - -LLVM_DUMP_METHOD void -CheckerRegistry::CmdLineOption::dumpToStream(llvm::raw_ostream &Out) const { - // The description can be just checked in Checkers.inc, the point here is to - // debug whether we succeeded in parsing it. - Out << OptionName << " (" << OptionType << ", " - << (IsHidden ? "hidden, " : "") << DevelopmentStatus << ") default: \"" - << DefaultValStr; -} - -static StringRef toString(CheckerRegistry::StateFromCmdLine Kind) { - switch (Kind) { - case CheckerRegistry::StateFromCmdLine::State_Disabled: - return "Disabled"; - case CheckerRegistry::StateFromCmdLine::State_Enabled: - return "Enabled"; - case CheckerRegistry::StateFromCmdLine::State_Unspecified: - return "Unspecified"; - } - llvm_unreachable("Unhandled CheckerRegistry::StateFromCmdLine enum"); -} - -LLVM_DUMP_METHOD void -CheckerRegistry::CheckerInfo::dumpToStream(llvm::raw_ostream &Out) const { - // The description can be just checked in Checkers.inc, the point here is to - // debug whether we succeeded in parsing it. Same with documentation uri. - Out << FullName << " (" << toString(State) << (IsHidden ? ", hidden" : "") - << ")\n"; - Out << " Options:\n"; - for (const CmdLineOption &Option : CmdLineOptions) { - Out << " "; - Option.dumpToStream(Out); - Out << '\n'; - } - Out << " Dependencies:\n"; - for (const CheckerInfo *Dependency : Dependencies) { - Out << " " << Dependency->FullName << '\n'; - } - Out << " Weak dependencies:\n"; - for (const CheckerInfo *Dependency : WeakDependencies) { - Out << " " << Dependency->FullName << '\n'; - } -} - -LLVM_DUMP_METHOD void -CheckerRegistry::PackageInfo::dumpToStream(llvm::raw_ostream &Out) const { - Out << FullName << "\n"; - Out << " Options:\n"; - for (const CmdLineOption &Option : CmdLineOptions) { - Out << " "; - Option.dumpToStream(Out); - Out << '\n'; - } -} - //===----------------------------------------------------------------------===// // Methods of CheckerRegistry. //===----------------------------------------------------------------------===// -CheckerRegistry::CheckerInfoListRange -CheckerRegistry::getMutableCheckersForCmdLineArg(StringRef CmdLineArg) { - auto It = binaryFind(Checkers, CmdLineArg); - - if (!isInPackage(*It, CmdLineArg)) - return {Checkers.end(), Checkers.end()}; - - // See how large the package is. - // If the package doesn't exist, assume the option refers to a single - // checker. - size_t Size = 1; - llvm::StringMap::const_iterator PackageSize = - PackageSizes.find(CmdLineArg); - - if (PackageSize != PackageSizes.end()) - Size = PackageSize->getValue(); - - return {It, It + Size}; -} - CheckerRegistry::CheckerRegistry( - ArrayRef Plugins, DiagnosticsEngine &Diags, - AnalyzerOptions &AnOpts, + CheckerRegistryData &Data, ArrayRef Plugins, + DiagnosticsEngine &Diags, AnalyzerOptions &AnOpts, ArrayRef> CheckerRegistrationFns) - : Diags(Diags), AnOpts(AnOpts) { + : Data(Data), Diags(Diags), AnOpts(AnOpts) { // Register builtin checkers. #define GET_CHECKERS @@ -216,9 +92,10 @@ CheckerRegistry::CheckerRegistry( continue; } + using RegisterPluginCheckerFn = void (*)(CheckerRegistry &); // Register its checkers. - RegisterCheckersFn RegisterPluginCheckers = - reinterpret_cast( + RegisterPluginCheckerFn RegisterPluginCheckers = + reinterpret_cast( Lib.getAddressOfSymbol("clang_registerCheckers")); if (RegisterPluginCheckers) RegisterPluginCheckers(*this); @@ -235,8 +112,8 @@ CheckerRegistry::CheckerRegistry( // FIXME: Alphabetical sort puts 'experimental' in the middle. // Would it be better to name it '~experimental' or something else // that's ASCIIbetically last? - llvm::sort(Packages, PackageNameLT{}); - llvm::sort(Checkers, CheckerNameLT{}); + llvm::sort(Data.Packages, checker_registry::PackageNameLT{}); + llvm::sort(Data.Checkers, checker_registry::CheckerNameLT{}); #define GET_CHECKER_DEPENDENCIES @@ -274,8 +151,8 @@ CheckerRegistry::CheckerRegistry( resolveDependencies(); #ifndef NDEBUG - for (auto &DepPair : Dependencies) { - for (auto &WeakDepPair : WeakDependencies) { + for (auto &DepPair : Data.Dependencies) { + for (auto &WeakDepPair : Data.WeakDependencies) { // Some assertions to enforce that strong dependencies are relations in // between purely modeling checkers, and weak dependencies are about // diagnostics. @@ -295,7 +172,7 @@ CheckerRegistry::CheckerRegistry( // command line. for (const std::pair &Opt : AnOpts.CheckersAndPackages) { CheckerInfoListRange CheckerForCmdLineArg = - getMutableCheckersForCmdLineArg(Opt.first); + Data.getMutableCheckersForCmdLineArg(Opt.first); if (CheckerForCmdLineArg.begin() == CheckerForCmdLineArg.end()) { Diags.Report(diag::err_unknown_analyzer_checker_or_package) << Opt.first; @@ -315,19 +192,16 @@ CheckerRegistry::CheckerRegistry( //===----------------------------------------------------------------------===// template -static bool -collectStrongDependencies(const CheckerRegistry::ConstCheckerInfoList &Deps, - const CheckerManager &Mgr, - CheckerRegistry::CheckerInfoSet &Ret, - IsEnabledFn IsEnabled); +static bool collectStrongDependencies(const ConstCheckerInfoList &Deps, + const CheckerManager &Mgr, + CheckerInfoSet &Ret, + IsEnabledFn IsEnabled); -/// Collects weak dependencies in \p enabledCheckers. +/// Collects weak dependencies in \p enabledData.Checkers. template -static void -collectWeakDependencies(const CheckerRegistry::ConstCheckerInfoList &Deps, - const CheckerManager &Mgr, - CheckerRegistry::CheckerInfoSet &Ret, - IsEnabledFn IsEnabled); +static void collectWeakDependencies(const ConstCheckerInfoList &Deps, + const CheckerManager &Mgr, + CheckerInfoSet &Ret, IsEnabledFn IsEnabled); void CheckerRegistry::initializeRegistry(const CheckerManager &Mgr) { // First, we calculate the list of enabled checkers as specified by the @@ -338,7 +212,7 @@ void CheckerRegistry::initializeRegistry(const CheckerManager &Mgr) { auto IsEnabledFromCmdLine = [&](const CheckerInfo *Checker) { return !Checker->isDisabled(Mgr); }; - for (const CheckerInfo &Checker : Checkers) { + for (const CheckerInfo &Checker : Data.Checkers) { if (!Checker.isEnabled(Mgr)) continue; @@ -362,7 +236,7 @@ void CheckerRegistry::initializeRegistry(const CheckerManager &Mgr) { auto IsEnabled = [&](const CheckerInfo *Checker) { return llvm::is_contained(Tmp, Checker); }; - for (const CheckerInfo &Checker : Checkers) { + for (const CheckerInfo &Checker : Data.Checkers) { if (!Checker.isEnabled(Mgr)) continue; @@ -378,19 +252,18 @@ void CheckerRegistry::initializeRegistry(const CheckerManager &Mgr) { } // Note that set_union also preserves the order of insertion. - EnabledCheckers.set_union(Deps); - EnabledCheckers.insert(&Checker); + Data.EnabledCheckers.set_union(Deps); + Data.EnabledCheckers.insert(&Checker); } } template -static bool -collectStrongDependencies(const CheckerRegistry::ConstCheckerInfoList &Deps, - const CheckerManager &Mgr, - CheckerRegistry::CheckerInfoSet &Ret, - IsEnabledFn IsEnabled) { +static bool collectStrongDependencies(const ConstCheckerInfoList &Deps, + const CheckerManager &Mgr, + CheckerInfoSet &Ret, + IsEnabledFn IsEnabled) { - for (const CheckerRegistry::CheckerInfo *Dependency : Deps) { + for (const CheckerInfo *Dependency : Deps) { if (!IsEnabled(Dependency)) return false; @@ -405,13 +278,12 @@ collectStrongDependencies(const CheckerRegistry::ConstCheckerInfoList &Deps, } template -static void -collectWeakDependencies(const CheckerRegistry::ConstCheckerInfoList &WeakDeps, - const CheckerManager &Mgr, - CheckerRegistry::CheckerInfoSet &Ret, - IsEnabledFn IsEnabled) { +static void collectWeakDependencies(const ConstCheckerInfoList &WeakDeps, + const CheckerManager &Mgr, + CheckerInfoSet &Ret, + IsEnabledFn IsEnabled) { - for (const CheckerRegistry::CheckerInfo *Dependency : WeakDeps) { + for (const CheckerInfo *Dependency : WeakDeps) { // Don't enable this checker if strong dependencies are unsatisfied, but // assume that weak dependencies are transitive. collectWeakDependencies(Dependency->WeakDependencies, Mgr, Ret, IsEnabled); @@ -425,18 +297,26 @@ collectWeakDependencies(const CheckerRegistry::ConstCheckerInfoList &WeakDeps, template void CheckerRegistry::resolveDependencies() { for (const std::pair &Entry : - (IsWeak ? WeakDependencies : Dependencies)) { + (IsWeak ? Data.WeakDependencies : Data.Dependencies)) { - auto CheckerIt = binaryFind(Checkers, Entry.first); - assert(CheckerIt != Checkers.end() && CheckerIt->FullName == Entry.first && + auto CheckerIt = binaryFind(Data.Checkers, Entry.first); + assert(CheckerIt != Data.Checkers.end() && + CheckerIt->FullName == Entry.first && "Failed to find the checker while attempting to set up its " "dependencies!"); - auto DependencyIt = binaryFind(Checkers, Entry.second); - assert(DependencyIt != Checkers.end() && + auto DependencyIt = binaryFind(Data.Checkers, Entry.second); + assert(DependencyIt != Data.Checkers.end() && DependencyIt->FullName == Entry.second && "Failed to find the dependency of a checker!"); + // We do allow diagnostics from unit test/example dependency checkers. + assert((DependencyIt->FullName.startswith("test") || + DependencyIt->FullName.startswith("example") || IsWeak || + DependencyIt->IsHidden) && + "Strong dependencies are modeling checkers, and as such " + "non-user facing! Mark them hidden in Checkers.td!"); + if (IsWeak) CheckerIt->WeakDependencies.emplace_back(&*DependencyIt); else @@ -445,12 +325,12 @@ template void CheckerRegistry::resolveDependencies() { } void CheckerRegistry::addDependency(StringRef FullName, StringRef Dependency) { - Dependencies.emplace_back(FullName, Dependency); + Data.Dependencies.emplace_back(FullName, Dependency); } void CheckerRegistry::addWeakDependency(StringRef FullName, StringRef Dependency) { - WeakDependencies.emplace_back(FullName, Dependency); + Data.WeakDependencies.emplace_back(FullName, Dependency); } //===----------------------------------------------------------------------===// @@ -459,8 +339,7 @@ void CheckerRegistry::addWeakDependency(StringRef FullName, /// Insert the checker/package option to AnalyzerOptions' config table, and /// validate it, if the user supplied it on the command line. -static void insertAndValidate(StringRef FullName, - const CheckerRegistry::CmdLineOption &Option, +static void insertAndValidate(StringRef FullName, const CmdLineOption &Option, AnalyzerOptions &AnOpts, DiagnosticsEngine &Diags) { @@ -509,10 +388,10 @@ static void insertAndValidate(StringRef FullName, } template -static void -insertOptionToCollection(StringRef FullName, T &Collection, - const CheckerRegistry::CmdLineOption &Option, - AnalyzerOptions &AnOpts, DiagnosticsEngine &Diags) { +static void insertOptionToCollection(StringRef FullName, T &Collection, + const CmdLineOption &Option, + AnalyzerOptions &AnOpts, + DiagnosticsEngine &Diags) { auto It = binaryFind(Collection, FullName); assert(It != Collection.end() && "Failed to find the checker while attempting to add a command line " @@ -525,20 +404,20 @@ insertOptionToCollection(StringRef FullName, T &Collection, void CheckerRegistry::resolveCheckerAndPackageOptions() { for (const std::pair &CheckerOptEntry : - CheckerOptions) { - insertOptionToCollection(CheckerOptEntry.first, Checkers, + Data.CheckerOptions) { + insertOptionToCollection(CheckerOptEntry.first, Data.Checkers, CheckerOptEntry.second, AnOpts, Diags); } for (const std::pair &PackageOptEntry : - PackageOptions) { - insertOptionToCollection(PackageOptEntry.first, Packages, + Data.PackageOptions) { + insertOptionToCollection(PackageOptEntry.first, Data.Packages, PackageOptEntry.second, AnOpts, Diags); } } void CheckerRegistry::addPackage(StringRef FullName) { - Packages.emplace_back(PackageInfo(FullName)); + Data.Packages.emplace_back(PackageInfo(FullName)); } void CheckerRegistry::addPackageOption(StringRef OptionType, @@ -548,22 +427,22 @@ void CheckerRegistry::addPackageOption(StringRef OptionType, StringRef Description, StringRef DevelopmentStatus, bool IsHidden) { - PackageOptions.emplace_back( + Data.PackageOptions.emplace_back( PackageFullName, CmdLineOption{OptionType, OptionName, DefaultValStr, Description, DevelopmentStatus, IsHidden}); } -void CheckerRegistry::addChecker(InitializationFunction Rfn, +void CheckerRegistry::addChecker(RegisterCheckerFn Rfn, ShouldRegisterFunction Sfn, StringRef Name, StringRef Desc, StringRef DocsUri, bool IsHidden) { - Checkers.emplace_back(Rfn, Sfn, Name, Desc, DocsUri, IsHidden); + Data.Checkers.emplace_back(Rfn, Sfn, Name, Desc, DocsUri, IsHidden); // Record the presence of the checker in its packages. StringRef PackageName, LeafName; std::tie(PackageName, LeafName) = Name.rsplit(PackageSeparator); while (!LeafName.empty()) { - PackageSizes[PackageName] += 1; + Data.PackageSizes[PackageName] += 1; std::tie(PackageName, LeafName) = PackageName.rsplit(PackageSeparator); } } @@ -575,29 +454,28 @@ void CheckerRegistry::addCheckerOption(StringRef OptionType, StringRef Description, StringRef DevelopmentStatus, bool IsHidden) { - CheckerOptions.emplace_back( + Data.CheckerOptions.emplace_back( CheckerFullName, CmdLineOption{OptionType, OptionName, DefaultValStr, Description, DevelopmentStatus, IsHidden}); } void CheckerRegistry::initializeManager(CheckerManager &CheckerMgr) const { // Initialize the CheckerManager with all enabled checkers. - for (const auto *Checker : EnabledCheckers) { + for (const auto *Checker : Data.EnabledCheckers) { CheckerMgr.setCurrentCheckerName(CheckerNameRef(Checker->FullName)); Checker->Initialize(CheckerMgr); } } -static void -isOptionContainedIn(const CheckerRegistry::CmdLineOptionList &OptionList, - StringRef SuppliedChecker, StringRef SuppliedOption, - const AnalyzerOptions &AnOpts, DiagnosticsEngine &Diags) { +static void isOptionContainedIn(const CmdLineOptionList &OptionList, + StringRef SuppliedChecker, + StringRef SuppliedOption, + const AnalyzerOptions &AnOpts, + DiagnosticsEngine &Diags) { if (!AnOpts.ShouldEmitErrorsOnInvalidConfigValue) return; - using CmdLineOption = CheckerRegistry::CmdLineOption; - auto SameOptName = [SuppliedOption](const CmdLineOption &Opt) { return Opt.OptionName == SuppliedOption; }; @@ -631,16 +509,16 @@ void CheckerRegistry::validateCheckerOptions() const { // it would return with an iterator to the first checker in the core, so we // we really have to use find here, which uses operator==. auto CheckerIt = - llvm::find(Checkers, CheckerInfo(SuppliedCheckerOrPackage)); - if (CheckerIt != Checkers.end()) { + llvm::find(Data.Checkers, CheckerInfo(SuppliedCheckerOrPackage)); + if (CheckerIt != Data.Checkers.end()) { isOptionContainedIn(CheckerIt->CmdLineOptions, SuppliedCheckerOrPackage, SuppliedOption, AnOpts, Diags); continue; } const auto *PackageIt = - llvm::find(Packages, PackageInfo(SuppliedCheckerOrPackage)); - if (PackageIt != Packages.end()) { + llvm::find(Data.Packages, PackageInfo(SuppliedCheckerOrPackage)); + if (PackageIt != Data.Packages.end()) { isOptionContainedIn(PackageIt->CmdLineOptions, SuppliedCheckerOrPackage, SuppliedOption, AnOpts, Diags); continue; @@ -651,122 +529,3 @@ void CheckerRegistry::validateCheckerOptions() const { } } -//===----------------------------------------------------------------------===// -// Printing functions. -//===----------------------------------------------------------------------===// - -void CheckerRegistry::printCheckerWithDescList(raw_ostream &Out, - size_t MaxNameChars) const { - // FIXME: Print available packages. - - Out << "CHECKERS:\n"; - - // Find the maximum option length. - size_t OptionFieldWidth = 0; - for (const auto &Checker : Checkers) { - // Limit the amount of padding we are willing to give up for alignment. - // Package.Name Description [Hidden] - size_t NameLength = Checker.FullName.size(); - if (NameLength <= MaxNameChars) - OptionFieldWidth = std::max(OptionFieldWidth, NameLength); - } - - const size_t InitialPad = 2; - - auto Print = [=](llvm::raw_ostream &Out, const CheckerInfo &Checker, - StringRef Description) { - AnalyzerOptions::printFormattedEntry(Out, {Checker.FullName, Description}, - InitialPad, OptionFieldWidth); - Out << '\n'; - }; - - for (const auto &Checker : Checkers) { - // The order of this if branches is significant, we wouldn't like to display - // developer checkers even in the alpha output. For example, - // alpha.cplusplus.IteratorModeling is a modeling checker, hence it's hidden - // by default, and users (even when the user is a developer of an alpha - // checker) shouldn't normally tinker with whether they should be enabled. - - if (Checker.IsHidden) { - if (AnOpts.ShowCheckerHelpDeveloper) - Print(Out, Checker, Checker.Desc); - continue; - } - - if (Checker.FullName.startswith("alpha")) { - if (AnOpts.ShowCheckerHelpAlpha) - Print(Out, Checker, - ("(Enable only for development!) " + Checker.Desc).str()); - continue; - } - - if (AnOpts.ShowCheckerHelp) - Print(Out, Checker, Checker.Desc); - } -} - -void CheckerRegistry::printEnabledCheckerList(raw_ostream &Out) const { - for (const auto *i : EnabledCheckers) - Out << i->FullName << '\n'; -} - -void CheckerRegistry::printCheckerOptionList(raw_ostream &Out) const { - Out << "OVERVIEW: Clang Static Analyzer Checker and Package Option List\n\n"; - Out << "USAGE: -analyzer-config \n\n"; - Out << " -analyzer-config OPTION1=VALUE, -analyzer-config " - "OPTION2=VALUE, ...\n\n"; - Out << "OPTIONS:\n\n"; - - std::multimap OptionMap; - - for (const CheckerInfo &Checker : Checkers) { - for (const CmdLineOption &Option : Checker.CmdLineOptions) { - OptionMap.insert({Checker.FullName, Option}); - } - } - - for (const PackageInfo &Package : Packages) { - for (const CmdLineOption &Option : Package.CmdLineOptions) { - OptionMap.insert({Package.FullName, Option}); - } - } - - auto Print = [] (llvm::raw_ostream &Out, StringRef FullOption, StringRef Desc) { - AnalyzerOptions::printFormattedEntry(Out, {FullOption, Desc}, - /*InitialPad*/ 2, - /*EntryWidth*/ 50, - /*MinLineWidth*/ 90); - Out << "\n\n"; - }; - for (const std::pair &Entry : - OptionMap) { - const CmdLineOption &Option = Entry.second; - std::string FullOption = (Entry.first + ":" + Option.OptionName).str(); - - std::string Desc = - ("(" + Option.OptionType + ") " + Option.Description + " (default: " + - (Option.DefaultValStr.empty() ? "\"\"" : Option.DefaultValStr) + ")") - .str(); - - // The list of these if branches is significant, we wouldn't like to - // display hidden alpha checker options for - // -analyzer-checker-option-help-alpha. - - if (Option.IsHidden) { - if (AnOpts.ShowCheckerOptionDeveloperList) - Print(Out, FullOption, Desc); - continue; - } - - if (Option.DevelopmentStatus == "alpha" || - Entry.first.startswith("alpha")) { - if (AnOpts.ShowCheckerOptionAlphaList) - Print(Out, FullOption, - llvm::Twine("(Enable only for development!) " + Desc).str()); - continue; - } - - if (AnOpts.ShowCheckerOptionList) - Print(Out, FullOption, Desc); - } -} diff --git a/clang/lib/StaticAnalyzer/Frontend/CreateCheckerManager.cpp b/clang/lib/StaticAnalyzer/Frontend/CreateCheckerManager.cpp index 140f807514439..21a60785eb525 100644 --- a/clang/lib/StaticAnalyzer/Frontend/CreateCheckerManager.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/CreateCheckerManager.cpp @@ -23,11 +23,11 @@ CheckerManager::CheckerManager( ArrayRef> checkerRegistrationFns) : Context(&Context), LangOpts(Context.getLangOpts()), AOptions(AOptions), PP(&PP), Diags(Context.getDiagnostics()), - Registry( - std::make_unique(plugins, Context.getDiagnostics(), - AOptions, checkerRegistrationFns)) { - Registry->initializeRegistry(*this); - Registry->initializeManager(*this); + RegistryData(std::make_unique()) { + CheckerRegistry Registry(*RegistryData, plugins, Context.getDiagnostics(), + AOptions, checkerRegistrationFns); + Registry.initializeRegistry(*this); + Registry.initializeManager(*this); finishedCheckerRegistration(); } @@ -36,8 +36,9 @@ CheckerManager::CheckerManager(AnalyzerOptions &AOptions, DiagnosticsEngine &Diags, ArrayRef plugins) : LangOpts(LangOpts), AOptions(AOptions), Diags(Diags), - Registry(std::make_unique(plugins, Diags, AOptions)) { - Registry->initializeRegistry(*this); + RegistryData(std::make_unique()) { + CheckerRegistry Registry(*RegistryData, plugins, Diags, AOptions, {}); + Registry.initializeRegistry(*this); } CheckerManager::~CheckerManager() { diff --git a/clang/lib/Tooling/ASTDiff/CMakeLists.txt b/clang/lib/Tooling/ASTDiff/CMakeLists.txt index 578d8ca0cbc11..38cf5370bc49d 100644 --- a/clang/lib/Tooling/ASTDiff/CMakeLists.txt +++ b/clang/lib/Tooling/ASTDiff/CMakeLists.txt @@ -8,4 +8,7 @@ add_clang_library(clangToolingASTDiff clangBasic clangAST clangLex + + DEPENDS + omp_gen ) diff --git a/clang/lib/Tooling/CMakeLists.txt b/clang/lib/Tooling/CMakeLists.txt index 71b6cc55e5040..7a58af59dad1e 100644 --- a/clang/lib/Tooling/CMakeLists.txt +++ b/clang/lib/Tooling/CMakeLists.txt @@ -31,6 +31,7 @@ add_clang_library(clangTooling DEPENDS ClangDriverOptions + omp_gen LINK_LIBS clangAST diff --git a/clang/lib/Tooling/Refactoring/AtomicChange.cpp b/clang/lib/Tooling/Refactoring/AtomicChange.cpp index 3be15b7d8509f..069e9c1eb36ef 100644 --- a/clang/lib/Tooling/Refactoring/AtomicChange.cpp +++ b/clang/lib/Tooling/Refactoring/AtomicChange.cpp @@ -204,6 +204,12 @@ AtomicChange::AtomicChange(const SourceManager &SM, Key = FilePath + ":" + std::to_string(FileIDAndOffset.second); } +AtomicChange::AtomicChange(const SourceManager &SM, SourceLocation KeyPosition, + llvm::Any M) + : AtomicChange(SM, KeyPosition) { + Metadata = std::move(M); +} + AtomicChange::AtomicChange(std::string Key, std::string FilePath, std::string Error, std::vector InsertedHeaders, diff --git a/clang/lib/Tooling/Refactoring/CMakeLists.txt b/clang/lib/Tooling/Refactoring/CMakeLists.txt index db889d2a06b5b..0565de224bbca 100644 --- a/clang/lib/Tooling/Refactoring/CMakeLists.txt +++ b/clang/lib/Tooling/Refactoring/CMakeLists.txt @@ -22,4 +22,7 @@ add_clang_library(clangToolingRefactoring clangLex clangRewrite clangToolingCore + + DEPENDS + omp_gen ) diff --git a/clang/lib/Tooling/Syntax/BuildTree.cpp b/clang/lib/Tooling/Syntax/BuildTree.cpp index 3ee66aabfb6d8..1f192180ec451 100644 --- a/clang/lib/Tooling/Syntax/BuildTree.cpp +++ b/clang/lib/Tooling/Syntax/BuildTree.cpp @@ -12,6 +12,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/Stmt.h" #include "clang/AST/TypeLoc.h" @@ -22,6 +23,7 @@ #include "clang/Basic/Specifiers.h" #include "clang/Basic/TokenKinds.h" #include "clang/Lex/Lexer.h" +#include "clang/Lex/LiteralSupport.h" #include "clang/Tooling/Syntax/Nodes.h" #include "clang/Tooling/Syntax/Tokens.h" #include "clang/Tooling/Syntax/Tree.h" @@ -114,6 +116,86 @@ struct GetStartLoc : TypeLocVisitor { }; } // namespace +static syntax::NodeKind getOperatorNodeKind(const CXXOperatorCallExpr &E) { + switch (E.getOperator()) { + // Comparison + case OO_EqualEqual: + case OO_ExclaimEqual: + case OO_Greater: + case OO_GreaterEqual: + case OO_Less: + case OO_LessEqual: + case OO_Spaceship: + // Assignment + case OO_Equal: + case OO_SlashEqual: + case OO_PercentEqual: + case OO_CaretEqual: + case OO_PipeEqual: + case OO_LessLessEqual: + case OO_GreaterGreaterEqual: + case OO_PlusEqual: + case OO_MinusEqual: + case OO_StarEqual: + case OO_AmpEqual: + // Binary computation + case OO_Slash: + case OO_Percent: + case OO_Caret: + case OO_Pipe: + case OO_LessLess: + case OO_GreaterGreater: + case OO_AmpAmp: + case OO_PipePipe: + case OO_ArrowStar: + case OO_Comma: + return syntax::NodeKind::BinaryOperatorExpression; + case OO_Tilde: + case OO_Exclaim: + return syntax::NodeKind::PrefixUnaryOperatorExpression; + // Prefix/Postfix increment/decrement + case OO_PlusPlus: + case OO_MinusMinus: + switch (E.getNumArgs()) { + case 1: + return syntax::NodeKind::PrefixUnaryOperatorExpression; + case 2: + return syntax::NodeKind::PostfixUnaryOperatorExpression; + default: + llvm_unreachable("Invalid number of arguments for operator"); + } + // Operators that can be unary or binary + case OO_Plus: + case OO_Minus: + case OO_Star: + case OO_Amp: + switch (E.getNumArgs()) { + case 1: + return syntax::NodeKind::PrefixUnaryOperatorExpression; + case 2: + return syntax::NodeKind::BinaryOperatorExpression; + default: + llvm_unreachable("Invalid number of arguments for operator"); + } + return syntax::NodeKind::BinaryOperatorExpression; + // Not yet supported by SyntaxTree + case OO_New: + case OO_Delete: + case OO_Array_New: + case OO_Array_Delete: + case OO_Coawait: + case OO_Call: + case OO_Subscript: + case OO_Arrow: + return syntax::NodeKind::UnknownExpression; + case OO_Conditional: // not overloadable + case NUM_OVERLOADED_OPERATORS: + case OO_None: + llvm_unreachable("Not an overloadable operator"); + } + llvm_unreachable("Unknown OverloadedOperatorKind enum"); +} + /// Gets the range of declarator as defined by the C++ grammar. E.g. /// `int a;` -> range of `a`, /// `int *a;` -> range of `*a`, @@ -135,7 +217,8 @@ static SourceRange getDeclaratorRange(const SourceManager &SM, TypeLoc T, } if (Initializer.isValid()) { auto InitializerEnd = Initializer.getEnd(); - assert(SM.isBeforeInTranslationUnit(End, InitializerEnd) || End == InitializerEnd); + assert(SM.isBeforeInTranslationUnit(End, InitializerEnd) || + End == InitializerEnd); End = InitializerEnd; } return SourceRange(Start, End); @@ -470,8 +553,8 @@ class syntax::TreeBuilder { namespace { class BuildTreeVisitor : public RecursiveASTVisitor { public: - explicit BuildTreeVisitor(ASTContext &Ctx, syntax::TreeBuilder &Builder) - : Builder(Builder), LangOpts(Ctx.getLangOpts()) {} + explicit BuildTreeVisitor(ASTContext &Context, syntax::TreeBuilder &Builder) + : Builder(Builder), Context(Context) {} bool shouldTraversePostOrder() const { return true; } @@ -578,15 +661,19 @@ class BuildTreeVisitor : public RecursiveASTVisitor { // RAV traverses it as a statement, we produce invalid node kinds in that // case. // FIXME: should do this in RAV instead? - if (S->getInit() && !TraverseStmt(S->getInit())) - return false; - if (S->getLoopVariable() && !TraverseDecl(S->getLoopVariable())) - return false; - if (S->getRangeInit() && !TraverseStmt(S->getRangeInit())) - return false; - if (S->getBody() && !TraverseStmt(S->getBody())) - return false; - return true; + bool Result = [&, this]() { + if (S->getInit() && !TraverseStmt(S->getInit())) + return false; + if (S->getLoopVariable() && !TraverseDecl(S->getLoopVariable())) + return false; + if (S->getRangeInit() && !TraverseStmt(S->getRangeInit())) + return false; + if (S->getBody() && !TraverseStmt(S->getBody())) + return false; + return true; + }(); + WalkUpFromCXXForRangeStmt(S); + return Result; } bool TraverseStmt(Stmt *S) { @@ -623,6 +710,55 @@ class BuildTreeVisitor : public RecursiveASTVisitor { return NNS; } + bool TraverseUserDefinedLiteral(UserDefinedLiteral *S) { + // The semantic AST node `UserDefinedLiteral` (UDL) may have one child node + // referencing the location of the UDL suffix (`_w` in `1.2_w`). The + // UDL suffix location does not point to the beginning of a token, so we + // can't represent the UDL suffix as a separate syntax tree node. + + return WalkUpFromUserDefinedLiteral(S); + } + + syntax::UserDefinedLiteralExpression * + buildUserDefinedLiteral(UserDefinedLiteral *S) { + switch (S->getLiteralOperatorKind()) { + case clang::UserDefinedLiteral::LOK_Integer: + return new (allocator()) syntax::IntegerUserDefinedLiteralExpression; + case clang::UserDefinedLiteral::LOK_Floating: + return new (allocator()) syntax::FloatUserDefinedLiteralExpression; + case clang::UserDefinedLiteral::LOK_Character: + return new (allocator()) syntax::CharUserDefinedLiteralExpression; + case clang::UserDefinedLiteral::LOK_String: + return new (allocator()) syntax::StringUserDefinedLiteralExpression; + case clang::UserDefinedLiteral::LOK_Raw: + case clang::UserDefinedLiteral::LOK_Template: + // For raw literal operator and numeric literal operator template we + // cannot get the type of the operand in the semantic AST. We get this + // information from the token. As integer and floating point have the same + // token kind, we run `NumericLiteralParser` again to distinguish them. + auto TokLoc = S->getBeginLoc(); + auto TokSpelling = + Builder.findToken(TokLoc)->text(Context.getSourceManager()); + auto Literal = + NumericLiteralParser(TokSpelling, TokLoc, Context.getSourceManager(), + Context.getLangOpts(), Context.getTargetInfo(), + Context.getDiagnostics()); + if (Literal.isIntegerLiteral()) + return new (allocator()) syntax::IntegerUserDefinedLiteralExpression; + else { + assert(Literal.isFloatingLiteral()); + return new (allocator()) syntax::FloatUserDefinedLiteralExpression; + } + } + llvm_unreachable("Unknown literal operator kind."); + } + + bool WalkUpFromUserDefinedLiteral(UserDefinedLiteral *S) { + Builder.markChildToken(S->getBeginLoc(), syntax::NodeRole::LiteralToken); + Builder.foldNode(Builder.getExprRange(S), buildUserDefinedLiteral(S), S); + return true; + } + bool WalkUpFromDeclRefExpr(DeclRefExpr *S) { if (auto *NNS = BuildNestedNameSpecifier(S->getQualifierLoc())) Builder.markChild(NNS, syntax::NodeRole::IdExpression_qualifier); @@ -647,6 +783,16 @@ class BuildTreeVisitor : public RecursiveASTVisitor { return true; } + bool WalkUpFromParenExpr(ParenExpr *S) { + Builder.markChildToken(S->getLParen(), syntax::NodeRole::OpenParen); + Builder.markExprChild(S->getSubExpr(), + syntax::NodeRole::ParenExpression_subExpression); + Builder.markChildToken(S->getRParen(), syntax::NodeRole::CloseParen); + Builder.foldNode(Builder.getExprRange(S), + new (allocator()) syntax::ParenExpression, S); + return true; + } + bool WalkUpFromIntegerLiteral(IntegerLiteral *S) { Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken); Builder.foldNode(Builder.getExprRange(S), @@ -654,6 +800,34 @@ class BuildTreeVisitor : public RecursiveASTVisitor { return true; } + bool WalkUpFromCharacterLiteral(CharacterLiteral *S) { + Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken); + Builder.foldNode(Builder.getExprRange(S), + new (allocator()) syntax::CharacterLiteralExpression, S); + return true; + } + + bool WalkUpFromFloatingLiteral(FloatingLiteral *S) { + Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken); + Builder.foldNode(Builder.getExprRange(S), + new (allocator()) syntax::FloatingLiteralExpression, S); + return true; + } + + bool WalkUpFromStringLiteral(StringLiteral *S) { + Builder.markChildToken(S->getBeginLoc(), syntax::NodeRole::LiteralToken); + Builder.foldNode(Builder.getExprRange(S), + new (allocator()) syntax::StringLiteralExpression, S); + return true; + } + + bool WalkUpFromCXXBoolLiteralExpr(CXXBoolLiteralExpr *S) { + Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken); + Builder.foldNode(Builder.getExprRange(S), + new (allocator()) syntax::BoolLiteralExpression, S); + return true; + } + bool WalkUpFromCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *S) { Builder.markChildToken(S->getLocation(), syntax::NodeRole::LiteralToken); Builder.foldNode(Builder.getExprRange(S), @@ -691,8 +865,29 @@ class BuildTreeVisitor : public RecursiveASTVisitor { return true; } + bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *S) { + if (getOperatorNodeKind(*S) == + syntax::NodeKind::PostfixUnaryOperatorExpression) { + // A postfix unary operator is declared as taking two operands. The + // second operand is used to distinguish from its prefix counterpart. In + // the semantic AST this "phantom" operand is represented as a + // `IntegerLiteral` with invalid `SourceLocation`. We skip visiting this + // operand because it does not correspond to anything written in source + // code + for (auto *child : S->children()) { + if (child->getSourceRange().isInvalid()) + continue; + if (!TraverseStmt(child)) + return false; + } + return WalkUpFromCXXOperatorCallExpr(S); + } else + return RecursiveASTVisitor::TraverseCXXOperatorCallExpr(S); + } + bool WalkUpFromCXXOperatorCallExpr(CXXOperatorCallExpr *S) { - if (S->isInfixBinaryOp()) { + switch (getOperatorNodeKind(*S)) { + case syntax::NodeKind::BinaryOperatorExpression: Builder.markExprChild( S->getArg(0), syntax::NodeRole::BinaryOperatorExpression_leftHandSide); @@ -705,8 +900,31 @@ class BuildTreeVisitor : public RecursiveASTVisitor { Builder.foldNode(Builder.getExprRange(S), new (allocator()) syntax::BinaryOperatorExpression, S); return true; + case syntax::NodeKind::PrefixUnaryOperatorExpression: + Builder.markChildToken( + S->getOperatorLoc(), + syntax::NodeRole::OperatorExpression_operatorToken); + Builder.markExprChild(S->getArg(0), + syntax::NodeRole::UnaryOperatorExpression_operand); + Builder.foldNode(Builder.getExprRange(S), + new (allocator()) syntax::PrefixUnaryOperatorExpression, + S); + return true; + case syntax::NodeKind::PostfixUnaryOperatorExpression: + Builder.markChildToken( + S->getOperatorLoc(), + syntax::NodeRole::OperatorExpression_operatorToken); + Builder.markExprChild(S->getArg(0), + syntax::NodeRole::UnaryOperatorExpression_operand); + Builder.foldNode(Builder.getExprRange(S), + new (allocator()) syntax::PostfixUnaryOperatorExpression, + S); + return true; + case syntax::NodeKind::UnknownExpression: + return RecursiveASTVisitor::WalkUpFromCXXOperatorCallExpr(S); + default: + llvm_unreachable("getOperatorNodeKind() does not return this value"); } - return RecursiveASTVisitor::WalkUpFromCXXOperatorCallExpr(S); } bool WalkUpFromNamespaceDecl(NamespaceDecl *S) { @@ -1058,7 +1276,7 @@ class BuildTreeVisitor : public RecursiveASTVisitor { llvm::BumpPtrAllocator &allocator() { return Builder.allocator(); } syntax::TreeBuilder &Builder; - const LangOptions &LangOpts; + const ASTContext &Context; }; } // namespace diff --git a/clang/lib/Tooling/Syntax/CMakeLists.txt b/clang/lib/Tooling/Syntax/CMakeLists.txt index eb266411036a0..e933faeb0f506 100644 --- a/clang/lib/Tooling/Syntax/CMakeLists.txt +++ b/clang/lib/Tooling/Syntax/CMakeLists.txt @@ -15,4 +15,7 @@ add_clang_library(clangToolingSyntax clangFrontend clangLex clangToolingCore + + DEPENDS + omp_gen ) diff --git a/clang/lib/Tooling/Syntax/Nodes.cpp b/clang/lib/Tooling/Syntax/Nodes.cpp index 623391a7d8446..2435ae0a91dd6 100644 --- a/clang/lib/Tooling/Syntax/Nodes.cpp +++ b/clang/lib/Tooling/Syntax/Nodes.cpp @@ -18,10 +18,28 @@ llvm::raw_ostream &syntax::operator<<(llvm::raw_ostream &OS, NodeKind K) { return OS << "TranslationUnit"; case NodeKind::UnknownExpression: return OS << "UnknownExpression"; - case NodeKind::CxxNullPtrExpression: - return OS << "CxxNullPtrExpression"; + case NodeKind::ParenExpression: + return OS << "ParenExpression"; case NodeKind::IntegerLiteralExpression: return OS << "IntegerLiteralExpression"; + case NodeKind::CharacterLiteralExpression: + return OS << "CharacterLiteralExpression"; + case NodeKind::FloatingLiteralExpression: + return OS << "FloatingLiteralExpression"; + case NodeKind::StringLiteralExpression: + return OS << "StringLiteralExpression"; + case NodeKind::BoolLiteralExpression: + return OS << "BoolLiteralExpression"; + case NodeKind::CxxNullPtrExpression: + return OS << "CxxNullPtrExpression"; + case NodeKind::IntegerUserDefinedLiteralExpression: + return OS << "IntegerUserDefinedLiteralExpression"; + case NodeKind::FloatUserDefinedLiteralExpression: + return OS << "FloatUserDefinedLiteralExpression"; + case NodeKind::CharUserDefinedLiteralExpression: + return OS << "CharUserDefinedLiteralExpression"; + case NodeKind::StringUserDefinedLiteralExpression: + return OS << "StringUserDefinedLiteralExpression"; case NodeKind::PrefixUnaryOperatorExpression: return OS << "PrefixUnaryOperatorExpression"; case NodeKind::PostfixUnaryOperatorExpression: @@ -172,6 +190,8 @@ llvm::raw_ostream &syntax::operator<<(llvm::raw_ostream &OS, NodeRole R) { return OS << "IdExpression_qualifier"; case syntax::NodeRole::NestedNameSpecifier_specifier: return OS << "NestedNameSpecifier_specifier"; + case syntax::NodeRole::ParenExpression_subExpression: + return OS << "ParenExpression_subExpression"; } llvm_unreachable("invalid role"); } @@ -195,16 +215,56 @@ syntax::UnqualifiedId *syntax::IdExpression::unqualifiedId() { findChild(syntax::NodeRole::IdExpression_id)); } +syntax::Leaf *syntax::ParenExpression::openParen() { + return llvm::cast_or_null( + findChild(syntax::NodeRole::OpenParen)); +} + +syntax::Expression *syntax::ParenExpression::subExpression() { + return llvm::cast_or_null( + findChild(syntax::NodeRole::ParenExpression_subExpression)); +} + +syntax::Leaf *syntax::ParenExpression::closeParen() { + return llvm::cast_or_null( + findChild(syntax::NodeRole::CloseParen)); +} + syntax::Leaf *syntax::IntegerLiteralExpression::literalToken() { return llvm::cast_or_null( findChild(syntax::NodeRole::LiteralToken)); } +syntax::Leaf *syntax::CharacterLiteralExpression::literalToken() { + return llvm::cast_or_null( + findChild(syntax::NodeRole::LiteralToken)); +} + +syntax::Leaf *syntax::FloatingLiteralExpression::literalToken() { + return llvm::cast_or_null( + findChild(syntax::NodeRole::LiteralToken)); +} + +syntax::Leaf *syntax::StringLiteralExpression::literalToken() { + return llvm::cast_or_null( + findChild(syntax::NodeRole::LiteralToken)); +} + +syntax::Leaf *syntax::BoolLiteralExpression::literalToken() { + return llvm::cast_or_null( + findChild(syntax::NodeRole::LiteralToken)); +} + syntax::Leaf *syntax::CxxNullPtrExpression::nullPtrKeyword() { return llvm::cast_or_null( findChild(syntax::NodeRole::LiteralToken)); } +syntax::Leaf *syntax::UserDefinedLiteralExpression::literalToken() { + return llvm::cast_or_null( + findChild(syntax::NodeRole::LiteralToken)); +} + syntax::Expression *syntax::BinaryOperatorExpression::lhs() { return llvm::cast_or_null( findChild(syntax::NodeRole::BinaryOperatorExpression_leftHandSide)); diff --git a/clang/lib/Tooling/Transformer/CMakeLists.txt b/clang/lib/Tooling/Transformer/CMakeLists.txt index 150b71b1ffcdb..4ab4bd6f08989 100644 --- a/clang/lib/Tooling/Transformer/CMakeLists.txt +++ b/clang/lib/Tooling/Transformer/CMakeLists.txt @@ -19,4 +19,7 @@ add_clang_library(clangTransformer clangLex clangToolingCore clangToolingRefactoring + + DEPENDS + omp_gen ) diff --git a/clang/lib/Tooling/Transformer/RangeSelector.cpp b/clang/lib/Tooling/Transformer/RangeSelector.cpp index baf2e785bfd0b..29b1a5b0372ea 100644 --- a/clang/lib/Tooling/Transformer/RangeSelector.cpp +++ b/clang/lib/Tooling/Transformer/RangeSelector.cpp @@ -146,7 +146,7 @@ RangeSelector transformer::statement(std::string ID) { }; } -RangeSelector transformer::range(RangeSelector Begin, RangeSelector End) { +RangeSelector transformer::enclose(RangeSelector Begin, RangeSelector End) { return [Begin, End](const MatchResult &Result) -> Expected { Expected BeginRange = Begin(Result); if (!BeginRange) @@ -165,8 +165,9 @@ RangeSelector transformer::range(RangeSelector Begin, RangeSelector End) { }; } -RangeSelector transformer::range(std::string BeginID, std::string EndID) { - return transformer::range(node(std::move(BeginID)), node(std::move(EndID))); +RangeSelector transformer::encloseNodes(std::string BeginID, + std::string EndID) { + return transformer::enclose(node(std::move(BeginID)), node(std::move(EndID))); } RangeSelector transformer::member(std::string ID) { diff --git a/clang/lib/Tooling/Transformer/RewriteRule.cpp b/clang/lib/Tooling/Transformer/RewriteRule.cpp index ddce6ce591851..995bec03cd669 100644 --- a/clang/lib/Tooling/Transformer/RewriteRule.cpp +++ b/clang/lib/Tooling/Transformer/RewriteRule.cpp @@ -47,6 +47,7 @@ translateEdits(const MatchResult &Result, ArrayRef ASTEdits) { transformer::Edit T; T.Range = *EditRange; T.Replacement = std::move(*Replacement); + T.Metadata = E.Metadata; Edits.push_back(std::move(T)); } return Edits; diff --git a/clang/lib/Tooling/Transformer/SourceCode.cpp b/clang/lib/Tooling/Transformer/SourceCode.cpp index a29d2e796d948..26b204851f058 100644 --- a/clang/lib/Tooling/Transformer/SourceCode.cpp +++ b/clang/lib/Tooling/Transformer/SourceCode.cpp @@ -37,11 +37,17 @@ StringRef clang::tooling::getText(CharSourceRange Range, CharSourceRange clang::tooling::maybeExtendRange(CharSourceRange Range, tok::TokenKind Next, ASTContext &Context) { - Optional Tok = Lexer::findNextToken( - Range.getEnd(), Context.getSourceManager(), Context.getLangOpts()); - if (!Tok || !Tok->is(Next)) + CharSourceRange R = Lexer::getAsCharRange(Range, Context.getSourceManager(), + Context.getLangOpts()); + if (R.isInvalid()) return Range; - return CharSourceRange::getTokenRange(Range.getBegin(), Tok->getLocation()); + Token Tok; + bool Err = + Lexer::getRawToken(R.getEnd(), Tok, Context.getSourceManager(), + Context.getLangOpts(), /*IgnoreWhiteSpace=*/true); + if (Err || !Tok.is(Next)) + return Range; + return CharSourceRange::getTokenRange(Range.getBegin(), Tok.getLocation()); } llvm::Error clang::tooling::validateEditRange(const CharSourceRange &Range, diff --git a/clang/lib/Tooling/Transformer/Stencil.cpp b/clang/lib/Tooling/Transformer/Stencil.cpp index 31b6ad9332c81..2670bf7adabf3 100644 --- a/clang/lib/Tooling/Transformer/Stencil.cpp +++ b/clang/lib/Tooling/Transformer/Stencil.cpp @@ -19,6 +19,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/Errc.h" +#include "llvm/Support/Error.h" #include #include #include @@ -232,8 +233,31 @@ Error evalData(const SelectorData &Data, const MatchFinder::MatchResult &Match, return RawRange.takeError(); CharSourceRange Range = Lexer::makeFileCharRange( *RawRange, *Match.SourceManager, Match.Context->getLangOpts()); + if (Range.isInvalid()) { + // Validate the original range to attempt to get a meaningful error message. + // If it's valid, then something else is the cause and we just return the + // generic failure message. + if (auto Err = tooling::validateEditRange(*RawRange, *Match.SourceManager)) + return handleErrors(std::move(Err), [](std::unique_ptr E) { + assert(E->convertToErrorCode() == + llvm::make_error_code(errc::invalid_argument) && + "Validation errors must carry the invalid_argument code"); + return llvm::createStringError( + errc::invalid_argument, + "selected range could not be resolved to a valid source range; " + + E->getMessage()); + }); + return llvm::createStringError( + errc::invalid_argument, + "selected range could not be resolved to a valid source range"); + } + // Validate `Range`, because `makeFileCharRange` accepts some ranges that + // `validateEditRange` rejects. if (auto Err = tooling::validateEditRange(Range, *Match.SourceManager)) - return Err; + return joinErrors( + llvm::createStringError(errc::invalid_argument, + "selected range is not valid for editing"), + std::move(Err)); *Result += tooling::getText(Range, *Match.Context); return Error::success(); } @@ -298,17 +322,11 @@ template class StencilImpl : public StencilInterface { }; } // namespace -Stencil transformer::detail::makeStencil(StringRef Text) { return text(Text); } - -Stencil transformer::detail::makeStencil(RangeSelector Selector) { - return selection(std::move(Selector)); -} - -Stencil transformer::text(StringRef Text) { +Stencil transformer::detail::makeStencil(StringRef Text) { return std::make_shared>(std::string(Text)); } -Stencil transformer::selection(RangeSelector Selector) { +Stencil transformer::detail::makeStencil(RangeSelector Selector) { return std::make_shared>(std::move(Selector)); } diff --git a/clang/lib/Tooling/Transformer/Transformer.cpp b/clang/lib/Tooling/Transformer/Transformer.cpp index 71340bf2f676d..e8fc00c4e953f 100644 --- a/clang/lib/Tooling/Transformer/Transformer.cpp +++ b/clang/lib/Tooling/Transformer/Transformer.cpp @@ -53,7 +53,7 @@ void Transformer::run(const MatchFinder::MatchResult &Result) { auto ID = Result.SourceManager->getFileID(T.Range.getBegin()); auto Iter = ChangesByFileID .emplace(ID, AtomicChange(*Result.SourceManager, - T.Range.getBegin())) + T.Range.getBegin(), T.Metadata)) .first; auto &AC = Iter->second; if (auto Err = AC.replace(*Result.SourceManager, T.Range, T.Replacement)) { diff --git a/clang/test/AST/Inputs/std-coroutine.h b/clang/test/AST/Inputs/std-coroutine.h index 7a424f1e99cf0..c1be9a19b8102 100644 --- a/clang/test/AST/Inputs/std-coroutine.h +++ b/clang/test/AST/Inputs/std-coroutine.h @@ -10,12 +10,12 @@ struct coroutine_traits { using promise_type = typename Ret::promise_type; }; template struct coroutine_handle { - static coroutine_handle from_address(void *); + static coroutine_handle from_address(void *) noexcept; }; template <> struct coroutine_handle { template - coroutine_handle(coroutine_handle); + coroutine_handle(coroutine_handle) noexcept; static coroutine_handle from_address(void *); }; @@ -26,9 +26,9 @@ struct suspend_always { }; struct suspend_never { - bool await_ready() { return true; } - void await_suspend(coroutine_handle<>) {} - void await_resume() {} + bool await_ready() noexcept { return true; } + void await_suspend(coroutine_handle<>) noexcept {} + void await_resume() noexcept {} }; } // namespace experimental diff --git a/clang/test/AST/alignas_maybe_odr_cleanup.cpp b/clang/test/AST/alignas_maybe_odr_cleanup.cpp index cdff1bfe8b80e..3adef4cba1440 100644 --- a/clang/test/AST/alignas_maybe_odr_cleanup.cpp +++ b/clang/test/AST/alignas_maybe_odr_cleanup.cpp @@ -15,8 +15,9 @@ struct FOO { } }; -// CHECK: AlignedAttr {{.*}} alignas -// CHECK: ConstantExpr {{.+}} 'int' Int: 32 -// CHECK: ImplicitCastExpr {{.*}} 'int' -// CHECK: DeclRefExpr {{.*}} 'const int' lvalue Var {{.*}} 'vec_align_bytes' 'const int' non_odr_use_constant -// CHECK: NullStmt +// CHECK: | `-AlignedAttr {{.*}} alignas +// CHECK-NEXT: | `-ConstantExpr {{.*}} 'int' +// CHECK-NEXT: | |-value: Int 32 +// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'int' +// CHECK-NEXT: | `-DeclRefExpr {{.*}} 'const int' lvalue Var {{.*}} 'vec_align_bytes' 'const int' non_odr_use_constant +// CHECK-NEXT: `-NullStmt {{.*}} diff --git a/clang/test/AST/ast-dump-APValue-anon-union.cpp b/clang/test/AST/ast-dump-APValue-anon-union.cpp new file mode 100644 index 0000000000000..1c9480c5a9430 --- /dev/null +++ b/clang/test/AST/ast-dump-APValue-anon-union.cpp @@ -0,0 +1,52 @@ +// Test without serialization: +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ +// RUN: -ast-dump %s -ast-dump-filter Test \ +// RUN: | FileCheck --strict-whitespace --match-full-lines %s +// +// Test with serialization: +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 -emit-pch -o %t %s +// RUN: %clang_cc1 -x c++ -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ +// RUN: -include-pch %t -ast-dump-all -ast-dump-filter Test /dev/null \ +// RUN: | sed -e "s/ //" -e "s/ imported//" \ +// RUN: | FileCheck --strict-whitespace --match-full-lines %s + +struct S0 { + union { + int i = 42; + }; +}; + +union U0 { + union { + float f = 3.1415f; + }; +}; + +union U1 { + union { + float f; + }; +}; + +void Test() { + constexpr S0 s0{}; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} s0 'const S0' constexpr listinit + // CHECK-NEXT: | |-value: Struct + // CHECK-NEXT: | | `-field: Union .i Int 42 + + constexpr U0 u0a{}; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} u0a 'const U0' constexpr listinit + // CHECK-NEXT: | |-value: Union None + + constexpr U0 u0b{3.1415f}; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} u0b 'const U0' constexpr listinit + // CHECK-NEXT: | |-value: Union . Union .f Float 3.141500e+00 + + constexpr U1 u1a{}; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} u1a 'const U1' constexpr listinit + // CHECK-NEXT: | |-value: Union . Union .f Float 0.000000e+00 + + constexpr U1 u1b{3.1415f}; + // CHECK: `-VarDecl {{.*}} col:{{.*}} u1b 'const U1' constexpr listinit + // CHECK-NEXT: |-value: Union . Union .f Float 3.141500e+00 +} diff --git a/clang/test/AST/ast-dump-APValue-arithmetic.cpp b/clang/test/AST/ast-dump-APValue-arithmetic.cpp new file mode 100644 index 0000000000000..835d8c8108346 --- /dev/null +++ b/clang/test/AST/ast-dump-APValue-arithmetic.cpp @@ -0,0 +1,49 @@ +// Test without serialization: +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ +// RUN: -ast-dump %s -ast-dump-filter Test \ +// RUN: | FileCheck --strict-whitespace --match-full-lines %s +// +// Test with serialization: +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 -emit-pch -o %t %s +// RUN: %clang_cc1 -x c++ -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ +// RUN: -include-pch %t -ast-dump-all -ast-dump-filter Test /dev/null \ +// RUN: | sed -e "s/ //" -e "s/ imported//" \ +// RUN: | FileCheck --strict-whitespace --match-full-lines %s + +void Test() { + constexpr int Int = 42; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} Int 'const int' constexpr cinit + // CHECK-NEXT: | |-value: Int 42 + + constexpr __int128 Int128 = (__int128)0xFFFFFFFFFFFFFFFF + (__int128)1; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} Int128 'const __int128' constexpr cinit + // CHECK-NEXT: | |-value: Int 18446744073709551616 + + constexpr float Float = 3.1415f; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} Float 'const float' constexpr cinit + // CHECK-NEXT: | |-value: Float 3.141500e+00 + + constexpr double Double = 3.1415f; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} Double 'const double' constexpr cinit + // CHECK-NEXT: | |-value: Float 3.141500e+00 + + constexpr _Complex int ComplexInt = 42 + 24i; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} referenced ComplexInt 'const _Complex int' constexpr cinit + // CHECK-NEXT: | |-value: ComplexInt 42 + 24i + + constexpr _Complex float ComplexFloat = 3.1415f + 42i; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} referenced ComplexFloat 'const _Complex float' constexpr cinit + // CHECK-NEXT: | |-value: ComplexFloat 3.141500e+00 + 4.200000e+01i + + constexpr _Complex int ArrayOfComplexInt[10] = {ComplexInt, ComplexInt, ComplexInt, ComplexInt}; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} ArrayOfComplexInt '_Complex int const[10]' constexpr cinit + // CHECK-NEXT: | |-value: Array size=10 + // CHECK-NEXT: | | |-elements: ComplexInt 42 + 24i, ComplexInt 42 + 24i, ComplexInt 42 + 24i, ComplexInt 42 + 24i + // CHECK-NEXT: | | `-filler: 6 x ComplexInt 0 + 0i + + constexpr _Complex float ArrayOfComplexFloat[10] = {ComplexFloat, ComplexFloat, ComplexInt, ComplexInt}; + // CHECK: `-VarDecl {{.*}} col:{{.*}} ArrayOfComplexFloat '_Complex float const[10]' constexpr cinit + // CHECK-NEXT: |-value: Array size=10 + // CHECK-NEXT: | |-elements: ComplexFloat 3.141500e+00 + 4.200000e+01i, ComplexFloat 3.141500e+00 + 4.200000e+01i, ComplexFloat 4.200000e+01 + 2.400000e+01i, ComplexFloat 4.200000e+01 + 2.400000e+01i + // CHECK-NEXT: | `-filler: 6 x ComplexFloat 0.000000e+00 + 0.000000e+00i +} diff --git a/clang/test/AST/ast-dump-APValue-array.cpp b/clang/test/AST/ast-dump-APValue-array.cpp new file mode 100644 index 0000000000000..f9b38ec332a5b --- /dev/null +++ b/clang/test/AST/ast-dump-APValue-array.cpp @@ -0,0 +1,82 @@ +// Test without serialization: +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ +// RUN: -ast-dump %s -ast-dump-filter Test \ +// RUN: | FileCheck --strict-whitespace --match-full-lines %s +// +// Test with serialization: +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 -emit-pch -o %t %s +// RUN: %clang_cc1 -x c++ -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ +// RUN: -include-pch %t -ast-dump-all -ast-dump-filter Test /dev/null \ +// RUN: | sed -e "s/ //" -e "s/ imported//" \ +// RUN: | FileCheck --strict-whitespace --match-full-lines %s + +struct S0 { + int arr[2]; +}; +union U0 { + int i; + float f; +}; + +struct S1 { + S0 s0 = {1, 2}; + U0 u0 = {.i = 42}; +}; + +void Test() { + constexpr int __attribute__((vector_size(sizeof(int) * 5))) arr_v5i[5] = { + {1, 2, 3, 4, 5}, + {1, 2, 3, 4}, + }; + // CHECK: | `-VarDecl {{.*}} line:{{.*}} arr_v5i '__attribute__((__vector_size__(5 * sizeof(int)))) int const[5]' constexpr cinit + // CHECK-NEXT: | |-value: Array size=5 + // CHECK-NEXT: | | |-element: Vector length=5 + // CHECK-NEXT: | | | |-elements: Int 1, Int 2, Int 3, Int 4 + // CHECK-NEXT: | | | `-element: Int 5 + // CHECK-NEXT: | | |-element: Vector length=5 + // CHECK-NEXT: | | | |-elements: Int 1, Int 2, Int 3, Int 4 + // CHECK-NEXT: | | | `-element: Int 0 + // CHECK-NEXT: | | `-filler: 3 x Vector length=5 + // CHECK-NEXT: | | |-elements: Int 0, Int 0, Int 0, Int 0 + // CHECK-NEXT: | | `-element: Int 0 + + constexpr float arr_f[3][5] = { + {1, 2, 3, 4, 5}, + }; + // CHECK: | `-VarDecl {{.*}} line:{{.*}} arr_f 'float const[3][5]' constexpr cinit + // CHECK-NEXT: | |-value: Array size=3 + // CHECK-NEXT: | | |-element: Array size=5 + // CHECK-NEXT: | | | |-elements: Float 1.000000e+00, Float 2.000000e+00, Float 3.000000e+00, Float 4.000000e+00 + // CHECK-NEXT: | | | `-element: Float 5.000000e+00 + // CHECK-NEXT: | | `-filler: 2 x Array size=5 + // CHECK-NEXT: | | `-filler: 5 x Float 0.000000e+00 + + constexpr S0 arr_s0[2] = {{1, 2}, {3, 4}}; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} arr_s0 'S0 const[2]' constexpr cinit + // CHECK-NEXT: | |-value: Array size=2 + // CHECK-NEXT: | | |-element: Struct + // CHECK-NEXT: | | | `-field: Array size=2 + // CHECK-NEXT: | | | `-elements: Int 1, Int 2 + // CHECK-NEXT: | | `-element: Struct + // CHECK-NEXT: | | `-field: Array size=2 + // CHECK-NEXT: | | `-elements: Int 3, Int 4 + + constexpr U0 arr_u0[2] = {{.i = 42}, {.f = 3.1415f}}; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} arr_u0 'U0 const[2]' constexpr cinit + // CHECK-NEXT: | |-value: Array size=2 + // CHECK-NEXT: | | `-elements: Union .i Int 42, Union .f Float 3.141500e+00 + + constexpr S1 arr_s1[2] = {}; + // CHECK: `-VarDecl {{.*}} col:{{.*}} arr_s1 'S1 const[2]' constexpr cinit + // CHECK-NEXT: |-value: Array size=2 + // CHECK-NEXT: | |-element: Struct + // CHECK-NEXT: | | |-field: Struct + // CHECK-NEXT: | | | `-field: Array size=2 + // CHECK-NEXT: | | | `-elements: Int 1, Int 2 + // CHECK-NEXT: | | `-field: Union .i Int 42 + // CHECK-NEXT: | `-element: Struct + // CHECK-NEXT: | |-field: Struct + // CHECK-NEXT: | | `-field: Array size=2 + // CHECK-NEXT: | | `-elements: Int 1, Int 2 + // CHECK-NEXT: | `-field: Union .i Int 42 +} diff --git a/clang/test/AST/ast-dump-APValue-struct.cpp b/clang/test/AST/ast-dump-APValue-struct.cpp new file mode 100644 index 0000000000000..4730404abc287 --- /dev/null +++ b/clang/test/AST/ast-dump-APValue-struct.cpp @@ -0,0 +1,113 @@ +// Test without serialization: +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ +// RUN: -ast-dump %s -ast-dump-filter Test \ +// RUN: | FileCheck --strict-whitespace --match-full-lines %s +// +// Test with serialization: +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 -emit-pch -o %t %s +// RUN: %clang_cc1 -x c++ -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ +// RUN: -include-pch %t -ast-dump-all -ast-dump-filter Test /dev/null \ +// RUN: | sed -e "s/ //" -e "s/ imported//" \ +// RUN: | FileCheck --strict-whitespace --match-full-lines %s + +struct S0 { + int i = 0; + union { + int j = 0; + } u0; +}; + +struct S1 { + int i = 0; + union { + struct { + int j = 0; + } s; + } u1; +}; + +struct S2 { + int i = 0; + union { + union { + int j = 0; + } u; + } u2; +}; + +struct S3 { + int i = 0; + union { + union { + struct { + int j = 0; + } j; + } u; + } u3; +}; + +struct S4 : S0 { + int i = 1, j = 2, k = 3; + struct { + } s; + int a = 4, b = 5, c = 6; +}; + +struct S5 : S4 { + int arr0[8] = {1, 2, 3, 4}; + int arr1[8] = {1, 2, 3, 4, 0, 0, 0, 0}; +}; + +void Test() { + constexpr S0 s0{}; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} s0 'const S0' constexpr listinit + // CHECK-NEXT: | |-value: Struct + // CHECK-NEXT: | | `-fields: Int 0, Union .j Int 0 + + constexpr S1 s1{}; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} s1 'const S1' constexpr listinit + // CHECK-NEXT: | |-value: Struct + // CHECK-NEXT: | | |-field: Int 0 + // CHECK-NEXT: | | `-field: Union .s + // CHECK-NEXT: | | `-Struct + // CHECK-NEXT: | | `-field: Int 0 + + constexpr S2 s2{}; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} s2 'const S2' constexpr listinit + // CHECK-NEXT: | |-value: Struct + // CHECK-NEXT: | | `-fields: Int 0, Union .u Union .j Int 0 + + constexpr S3 s3{}; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} s3 'const S3' constexpr listinit + // CHECK-NEXT: | |-value: Struct + // CHECK-NEXT: | | |-field: Int 0 + // CHECK-NEXT: | | `-field: Union .u + // CHECK-NEXT: | | `-Union .j + // CHECK-NEXT: | | `-Struct + // CHECK-NEXT: | | `-field: Int 0 + + constexpr S4 s4{}; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} s4 'const S4' constexpr listinit + // CHECK-NEXT: | |-value: Struct + // CHECK-NEXT: | | |-base: Struct + // CHECK-NEXT: | | | `-fields: Int 0, Union .j Int 0 + // CHECK-NEXT: | | |-fields: Int 1, Int 2, Int 3 + // CHECK-NEXT: | | |-field: Struct + // CHECK-NEXT: | | `-fields: Int 4, Int 5, Int 6 + + constexpr S5 s5{}; + // CHECK: `-VarDecl {{.*}} col:{{.*}} s5 'const S5' constexpr listinit + // CHECK-NEXT: |-value: Struct + // CHECK-NEXT: | |-base: Struct + // CHECK-NEXT: | | |-base: Struct + // CHECK-NEXT: | | | `-fields: Int 0, Union .j Int 0 + // CHECK-NEXT: | | |-fields: Int 1, Int 2, Int 3 + // CHECK-NEXT: | | |-field: Struct + // CHECK-NEXT: | | `-fields: Int 4, Int 5, Int 6 + // CHECK-NEXT: | |-field: Array size=8 + // CHECK-NEXT: | | |-elements: Int 1, Int 2, Int 3, Int 4 + // CHECK-NEXT: | | `-filler: 4 x Int 0 + // CHECK-NEXT: | `-field: Array size=8 + // CHECK-NEXT: | |-elements: Int 1, Int 2, Int 3, Int 4 + // CHECK-NEXT: | `-elements: Int 0, Int 0, Int 0, Int 0 +} diff --git a/clang/test/AST/ast-dump-APValue-todo.cpp b/clang/test/AST/ast-dump-APValue-todo.cpp new file mode 100644 index 0000000000000..78cc9cf36c73c --- /dev/null +++ b/clang/test/AST/ast-dump-APValue-todo.cpp @@ -0,0 +1,26 @@ +// Test without serialization: +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ +// RUN: -ast-dump %s -ast-dump-filter Test \ +// RUN: | FileCheck --strict-whitespace --match-full-lines %s +// +// Test with serialization: +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 -emit-pch -o %t %s +// RUN: %clang_cc1 -x c++ -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ +// RUN: -include-pch %t -ast-dump-all -ast-dump-filter Test /dev/null \ +// RUN: | sed -e "s/ //" -e "s/ imported//" \ +// RUN: | FileCheck --strict-whitespace --match-full-lines %s + +int i; +struct S { + int i; +}; + +void Test() { + constexpr int *pi = &i; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} pi 'int *const' constexpr cinit + // CHECK-NEXT: | |-value: LValue + + constexpr int(S::*pmi) = &S::i; + // CHECK: `-VarDecl {{.*}} col:{{.*}} pmi 'int (S::*const)' constexpr cinit + // CHECK-NEXT: |-value: MemberPointer +} diff --git a/clang/test/AST/ast-dump-APValue-union.cpp b/clang/test/AST/ast-dump-APValue-union.cpp new file mode 100644 index 0000000000000..c717b6ece7382 --- /dev/null +++ b/clang/test/AST/ast-dump-APValue-union.cpp @@ -0,0 +1,63 @@ +// Test without serialization: +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ +// RUN: -ast-dump %s -ast-dump-filter Test \ +// RUN: | FileCheck --strict-whitespace --match-full-lines %s +// +// Test with serialization: +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 -emit-pch -o %t %s +// RUN: %clang_cc1 -x c++ -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ +// RUN: -include-pch %t -ast-dump-all -ast-dump-filter Test /dev/null \ +// RUN: | sed -e "s/ //" -e "s/ imported//" \ +// RUN: | FileCheck --strict-whitespace --match-full-lines %s + +union U0 { + int i = 42; + float f; +}; + +union U1 { + union Uinner { + int i; + float f = 3.1415f; + } uinner; +}; + +union U2 { + union Uinner { + double d; + int arr[2] = {1, 2}; + } uinner; +}; + +union U3 { + union Uinner { + double d = 3.1415; + int arr[2]; + } uinner; + float f; +}; + +void Test() { + constexpr U0 u0{}; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} u0 'const U0' constexpr listinit + // CHECK-NEXT: | |-value: Union .i Int 42 + + constexpr U1 u1{}; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} u1 'const U1' constexpr listinit + // CHECK-NEXT: | |-value: Union .uinner Union .f Float 3.141500e+00 + + constexpr U2 u2{}; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} u2 'const U2' constexpr listinit + // CHECK-NEXT: | |-value: Union .uinner + // CHECK-NEXT: | | `-Union .arr + // CHECK-NEXT: | | `-Array size=2 + // CHECK-NEXT: | | `-elements: Int 1, Int 2 + + constexpr U3 u3a = {.f = 3.1415}; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} u3a 'const U3' constexpr cinit + // CHECK-NEXT: | |-value: Union .f Float 3.141500e+00 + + constexpr U3 u3b = {.uinner = {}}; + // CHECK: `-VarDecl {{.*}} col:{{.*}} u3b 'const U3' constexpr cinit + // CHECK-NEXT: |-value: Union .uinner Union .d Float 3.141500e+00 +} diff --git a/clang/test/AST/ast-dump-APValue-vector.cpp b/clang/test/AST/ast-dump-APValue-vector.cpp new file mode 100644 index 0000000000000..a9ec1d361c412 --- /dev/null +++ b/clang/test/AST/ast-dump-APValue-vector.cpp @@ -0,0 +1,43 @@ +// Test without serialization: +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ +// RUN: -ast-dump %s -ast-dump-filter Test \ +// RUN: | FileCheck --strict-whitespace --match-full-lines %s +// +// Test with serialization: +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 -emit-pch -o %t %s +// RUN: %clang_cc1 -x c++ -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ +// RUN: -include-pch %t -ast-dump-all -ast-dump-filter Test /dev/null \ +// RUN: | sed -e "s/ //" -e "s/ imported//" \ +// RUN: | FileCheck --strict-whitespace --match-full-lines %s + +void Test() { + constexpr int __attribute__((vector_size(sizeof(int) * 1))) v1i = {1}; + // CHECK: |-DeclStmt {{.*}} + // CHECK-NEXT: | `-VarDecl {{.*}} col:{{.*}} v1i '__attribute__((__vector_size__(1 * sizeof(int)))) int const' constexpr cinit + // CHECK-NEXT: | |-value: Vector length=1 + // CHECK-NEXT: | | `-element: Int 1 + + constexpr int __attribute__((vector_size(sizeof(int) * 4))) v4i = {1, 2, 3, 4}; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} v4i '__attribute__((__vector_size__(4 * sizeof(int)))) int const' constexpr cinit + // CHECK-NEXT: | |-value: Vector length=4 + // CHECK-NEXT: | | `-elements: Int 1, Int 2, Int 3, Int 4 + + constexpr int __attribute__((vector_size(sizeof(int) * 5))) v5i = {1, 2, 3, 4}; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} v5i '__attribute__((__vector_size__(5 * sizeof(int)))) int const' constexpr cinit + // CHECK-NEXT: | |-value: Vector length=5 + // CHECK-NEXT: | | |-elements: Int 1, Int 2, Int 3, Int 4 + // CHECK-NEXT: | | `-element: Int 0 + + constexpr int __attribute__((vector_size(sizeof(int) * 8))) v8i = {1, 2, 3, 4}; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} v8i '__attribute__((__vector_size__(8 * sizeof(int)))) int const' constexpr cinit + // CHECK-NEXT: | |-value: Vector length=8 + // CHECK-NEXT: | | |-elements: Int 1, Int 2, Int 3, Int 4 + // CHECK-NEXT: | | `-elements: Int 0, Int 0, Int 0, Int 0 + + constexpr int __attribute__((vector_size(sizeof(int) * 9))) v9i = {1, 2, 3, 4}; + // CHECK: `-VarDecl {{.*}} col:{{.*}} v9i '__attribute__((__vector_size__(9 * sizeof(int)))) int const' constexpr cinit + // CHECK-NEXT: |-value: Vector length=9 + // CHECK-NEXT: | |-elements: Int 1, Int 2, Int 3, Int 4 + // CHECK-NEXT: | |-elements: Int 0, Int 0, Int 0, Int 0 + // CHECK-NEXT: | `-element: Int 0 +} diff --git a/clang/test/AST/ast-dump-attr.cpp b/clang/test/AST/ast-dump-attr.cpp index 50eef3e0d97a0..95491a02f8b2d 100644 --- a/clang/test/AST/ast-dump-attr.cpp +++ b/clang/test/AST/ast-dump-attr.cpp @@ -45,6 +45,7 @@ int TestAlignedExpr __attribute__((aligned(4))); // CHECK: VarDecl{{.*}}TestAlignedExpr // CHECK-NEXT: AlignedAttr {{.*}} aligned // CHECK-NEXT: ConstantExpr +// CHECK-NEXT: value: Int 4 // CHECK-NEXT: IntegerLiteral int TestEnum __attribute__((visibility("default"))); diff --git a/clang/test/AST/ast-dump-color.cpp b/clang/test/AST/ast-dump-color.cpp index 6651ef2652e02..baaf9729c7ce7 100644 --- a/clang/test/AST/ast-dump-color.cpp +++ b/clang/test/AST/ast-dump-color.cpp @@ -49,13 +49,15 @@ struct Invalid { //CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:10:11[[RESET]]> [[Green]]'int'[[RESET]][[Cyan:.\[0;36m]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}} //CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:14[[RESET]], [[Yellow]]line:15:3[[RESET]]>{{$}} //CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:3[[RESET]], [[Yellow]]line:12:27[[RESET]]>{{$}} -//CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[MAGENTA]]ConstantExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] Int: 1[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[MAGENTA]]ConstantExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | | | |-value: [[RESET]][[Cyan]]Int [[CYAN]]1[[RESET]][[RESET]]{{$}} //CHECK: {{^}}[[Blue]]| | | | `-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}} //CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[MAGENTA]]AttributedStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:12:5[[RESET]], [[Yellow]]col:27[[RESET]]>{{$}} //CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[BLUE]]FallThroughAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:7[[RESET]], [[Yellow]]col:14[[RESET]]>{{$}} //CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[MAGENTA]]NullStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:27[[RESET]]>{{$}} //CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:3[[RESET]], [[Yellow]]line:14:5[[RESET]]>{{$}} -//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]ConstantExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] Int: 2[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]ConstantExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | | |-value: [[RESET]][[Cyan]]Int [[CYAN]]2[[RESET]][[RESET]]{{$}} //CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 2[[RESET]]{{$}} //CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]NullStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:14:5[[RESET]]>{{$}} //CHECK: {{^}}[[Blue]]| `-[[RESET]][[Blue]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:8:4[[RESET]], [[Yellow]]col:11[[RESET]]>{{$}} diff --git a/clang/test/AST/ast-dump-comment.cpp b/clang/test/AST/ast-dump-comment.cpp index da73483f041a3..8df0416cd092b 100644 --- a/clang/test/AST/ast-dump-comment.cpp +++ b/clang/test/AST/ast-dump-comment.cpp @@ -1,4 +1,12 @@ -// RUN: %clang_cc1 -Wdocumentation -ast-dump -ast-dump-filter Test %s | FileCheck -strict-whitespace %s +// Without serialization: +// RUN: %clang_cc1 -Wdocumentation -ast-dump -ast-dump-filter Test %s \ +// RUN: | FileCheck -strict-whitespace %s +// +// With serialization: +// RUN: %clang_cc1 -Wdocumentation -emit-pch -o %t %s +// RUN: %clang_cc1 -x c++ -Wdocumentation -include-pch %t -ast-dump-all -ast-dump-filter Test /dev/null \ +// RUN: | sed -e "s/ //" -e "s/ imported//" \ +// RUN: | FileCheck --strict-whitespace %s /// Aaa int TestLocation; diff --git a/clang/test/AST/ast-dump-constant-expr.cpp b/clang/test/AST/ast-dump-constant-expr.cpp index c9ddb245ef647..43f68cac72067 100644 --- a/clang/test/AST/ast-dump-constant-expr.cpp +++ b/clang/test/AST/ast-dump-constant-expr.cpp @@ -54,27 +54,32 @@ void Test() { // CHECK-NEXT:FunctionDecl {{.*}} <{{.*}}ast-dump-constant-expr.cpp:42:1, line:52:1> line:42:6{{( imported)?}} Test 'void ()' // CHECK-NEXT:`-CompoundStmt {{.*}} // CHECK-NEXT: |-CStyleCastExpr {{.*}} 'void' -// CHECK-NEXT: | `-ConstantExpr {{.*}} 'int' Int: 42 +// CHECK-NEXT: | `-ConstantExpr {{.*}} 'int' +// CHECK-NEXT: | |-value: Int 42 // CHECK-NEXT: | `-CallExpr {{.*}} 'int' // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'int (*)()' // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'int ()' lvalue Function {{.*}} 'test_Int' 'int ()' // CHECK-NEXT: |-CStyleCastExpr {{.*}} 'void' -// CHECK-NEXT: | `-ConstantExpr {{.*}} 'float' Float: 1.000000e+00 +// CHECK-NEXT: | `-ConstantExpr {{.*}} 'float' +// CHECK-NEXT: | |-value: Float 1.000000e+00 // CHECK-NEXT: | `-CallExpr {{.*}} 'float' // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'float (*)()' // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'float ()' lvalue Function {{.*}} 'test_Float' 'float ()' // CHECK-NEXT: |-CStyleCastExpr {{.*}} 'void' -// CHECK-NEXT: | `-ConstantExpr {{.*}} '_Complex int' ComplexInt: 1, 2 +// CHECK-NEXT: | `-ConstantExpr {{.*}} '_Complex int' +// CHECK-NEXT: | |-value: ComplexInt 1 + 2i // CHECK-NEXT: | `-CallExpr {{.*}} '_Complex int' // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Complex int (*)()' // CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Complex int ()' lvalue Function {{.*}} 'test_ComplexInt' '_Complex int ()' // CHECK-NEXT: |-CStyleCastExpr {{.*}} 'void' -// CHECK-NEXT: | `-ConstantExpr {{.*}} '_Complex float' ComplexFloat: 1.200000e+00, 3.400000e+00 +// CHECK-NEXT: | `-ConstantExpr {{.*}} '_Complex float' +// CHECK-NEXT: | |-value: ComplexFloat 1.200000e+00 + 3.400000e+00i // CHECK-NEXT: | `-CallExpr {{.*}} '_Complex float' // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Complex float (*)()' // CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Complex float ()' lvalue Function {{.*}} 'test_ComplexFloat' '_Complex float ()' // CHECK-NEXT: `-CStyleCastExpr {{.*}} 'void' -// CHECK-NEXT: `-ConstantExpr {{.*}} '__int128' Int: 18446744073709551616 +// CHECK-NEXT: `-ConstantExpr {{.*}} '__int128' +// CHECK-NEXT: |-value: Int 18446744073709551616 // CHECK-NEXT: `-CallExpr {{.*}} '__int128' // CHECK-NEXT: `-ImplicitCastExpr {{.*}} '__int128 (*)()' // CHECK-NEXT: `-DeclRefExpr {{.*}} '__int128 ()' lvalue Function {{.*}} 'test_Int128' '__int128 ()' diff --git a/clang/test/AST/ast-dump-decl.cpp b/clang/test/AST/ast-dump-decl.cpp index 3809683bd9dc7..97bb7964c47b8 100644 --- a/clang/test/AST/ast-dump-decl.cpp +++ b/clang/test/AST/ast-dump-decl.cpp @@ -224,19 +224,27 @@ namespace testFunctionTemplateDecl { // CHECK-NEXT: | `-CompoundStmt 0x{{.+}} // CHECK-NEXT: |-FunctionDecl 0x{{.+}} col:29 used TestFunctionTemplate 'void (testFunctionTemplateDecl::A)' // CHECK-NEXT: | |-TemplateArgument type 'testFunctionTemplateDecl::A' + // CHECK-NEXT: | | `-RecordType 0{{.+}} 'testFunctionTemplateDecl::A' + // CHECK-NEXT: | | `-CXXRecord 0x{{.+}} 'A' // CHECK-NEXT: | |-ParmVarDecl 0x{{.+}} col:51 'testFunctionTemplateDecl::A':'testFunctionTemplateDecl::A' // CHECK-NEXT: | `-CompoundStmt 0x{{.+}} // CHECK-NEXT: |-Function 0x{{.+}} 'TestFunctionTemplate' 'void (testFunctionTemplateDecl::B)' // CHECK-NEXT: |-FunctionDecl 0x{{.+}} col:29 TestFunctionTemplate 'void (testFunctionTemplateDecl::C)' // CHECK-NEXT: | |-TemplateArgument type 'testFunctionTemplateDecl::C' + // CHECK-NEXT: | | `-RecordType 0{{.+}} 'testFunctionTemplateDecl::C' + // CHECK-NEXT: | | `-CXXRecord 0x{{.+}} 'C' // CHECK-NEXT: | `-ParmVarDecl 0x{{.+}} col:51 'testFunctionTemplateDecl::C':'testFunctionTemplateDecl::C' // CHECK-NEXT: `-FunctionDecl 0x{{.+}} col:29 TestFunctionTemplate 'void (testFunctionTemplateDecl::D)' // CHECK-NEXT: |-TemplateArgument type 'testFunctionTemplateDecl::D' + // CHECK-NEXT: | `-RecordType 0{{.+}} 'testFunctionTemplateDecl::D' + // CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'D' // CHECK-NEXT: |-ParmVarDecl 0x{{.+}} col:51 'testFunctionTemplateDecl::D':'testFunctionTemplateDecl::D' // CHECK-NEXT: `-CompoundStmt 0x{{.+}} - // CHECK: FunctionDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-26]]:3, col:41> col:19 TestFunctionTemplate 'void (testFunctionTemplateDecl::B)' + // CHECK: FunctionDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-32]]:3, col:41> col:19 TestFunctionTemplate 'void (testFunctionTemplateDecl::B)' // CHECK-NEXT: |-TemplateArgument type 'testFunctionTemplateDecl::B' + // CHECK-NEXT: | `-RecordType 0{{.+}} 'testFunctionTemplateDecl::B' + // CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'B' // CHECK-NEXT: `-ParmVarDecl 0x{{.+}} col:41 'testFunctionTemplateDecl::B' @@ -311,19 +319,21 @@ namespace testClassTemplateDecl { // CHECK-NEXT: | | |-MoveAssignment // CHECK-NEXT: | | `-Destructor non_trivial user_declared // CHECK-NEXT: | |-TemplateArgument type 'testClassTemplateDecl::A' +// CHECK-NEXT: | | `-RecordType 0{{.+}} 'testClassTemplateDecl::A' +// CHECK-NEXT: | | `-CXXRecord 0x{{.+}} 'A' // CHECK-NEXT: | |-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} col:30 implicit class TestClassTemplate -// CHECK-NEXT: | |-AccessSpecDecl 0x{{.+}} col:3 public -// CHECK-NEXT: | |-CXXConstructorDecl 0x{{.+}} col:5 used TestClassTemplate 'void ()' -// CHECK-NEXT: | |-CXXDestructorDecl 0x{{.+}} col:5 used ~TestClassTemplate 'void () noexcept' -// CHECK-NEXT: | |-CXXMethodDecl 0x{{.+}} col:9 j 'int ()' -// CHECK-NEXT: | |-FieldDecl 0x{{.+}} col:9 i 'int' -// CHECK-NEXT: | `-CXXConstructorDecl 0x{{.+}} col:30 implicit constexpr TestClassTemplate 'void (const testClassTemplateDecl::TestClassTemplate &)' inline default trivial noexcept-unevaluated 0x{{.+}} +// CHECK-NEXT: | |-AccessSpecDecl 0x{{.+}} col:3 public +// CHECK-NEXT: | |-CXXConstructorDecl 0x{{.+}} col:5 used TestClassTemplate 'void ()' +// CHECK-NEXT: | |-CXXDestructorDecl 0x{{.+}} col:5 used ~TestClassTemplate 'void () noexcept' +// CHECK-NEXT: | |-CXXMethodDecl 0x{{.+}} col:9 j 'int ()' +// CHECK-NEXT: | |-FieldDecl 0x{{.+}} col:9 i 'int' +// CHECK-NEXT: | `-CXXConstructorDecl 0x{{.+}} col:30 implicit constexpr TestClassTemplate 'void (const testClassTemplateDecl::TestClassTemplate &)' inline default trivial noexcept-unevaluated 0x{{.+}} // CHECK-NEXT: | `-ParmVarDecl 0x{{.+}} col:30 'const testClassTemplateDecl::TestClassTemplate &' // CHECK-NEXT: |-ClassTemplateSpecialization 0x{{.+}} 'TestClassTemplate' // CHECK-NEXT: |-ClassTemplateSpecialization 0x{{.+}} 'TestClassTemplate' // CHECK-NEXT: `-ClassTemplateSpecialization 0x{{.+}} 'TestClassTemplate' -// CHECK: ClassTemplateSpecializationDecl 0x{{.+}} <{{.+}}:[[@LINE-65]]:3, line:[[@LINE-63]]:3> line:[[@LINE-65]]:20 class TestClassTemplate definition +// CHECK: ClassTemplateSpecializationDecl 0x{{.+}} <{{.+}}:[[@LINE-67]]:3, line:[[@LINE-65]]:3> line:[[@LINE-67]]:20 class TestClassTemplate definition // CHECK-NEXT: |-DefinitionData pass_in_registers standard_layout trivially_copyable trivial literal // CHECK-NEXT: | |-DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param @@ -332,8 +342,10 @@ namespace testClassTemplateDecl { // CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit // CHECK-NEXT: |-TemplateArgument type 'testClassTemplateDecl::B' +// CHECK-NEXT: | `-RecordType 0{{.+}} 'testClassTemplateDecl::B' +// CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'B' // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} col:20 implicit class TestClassTemplate -// CHECK-NEXT: `-FieldDecl 0x{{.+}} col:9 j 'int' +// CHECK-NEXT: `-FieldDecl 0x{{.+}} col:9 j 'int' // CHECK: ClassTemplateSpecializationDecl 0x{{.+}} <{{.+}}:{{.*}}:3, col:44> col:25 class TestClassTemplate definition // CHECK-NEXT: |-DefinitionData standard_layout has_user_declared_ctor can_const_default_init @@ -344,14 +356,16 @@ namespace testClassTemplateDecl { // CHECK-NEXT: | |-MoveAssignment // CHECK-NEXT: | `-Destructor non_trivial user_declared // CHECK-NEXT: |-TemplateArgument type 'testClassTemplateDecl::C' -// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} col:30 implicit class TestClassTemplate -// CHECK-NEXT: |-AccessSpecDecl 0x{{.+}} col:3 public -// CHECK-NEXT: |-CXXConstructorDecl 0x{{.+}} col:5 TestClassTemplate 'void ()' -// CHECK-NEXT: |-CXXDestructorDecl 0x{{.+}} col:5 ~TestClassTemplate 'void ()' noexcept-unevaluated 0x{{.+}} -// CHECK-NEXT: |-CXXMethodDecl 0x{{.+}} col:9 j 'int ()' -// CHECK-NEXT: `-FieldDecl 0x{{.+}} col:9 i 'int' - -// CHECK: ClassTemplateSpecializationDecl 0x{{.+}} <{{.+}}:[[@LINE-85]]:3, col:37> col:18 class TestClassTemplate definition +// CHECK-NEXT: | `-RecordType 0{{.+}} 'testClassTemplateDecl::C' +// CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'C' +// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} col:30 implicit class TestClassTemplate +// CHECK-NEXT: |-AccessSpecDecl 0x{{.+}} col:3 public +// CHECK-NEXT: |-CXXConstructorDecl 0x{{.+}} col:5 TestClassTemplate 'void ()' +// CHECK-NEXT: |-CXXDestructorDecl 0x{{.+}} col:5 ~TestClassTemplate 'void ()' noexcept-unevaluated 0x{{.+}} +// CHECK-NEXT: |-CXXMethodDecl 0x{{.+}} col:9 j 'int ()' +// CHECK-NEXT: `-FieldDecl 0x{{.+}} col:9 i 'int' + +// CHECK: ClassTemplateSpecializationDecl 0x{{.+}} <{{.+}}:[[@LINE-91]]:3, col:37> col:18 class TestClassTemplate definition // CHECK-NEXT: |-DefinitionData standard_layout has_user_declared_ctor can_const_default_init // CHECK-NEXT: | |-DefaultConstructor exists non_trivial user_provided // CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param @@ -360,17 +374,19 @@ namespace testClassTemplateDecl { // CHECK-NEXT: | |-MoveAssignment // CHECK-NEXT: | `-Destructor non_trivial user_declared // CHECK-NEXT: |-TemplateArgument type 'testClassTemplateDecl::D' -// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} col:30 implicit class TestClassTemplate -// CHECK-NEXT: |-AccessSpecDecl 0x{{.+}} col:3 public -// CHECK-NEXT: |-CXXConstructorDecl 0x{{.+}} col:5 TestClassTemplate 'void ()' -// CHECK-NEXT: |-CXXDestructorDecl 0x{{.+}} col:5 ~TestClassTemplate 'void ()' noexcept-unevaluated 0x{{.+}} -// CHECK-NEXT: |-CXXMethodDecl 0x{{.+}} col:9 j 'int ()' -// CHECK-NEXT: `-FieldDecl 0x{{.+}} col:9 i 'int' - -// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-98]]:3, line:[[@LINE-96]]:3> line:[[@LINE-98]]:44 TestClassTemplatePartial +// CHECK-NEXT: | `-RecordType 0{{.+}} 'testClassTemplateDecl::D' +// CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'D' +// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} col:30 implicit class TestClassTemplate +// CHECK-NEXT: |-AccessSpecDecl 0x{{.+}} col:3 public +// CHECK-NEXT: |-CXXConstructorDecl 0x{{.+}} col:5 TestClassTemplate 'void ()' +// CHECK-NEXT: |-CXXDestructorDecl 0x{{.+}} col:5 ~TestClassTemplate 'void ()' noexcept-unevaluated 0x{{.+}} +// CHECK-NEXT: |-CXXMethodDecl 0x{{.+}} col:9 j 'int ()' +// CHECK-NEXT: `-FieldDecl 0x{{.+}} col:9 i 'int' + +// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-106]]:3, line:[[@LINE-104]]:3> line:[[@LINE-106]]:44 TestClassTemplatePartial // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 typename depth 0 index 0 T1 // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:34 typename depth 0 index 1 T2 -// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} line:[[@LINE-101]]:44 class TestClassTemplatePartial definition +// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} line:[[@LINE-109]]:44 class TestClassTemplatePartial definition // CHECK-NEXT: |-DefinitionData standard_layout trivially_copyable trivial literal // CHECK-NEXT: | |-DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param @@ -379,9 +395,9 @@ namespace testClassTemplateDecl { // CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} col:44 implicit class TestClassTemplatePartial -// CHECK-NEXT: `-FieldDecl 0x{{.+}} col:9 i 'int' +// CHECK-NEXT: `-FieldDecl 0x{{.+}} col:9 i 'int' -// CHECK: ClassTemplatePartialSpecializationDecl 0x{{.+}} <{{.+}}:[[@LINE-109]]:3, line:[[@LINE-107]]:3> line:[[@LINE-109]]:31 class TestClassTemplatePartial definition +// CHECK: ClassTemplatePartialSpecializationDecl 0x{{.+}} <{{.+}}:[[@LINE-117]]:3, line:[[@LINE-115]]:3> line:[[@LINE-117]]:31 class TestClassTemplatePartial definition // CHECK-NEXT: |-DefinitionData standard_layout trivially_copyable trivial literal // CHECK-NEXT: | |-DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param @@ -390,20 +406,25 @@ namespace testClassTemplateDecl { // CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit // CHECK-NEXT: |-TemplateArgument type 'type-parameter-0-0' +// CHECK-NEXT: | `-TemplateTypeParmType 0x{{.+}} 'type-parameter-0-0' dependent depth 0 index 0 // CHECK-NEXT: |-TemplateArgument type 'testClassTemplateDecl::A' +// CHECK-NEXT: | `-RecordType 0x{{.+}} 'testClassTemplateDecl::A' +// CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'A' // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 referenced typename depth 0 index 0 T1 // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} col:31 implicit class TestClassTemplatePartial -// CHECK-NEXT: `-FieldDecl 0x{{.+}} col:9 j 'int' +// CHECK-NEXT: `-FieldDecl 0x{{.+}} col:9 j 'int' -// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-119]]:3, col:37> col:37 TestTemplateDefaultType +// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-130]]:3, col:37> col:37 TestTemplateDefaultType // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 typename depth 0 index 0 T // CHECK-NEXT: | `-TemplateArgument type 'int' +// CHECK-NEXT: | `-BuiltinType 0x{{.+}} 'int' // CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} col:37 struct TestTemplateDefaultType -// CHECK: ClassTemplateDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-123]]:3, col:57> col:31 TestTemplateDefaultType +// CHECK: ClassTemplateDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-135]]:3, col:57> col:31 TestTemplateDefaultType // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 typename depth 0 index 0 T // CHECK-NEXT: | `-TemplateArgument type 'int' -// CHECK-NEXT: | `-inherited from TemplateTypeParm 0x{{.+}} 'T' +// CHECK-NEXT: | |-inherited from TemplateTypeParm 0x{{.+}} 'T' +// CHECK-NEXT: | `-BuiltinType 0x{{.+}} 'int' // CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} col:31 struct TestTemplateDefaultType definition // CHECK-NEXT: |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init // CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr @@ -414,10 +435,11 @@ namespace testClassTemplateDecl { // CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit // CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} col:31 implicit struct TestTemplateDefaultType -// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-135]]:3, col:31> col:31 TestTemplateDefaultNonType +// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-148]]:3, col:31> col:31 TestTemplateDefaultNonType // CHECK-NEXT: |-NonTypeTemplateParmDecl 0x{{.+}} col:16 'int' depth 0 index 0 I // CHECK-NEXT: | `-TemplateArgument expr // CHECK-NEXT: | `-ConstantExpr 0x{{.+}} 'int' +// CHECK-NEXT: | |-value: Int 42 // CHECK-NEXT: | `-IntegerLiteral 0x{{.+}} 'int' 42 // CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} col:31 struct TestTemplateDefaultNonType @@ -456,9 +478,11 @@ namespace testCanonicalTemplate { // CHECK-NEXT: | `-ParmVarDecl 0x{{.*}} col:51 'T' // CHECK-NEXT: `-FunctionDecl 0x{{.*}} col:29 used TestFunctionTemplate 'void (testCanonicalTemplate::A)' // CHECK-NEXT: |-TemplateArgument type 'testCanonicalTemplate::A' + // CHECK-NEXT: | `-RecordType 0x{{.+}} 'testCanonicalTemplate::A' + // CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'A' // CHECK-NEXT: `-ParmVarDecl 0x{{.*}} col:51 'testCanonicalTemplate::A':'testCanonicalTemplate::A' - // CHECK: FunctionTemplateDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-10]]:3, col:51> col:29 TestFunctionTemplate + // CHECK: FunctionTemplateDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-12]]:3, col:51> col:29 TestFunctionTemplate // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 referenced typename depth 0 index 0 T // CHECK-NEXT: |-FunctionDecl{{.*}} 0x{{.+}} prev 0x{{.+}} col:29 TestFunctionTemplate 'void (T)' // CHECK-NEXT: | `-ParmVarDecl 0x{{.+}} col:51 'T' @@ -493,13 +517,15 @@ namespace testCanonicalTemplate { // CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit // CHECK-NEXT: |-TemplateArgument type 'testCanonicalTemplate::A' + // CHECK-NEXT: | `-RecordType 0x{{.+}} 'testCanonicalTemplate::A' + // CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'A' // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} col:31 implicit class TestClassTemplate - // CHECK-NEXT: |-FriendDecl 0x{{.+}} col:40 + // CHECK-NEXT: |-FriendDecl 0x{{.+}} col:40 // CHECK-NEXT: | `-ClassTemplateDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} col:40 TestClassTemplate // CHECK-NEXT: | |-TemplateTypeParmDecl 0x{{.+}} col:23 typename depth 0 index 0 T2 // CHECK-NEXT: | |-CXXRecordDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} col:40 class TestClassTemplate // CHECK-NEXT: | `-ClassTemplateSpecialization 0x{{.+}} 'TestClassTemplate' - // CHECK-NEXT: |-CXXConstructorDecl 0x{{.+}} col:31 implicit used constexpr TestClassTemplate 'void () noexcept' inline default trivial + // CHECK-NEXT: |-CXXConstructorDecl 0x{{.+}} col:31 implicit used constexpr TestClassTemplate 'void () noexcept' inline default trivial // CHECK-NEXT: | `-CompoundStmt 0x{{.+}} // CHECK-NEXT: |-CXXConstructorDecl 0x{{.+}} col:31 implicit constexpr TestClassTemplate 'void (const testCanonicalTemplate::TestClassTemplate &)' inline default trivial noexcept-unevaluated 0x{{.+}} // CHECK-NEXT: | `-ParmVarDecl 0x{{.+}} col:31 'const testCanonicalTemplate::TestClassTemplate &' @@ -524,6 +550,8 @@ namespace testCanonicalTemplate { // CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit // CHECK-NEXT: |-TemplateArgument type 'testCanonicalTemplate::A' + // CHECK-NEXT: | `-RecordType 0x{{.+}} 'testCanonicalTemplate::A' + // CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'A' // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} col:31 implicit class TestClassTemplate2 // CHECK-NEXT: |-CXXConstructorDecl 0x{{.+}} col:31 implicit used constexpr TestClassTemplate2 'void () noexcept' inline default trivial // CHECK-NEXT: | `-CompoundStmt 0x{{.+}} @@ -532,14 +560,14 @@ namespace testCanonicalTemplate { // CHECK-NEXT: `-CXXConstructorDecl 0x{{.+}} col:31 implicit constexpr TestClassTemplate2 'void (testCanonicalTemplate::TestClassTemplate2 &&)' inline default trivial noexcept-unevaluated 0x{{.+}} // CHECK-NEXT: `-ParmVarDecl 0x{{.+}} col:31 'testCanonicalTemplate::TestClassTemplate2 &&' - // CHECK: ClassTemplateDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-24]]:3, col:31> col:31 TestClassTemplate2 + // CHECK: ClassTemplateDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-26]]:3, col:31> col:31 TestClassTemplate2 // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 typename depth 0 index 0 T1 // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} col:31 class TestClassTemplate2 // CHECK-NEXT: `-ClassTemplateSpecialization 0x{{.+}} 'TestClassTemplate2' - // CHECK: ClassTemplateDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-28]]:3, line:[[@LINE-27]]:3> line:[[@LINE-28]]:31 TestClassTemplate2 + // CHECK: ClassTemplateDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-30]]:3, line:[[@LINE-29]]:3> line:[[@LINE-30]]:31 TestClassTemplate2 // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 typename depth 0 index 0 T1 - // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} line:[[@LINE-30]]:31 class TestClassTemplate2 definition + // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} line:[[@LINE-32]]:31 class TestClassTemplate2 definition // CHECK-NEXT: | |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init // CHECK-NEXT: | | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr // CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param @@ -567,22 +595,25 @@ namespace testCanonicalTemplate { // CHECK-NEXT: |-VarDecl 0x{{.+}} col:43 TestVarTemplate 'const T' static // CHECK-NEXT: |-VarTemplateSpecializationDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} col:14 referenced TestVarTemplate 'const int':'const int' cinit // CHECK-NEXT: | |-TemplateArgument type 'int' + // CHECK-NEXT: | | `-BuiltinType 0x{{.+}} 'int' // CHECK-NEXT: | `-InitListExpr 0x{{.+}} 'int':'int' - // CHECK-NEXT: `-VarTemplateSpecializationDecl 0x{{.+}} col:43 referenced TestVarTemplate 'const int':'const int' static + // CHECK-NEXT: `-VarTemplateSpecializationDecl 0x{{.+}} col:43 referenced TestVarTemplate 'const int':'const int' static // CHECK-NEXT: `-TemplateArgument type 'int' - // CHECK: VarTemplateSpecializationDecl 0x{{.+}} <{{.+}}:[[@LINE-20]]:28, col:43> col:43 referenced TestVarTemplate 'const int':'const int' static + // CHECK: VarTemplateSpecializationDecl 0x{{.+}} <{{.+}}:[[@LINE-21]]:28, col:43> col:43 referenced TestVarTemplate 'const int':'const int' static // CHECK-NEXT:`-TemplateArgument type 'int' + // CHECK-NEXT: `-BuiltinType 0x{{.+}} 'int' - // CHECK: VarTemplateDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-21]]:3, line:[[@LINE-20]]:34> col:14 TestVarTemplate - // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 referenced typename depth 0 index 0 T - // CHECK-NEXT: |-VarDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} col:14 TestVarTemplate 'const T' cinit + // CHECK: VarTemplateDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-23]]:3, line:[[@LINE-22]]:34> col:14 TestVarTemplate + // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 referenced typename depth 0 index 0 T + // CHECK-NEXT: |-VarDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} col:14 TestVarTemplate 'const T' cinit // CHECK-NEXT: | `-InitListExpr 0x{{.+}} 'void' // CHECK-NEXT: |-VarTemplateSpecialization 0x{{.+}} 'TestVarTemplate' 'const int':'const int' // CHECK-NEXT: `-VarTemplateSpecialization 0x{{.+}} 'TestVarTemplate' 'const int':'const int' - // CHECK: VarTemplateSpecializationDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-27]]:3, col:34> col:14 referenced TestVarTemplate 'const int':'const int' cinit + // CHECK: VarTemplateSpecializationDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-29]]:3, col:34> col:14 referenced TestVarTemplate 'const int':'const int' cinit // CHECK-NEXT: |-TemplateArgument type 'int' + // CHECK-NEXT: | `-BuiltinType 0x{{.+}} 'int' // CHECK-NEXT: `-InitListExpr 0x{{.+}} 'int':'int' } @@ -614,6 +645,7 @@ namespace TestNonTypeTemplateParmDecl { // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'int' depth 0 index 0 I // CHECK-NEXT: TemplateArgument expr // CHECK-NEXT: ConstantExpr{{.*}} 'int' +// CHECK-NEXT: value: Int 1 // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 1 // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'int' depth 0 index 1 ... J diff --git a/clang/test/AST/ast-dump-lambda-body-not-duplicated.cpp b/clang/test/AST/ast-dump-lambda-body-not-duplicated.cpp new file mode 100644 index 0000000000000..558455e239c74 --- /dev/null +++ b/clang/test/AST/ast-dump-lambda-body-not-duplicated.cpp @@ -0,0 +1,40 @@ +// Test without serialization: +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -ast-dump %s \ +// RUN: | FileCheck %s +// +// Test with serialization: +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -emit-pch -o %t %s +// RUN: %clang_cc1 -x c++ -triple x86_64-unknown-unknown -Wno-unused-value \ +// RUN: -include-pch %t -ast-dump-all /dev/null \ +// RUN: | FileCheck %s + +// Make sure that the Stmt * for the body of the LambdaExpr is +// equal to the Stmt * for the body of the call operator. +void Test0() { + []() { + return 42; + }; +} + +// CHECK: FunctionDecl {{.*}} Test0 +// +// CHECK: CXXMethodDecl {{.*}} operator() 'int () const' inline +// CHECK-NEXT: CompoundStmt 0x[[TMP0:.*]] +// CHECK: IntegerLiteral {{.*}} 'int' 42 +// +// CHECK: CompoundStmt 0x[[TMP0]] +// Check: IntegerLiteral {{.*}} 'int' 42 + +void Test1() { + [](auto x) { return x; }; +} + +// CHECK: FunctionDecl {{.*}} Test1 +// +// CHECK: CXXMethodDecl {{.*}} operator() 'auto (auto) const' inline +// CHECK-NEXT: ParmVarDecl {{.*}} referenced x 'auto' +// CHECK-NEXT: CompoundStmt 0x[[TMP1:.*]] +// CHECK: DeclRefExpr {{.*}} 'x' 'auto' +// +// CHECK: CompoundStmt 0x[[TMP1]] +// CHECK: DeclRefExpr {{.*}} 'x' 'auto' diff --git a/clang/test/AST/ast-dump-lambda.cpp b/clang/test/AST/ast-dump-lambda.cpp index a3ca4a8fc534f..37fb62ef9930e 100644 --- a/clang/test/AST/ast-dump-lambda.cpp +++ b/clang/test/AST/ast-dump-lambda.cpp @@ -7,7 +7,7 @@ // RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ // RUN: -emit-pch -o %t %s // RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ -// RUN: -x c++ -include-pch %t -ast-dump-all -ast-dump-filter test \ +// RUN: -x c++ -include-pch %t -ast-dump-all -ast-dump-filter test /dev/null \ // RUN: | FileCheck -strict-whitespace --match-full-lines %s diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_template_1.cpp b/clang/test/AST/ast-dump-openmp-begin-declare-variant_template_1.cpp index 6a663d5d75d94..5916958b94625 100644 --- a/clang/test/AST/ast-dump-openmp-begin-declare-variant_template_1.cpp +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_template_1.cpp @@ -118,7 +118,7 @@ int test() { // CHECK-NEXT: | | `-IntegerLiteral [[ADDR_58:0x[a-z0-9]*]] 'int' 0 // CHECK-NEXT: | `-FunctionDecl [[ADDR_59:0x[a-z0-9]*]] line:37:5 used test1 'int ({{.*}})' // CHECK-NEXT: | |-TemplateArgument type 'double' -// CHECK-NEXT: | `-CompoundStmt [[ADDR_60:0x[a-z0-9]*]] +// CHECK: | `-CompoundStmt [[ADDR_60:0x[a-z0-9]*]] // CHECK-NEXT: | `-ReturnStmt [[ADDR_61:0x[a-z0-9]*]] // CHECK-NEXT: | `-PseudoObjectExpr [[ADDR_62:0x[a-z0-9]*]] 'int' // CHECK-NEXT: | |-CallExpr [[ADDR_63:0x[a-z0-9]*]] 'int' @@ -153,7 +153,8 @@ int test() { // CHECK-NEXT: | `-PseudoObjectExpr [[ADDR_85:0x[a-z0-9]*]] 'int' // CHECK-NEXT: | |-CallExpr [[ADDR_86:0x[a-z0-9]*]] 'int' // CHECK-NEXT: | | `-SubstNonTypeTemplateParmExpr [[ADDR_87:0x[a-z0-9]*]] 'int (*)({{.*}})' -// CHECK-NEXT: | | `-UnaryOperator [[ADDR_88:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow +// CHECK-NEXT: | | |-NonTypeTemplateParmDecl {{.*}} referenced 'Ty':'int (*)()' depth 0 index 0 fn +// CHECK-NEXT: | | `-UnaryOperator [[ADDR_88:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow // CHECK-NEXT: | | `-DeclRefExpr [[ADDR_89:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_0]] 'also_before' 'int ({{.*}})' // CHECK-NEXT: | `-CallExpr [[ADDR_90:0x[a-z0-9]*]] 'int' // CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_91:0x[a-z0-9]*]] 'int (*)({{.*}})' diff --git a/clang/test/AST/ast-dump-openmp-target-parallel-for-simd.c b/clang/test/AST/ast-dump-openmp-target-parallel-for-simd.c index f45aac455ac4a..d65a729aa4022 100644 --- a/clang/test/AST/ast-dump-openmp-target-parallel-for-simd.c +++ b/clang/test/AST/ast-dump-openmp-target-parallel-for-simd.c @@ -71,7 +71,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -102,7 +102,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -129,7 +129,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -202,9 +202,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -250,9 +250,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -294,9 +294,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -387,9 +387,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -435,9 +435,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -479,9 +479,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -572,9 +572,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -620,9 +620,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -664,9 +664,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -774,11 +774,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | |-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | |-DeclStmt {{.*}} @@ -839,11 +839,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | |-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | |-CapturedStmt {{.*}} // CHECK-NEXT: | | |-CapturedDecl {{.*}} <> nothrow @@ -900,11 +900,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | |-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | |-ForStmt {{.*}} // CHECK-NEXT: | | |-DeclStmt {{.*}} diff --git a/clang/test/AST/ast-dump-openmp-target-parallel-for.c b/clang/test/AST/ast-dump-openmp-target-parallel-for.c index cbc6445e30e07..abfa75ba10df4 100644 --- a/clang/test/AST/ast-dump-openmp-target-parallel-for.c +++ b/clang/test/AST/ast-dump-openmp-target-parallel-for.c @@ -71,7 +71,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -102,7 +102,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -129,7 +129,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -202,9 +202,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -250,9 +250,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -294,9 +294,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -387,9 +387,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -435,9 +435,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -479,9 +479,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -572,9 +572,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -620,9 +620,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -664,9 +664,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -774,11 +774,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | |-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | |-DeclStmt {{.*}} @@ -839,11 +839,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | |-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | |-CapturedStmt {{.*}} // CHECK-NEXT: | | |-CapturedDecl {{.*}} <> nothrow @@ -900,11 +900,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | |-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | |-ForStmt {{.*}} // CHECK-NEXT: | | |-DeclStmt {{.*}} diff --git a/clang/test/AST/ast-dump-openmp-target-simd.c b/clang/test/AST/ast-dump-openmp-target-simd.c index d66cb2b42d741..404b1b197ab11 100644 --- a/clang/test/AST/ast-dump-openmp-target-simd.c +++ b/clang/test/AST/ast-dump-openmp-target-simd.c @@ -73,7 +73,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -146,9 +146,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -239,9 +239,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -332,9 +332,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -442,11 +442,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | |-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | |-ForStmt {{.*}} // CHECK-NEXT: | | |-DeclStmt {{.*}} diff --git a/clang/test/AST/ast-dump-openmp-target-teams-distribute-parallel-for-simd.c b/clang/test/AST/ast-dump-openmp-target-teams-distribute-parallel-for-simd.c index 5edcaa5a1082c..acb3cf37f08cb 100644 --- a/clang/test/AST/ast-dump-openmp-target-teams-distribute-parallel-for-simd.c +++ b/clang/test/AST/ast-dump-openmp-target-teams-distribute-parallel-for-simd.c @@ -77,7 +77,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | | | `-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} @@ -104,7 +104,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <> nothrow @@ -135,7 +135,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -168,7 +168,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -201,7 +201,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -228,7 +228,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -259,7 +259,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -340,9 +340,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} @@ -384,9 +384,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <> nothrow @@ -432,9 +432,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -482,9 +482,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -532,9 +532,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -576,9 +576,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -624,9 +624,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -725,9 +725,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} @@ -769,9 +769,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <> nothrow @@ -817,9 +817,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -867,9 +867,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -917,9 +917,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -961,9 +961,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -1009,9 +1009,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -1110,9 +1110,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} @@ -1154,9 +1154,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <> nothrow @@ -1202,9 +1202,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -1252,9 +1252,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -1302,9 +1302,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -1346,9 +1346,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -1394,9 +1394,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -1512,11 +1512,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | | |-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} @@ -1573,11 +1573,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | |-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <> nothrow @@ -1638,11 +1638,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | |-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | |-DeclStmt {{.*}} @@ -1705,11 +1705,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | |-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | |-CapturedStmt {{.*}} // CHECK-NEXT: | | |-CapturedDecl {{.*}} <> nothrow @@ -1772,11 +1772,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | |-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | |-DeclStmt {{.*}} @@ -1833,11 +1833,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | |-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | |-CapturedStmt {{.*}} // CHECK-NEXT: | | |-CapturedDecl {{.*}} <> nothrow @@ -1898,11 +1898,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | |-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | |-ForStmt {{.*}} // CHECK-NEXT: | | |-DeclStmt {{.*}} diff --git a/clang/test/AST/ast-dump-openmp-target-teams-distribute-parallel-for.c b/clang/test/AST/ast-dump-openmp-target-teams-distribute-parallel-for.c index 0d816abf5f006..807d8f138c699 100644 --- a/clang/test/AST/ast-dump-openmp-target-teams-distribute-parallel-for.c +++ b/clang/test/AST/ast-dump-openmp-target-teams-distribute-parallel-for.c @@ -77,7 +77,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | | | `-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} @@ -104,7 +104,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <> nothrow @@ -135,7 +135,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -168,7 +168,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -201,7 +201,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -228,7 +228,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -259,7 +259,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -340,9 +340,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} @@ -384,9 +384,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <> nothrow @@ -432,9 +432,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -482,9 +482,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -532,9 +532,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -576,9 +576,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -624,9 +624,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -725,9 +725,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} @@ -769,9 +769,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <> nothrow @@ -817,9 +817,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -867,9 +867,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -917,9 +917,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -961,9 +961,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -1009,9 +1009,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -1110,9 +1110,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | | | `-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} @@ -1154,9 +1154,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <> nothrow @@ -1202,9 +1202,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -1252,9 +1252,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -1302,9 +1302,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -1346,9 +1346,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -1394,9 +1394,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -1512,11 +1512,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | | |-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} @@ -1573,11 +1573,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | |-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <> nothrow @@ -1638,11 +1638,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | |-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | |-DeclStmt {{.*}} @@ -1705,11 +1705,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | |-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | |-CapturedStmt {{.*}} // CHECK-NEXT: | | |-CapturedDecl {{.*}} <> nothrow @@ -1772,11 +1772,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | |-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | |-DeclStmt {{.*}} @@ -1833,11 +1833,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | |-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | |-CapturedStmt {{.*}} // CHECK-NEXT: | | |-CapturedDecl {{.*}} <> nothrow @@ -1898,11 +1898,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | |-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | |-ForStmt {{.*}} // CHECK-NEXT: | | |-DeclStmt {{.*}} diff --git a/clang/test/AST/ast-dump-openmp-target-teams-distribute-simd.c b/clang/test/AST/ast-dump-openmp-target-teams-distribute-simd.c index a113ce2ca4468..83e530c87e3f9 100644 --- a/clang/test/AST/ast-dump-openmp-target-teams-distribute-simd.c +++ b/clang/test/AST/ast-dump-openmp-target-teams-distribute-simd.c @@ -71,7 +71,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -102,7 +102,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -129,7 +129,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -202,9 +202,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -250,9 +250,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -294,9 +294,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -387,9 +387,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -435,9 +435,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -479,9 +479,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -572,9 +572,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -620,9 +620,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -664,9 +664,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -774,11 +774,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | |-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | |-DeclStmt {{.*}} @@ -839,11 +839,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | |-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | |-CapturedStmt {{.*}} // CHECK-NEXT: | | |-CapturedDecl {{.*}} <> nothrow @@ -900,11 +900,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | |-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | |-ForStmt {{.*}} // CHECK-NEXT: | | |-DeclStmt {{.*}} diff --git a/clang/test/AST/ast-dump-openmp-target-teams-distribute.c b/clang/test/AST/ast-dump-openmp-target-teams-distribute.c index 9754294e0396b..a4ebf15356e24 100644 --- a/clang/test/AST/ast-dump-openmp-target-teams-distribute.c +++ b/clang/test/AST/ast-dump-openmp-target-teams-distribute.c @@ -71,7 +71,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -102,7 +102,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -129,7 +129,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -202,9 +202,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -250,9 +250,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -294,9 +294,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -387,9 +387,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -435,9 +435,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -479,9 +479,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -572,9 +572,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | | `-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | | |-DeclStmt {{.*}} @@ -620,9 +620,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-CapturedStmt {{.*}} // CHECK-NEXT: | | | |-CapturedDecl {{.*}} <> nothrow @@ -664,9 +664,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-ForStmt {{.*}} // CHECK-NEXT: | | | |-DeclStmt {{.*}} @@ -774,11 +774,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | |-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | | |-ForStmt {{.*}} // CHECK-NEXT: | | | | |-DeclStmt {{.*}} @@ -839,11 +839,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | |-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | |-CapturedStmt {{.*}} // CHECK-NEXT: | | |-CapturedDecl {{.*}} <> nothrow @@ -900,11 +900,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | |-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | |-ForStmt {{.*}} // CHECK-NEXT: | | |-DeclStmt {{.*}} diff --git a/clang/test/AST/ast-dump-openmp-teams-distribute-parallel-for-simd.c b/clang/test/AST/ast-dump-openmp-teams-distribute-parallel-for-simd.c index 85a67e2f7e04e..204b4fe1365e6 100644 --- a/clang/test/AST/ast-dump-openmp-teams-distribute-parallel-for-simd.c +++ b/clang/test/AST/ast-dump-openmp-teams-distribute-parallel-for-simd.c @@ -189,7 +189,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-OMPTeamsDistributeParallelForSimdDirective {{.*}} // CHECK-NEXT: | | | `-CapturedStmt {{.*}} @@ -532,9 +532,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-OMPTeamsDistributeParallelForSimdDirective {{.*}} // CHECK-NEXT: | | | `-CapturedStmt {{.*}} @@ -943,9 +943,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-OMPTeamsDistributeParallelForSimdDirective {{.*}} // CHECK-NEXT: | | | |-OMPCollapseClause {{.*}} @@ -1376,9 +1376,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-OMPTeamsDistributeParallelForSimdDirective {{.*}} // CHECK-NEXT: | | | |-OMPCollapseClause {{.*}} @@ -1893,11 +1893,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | |-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | |-OMPTeamsDistributeParallelForSimdDirective {{.*}} // CHECK-NEXT: | | |-OMPCollapseClause {{.*}} diff --git a/clang/test/AST/ast-dump-openmp-teams-distribute-parallel-for.c b/clang/test/AST/ast-dump-openmp-teams-distribute-parallel-for.c index 68b99a09a5590..8c86d6c8e3765 100644 --- a/clang/test/AST/ast-dump-openmp-teams-distribute-parallel-for.c +++ b/clang/test/AST/ast-dump-openmp-teams-distribute-parallel-for.c @@ -189,7 +189,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-OMPTeamsDistributeParallelForDirective {{.*}} // CHECK-NEXT: | | | `-CapturedStmt {{.*}} @@ -532,9 +532,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-OMPTeamsDistributeParallelForDirective {{.*}} // CHECK-NEXT: | | | `-CapturedStmt {{.*}} @@ -943,9 +943,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-OMPTeamsDistributeParallelForDirective {{.*}} // CHECK-NEXT: | | | |-OMPCollapseClause {{.*}} @@ -1376,9 +1376,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-OMPTeamsDistributeParallelForDirective {{.*}} // CHECK-NEXT: | | | |-OMPCollapseClause {{.*}} @@ -1893,11 +1893,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | |-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | |-OMPTeamsDistributeParallelForDirective {{.*}} // CHECK-NEXT: | | |-OMPCollapseClause {{.*}} diff --git a/clang/test/AST/ast-dump-openmp-teams-distribute-simd.c b/clang/test/AST/ast-dump-openmp-teams-distribute-simd.c index bbdb722fd760d..a4ad08b8bef2c 100644 --- a/clang/test/AST/ast-dump-openmp-teams-distribute-simd.c +++ b/clang/test/AST/ast-dump-openmp-teams-distribute-simd.c @@ -125,7 +125,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-OMPTeamsDistributeSimdDirective {{.*}} // CHECK-NEXT: | | | `-CapturedStmt {{.*}} @@ -308,9 +308,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-OMPTeamsDistributeSimdDirective {{.*}} // CHECK-NEXT: | | | `-CapturedStmt {{.*}} @@ -527,9 +527,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-OMPTeamsDistributeSimdDirective {{.*}} // CHECK-NEXT: | | | |-OMPCollapseClause {{.*}} @@ -768,9 +768,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-OMPTeamsDistributeSimdDirective {{.*}} // CHECK-NEXT: | | | |-OMPCollapseClause {{.*}} @@ -1061,11 +1061,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | |-FieldDecl {{.*}} col:23 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | |-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | |-OMPTeamsDistributeSimdDirective {{.*}} // CHECK-NEXT: | | |-OMPCollapseClause {{.*}} diff --git a/clang/test/AST/ast-dump-openmp-teams-distribute.c b/clang/test/AST/ast-dump-openmp-teams-distribute.c index 17689709faabe..8c1e6b70cff69 100644 --- a/clang/test/AST/ast-dump-openmp-teams-distribute.c +++ b/clang/test/AST/ast-dump-openmp-teams-distribute.c @@ -125,7 +125,7 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-OMPTeamsDistributeDirective {{.*}} // CHECK-NEXT: | | | `-CapturedStmt {{.*}} @@ -308,9 +308,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-OMPTeamsDistributeDirective {{.*}} // CHECK-NEXT: | | | `-CapturedStmt {{.*}} @@ -527,9 +527,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:25 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-OMPTeamsDistributeDirective {{.*}} // CHECK-NEXT: | | | |-OMPCollapseClause {{.*}} @@ -768,9 +768,9 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | | `-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | | |-OMPTeamsDistributeDirective {{.*}} // CHECK-NEXT: | | | |-OMPCollapseClause {{.*}} @@ -1061,11 +1061,11 @@ void test_five(int x, int y, int z) { // CHECK-NEXT: | |-RecordDecl {{.*}} col:1 implicit struct definition // CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <> Implicit // CHECK-NEXT: | | |-FieldDecl {{.*}} col:3 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | |-FieldDecl {{.*}} col:5 implicit 'int' -// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | | `-FieldDecl {{.*}} col:27 implicit 'int' -// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit 9 +// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <> Implicit {{.*}} // CHECK-NEXT: | `-CapturedDecl {{.*}} <> nothrow // CHECK-NEXT: | |-OMPTeamsDistributeDirective {{.*}} // CHECK-NEXT: | | |-OMPCollapseClause {{.*}} diff --git a/clang/test/AST/ast-dump-records.cpp b/clang/test/AST/ast-dump-records.cpp index f379b2dba529b..cb7ac83204312 100644 --- a/clang/test/AST/ast-dump-records.cpp +++ b/clang/test/AST/ast-dump-records.cpp @@ -15,7 +15,7 @@ struct B; // CHECK: CXXRecordDecl 0x{{[^ ]*}} col:8 referenced struct B struct A { - // CHECK: CXXRecordDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} line:[[@LINE-1]]:8 struct A definition + // CHECK: CXXRecordDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} line:[[@LINE-1]]:8 struct A definition // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param @@ -33,14 +33,17 @@ struct A { int d : 12; // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} col:7 d 'int' // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} 'int' + // CHECK-NEXT: value: Int 12 // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 12 int : 0; // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} col:7 'int' // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} 'int' + // CHECK-NEXT: value: Int 0 // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 0 int e : 10; // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} col:7 e 'int' // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} 'int' + // CHECK-NEXT: value: Int 10 // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 10 B *f; // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} col:6 f 'B *' @@ -141,7 +144,7 @@ union F; // CHECK: CXXRecordDecl 0x{{[^ ]*}} col:7 union F union E { - // CHECK: CXXRecordDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} line:[[@LINE-1]]:7 union E definition + // CHECK: CXXRecordDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} line:[[@LINE-1]]:7 union E definition // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param @@ -159,14 +162,17 @@ union E { int d : 12; // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} col:7 d 'int' // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} 'int' + // CHECK-NEXT: value: Int 12 // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 12 int : 0; // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} col:7 'int' // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} 'int' + // CHECK-NEXT: value: Int 0 // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 0 int e : 10; // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} col:7 e 'int' // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} 'int' + // CHECK-NEXT: value: Int 10 // CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} 'int' 10 B *f; // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} col:6 f 'B *' diff --git a/clang/test/AST/ast-dump-recovery.cpp b/clang/test/AST/ast-dump-recovery.cpp index e2a7151306287..740864a26481b 100644 --- a/clang/test/AST/ast-dump-recovery.cpp +++ b/clang/test/AST/ast-dump-recovery.cpp @@ -4,7 +4,6 @@ int some_func(int *); // CHECK: VarDecl {{.*}} invalid_call -// CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'int' contains-errors // CHECK-NEXT: `-RecoveryExpr {{.*}} 'int' contains-errors // CHECK-NEXT: |-UnresolvedLookupExpr {{.*}} 'some_func' // CHECK-NEXT: `-IntegerLiteral {{.*}} 123 @@ -34,7 +33,6 @@ int ambig_func(double); int ambig_func(float); // CHECK: VarDecl {{.*}} ambig_call -// CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'int' contains-errors // CHECK-NEXT: `-RecoveryExpr {{.*}} 'int' contains-errors // CHECK-NEXT: |-UnresolvedLookupExpr {{.*}} 'ambig_func' // CHECK-NEXT: `-IntegerLiteral {{.*}} 123 @@ -211,3 +209,16 @@ struct { } NoCrashOnInvalidInitList = { .abc = nullptr, }; + +// Verify the value category of recovery expression. +int prvalue(int); +int &lvalue(int); +int &&xvalue(int); +void ValueCategory() { + // CHECK: RecoveryExpr {{.*}} 'int' contains-errors + prvalue(); // call to a function (nonreference return type) yields a prvalue (not print by default) + // CHECK: RecoveryExpr {{.*}} 'int' contains-errors lvalue + lvalue(); // call to a function (lvalue reference return type) yields an lvalue. + // CHECK: RecoveryExpr {{.*}} 'int' contains-errors xvalue + xvalue(); // call to a function (rvalue reference return type) yields an xvalue. +} diff --git a/clang/test/AST/ast-dump-stmt.cpp b/clang/test/AST/ast-dump-stmt.cpp index e4d8d8218b4e3..585a94bd1920a 100644 --- a/clang/test/AST/ast-dump-stmt.cpp +++ b/clang/test/AST/ast-dump-stmt.cpp @@ -130,6 +130,7 @@ void TestIf(bool b) { ; // CHECK: IfStmt 0x{{[^ ]*}} // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} 'bool' + // CHECK-NEXT: value: Int 1 // CHECK-NEXT: BinaryOperator // CHECK-NEXT: UnaryExprOrTypeTraitExpr // CHECK-NEXT: ParenExpr @@ -144,6 +145,7 @@ void TestIf(bool b) { ; // CHECK: IfStmt 0x{{[^ ]*}} has_else // CHECK-NEXT: ConstantExpr 0x{{[^ ]*}} 'bool' + // CHECK-NEXT: value: Int 1 // CHECK-NEXT: BinaryOperator // CHECK-NEXT: UnaryExprOrTypeTraitExpr // CHECK-NEXT: ParenExpr diff --git a/clang/test/AST/ast-dump-template-decls-json.cpp b/clang/test/AST/ast-dump-template-decls-json.cpp index 658358c5789e6..f074d6f0137db 100644 --- a/clang/test/AST/ast-dump-template-decls-json.cpp +++ b/clang/test/AST/ast-dump-template-decls-json.cpp @@ -597,13 +597,31 @@ void V::f() {} // CHECK-NEXT: "kind": "TemplateArgument", // CHECK-NEXT: "type": { // CHECK-NEXT: "qualType": "float" -// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "BuiltinType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "float" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "kind": "TemplateArgument", // CHECK-NEXT: "type": { // CHECK-NEXT: "qualType": "int" -// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "BuiltinType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "int" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "id": "0x{{.*}}", @@ -1120,7 +1138,16 @@ void V::f() {} // CHECK-NEXT: "kind": "TemplateArgument", // CHECK-NEXT: "type": { // CHECK-NEXT: "qualType": "int" -// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "BuiltinType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "int" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: }, @@ -1238,7 +1265,16 @@ void V::f() {} // CHECK-NEXT: "kind": "TemplateArgument", // CHECK-NEXT: "type": { // CHECK-NEXT: "qualType": "void" -// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "BuiltinType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: }, @@ -1511,7 +1547,16 @@ void V::f() {} // CHECK-NEXT: "kind": "TemplateArgument", // CHECK-NEXT: "type": { // CHECK-NEXT: "qualType": "int" -// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "BuiltinType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "int" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "id": "0x{{.*}}", @@ -1799,13 +1844,38 @@ void V::f() {} // CHECK-NEXT: "kind": "TemplateArgument", // CHECK-NEXT: "type": { // CHECK-NEXT: "qualType": "type-parameter-0-0" -// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "TemplateTypeParmType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "type-parameter-0-0" +// CHECK-NEXT: }, +// CHECK-NEXT: "isDependent": true, +// CHECK-NEXT: "isInstantiationDependent": true, +// CHECK-NEXT: "depth": 0, +// CHECK-NEXT: "index": 0, +// CHECK-NEXT: "decl": { +// CHECK-NEXT: "id": "0x0" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "kind": "TemplateArgument", // CHECK-NEXT: "type": { // CHECK-NEXT: "qualType": "int" -// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "BuiltinType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "int" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "id": "0x{{.*}}", diff --git a/clang/test/AST/ast-dump-template-decls.cpp b/clang/test/AST/ast-dump-template-decls.cpp index 29d2335ce0151..e58731ae6d51d 100644 --- a/clang/test/AST/ast-dump-template-decls.cpp +++ b/clang/test/AST/ast-dump-template-decls.cpp @@ -79,8 +79,8 @@ struct S {}; template // CHECK: ClassTemplatePartialSpecializationDecl 0x{{[^ ]*}} col:8 struct S definition // CHECK: TemplateArgument type 'type-parameter-0-0' -// CHECK-NEXT: TemplateArgument type 'int' -// CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} col:20 referenced typename depth 0 index 0 Ty +// CHECK: TemplateArgument type 'int' +// CHECK: TemplateTypeParmDecl 0x{{[^ ]*}} col:20 referenced typename depth 0 index 0 Ty struct S {}; template diff --git a/clang/test/AST/coroutine-source-location-crash.cpp b/clang/test/AST/coroutine-source-location-crash.cpp index 24fe3bcb224ef..6c0184d2076d4 100644 --- a/clang/test/AST/coroutine-source-location-crash.cpp +++ b/clang/test/AST/coroutine-source-location-crash.cpp @@ -24,7 +24,7 @@ struct coro_t { struct promise_type { coro_t get_return_object(); suspend_never initial_suspend(); - suspend_never final_suspend(); + suspend_never final_suspend() noexcept; void return_void(); static void unhandled_exception(); }; diff --git a/clang/test/AST/float16.cpp b/clang/test/AST/float16.cpp index c886aa9cf0f1b..807289ac0a7f1 100644 --- a/clang/test/AST/float16.cpp +++ b/clang/test/AST/float16.cpp @@ -178,7 +178,7 @@ template C func1t(C arg) { //CHECK-NEXT: | | `-FloatingLiteral {{.*}} '_Float16' 2.000000e+00 //CHECK-NEXT: | `-FunctionDecl {{.*}} used func1t '_Float16 (_Float16)' //CHECK-NEXT: | |-TemplateArgument type '_Float16' -//CHECK-NEXT: | |-ParmVarDecl {{.*}} used arg '_Float16':'_Float16' +//CHECK: | |-ParmVarDecl {{.*}} used arg '_Float16':'_Float16' //CHECK-NEXT: | `-CompoundStmt //CHECK-NEXT: | `-ReturnStmt //CHECK-NEXT: | `-BinaryOperator {{.*}} '_Float16' '*' diff --git a/clang/test/AST/pr43983.cpp b/clang/test/AST/pr43983.cpp index dd7ce76a38bc8..c27d825dbb1b0 100644 --- a/clang/test/AST/pr43983.cpp +++ b/clang/test/AST/pr43983.cpp @@ -9,6 +9,7 @@ struct B { _Alignas(64) struct { int b; }; }; -// CHECK: AlignedAttr {{.*}} _Alignas -// CHECK: ConstantExpr {{.*}} 64 -// CHECK: IntegerLiteral {{.*}} 64 +// CHECK: | `-AlignedAttr {{.*}} _Alignas +// CHECK-NEXT: | `-ConstantExpr {{.*}} 'int' +// CHECK-NEXT: | |-value: Int 64 +// CHECK-NEXT: | `-IntegerLiteral {{.*}} 'int' 64 diff --git a/clang/test/AST/regression-new-expr-crash.cpp b/clang/test/AST/regression-new-expr-crash.cpp new file mode 100644 index 0000000000000..81dd193b93e88 --- /dev/null +++ b/clang/test/AST/regression-new-expr-crash.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only %s + +struct Bar {int a;}; +const Bar arr[2] = {{1}}; + +struct Foo {}; + +const int b = 2; + +void foo(int a) { + Foo *foo_array; + foo_array = new Foo[arr[0].a]; +} diff --git a/clang/test/Analysis/Inputs/system-header-simulator-cxx.h b/clang/test/Analysis/Inputs/system-header-simulator-cxx.h index 4729b0439ad0f..fe4b9d081e9c8 100644 --- a/clang/test/Analysis/Inputs/system-header-simulator-cxx.h +++ b/clang/test/Analysis/Inputs/system-header-simulator-cxx.h @@ -946,10 +946,15 @@ namespace std { template // TODO: Implement the stub for deleter. class unique_ptr { public: + unique_ptr() {} + unique_ptr(T *) {} unique_ptr(const unique_ptr &) = delete; unique_ptr(unique_ptr &&); T *get() const; + T *release() const; + void reset(T *p = nullptr) const; + void swap(unique_ptr &p) const; typename std::add_lvalue_reference::type operator*() const; T *operator->() const; diff --git a/clang/test/Analysis/analyzer-config.c b/clang/test/Analysis/analyzer-config.c index 1d4a96389fb36..d286f1258c21a 100644 --- a/clang/test/Analysis/analyzer-config.c +++ b/clang/test/Analysis/analyzer-config.c @@ -13,6 +13,7 @@ // CHECK-NEXT: alpha.security.MmapWriteExec:MmapProtRead = 0x01 // CHECK-NEXT: alpha.security.taint.TaintPropagation:Config = "" // CHECK-NEXT: apiModeling.StdCLibraryFunctions:DisplayLoadedSummaries = false +// CHECK-NEXT: apiModeling.StdCLibraryFunctions:ModelPOSIX = false // CHECK-NEXT: apply-fixits = false // CHECK-NEXT: avoid-suppressing-null-argument-paths = false // CHECK-NEXT: c++-allocator-inlining = true @@ -39,9 +40,11 @@ // CHECK-NEXT: core.CallAndMessage:ParameterCount = true // CHECK-NEXT: core.CallAndMessage:UndefReceiver = true // CHECK-NEXT: cplusplus.Move:WarnOn = KnownsAndLocals +// CHECK-NEXT: cplusplus.SmartPtrModeling:ModelSmartPtrDereference = false // CHECK-NEXT: crosscheck-with-z3 = false // CHECK-NEXT: ctu-dir = "" -// CHECK-NEXT: ctu-import-threshold = 100 +// CHECK-NEXT: ctu-import-cpp-threshold = 8 +// CHECK-NEXT: ctu-import-threshold = 24 // CHECK-NEXT: ctu-index-name = externalDefMap.txt // CHECK-NEXT: ctu-invocation-list = invocations.yaml // CHECK-NEXT: deadcode.DeadStores:ShowFixIts = false @@ -50,6 +53,7 @@ // CHECK-NEXT: debug.AnalysisOrder:Bind = false // CHECK-NEXT: debug.AnalysisOrder:EndAnalysis = false // CHECK-NEXT: debug.AnalysisOrder:EndFunction = false +// CHECK-NEXT: debug.AnalysisOrder:EvalCall = false // CHECK-NEXT: debug.AnalysisOrder:LiveSymbols = false // CHECK-NEXT: debug.AnalysisOrder:NewAllocator = false // CHECK-NEXT: debug.AnalysisOrder:PointerEscape = false diff --git a/clang/test/Analysis/checker-plugins.c b/clang/test/Analysis/checker-plugins.c index fbc9c9bd1c22b..69fab8fa6eed1 100644 --- a/clang/test/Analysis/checker-plugins.c +++ b/clang/test/Analysis/checker-plugins.c @@ -116,4 +116,5 @@ void caller() { // RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-CHECKER-OPTION-HELP // CHECK-CHECKER-OPTION-HELP: example.MyChecker:ExampleOption (bool) This is an -// CHECK-CHECKER-OPTION-HELP-SAME: example checker opt. (default: false) +// CHECK-CHECKER-OPTION-HELP-SAME: example checker opt. (default: +// CHECK-CHECKER-OPTION-HELP-NEXT: false) diff --git a/clang/test/Analysis/ctu-import-threshold.c b/clang/test/Analysis/ctu-import-threshold.c index 82711b873d106..62bbeda20d5ba 100644 --- a/clang/test/Analysis/ctu-import-threshold.c +++ b/clang/test/Analysis/ctu-import-threshold.c @@ -1,5 +1,6 @@ // Ensure analyzer option 'ctu-import-threshold' is a recognized option. // // RUN: %clang_cc1 -analyze -analyzer-config ctu-import-threshold=30 -verify %s +// RUN: %clang_cc1 -analyze -analyzer-config ctu-import-cpp-threshold=30 -verify %s // // expected-no-diagnostics diff --git a/clang/test/Analysis/cxxctr-evalcall-analysis-order.cpp b/clang/test/Analysis/cxxctr-evalcall-analysis-order.cpp new file mode 100644 index 0000000000000..0e1ec2f9de566 --- /dev/null +++ b/clang/test/Analysis/cxxctr-evalcall-analysis-order.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_analyze_cc1 %s \ +// RUN: -analyzer-checker=debug.AnalysisOrder \ +// RUN: -analyzer-config debug.AnalysisOrder:EvalCall=true \ +// RUN: -analyzer-config debug.AnalysisOrder:PreCall=true \ +// RUN: -analyzer-config debug.AnalysisOrder:PostCall=true \ +// RUN: 2>&1 | FileCheck %s + +// This test ensures that eval::Call event will be triggered for constructors. + +class C { +public: + C(){}; + C(int x){}; + C(int x, int y){}; +}; + +void foo() { + C C0; + C C1(42); + C *C2 = new C{2, 3}; +} + +// CHECK: PreCall (C::C) [CXXConstructorCall] +// CHECK-NEXT: EvalCall (C::C) {argno: 0} [CXXConstructorCall] +// CHECK-NEXT: PostCall (C::C) [CXXConstructorCall] +// CHECK-NEXT: PreCall (C::C) [CXXConstructorCall] +// CHECK-NEXT: EvalCall (C::C) {argno: 1} [CXXConstructorCall] +// CHECK-NEXT: PostCall (C::C) [CXXConstructorCall] +// CHECK-NEXT: PreCall (operator new) [CXXAllocatorCall] +// CHECK-NEXT: PostCall (operator new) [CXXAllocatorCall] +// CHECK-NEXT: PreCall (C::C) [CXXConstructorCall] +// CHECK-NEXT: EvalCall (C::C) {argno: 2} [CXXConstructorCall] +// CHECK-NEXT: PostCall (C::C) [CXXConstructorCall] diff --git a/clang/test/Analysis/exploded-graph-rewriter/l_name_starts_with_l.cpp b/clang/test/Analysis/exploded-graph-rewriter/l_name_starts_with_l.cpp new file mode 100644 index 0000000000000..a5d2443ea0b45 --- /dev/null +++ b/clang/test/Analysis/exploded-graph-rewriter/l_name_starts_with_l.cpp @@ -0,0 +1,28 @@ +// CAUTION: The name of this file should start with `l` for proper tests. +// FIXME: Figure out how to use %clang_analyze_cc1 with our lit.local.cfg. +// RUN: %clang_cc1 -analyze -triple x86_64-unknown-linux-gnu \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-dump-egraph=%t.dot %s +// RUN: %exploded_graph_rewriter %t.dot | FileCheck %s +// REQUIRES: asserts + +void test1() { + // Here __FILE__ macros produces a string with `\` delimiters on Windows + // and the name of the file starts with `l`. + char text[] = __FILE__; +} + +void test2() { + // Here `\l` is in the middle of the literal. + char text[] = "string\\literal"; +} + +void test() { + test1(); + test2(); +} + +// This test is passed if exploded_graph_rewriter handles dot file without errors. +// CHECK: digraph "ExplodedGraph" +// CHECK: shape=record,label=< +// CHECK: char text[] = "string\\literal"; diff --git a/clang/test/Analysis/exploded-graph-rewriter/win_path_forbidden_chars.cpp b/clang/test/Analysis/exploded-graph-rewriter/win_path_forbidden_chars.cpp new file mode 100644 index 0000000000000..4eac964a4f440 --- /dev/null +++ b/clang/test/Analysis/exploded-graph-rewriter/win_path_forbidden_chars.cpp @@ -0,0 +1,20 @@ +// FIXME: Figure out how to use %clang_analyze_cc1 with our lit.local.cfg. +// RUN: %clang_cc1 -analyze -triple x86_64-unknown-linux-gnu \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-dump-egraph=%t.dot %s +// RUN: %exploded_graph_rewriter --verbose %t.dot 2>&1 | FileCheck %s +// REQUIRES: asserts +// UNSUPPORTED: !windows + +// Angle brackets shall not be presented in the field `file`, +// because exploded_graph_rewriter handles it as a file path +// and such symbols are forbidden on Windows platform. + +void test() { + // This produces angle brackets. + char text[] = __FILE__; +} + +// This test is passed if exploded_graph_rewriter handles dot file without errors. +// CHECK: DEBUG:root:Line: digraph "Exploded Graph" +// CHECK: \"file\": \"scratch space\" diff --git a/clang/test/Analysis/fuchsia_handle.cpp b/clang/test/Analysis/fuchsia_handle.cpp index c20622be543f6..dade5261bd78e 100644 --- a/clang/test/Analysis/fuchsia_handle.cpp +++ b/clang/test/Analysis/fuchsia_handle.cpp @@ -261,7 +261,7 @@ struct HandleWrapperUnkonwDtor { T handle; }; -void doNotWarnOnUnkownDtor() { +void doNotWarnOnUnknownDtor() { HandleWrapperUnkonwDtor w1; zx_handle_t sb; if (zx_channel_create(0, w1.get_handle_address(), &sb)) diff --git a/clang/test/Analysis/invalidated-iterator.cpp b/clang/test/Analysis/invalidated-iterator.cpp index a9ccc3b758348..778a8e01d9938 100644 --- a/clang/test/Analysis/invalidated-iterator.cpp +++ b/clang/test/Analysis/invalidated-iterator.cpp @@ -120,3 +120,80 @@ void assignment(std::vector &V) { V.erase(i); auto j = V.cbegin(); // no-warning } + +template +struct cont_with_ptr_iterator { + T *begin() const; + T *end() const; + T &operator[](size_t); + void push_back(const T&); + T* erase(T*); +}; + +void invalidated_dereference_end_ptr_iterator(cont_with_ptr_iterator &C) { + auto i = C.begin(); + C.erase(i); + (void) *i; // expected-warning{{Invalidated iterator accessed}} +} + +void invalidated_prefix_increment_end_ptr_iterator( + cont_with_ptr_iterator &C) { + auto i = C.begin(); + C.erase(i); + ++i; // expected-warning{{Invalidated iterator accessed}} +} + +void invalidated_prefix_decrement_end_ptr_iterator( + cont_with_ptr_iterator &C) { + auto i = C.begin() + 1; + C.erase(i); + --i; // expected-warning{{Invalidated iterator accessed}} +} + +void invalidated_postfix_increment_end_ptr_iterator( + cont_with_ptr_iterator &C) { + auto i = C.begin(); + C.erase(i); + i++; // expected-warning{{Invalidated iterator accessed}} +} + +void invalidated_postfix_decrement_end_ptr_iterator( + cont_with_ptr_iterator &C) { + auto i = C.begin() + 1; + C.erase(i); + i--; // expected-warning{{Invalidated iterator accessed}} +} + +void invalidated_increment_by_2_end_ptr_iterator( + cont_with_ptr_iterator &C) { + auto i = C.begin(); + C.erase(i); + i += 2; // expected-warning{{Invalidated iterator accessed}} +} + +void invalidated_increment_by_2_copy_end_ptr_iterator( + cont_with_ptr_iterator &C) { + auto i = C.begin(); + C.erase(i); + auto j = i + 2; // expected-warning{{Invalidated iterator accessed}} +} + +void invalidated_decrement_by_2_end_ptr_iterator( + cont_with_ptr_iterator &C) { + auto i = C.begin(); + C.erase(i); + i -= 2; // expected-warning{{Invalidated iterator accessed}} +} + +void invalidated_decrement_by_2_copy_end_ptr_iterator( + cont_with_ptr_iterator &C) { + auto i = C.begin(); + C.erase(i); + auto j = i - 2; // expected-warning{{Invalidated iterator accessed}} +} + +void invalidated_subscript_end_ptr_iterator(cont_with_ptr_iterator &C) { + auto i = C.begin(); + C.erase(i); + (void) i[1]; // expected-warning{{Invalidated iterator accessed}} +} diff --git a/clang/test/Analysis/iterator-modeling.cpp b/clang/test/Analysis/iterator-modeling.cpp index bb37a7565ca16..f19848b8dc935 100644 --- a/clang/test/Analysis/iterator-modeling.cpp +++ b/clang/test/Analysis/iterator-modeling.cpp @@ -1,12 +1,12 @@ -// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=false %s -verify +// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=false %s -verify -analyzer-config display-checker-name=false -// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 %s -verify +// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 %s -verify -analyzer-config display-checker-name=false -// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 -DSTD_ADVANCE_INLINE_LEVEL=0 %s -verify +// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 -DSTD_ADVANCE_INLINE_LEVEL=0 %s -verify -analyzer-config display-checker-name=false -// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 -DSTD_ADVANCE_INLINE_LEVEL=1 %s -verify +// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 -DSTD_ADVANCE_INLINE_LEVEL=1 %s -verify -analyzer-config display-checker-name=false -// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 -DSTD_ADVANCE_INLINE_LEVEL=2 %s -verify +// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 -DSTD_ADVANCE_INLINE_LEVEL=2 %s -verify -analyzer-config display-checker-name=false // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,alpha.cplusplus.IteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true %s 2>&1 | FileCheck %s @@ -18,6 +18,7 @@ template long clang_analyzer_container_end(const Container&); template long clang_analyzer_iterator_position(const Iterator&); +long clang_analyzer_iterator_position(int*); template void* clang_analyzer_iterator_container(const Iterator&); template @@ -33,7 +34,7 @@ void begin(const std::vector &v) { clang_analyzer_eval(clang_analyzer_iterator_container(i) == &v); // expected-warning{{TRUE}} clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()"); - clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.begin()}} + clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.begin(){{$}}}} if (i != v.begin()) { clang_analyzer_warnIfReached(); @@ -45,7 +46,7 @@ void end(const std::vector &v) { clang_analyzer_eval(clang_analyzer_iterator_container(i) == &v); // expected-warning{{TRUE}} clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()"); - clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.end(){{$}}}} if (i != v.end()) { clang_analyzer_warnIfReached(); @@ -59,8 +60,8 @@ void prefix_increment(const std::vector &v) { auto j = ++i; - clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.begin() + 1}} - clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.begin() + 1}} + clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.begin() + 1{{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning-re {{$v.begin() + 1{{$}}}} } void prefix_decrement(const std::vector &v) { @@ -70,8 +71,8 @@ void prefix_decrement(const std::vector &v) { auto j = --i; - clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.end() - 1}} - clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.end() - 1}} + clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.end() - 1{{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning-re {{$v.end() - 1{{$}}}} } void postfix_increment(const std::vector &v) { @@ -81,8 +82,8 @@ void postfix_increment(const std::vector &v) { auto j = i++; - clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.begin() + 1}} - clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.begin()}} + clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.begin() + 1{{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning-re {{$v.begin(){{$}}}} } void postfix_decrement(const std::vector &v) { @@ -92,8 +93,8 @@ void postfix_decrement(const std::vector &v) { auto j = i--; - clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.end() - 1}} - clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.end() - 1{{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning-re {{$v.end(){{$}}}} } void plus_equal(const std::vector &v) { @@ -103,7 +104,7 @@ void plus_equal(const std::vector &v) { i += 2; - clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.begin() + 2}} + clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.begin() + 2{{$}}}} } void plus_equal_negative(const std::vector &v) { @@ -113,7 +114,7 @@ void plus_equal_negative(const std::vector &v) { i += -2; - clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.end() - 2}} + clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.end() - 2{{$}}}} } void minus_equal(const std::vector &v) { @@ -123,7 +124,7 @@ void minus_equal(const std::vector &v) { i -= 2; - clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.end() - 2}} + clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.end() - 2{{$}}}} } void minus_equal_negative(const std::vector &v) { @@ -133,7 +134,7 @@ void minus_equal_negative(const std::vector &v) { i -= -2; - clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.begin() + 2}} + clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.begin() + 2{{$}}}} } void copy(const std::vector &v) { @@ -144,7 +145,8 @@ void copy(const std::vector &v) { auto i2 = i1; clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.end(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$v.end(){{$}}}} } void plus(const std::vector &v) { @@ -155,7 +157,8 @@ void plus(const std::vector &v) { auto i2 = i1 + 2; clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.begin() + 2}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re{{$v.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re{{$v.begin() + 2{{$}}}} } void plus_negative(const std::vector &v) { @@ -166,7 +169,8 @@ void plus_negative(const std::vector &v) { auto i2 = i1 + (-2); clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.end() - 2}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.end(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$v.end() - 2{{$}}}} } void minus(const std::vector &v) { @@ -177,7 +181,8 @@ void minus(const std::vector &v) { auto i2 = i1 - 2; clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.end() - 2}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.end(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$v.end() - 2{{$}}}} } void minus_negative(const std::vector &v) { @@ -188,7 +193,8 @@ void minus_negative(const std::vector &v) { auto i2 = i1 - (-2); clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.begin() + 2}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$v.begin() + 2{{$}}}} } void copy_and_increment1(const std::vector &v) { @@ -199,8 +205,8 @@ void copy_and_increment1(const std::vector &v) { auto i2 = i1; ++i1; - clang_analyzer_express(clang_analyzer_iterator_position(i1)); //expected-warning{{$v.begin() + 1}} - clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.begin()}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.begin() + 1{{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$v.begin(){{$}}}} } void copy_and_increment2(const std::vector &v) { @@ -211,8 +217,8 @@ void copy_and_increment2(const std::vector &v) { auto i2 = i1; ++i2; - clang_analyzer_express(clang_analyzer_iterator_position(i1)); //expected-warning{{$v.begin()}} - clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.begin() + 1}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$v.begin() + 1{{$}}}} } void copy_and_decrement1(const std::vector &v) { @@ -223,8 +229,8 @@ void copy_and_decrement1(const std::vector &v) { auto i2 = i1; --i1; - clang_analyzer_express(clang_analyzer_iterator_position(i1)); //expected-warning{{$v.end() - 1}} - clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.end() - 1{{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$v.end(){{$}}}} } void copy_and_decrement2(const std::vector &v) { @@ -235,8 +241,8 @@ void copy_and_decrement2(const std::vector &v) { auto i2 = i1; --i2; - clang_analyzer_express(clang_analyzer_iterator_position(i1)); //expected-warning{{$v.end()}} - clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.end() - 1}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.end(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$v.end() - 1{{$}}}} } /// std::advance(), std::prev(), std::next() @@ -248,7 +254,7 @@ void std_advance_minus(const std::vector &v) { std::advance(i, -1); - clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.end() - 1}} + clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.end() - 1{{$}}}} } void std_advance_plus(const std::vector &v) { @@ -258,7 +264,7 @@ void std_advance_plus(const std::vector &v) { std::advance(i, 1); - clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.begin() + 1}} + clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.begin() + 1{{$}}}} } void std_prev(const std::vector &v) { @@ -268,7 +274,7 @@ void std_prev(const std::vector &v) { auto j = std::prev(i); - clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.end() - 1}} + clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning-re {{$v.end() - 1{{$}}}} } void std_prev2(const std::vector &v) { @@ -278,7 +284,7 @@ void std_prev2(const std::vector &v) { auto j = std::prev(i, 2); - clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.end() - 2}} + clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning-re {{$v.end() - 2{{$}}}} } void std_next(const std::vector &v) { @@ -288,7 +294,7 @@ void std_next(const std::vector &v) { auto j = std::next(i); - clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.begin() + 1}} + clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning-re {{$v.begin() + 1{{$}}}} } void std_next2(const std::vector &v) { @@ -298,7 +304,7 @@ void std_next2(const std::vector &v) { auto j = std::next(i, 2); - clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.begin() + 2}} + clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning-re {{$v.begin() + 2{{$}}}} } //////////////////////////////////////////////////////////////////////////////// @@ -356,7 +362,7 @@ void list_move_assignment(std::list &L1, std::list &L2) { clang_analyzer_eval(clang_analyzer_iterator_container(i1) == &L1); // expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &L1); // expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L2.begin()}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L2.begin(){{$}}}} } void vector_move_assignment(std::vector &V1, std::vector &V2) { @@ -374,7 +380,7 @@ void vector_move_assignment(std::vector &V1, std::vector &V2) { clang_analyzer_eval(clang_analyzer_iterator_container(i1) == &V1); // expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &V1); // expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$V2.begin()}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$V2.begin(){{$}}}} } void deque_move_assignment(std::deque &D1, std::deque &D2) { @@ -392,7 +398,7 @@ void deque_move_assignment(std::deque &D1, std::deque &D2) { clang_analyzer_eval(clang_analyzer_iterator_container(i1) == &D1); // expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &D1); // expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$D2.begin()}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$D2.begin(){{$}}}} } void forward_list_move_assignment(std::forward_list &FL1, @@ -409,7 +415,7 @@ void forward_list_move_assignment(std::forward_list &FL1, clang_analyzer_eval(clang_analyzer_iterator_container(i1) == &FL1); // expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$FL2.begin()}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$FL2.begin(){{$}}}} } @@ -506,9 +512,9 @@ void list_push_back(std::list &L, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end() - 1}} - clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} FIXME: Should be $L.end() + 1 + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end() - 1{{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} FIXME: Should be $L.end() + 1 } /// std::vector-like containers: The past-the-end iterator is invalidated. @@ -525,8 +531,8 @@ void vector_push_back(std::vector &V, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$V.end() - 1}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$V.end() - 1{{$}}}} } /// std::deque-like containers: All iterators, including the past-the-end @@ -566,9 +572,9 @@ void list_emplace_back(std::list &L, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end()}} - clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} FIXME: Should be $L.end() + 1 + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end() - 1{{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} FIXME: Should be $L.end() + 1 } /// std::vector-like containers: The past-the-end iterator is invalidated. @@ -585,8 +591,8 @@ void vector_emplace_back(std::vector &V, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$V.end() - 1}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$V.end() - 1{{$}}}} } /// std::deque-like containers: All iterators, including the past-the-end @@ -626,8 +632,8 @@ void list_pop_back(std::list &L, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} - clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} FIXME: Should be $L.end() - 1 + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} FIXME: Should be $L.end() - 1 } /// std::vector-like containers: Iterators to the last element, as well as the @@ -645,7 +651,7 @@ void vector_pop_back(std::vector &V, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} } /// std::deque-like containers: Iterators to the last element are invalidated. @@ -664,7 +670,7 @@ void deque_pop_back(std::deque &D, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$D.begin()}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$D.begin(){{$}}}} } /// push_front() @@ -687,8 +693,8 @@ void list_push_front(std::list &L, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end(){{$}}}} } /// std::deque-like containers: All iterators, including the past-the-end @@ -720,8 +726,8 @@ void forward_list_push_front(std::forward_list &FL, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$FL.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$FL.end(){{$}}}} } /// emplace_front() @@ -744,8 +750,8 @@ void list_emplace_front(std::list &L, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end(){{$}}}} } /// std::deque-like containers: All iterators, including the past-the-end @@ -777,8 +783,8 @@ void forward_list_emplace_front(std::forward_list &FL, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$FL.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$FL.end(){{$}}}} } /// pop_front() @@ -802,8 +808,8 @@ void list_pop_front(std::list &L, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.begin() + 1}} - clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.begin() + 1{{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} } /// std::deque-like containers: Iterators to the first element are invalidated. @@ -821,8 +827,8 @@ void deque_pop_front(std::deque &D, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$D.begin() + 1}} - clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$D.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$D.begin() + 1{{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$D.end(){{$}}}} } /// std::forward_list-like containers: Iterators to the first element are @@ -840,8 +846,8 @@ void forward_list_pop_front(std::list &FL, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$FL.begin() + 1}} - clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$FL.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$FL.begin() + 1{{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$FL.end(){{$}}}} } /// insert() @@ -867,9 +873,9 @@ void list_insert_begin(std::list &L, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $L.begin() - 1 - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end(){{$}}}} } void list_insert_behind_begin(std::list &L, int n) { @@ -884,10 +890,10 @@ void list_insert_behind_begin(std::list &L, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} FIXME: Should be $L.begin() - 1 - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.begin() + 1}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} FIXME: Should be $L.begin() - 1 + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.begin() + 1{{$}}}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.begin() - clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} } template Iter return_any_iterator(const Iter &It); @@ -905,10 +911,10 @@ void list_insert_unknown(std::list &L, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$i1}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$i1{{$}}}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i - 1 - clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} } void list_insert_ahead_of_end(std::list &L, int n) { @@ -923,9 +929,9 @@ void list_insert_ahead_of_end(std::list &L, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end() - 1}} - clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end() - 1{{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() - 2 } @@ -941,9 +947,9 @@ void list_insert_end(std::list &L, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end() - 1}} FIXME: should be $L.end() - 2 - clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end() - 1{{$}}}} FIXME: should be $L.end() - 2 + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() - 1 } @@ -977,7 +983,7 @@ void vector_insert_behind_begin(std::vector &V, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} FIXME: Should be $V.begin() - 1 + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} FIXME: Should be $V.begin() - 1 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); // FIXME: expect -warning $V.begin() } @@ -994,7 +1000,7 @@ void vector_insert_unknown(std::vector &V, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expecte warning $i1 - 1 } @@ -1010,7 +1016,7 @@ void vector_insert_ahead_of_end(std::vector &V, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() - 2 } @@ -1026,8 +1032,8 @@ void vector_insert_end(std::vector &V, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$V.end() - 1}} FIXME: Should be $V.end() - 2 + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$V.end() - 1{{$}}}} FIXME: Should be $V.end() - 2 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() - 1 } @@ -1130,9 +1136,9 @@ void forward_list_insert_after_begin(std::forward_list &FL, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}} // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $FL.begin() + 1 - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$FL.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$FL.end(){{$}}}} } void forward_list_insert_after_behind_begin(std::forward_list &FL, int n) { @@ -1147,10 +1153,10 @@ void forward_list_insert_after_behind_begin(std::forward_list &FL, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$FL.begin() + 1}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$FL.begin() + 1{{$}}}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $FL.begin() + 2 - clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$FL.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$FL.end(){{$}}}} } void forward_list_insert_after_unknown(std::forward_list &FL, int n) { @@ -1166,10 +1172,10 @@ void forward_list_insert_after_unknown(std::forward_list &FL, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$i1}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$i1{{$}}}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1 - clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$FL.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$FL.end(){{$}}}} } /// emplace() @@ -1195,9 +1201,9 @@ void list_emplace_begin(std::list &L, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $L.begin() - 1 - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end(){{$}}}} } void list_emplace_behind_begin(std::list &L, int n) { @@ -1212,10 +1218,10 @@ void list_emplace_behind_begin(std::list &L, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} FIXME: Should be $L.begin() - 1 - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.begin() + 1}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} FIXME: Should be $L.begin() - 1 + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.begin() + 1{{$}}}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.begin() - clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} } template Iter return_any_iterator(const Iter &It); @@ -1233,10 +1239,10 @@ void list_emplace_unknown(std::list &L, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$i1}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$i1{{$}}}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i - 1 - clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} } void list_emplace_ahead_of_end(std::list &L, int n) { @@ -1251,9 +1257,9 @@ void list_emplace_ahead_of_end(std::list &L, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end() - 1}} - clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end() - 1{{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() - 2 } @@ -1269,9 +1275,9 @@ void list_emplace_end(std::list &L, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end() - 1}} FIXME: should be $L.end() - 2 - clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end() - 1{{$}}}} FIXME: should be $L.end() - 2 + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() - 1 } @@ -1304,7 +1310,7 @@ void vector_emplace_behind_begin(std::vector &V, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} FIXME: Should be $V.begin() - 1 + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} FIXME: Should be $V.begin() - 1 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); // FIXME: expect -warning $V.begin() } @@ -1321,7 +1327,7 @@ void vector_emplace_unknown(std::vector &V, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expecte warning $i1 - 1 } @@ -1337,7 +1343,7 @@ void vector_emplace_ahead_of_end(std::vector &V, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() - 2 } @@ -1353,8 +1359,8 @@ void vector_emplace_end(std::vector &V, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$V.end() - 1}} FIXME: Should be $V.end() - 2 + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$V.end() - 1{{$}}}} FIXME: Should be $V.end() - 2 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() - 1 } @@ -1455,9 +1461,9 @@ void forward_list_emplace_after_begin(std::forward_list &FL, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}} // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $FL.begin() + 1 - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$FL.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$FL.end(){{$}}}} } void forward_list_emplace_after_behind_begin(std::forward_list &FL, @@ -1473,10 +1479,10 @@ void forward_list_emplace_after_behind_begin(std::forward_list &FL, clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$FL.begin() + 1}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$FL.begin() + 1{{$}}}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $FL.begin() + 2 - clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$FL.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$FL.end(){{$}}}} } void forward_list_emplace_after_unknown(std::forward_list &FL, int n) { @@ -1492,10 +1498,10 @@ void forward_list_emplace_after_unknown(std::forward_list &FL, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$i1}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$i1{{$}}}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1 - clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$FL.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$FL.end(){{$}}}} } /// erase() @@ -1523,9 +1529,9 @@ void list_erase_begin(std::list &L) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.begin() + 1}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.begin() + 1{{$}}}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.begin() + 1 - clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} } void list_erase_behind_begin(std::list &L, int n) { @@ -1540,9 +1546,9 @@ void list_erase_behind_begin(std::list &L, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} FIXME: Should be $L.begin() + 1 + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} FIXME: Should be $L.begin() + 1 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.begin() + 2 - clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} } void list_erase_unknown(std::list &L) { @@ -1558,9 +1564,9 @@ void list_erase_unknown(std::list &L) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1 - clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} } void list_erase_ahead_of_end(std::list &L) { @@ -1575,8 +1581,8 @@ void list_erase_ahead_of_end(std::list &L) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} - clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() } @@ -1610,7 +1616,7 @@ void vector_erase_behind_begin(std::vector &V, int n) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} FIXME: Should be $V.begin() + 1 + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} FIXME: Should be $V.begin() + 1 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.begin() + 2 } @@ -1627,7 +1633,7 @@ void vector_erase_unknown(std::vector &V) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1 } @@ -1643,7 +1649,7 @@ void vector_erase_ahead_of_end(std::vector &V) { clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() } @@ -1743,10 +1749,10 @@ void forward_list_erase_after_begin(std::forward_list &FL) { clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i3)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}} - clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$FL.begin() + 2}} FIXME: Should be $FL.begin() + 1 + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$FL.begin() + 2{{$}}}} FIXME: Should be $FL.begin() + 1 // clang_analyzer_express(clang_analyzer_iterator_position(i4)); FIXME: expect warning $FL.begin() + 1 - clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$FL.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning-re {{$FL.end(){{$}}}} } void forward_list_erase_after_unknown(std::forward_list &FL) { @@ -1768,11 +1774,11 @@ void forward_list_erase_after_unknown(std::forward_list &FL) { clang_analyzer_eval(clang_analyzer_iterator_validity(i3)); //expected-warning{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i4)); //expected-warning{{TRUE}} - clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}} - clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$i1}} - clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$i1 + 2}} FIXME: Should be $i1 + 1 + clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$i1{{$}}}} + clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning-re {{$i1 + 2{{$}}}} FIXME: Should be $i1 + 1 // clang_analyzer_express(clang_analyzer_iterator_position(i5)); FIXME: expect warning $i1 + 1 - clang_analyzer_express(clang_analyzer_iterator_position(i4)); // expected-warning{{$FL.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i4)); // expected-warning-re {{$FL.end(){{$}}}} } struct simple_iterator_base { @@ -1806,7 +1812,7 @@ struct simple_container { void good_derived(simple_container c) { auto i0 = c.end(); - + if (i0 != c.end()) { clang_analyzer_warnIfReached(); } @@ -1859,24 +1865,134 @@ void non_std_find(std::vector &V, int e) { } } +template +struct cont_with_ptr_iterator { + typedef T* iterator; + T* begin() const; + T* end() const; +}; + +void begin_ptr_iterator(const cont_with_ptr_iterator &c) { + auto i = c.begin(); + + clang_analyzer_eval(clang_analyzer_iterator_container(i) == &c); // expected-warning{{TRUE}} + clang_analyzer_denote(clang_analyzer_container_begin(c), "$c.begin()"); + clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning{{$c.begin()}} + + if (i != c.begin()) { + clang_analyzer_warnIfReached(); + } + } + +void prefix_increment_ptr_iterator(const cont_with_ptr_iterator &c) { + auto i = c.begin(); + + clang_analyzer_denote(clang_analyzer_container_begin(c), "$c.begin()"); + + auto j = ++i; + + clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning{{$c.begin() + 1}} + clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning{{$c.begin() + 1}} +} + +void prefix_decrement_ptr_iterator(const cont_with_ptr_iterator &c) { + auto i = c.end(); + + clang_analyzer_denote(clang_analyzer_container_end(c), "$c.end()"); + + auto j = --i; + + clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning{{$c.end() - 1}} + clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning{{$c.end() - 1}} +} + +void postfix_increment_ptr_iterator(const cont_with_ptr_iterator &c) { + auto i = c.begin(); + + clang_analyzer_denote(clang_analyzer_container_begin(c), "$c.begin()"); + + auto j = i++; + + clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning{{$c.begin() + 1}} + clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning{{$c.begin()}} +} + +void postfix_decrement_ptr_iterator(const cont_with_ptr_iterator &c) { + auto i = c.end(); + + clang_analyzer_denote(clang_analyzer_container_end(c), "$c.end()"); + + auto j = i--; + + clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning{{$c.end() - 1}} + clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning{{$c.end()}} +} + +void plus_equal_ptr_iterator(const cont_with_ptr_iterator &c) { + auto i = c.begin(); + + clang_analyzer_denote(clang_analyzer_container_begin(c), "$c.begin()"); + + i += 2; + + clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning{{$c.begin() + 2}} +} + +void minus_equal_ptr_iterator(const cont_with_ptr_iterator &c) { + auto i = c.end(); + + clang_analyzer_denote(clang_analyzer_container_end(c), "$c.end()"); + + i -= 2; + + clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning{{$c.end() - 2}} +} + +void plus_ptr_iterator(const cont_with_ptr_iterator &c) { + auto i1 = c.begin(); + + clang_analyzer_denote(clang_analyzer_container_begin(c), "$c.begin()"); + + auto i2 = i1 + 2; + + clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &c); // expected-warning{{TRUE}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$c.begin()}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$c.begin() + 2}} +} + +void minus_ptr_iterator(const cont_with_ptr_iterator &c) { + auto i1 = c.end(); + + clang_analyzer_denote(clang_analyzer_container_end(c), "$c.end()"); + + auto i2 = i1 - 2; + + clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &c); // expected-warning{{TRUE}} + clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$c.end()}} + clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$c.end() - 2}} +} + void clang_analyzer_printState(); void print_state(std::vector &V) { const auto i0 = V.cbegin(); clang_analyzer_printState(); -// CHECK: "checker_messages": [ -// CHECK: { "checker": "alpha.cplusplus.IteratorModeling", "messages": [ -// CHECK-NEXT: "Iterator Positions :", -// CHECK-NEXT: "i0 : Valid ; Container == SymRegion{reg_$[[#]] & V>} ; Offset == conj_$[[#]]{long, LC[[#]], S[[#]], #[[#]]}" -// CHECK-NEXT: ]} + // CHECK: "checker_messages": [ + // CHECK: { "checker": "alpha.cplusplus.IteratorModeling", "messages": [ + // CHECK-NEXT: "Iterator Positions :", + // CHECK-NEXT: "i0 : Valid ; Container == SymRegion{reg_$[[#]] & V>} ; Offset == conj_$[[#]]{long, LC[[#]], S[[#]], #[[#]]}" + // CHECK-NEXT: ]} + *i0; const auto i1 = V.cend(); clang_analyzer_printState(); - -// CHECK: "checker_messages": [ -// CHECK: { "checker": "alpha.cplusplus.IteratorModeling", "messages": [ -// CHECK-NEXT: "Iterator Positions :", -// CHECK-NEXT: "i1 : Valid ; Container == SymRegion{reg_$[[#]] & V>} ; Offset == conj_$[[#]]{long, LC[[#]], S[[#]], #[[#]]}" -// CHECK-NEXT: ]} + + // CHECK: "checker_messages": [ + // CHECK: { "checker": "alpha.cplusplus.IteratorModeling", "messages": [ + // CHECK-NEXT: "Iterator Positions :", + // CHECK-NEXT: "i1 : Valid ; Container == SymRegion{reg_$[[#]] & V>} ; Offset == conj_$[[#]]{long, LC[[#]], S[[#]], #[[#]]}" + // CHECK-NEXT: ]} + + *i1; } diff --git a/clang/test/Analysis/iterator-range.cpp b/clang/test/Analysis/iterator-range.cpp index ad8ce92ecfb88..657ae89998e81 100644 --- a/clang/test/Analysis/iterator-range.cpp +++ b/clang/test/Analysis/iterator-range.cpp @@ -854,3 +854,84 @@ void deref_end_after_pop_back(std::vector &V) { *i; // expected-warning{{Past-the-end iterator dereferenced}} // expected-note@-1{{Past-the-end iterator dereferenced}} } + +template +struct cont_with_ptr_iterator { + T* begin() const; + T* end() const; +}; + +void deref_end_ptr_iterator(const cont_with_ptr_iterator &c) { + auto i = c.end(); + (void) *i; // expected-warning{{Past-the-end iterator dereferenced}} + // expected-note@-1{{Past-the-end iterator dereferenced}} +} + +void array_deref_end_ptr_iterator(const cont_with_ptr_iterator &c) { + auto i = c.end(); + (void) i[0]; // expected-warning{{Past-the-end iterator dereferenced}} + // expected-note@-1{{Past-the-end iterator dereferenced}} +} + +void arrow_deref_end_ptr_iterator(const cont_with_ptr_iterator &c) { + auto i = c.end(); + (void) i->n; // expected-warning{{Past-the-end iterator dereferenced}} + // expected-note@-1{{Past-the-end iterator dereferenced}} +} + +void arrow_star_deref_end_ptr_iterator(const cont_with_ptr_iterator &c, + int S::*p) { + auto i = c.end(); + (void)(i->*p); // expected-warning{{Past-the-end iterator dereferenced}} + // expected-note@-1{{Past-the-end iterator dereferenced}} +} + +void prefix_incr_end_ptr_iterator(const cont_with_ptr_iterator &c) { + auto i = c.end(); + ++i; // expected-warning{{Iterator incremented behind the past-the-end iterator}} + // expected-note@-1{{Iterator incremented behind the past-the-end iterator}} +} + +void postfix_incr_end_ptr_iterator(const cont_with_ptr_iterator &c) { + auto i = c.end(); + i++; // expected-warning{{Iterator incremented behind the past-the-end iterator}} + // expected-note@-1{{Iterator incremented behind the past-the-end iterator}} +} + +void prefix_decr_begin_ptr_iterator(const cont_with_ptr_iterator &c) { + auto i = c.begin(); + --i; // expected-warning{{Iterator decremented ahead of its valid range}} + // expected-note@-1{{Iterator decremented ahead of its valid range}} +} + +void postfix_decr_begin_ptr_iterator(const cont_with_ptr_iterator &c) { + auto i = c.begin(); + i--; // expected-warning{{Iterator decremented ahead of its valid range}} + // expected-note@-1{{Iterator decremented ahead of its valid range}} +} + +void prefix_add_2_end_ptr_iterator(const cont_with_ptr_iterator &c) { + auto i = c.end(); + (void)(i + 2); // expected-warning{{Iterator incremented behind the past-the-end iterator}} + // expected-note@-1{{Iterator incremented behind the past-the-end iterator}} +} + +void postfix_add_assign_2_end_ptr_iterator(const cont_with_ptr_iterator &c) { + auto i = c.end(); + i += 2; // expected-warning{{Iterator incremented behind the past-the-end iterator}} + // expected-note@-1{{Iterator incremented behind the past-the-end iterator}} +} + +void prefix_minus_2_begin_ptr_iterator(const cont_with_ptr_iterator &c) { + auto i = c.begin(); + (void)(i - 2); // expected-warning{{Iterator decremented ahead of its valid range}} + // expected-note@-1{{Iterator decremented ahead of its valid range}} +} + +void postfix_minus_assign_2_begin_ptr_iterator( + const cont_with_ptr_iterator &c) { + auto i = c.begin(); + i -= 2; // expected-warning{{Iterator decremented ahead of its valid range}} + // expected-note@-1{{Iterator decremented ahead of its valid range}} +} + diff --git a/clang/test/Analysis/mismatched-iterator.cpp b/clang/test/Analysis/mismatched-iterator.cpp index c58d14d72fda5..570e742751ead 100644 --- a/clang/test/Analysis/mismatched-iterator.cpp +++ b/clang/test/Analysis/mismatched-iterator.cpp @@ -118,3 +118,15 @@ void ignore_conjured2() { if (V1.cbegin() == V2.cbegin()) {} //no-warning } + +template +struct cont_with_ptr_iterator { + T *begin() const; + T *end() const; +}; + +void comparison_ptr_iterator(cont_with_ptr_iterator &C1, + cont_with_ptr_iterator &C2) { + if (C1.begin() != C2.end()) {} // expected-warning{{Iterators of different containers used where the same container is expected}} +} + diff --git a/clang/test/Analysis/more-dtors-cfg-output.cpp b/clang/test/Analysis/more-dtors-cfg-output.cpp index c0df5953aa6e1..668210a0f61e0 100644 --- a/clang/test/Analysis/more-dtors-cfg-output.cpp +++ b/clang/test/Analysis/more-dtors-cfg-output.cpp @@ -278,16 +278,16 @@ void new_default_ctor_with_default_arg(long count) { namespace std::experimental { template struct coroutine_handle { - static coroutine_handle from_address(void *); + static coroutine_handle from_address(void *) noexcept; }; } struct TestPromise { TestPromise initial_suspend(); - TestPromise final_suspend(); - bool await_ready(); - void await_suspend(const std::experimental::coroutine_handle &); - void await_resume(); + TestPromise final_suspend() noexcept; + bool await_ready() noexcept; + void await_suspend(const std::experimental::coroutine_handle &) noexcept; + void await_resume() noexcept; Foo return_value(const Bar &); Bar get_return_object(); void unhandled_exception(); diff --git a/clang/test/Analysis/new-ctor-conservative.cpp b/clang/test/Analysis/new-ctor-conservative.cpp index 6cd403b50e5a4..83c4bed1530c5 100644 --- a/clang/test/Analysis/new-ctor-conservative.cpp +++ b/clang/test/Analysis/new-ctor-conservative.cpp @@ -27,6 +27,7 @@ void checkNewArray() { S *s = new S[10]; // FIXME: Should be true once we inline array constructors. clang_analyzer_eval(s[0].x == 1); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(s[1].x == 1); // expected-warning{{UNKNOWN}} } struct NullS { diff --git a/clang/test/Analysis/smart-ptr.cpp b/clang/test/Analysis/smart-ptr.cpp index ae6966b4e6f4a..4ab7e2bbd3bfc 100644 --- a/clang/test/Analysis/smart-ptr.cpp +++ b/clang/test/Analysis/smart-ptr.cpp @@ -1,16 +1,18 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection\ -// RUN: -analyzer-checker cplusplus.Move,cplusplus.SmartPtr\ +// RUN: -analyzer-checker cplusplus.Move,alpha.cplusplus.SmartPtr\ +// RUN: -analyzer-config cplusplus.SmartPtrModeling:ModelSmartPtrDereference=true\ // RUN: -std=c++11 -verify %s #include "Inputs/system-header-simulator-cxx.h" void clang_analyzer_warnIfReached(); +void clang_analyzer_numTimesReached(); void derefAfterMove(std::unique_ptr P) { std::unique_ptr Q = std::move(P); if (Q) clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} - *Q.get() = 1; // no-warning + *Q.get() = 1; // no-warning if (P) clang_analyzer_warnIfReached(); // no-warning // TODO: Report a null dereference (instead). @@ -26,3 +28,76 @@ void bar(S *s, void (S::*func)(void)) { (s->*func)(); // no-crash } } // namespace testUnknownCallee + +class A { +public: + A(){}; + void foo(); +}; + +A *return_null() { + return nullptr; +} + +void derefAfterValidCtr() { + std::unique_ptr P(new A()); + P->foo(); // No warning. +} + +void derefOfUnknown(std::unique_ptr P) { + P->foo(); // No warning. +} + +void derefAfterDefaultCtr() { + std::unique_ptr P; + P->foo(); // expected-warning {{Dereference of null smart pointer [alpha.cplusplus.SmartPtr]}} +} + +void derefAfterCtrWithNull() { + std::unique_ptr P(nullptr); + *P; // expected-warning {{Dereference of null smart pointer [alpha.cplusplus.SmartPtr]}} +} + +void derefAfterCtrWithNullReturnMethod() { + std::unique_ptr P(return_null()); + P->foo(); // expected-warning {{Dereference of null smart pointer [alpha.cplusplus.SmartPtr]}} +} + +void derefAfterRelease() { + std::unique_ptr P(new A()); + P.release(); + clang_analyzer_numTimesReached(); // expected-warning {{1}} + P->foo(); // expected-warning {{Dereference of null smart pointer [alpha.cplusplus.SmartPtr]}} +} + +void derefAfterReset() { + std::unique_ptr P(new A()); + P.reset(); + clang_analyzer_numTimesReached(); // expected-warning {{1}} + P->foo(); // expected-warning {{Dereference of null smart pointer [alpha.cplusplus.SmartPtr]}} +} + +void derefAfterResetWithNull() { + std::unique_ptr P(new A()); + P.reset(nullptr); + P->foo(); // expected-warning {{Dereference of null smart pointer [alpha.cplusplus.SmartPtr]}} +} + +void derefAfterResetWithNonNull() { + std::unique_ptr P; + P.reset(new A()); + P->foo(); // No warning. +} + +void derefAfterReleaseAndResetWithNonNull() { + std::unique_ptr P(new A()); + P.release(); + P.reset(new A()); + P->foo(); // No warning. +} + +void derefOnReleasedNullRawPtr() { + std::unique_ptr P; + A *AP = P.release(); + AP->foo(); // expected-warning {{Called C++ object pointer is null [core.CallAndMessage]}} +} diff --git a/clang/test/Analysis/std-c-library-functions-POSIX.c b/clang/test/Analysis/std-c-library-functions-POSIX.c new file mode 100644 index 0000000000000..e6f5b19baa00e --- /dev/null +++ b/clang/test/Analysis/std-c-library-functions-POSIX.c @@ -0,0 +1,178 @@ +// RUN: %clang_analyze_cc1 %s \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \ +// RUN: -analyzer-config apiModeling.StdCLibraryFunctions:ModelPOSIX=true \ +// RUN: -analyzer-config apiModeling.StdCLibraryFunctions:DisplayLoadedSummaries=true \ +// RUN: -analyzer-checker=debug.ExprInspection \ +// RUN: -analyzer-config eagerly-assume=false \ +// RUN: -triple i686-unknown-linux 2>&1 | FileCheck %s + +// CHECK: Loaded summary for: long a64l(const char *str64) +// CHECK: Loaded summary for: char *l64a(long value) +// CHECK: Loaded summary for: int access(const char *pathname, int amode) +// CHECK: Loaded summary for: int faccessat(int dirfd, const char *pathname, int mode, int flags) +// CHECK: Loaded summary for: int dup(int fildes) +// CHECK: Loaded summary for: int dup2(int fildes1, int filedes2) +// CHECK: Loaded summary for: int fdatasync(int fildes) +// CHECK: Loaded summary for: int fnmatch(const char *pattern, const char *string, int flags) +// CHECK: Loaded summary for: int fsync(int fildes) +// CHECK: Loaded summary for: int truncate(const char *path, off_t length) +// CHECK: Loaded summary for: int symlink(const char *oldpath, const char *newpath) +// CHECK: Loaded summary for: int symlinkat(const char *oldpath, int newdirfd, const char *newpath) +// CHECK: Loaded summary for: int lockf(int fd, int cmd, off_t len) +// CHECK: Loaded summary for: int creat(const char *pathname, mode_t mode) +// CHECK: Loaded summary for: unsigned int sleep(unsigned int seconds) +// CHECK: Loaded summary for: int dirfd(DIR *dirp) +// CHECK: Loaded summary for: unsigned int alarm(unsigned int seconds) +// CHECK: Loaded summary for: int closedir(DIR *dir) +// CHECK: Loaded summary for: char *strdup(const char *s) +// CHECK: Loaded summary for: char *strndup(const char *s, size_t n) +// CHECK: Loaded summary for: int mkstemp(char *template) +// CHECK: Loaded summary for: char *mkdtemp(char *template) +// CHECK: Loaded summary for: char *getcwd(char *buf, size_t size) +// CHECK: Loaded summary for: int mkdir(const char *pathname, mode_t mode) +// CHECK: Loaded summary for: int mkdirat(int dirfd, const char *pathname, mode_t mode) +// CHECK: Loaded summary for: int mknod(const char *pathname, mode_t mode, dev_t dev) +// CHECK: Loaded summary for: int mknodat(int dirfd, const char *pathname, mode_t mode, dev_t dev) +// CHECK: Loaded summary for: int chmod(const char *path, mode_t mode) +// CHECK: Loaded summary for: int fchmodat(int dirfd, const char *pathname, mode_t mode, int flags) +// CHECK: Loaded summary for: int fchmod(int fildes, mode_t mode) +// CHECK: Loaded summary for: int fchownat(int dirfd, const char *pathname, uid_t owner, gid_t group, int flags) +// CHECK: Loaded summary for: int chown(const char *path, uid_t owner, gid_t group) +// CHECK: Loaded summary for: int lchown(const char *path, uid_t owner, gid_t group) +// CHECK: Loaded summary for: int fchown(int fildes, uid_t owner, gid_t group) +// CHECK: Loaded summary for: int rmdir(const char *pathname) +// CHECK: Loaded summary for: int chdir(const char *path) +// CHECK: Loaded summary for: int link(const char *oldpath, const char *newpath) +// CHECK: Loaded summary for: int linkat(int fd1, const char *path1, int fd2, const char *path2, int flag) +// CHECK: Loaded summary for: int unlink(const char *pathname) +// CHECK: Loaded summary for: int unlinkat(int fd, const char *path, int flag) +// CHECK: Loaded summary for: int fstat(int fd, struct stat *statbuf) +// CHECK: Loaded summary for: int stat(const char *restrict path, struct stat *restrict buf) +// CHECK: Loaded summary for: int lstat(const char *restrict path, struct stat *restrict buf) +// CHECK: Loaded summary for: int fstatat(int fd, const char *restrict path, struct stat *restrict buf, int flag) +// CHECK: Loaded summary for: DIR *opendir(const char *name) +// CHECK: Loaded summary for: DIR *fdopendir(int fd) +// CHECK: Loaded summary for: int isatty(int fildes) +// CHECK: Loaded summary for: FILE *popen(const char *command, const char *type) +// CHECK: Loaded summary for: int pclose(FILE *stream) +// CHECK: Loaded summary for: int close(int fildes) +// CHECK: Loaded summary for: long fpathconf(int fildes, int name) +// CHECK: Loaded summary for: long pathconf(const char *path, int name) +// CHECK: Loaded summary for: FILE *fdopen(int fd, const char *mode) +// CHECK: Loaded summary for: void rewinddir(DIR *dir) +// CHECK: Loaded summary for: void seekdir(DIR *dirp, long loc) +// CHECK: Loaded summary for: int rand_r(unsigned int *seedp) +// CHECK: Loaded summary for: int strcasecmp(const char *s1, const char *s2) +// CHECK: Loaded summary for: int strncasecmp(const char *s1, const char *s2, size_t n) +// CHECK: Loaded summary for: int fileno(FILE *stream) +// CHECK: Loaded summary for: int fseeko(FILE *stream, off_t offset, int whence) +// CHECK: Loaded summary for: off_t ftello(FILE *stream) +// CHECK: Loaded summary for: void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) +// CHECK: Loaded summary for: void *mmap64(void *addr, size_t length, int prot, int flags, int fd, off64_t offset) +// CHECK: Loaded summary for: int pipe(int fildes[2]) +// CHECK: Loaded summary for: off_t lseek(int fildes, off_t offset, int whence) +// CHECK: Loaded summary for: ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize) +// CHECK: Loaded summary for: ssize_t readlinkat(int fd, const char *restrict path, char *restrict buf, size_t bufsize) +// CHECK: Loaded summary for: int renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) +// CHECK: Loaded summary for: char *realpath(const char *restrict file_name, char *restrict resolved_name) +// CHECK: Loaded summary for: int execv(const char *path, char *const argv[]) +// CHECK: Loaded summary for: int execvp(const char *file, char *const argv[]) +// CHECK: Loaded summary for: int getopt(int argc, char *const argv[], const char *optstring) + +long a64l(const char *str64); +char *l64a(long value); +int access(const char *pathname, int amode); +int faccessat(int dirfd, const char *pathname, int mode, int flags); +int dup(int fildes); +int dup2(int fildes1, int filedes2); +int fdatasync(int fildes); +int fnmatch(const char *pattern, const char *string, int flags); +int fsync(int fildes); +typedef unsigned long off_t; +int truncate(const char *path, off_t length); +int symlink(const char *oldpath, const char *newpath); +int symlinkat(const char *oldpath, int newdirfd, const char *newpath); +int lockf(int fd, int cmd, off_t len); +typedef unsigned mode_t; +int creat(const char *pathname, mode_t mode); +unsigned int sleep(unsigned int seconds); +typedef struct { + int a; +} DIR; +int dirfd(DIR *dirp); +unsigned int alarm(unsigned int seconds); +int closedir(DIR *dir); +char *strdup(const char *s); +typedef typeof(sizeof(int)) size_t; +char *strndup(const char *s, size_t n); +/*FIXME How to define wchar_t in the test?*/ +/*typedef __wchar_t wchar_t;*/ +/*wchar_t *wcsdup(const wchar_t *s);*/ +int mkstemp(char *template); +char *mkdtemp(char *template); +char *getcwd(char *buf, size_t size); +int mkdir(const char *pathname, mode_t mode); +int mkdirat(int dirfd, const char *pathname, mode_t mode); +typedef int dev_t; +int mknod(const char *pathname, mode_t mode, dev_t dev); +int mknodat(int dirfd, const char *pathname, mode_t mode, dev_t dev); +int chmod(const char *path, mode_t mode); +int fchmodat(int dirfd, const char *pathname, mode_t mode, int flags); +int fchmod(int fildes, mode_t mode); +typedef int uid_t; +typedef int gid_t; +int fchownat(int dirfd, const char *pathname, uid_t owner, gid_t group, int flags); +int chown(const char *path, uid_t owner, gid_t group); +int lchown(const char *path, uid_t owner, gid_t group); +int fchown(int fildes, uid_t owner, gid_t group); +int rmdir(const char *pathname); +int chdir(const char *path); +int link(const char *oldpath, const char *newpath); +int linkat(int fd1, const char *path1, int fd2, const char *path2, int flag); +int unlink(const char *pathname); +int unlinkat(int fd, const char *path, int flag); +struct stat; +int fstat(int fd, struct stat *statbuf); +int stat(const char *restrict path, struct stat *restrict buf); +int lstat(const char *restrict path, struct stat *restrict buf); +int fstatat(int fd, const char *restrict path, struct stat *restrict buf, int flag); +DIR *opendir(const char *name); +DIR *fdopendir(int fd); +int isatty(int fildes); +typedef struct { + int x; +} FILE; +FILE *popen(const char *command, const char *type); +int pclose(FILE *stream); +int close(int fildes); +long fpathconf(int fildes, int name); +long pathconf(const char *path, int name); +FILE *fdopen(int fd, const char *mode); +void rewinddir(DIR *dir); +void seekdir(DIR *dirp, long loc); +int rand_r(unsigned int *seedp); +int strcasecmp(const char *s1, const char *s2); +int strncasecmp(const char *s1, const char *s2, size_t n); +int fileno(FILE *stream); +int fseeko(FILE *stream, off_t offset, int whence); +off_t ftello(FILE *stream); +void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); +typedef off_t off64_t; +void *mmap64(void *addr, size_t length, int prot, int flags, int fd, off64_t offset); +int pipe(int fildes[2]); +off_t lseek(int fildes, off_t offset, int whence); +typedef size_t ssize_t; +ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize); +ssize_t readlinkat(int fd, const char *restrict path, char *restrict buf, size_t bufsize); +int renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath); +char *realpath(const char *restrict file_name, char *restrict resolved_name); +int execv(const char *path, char *const argv[]); +int execvp(const char *file, char *const argv[]); +int getopt(int argc, char *const argv[], const char *optstring); + +// Must have at least one call expression to initialize the summary map. +int bar(void); +void foo() { + bar(); +} diff --git a/clang/test/Analysis/std-c-library-functions-arg-constraints.c b/clang/test/Analysis/std-c-library-functions-arg-constraints.c index b99248d337b34..b23700a96f38f 100644 --- a/clang/test/Analysis/std-c-library-functions-arg-constraints.c +++ b/clang/test/Analysis/std-c-library-functions-arg-constraints.c @@ -2,7 +2,7 @@ // RUN: %clang_analyze_cc1 %s \ // RUN: -analyzer-checker=core \ // RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \ -// RUN: -analyzer-checker=alpha.apiModeling.StdCLibraryFunctionArgs \ +// RUN: -analyzer-checker=alpha.unix.StdCLibraryFunctionArgs \ // RUN: -analyzer-checker=debug.StdCLibraryFunctionsTester \ // RUN: -analyzer-checker=debug.ExprInspection \ // RUN: -triple x86_64-unknown-linux-gnu \ @@ -12,7 +12,7 @@ // RUN: %clang_analyze_cc1 %s \ // RUN: -analyzer-checker=core \ // RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \ -// RUN: -analyzer-checker=alpha.apiModeling.StdCLibraryFunctionArgs \ +// RUN: -analyzer-checker=alpha.unix.StdCLibraryFunctionArgs \ // RUN: -analyzer-checker=debug.StdCLibraryFunctionsTester \ // RUN: -analyzer-checker=debug.ExprInspection \ // RUN: -triple x86_64-unknown-linux-gnu \ diff --git a/clang/test/Analysis/std-c-library-functions-arg-constraints.cpp b/clang/test/Analysis/std-c-library-functions-arg-constraints.cpp index ebc841a07fb73..ae26834402e69 100644 --- a/clang/test/Analysis/std-c-library-functions-arg-constraints.cpp +++ b/clang/test/Analysis/std-c-library-functions-arg-constraints.cpp @@ -1,7 +1,7 @@ // RUN: %clang_analyze_cc1 %s \ // RUN: -analyzer-checker=core \ // RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \ -// RUN: -analyzer-checker=alpha.apiModeling.StdCLibraryFunctionArgs \ +// RUN: -analyzer-checker=alpha.unix.StdCLibraryFunctionArgs \ // RUN: -analyzer-checker=debug.StdCLibraryFunctionsTester \ // RUN: -analyzer-checker=debug.ExprInspection \ // RUN: -analyzer-config eagerly-assume=false \ diff --git a/clang/test/Analysis/stream-note.c b/clang/test/Analysis/stream-note.c new file mode 100644 index 0000000000000..08927e8902be4 --- /dev/null +++ b/clang/test/Analysis/stream-note.c @@ -0,0 +1,48 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream -analyzer-output text -verify %s + +#include "Inputs/system-header-simulator.h" + +void check_note_at_correct_open() { + FILE *F1 = tmpfile(); // expected-note {{Stream opened here}} + if (!F1) + // expected-note@-1 {{'F1' is non-null}} + // expected-note@-2 {{Taking false branch}} + return; + FILE *F2 = tmpfile(); + if (!F2) { + // expected-note@-1 {{'F2' is non-null}} + // expected-note@-2 {{Taking false branch}} + fclose(F1); + return; + } + rewind(F2); + fclose(F2); + rewind(F1); +} +// expected-warning@-1 {{Opened stream never closed. Potential resource leak}} +// expected-note@-2 {{Opened stream never closed. Potential resource leak}} + +void check_note_fopen() { + FILE *F = fopen("file", "r"); // expected-note {{Stream opened here}} + if (!F) + // expected-note@-1 {{'F' is non-null}} + // expected-note@-2 {{Taking false branch}} + return; +} +// expected-warning@-1 {{Opened stream never closed. Potential resource leak}} +// expected-note@-2 {{Opened stream never closed. Potential resource leak}} + +void check_note_freopen() { + FILE *F = fopen("file", "r"); // expected-note {{Stream opened here}} + if (!F) + // expected-note@-1 {{'F' is non-null}} + // expected-note@-2 {{Taking false branch}} + return; + F = freopen(0, "w", F); // expected-note {{Stream reopened here}} + if (!F) + // expected-note@-1 {{'F' is non-null}} + // expected-note@-2 {{Taking false branch}} + return; +} +// expected-warning@-1 {{Opened stream never closed. Potential resource leak}} +// expected-note@-2 {{Opened stream never closed. Potential resource leak}} diff --git a/clang/test/Analysis/stream.c b/clang/test/Analysis/stream.c index dbbcc8715e0d2..cd5d28ae84554 100644 --- a/clang/test/Analysis/stream.c +++ b/clang/test/Analysis/stream.c @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.unix.Stream -analyzer-store region -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream -verify %s #include "Inputs/system-header-simulator.h" @@ -139,7 +139,7 @@ void f_leak(int c) { if (!p) return; if(c) - return; // expected-warning {{Opened File never closed. Potential Resource leak}} + return; // expected-warning {{Opened stream never closed. Potential resource leak}} fclose(p); } @@ -240,3 +240,28 @@ void check_escape4() { fwrite("1", 1, 1, F); // expected-warning {{might be 'indeterminate'}} fclose(F); } + +int Test; +_Noreturn void handle_error(); + +void check_leak_noreturn_1() { + FILE *F1 = tmpfile(); + if (!F1) + return; + if (Test == 1) { + handle_error(); // no warning + } + rewind(F1); +} // expected-warning {{Opened stream never closed. Potential resource leak}} + +// Check that "location uniqueing" works. +// This results in reporting only one occurence of resource leak for a stream. +void check_leak_noreturn_2() { + FILE *F1 = tmpfile(); + if (!F1) + return; + if (Test == 1) { + return; // expected-warning {{Opened stream never closed. Potential resource leak}} + } + rewind(F1); +} // no warning diff --git a/clang/test/Analysis/stream.cpp b/clang/test/Analysis/stream.cpp index c76b9d7498d09..7eca505bcaf5d 100644 --- a/clang/test/Analysis/stream.cpp +++ b/clang/test/Analysis/stream.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.unix.Stream -analyzer-store region -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream -verify %s typedef struct _IO_FILE FILE; extern FILE *fopen(const char *path, const char *mode); @@ -19,4 +19,4 @@ void f1() { void f2() { FILE *f = fopen("file", "r"); -} // expected-warning {{Opened File never closed. Potential Resource leak}} +} // expected-warning {{Opened stream never closed. Potential resource leak}} diff --git a/clang/test/Analysis/use-after-move.cpp b/clang/test/Analysis/use-after-move.cpp index c25f4393cdf92..d7b6c74fabd6c 100644 --- a/clang/test/Analysis/use-after-move.cpp +++ b/clang/test/Analysis/use-after-move.cpp @@ -1,36 +1,36 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ // RUN: -analyzer-config exploration_strategy=unexplored_first_queue\ -// RUN: -analyzer-checker core,cplusplus.SmartPtr,debug.ExprInspection\ +// RUN: -analyzer-checker core,cplusplus.SmartPtrModeling,debug.ExprInspection\ // RUN: -verify=expected,peaceful,non-aggressive // RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ // RUN: -analyzer-config exploration_strategy=dfs -DDFS\ -// RUN: -analyzer-checker core,cplusplus.SmartPtr,debug.ExprInspection\ +// RUN: -analyzer-checker core,cplusplus.SmartPtrModeling,debug.ExprInspection\ // RUN: -verify=expected,peaceful,non-aggressive // RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ // RUN: -analyzer-config exploration_strategy=unexplored_first_queue\ // RUN: -analyzer-config cplusplus.Move:WarnOn=KnownsOnly\ -// RUN: -analyzer-checker core,cplusplus.SmartPtr,debug.ExprInspection\ +// RUN: -analyzer-checker core,cplusplus.SmartPtrModeling,debug.ExprInspection\ // RUN: -verify=expected,non-aggressive // RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move -verify %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ // RUN: -analyzer-config exploration_strategy=dfs -DDFS\ // RUN: -analyzer-config cplusplus.Move:WarnOn=KnownsOnly\ -// RUN: -analyzer-checker core,cplusplus.SmartPtr,debug.ExprInspection\ +// RUN: -analyzer-checker core,cplusplus.SmartPtrModeling,debug.ExprInspection\ // RUN: -verify=expected,non-aggressive // RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ // RUN: -analyzer-config exploration_strategy=unexplored_first_queue\ // RUN: -analyzer-config cplusplus.Move:WarnOn=All\ -// RUN: -analyzer-checker core,cplusplus.SmartPtr,debug.ExprInspection\ +// RUN: -analyzer-checker core,cplusplus.SmartPtrModeling,debug.ExprInspection\ // RUN: -verify=expected,peaceful,aggressive // RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move %s\ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ // RUN: -analyzer-config exploration_strategy=dfs -DDFS\ // RUN: -analyzer-config cplusplus.Move:WarnOn=All\ -// RUN: -analyzer-checker core,cplusplus.SmartPtr,debug.ExprInspection\ +// RUN: -analyzer-checker core,cplusplus.SmartPtrModeling,debug.ExprInspection\ // RUN: -verify=expected,peaceful,aggressive // RUN: not %clang_analyze_cc1 -verify %s \ @@ -49,7 +49,7 @@ // RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\ // RUN: -analyzer-config exploration_strategy=dfs -DDFS\ // RUN: -analyzer-config cplusplus.Move:WarnOn=All -DAGGRESSIVE_DFS\ -// RUN: -analyzer-checker core,cplusplus.SmartPtr,debug.ExprInspection\ +// RUN: -analyzer-checker core,cplusplus.SmartPtrModeling,debug.ExprInspection\ // RUN: -verify=expected,peaceful,aggressive %s 2>&1 | FileCheck %s #include "Inputs/system-header-simulator-cxx.h" diff --git a/clang/test/Analysis/weak-dependencies.c b/clang/test/Analysis/weak-dependencies.c index a2179ecaff57f..62cb10b5b5235 100644 --- a/clang/test/Analysis/weak-dependencies.c +++ b/clang/test/Analysis/weak-dependencies.c @@ -1,5 +1,5 @@ // RUN: %clang_analyze_cc1 %s -verify \ -// RUN: -analyzer-checker=alpha.apiModeling.StdCLibraryFunctionArgs \ +// RUN: -analyzer-checker=alpha.unix.StdCLibraryFunctionArgs \ // RUN: -analyzer-checker=core typedef __typeof(sizeof(int)) size_t; diff --git a/clang/test/CXX/drs/dr4xx.cpp b/clang/test/CXX/drs/dr4xx.cpp index 2c762237037d2..ff90ee82d4d40 100644 --- a/clang/test/CXX/drs/dr4xx.cpp +++ b/clang/test/CXX/drs/dr4xx.cpp @@ -690,7 +690,7 @@ namespace dr457 { // dr457: yes }; } -namespace dr458 { // dr458: no +namespace dr458 { // dr458: 11 struct A { int T; int f(); @@ -706,9 +706,9 @@ namespace dr458 { // dr458: no int A::f() { return T; } - template + template // expected-note {{declared here}} int A::g() { - return T; // FIXME: this is invalid, it finds the template parameter + return T; // expected-error {{'T' does not refer to a value}} } template @@ -719,9 +719,9 @@ namespace dr458 { // dr458: no int B::g() { return T; } - template template + template template // expected-note {{declared here}} int B::h() { - return T; // FIXME: this is invalid, it finds the template parameter + return T; // expected-error {{'T' does not refer to a value}} } } diff --git a/clang/test/CXX/expr/expr.const/p2-0x.cpp b/clang/test/CXX/expr/expr.const/p2-0x.cpp index c418767f8d12d..b9235eeeb1721 100644 --- a/clang/test/CXX/expr/expr.const/p2-0x.cpp +++ b/clang/test/CXX/expr/expr.const/p2-0x.cpp @@ -376,7 +376,7 @@ namespace References { int &d = c; constexpr int e = 42; int &f = const_cast(e); - extern int &g; + extern int &g; // expected-note {{here}} constexpr int &h(); // expected-note {{here}} int &i = h(); // expected-note {{here}} constexpr int &j() { return b; } @@ -390,7 +390,7 @@ namespace References { int D2 : &d - &c + 1; int E : e / 2; int F : f - 11; - int G : g; // expected-error {{constant expression}} + int G : g; // expected-error {{constant expression}} expected-note {{initializer of 'g' is unknown}} int H : h(); // expected-error {{constant expression}} expected-note {{undefined function 'h'}} int I : i; // expected-error {{constant expression}} expected-note {{initializer of 'i' is not a constant expression}} int J : j(); diff --git a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2.cpp b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2.cpp index 6c0df1aff231a..ecb82372bcb47 100644 --- a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2.cpp +++ b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2.cpp @@ -1,4 +1,6 @@ -// RUN: %clang_cc1 -std=c++98 -verify %s +// RUN: %clang_cc1 -std=c++98 -verify=cxx98 %s +// RUN: %clang_cc1 -std=c++11 -verify=cxx11 %s +// cxx11-no-diagnostics template struct S; @@ -13,9 +15,9 @@ template struct T { // - a constant with literal type and is initialized with an expression // that is value-dependent. const int k = n; - typename S::T check3; // ok, u is value-dependent + typename S::T check3; // ok, k is value-dependent - const int &i = k; - typename S::T check4; // expected-error {{not an integral constant expression}} + const int &i = k; // cxx98-note {{declared here}} + typename S::T check4; // cxx98-error {{not an integral constant expression}} cxx98-note {{read of variable 'i' of non-integral, non-enumeration type 'const int &'}} } }; diff --git a/clang/test/CXX/temp/temp.res/temp.local/p8.cpp b/clang/test/CXX/temp/temp.res/temp.local/p8.cpp index fecfed06f109c..6b2071eb12ce0 100644 --- a/clang/test/CXX/temp/temp.res/temp.local/p8.cpp +++ b/clang/test/CXX/temp/temp.res/temp.local/p8.cpp @@ -1,5 +1,4 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -// expected-no-diagnostics namespace N { enum { C }; @@ -52,3 +51,104 @@ void N::Y::f(D) { D d; } +// Ensure we properly interleave the searches within classes and template parameter lists. +namespace SearchClassBetweenTemplateParameterLists { + int AA, BB; // none of the below lookups should ever consider these + + struct Base { + using AA = void; + using BB = void; + }; + struct BaseT : Base { + using T = void; + }; + struct BaseU : Base { + using U = void; + }; + + template struct A { + using AA = void; + template struct B { + using BB = void; + void f(U); + void g(U); + void h(T); + void i(T); + template void j(V); + template void k(U); + + // OK: these find the template parameter not the member. + template void l(AA x) { AA aa; } + template void m(BB x) { BB bb; } + + struct C : Base { + // All OK; these find the template parameters. + template void f(T x) { T t; } + template void g(U x) { U u; } + template void h(AA x) { AA aa; } + template void i(BB x) { BB bb; } + }; + + struct CT : BaseT { + template void f(T x) { // expected-error {{void}} + T t; // expected-error {{incomplete}} + } + template void g(U x) { U u; } + template void h(AA x) { AA aa; } + template void i(BB x) { BB bb; } + }; + + struct CU : BaseU { + template void f(T x) { T t; } + template void g(U x) { // expected-error {{void}} + U u; // expected-error {{incomplete}} + } + template void h(AA x) { AA aa; } + template void i(BB x) { BB bb; } + }; + }; + }; + + // Search order for the below is: + // 1) template parameter scope of the function itself (if any) + // 2) class of which function is a member + // 3) template parameter scope of inner class + // 4) class of which class is a member + // 5) template parameter scope of outer class + + // OK, 'AA' found in (3) + template template + void A::B::f(AA) { + AA aa; + } + + // error, 'BB' found in (2) + template template + void A::B::g(BB) { // expected-error {{does not match}} + BB bb; // expected-error {{incomplete type}} + } + + // error, 'AA' found in (4) + template template + void A::B::h(AA) { // expected-error {{does not match}} + AA aa; // expected-error {{incomplete type}} + } + + // error, 'BB' found in (2) + template template + void A::B::i(BB) { // expected-error {{does not match}} + BB bb; // expected-error {{incomplete type}} + } + + // OK, 'BB' found in (1) + template template template + void A::B::j(BB) { + BB bb; + } + + // error, 'BB' found in (2) + template template template + void A::B::k(V) { // expected-error {{does not match}} + BB bb; // expected-error {{incomplete type}} + } +} diff --git a/clang/test/CodeCompletion/after-function-equals.cpp b/clang/test/CodeCompletion/after-function-equals.cpp new file mode 100644 index 0000000000000..871c2a3f6d917 --- /dev/null +++ b/clang/test/CodeCompletion/after-function-equals.cpp @@ -0,0 +1,47 @@ +struct A { + A() = default; + // RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:2:9 -std=gnu++11 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s + // CHECK-CC1: COMPLETION: default + // CHECK-CC1-NEXT: COMPLETION: delete + + A(const A &) = default; + // RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:7:18 -std=gnu++11 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s + // CHECK-CC2: COMPLETION: default + // CHECK-CC2-NEXT: COMPLETION: delete + + A(const A &, int) = delete; + // RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:12:23 -std=gnu++11 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s + // CHECK-CC3-NOT: COMPLETION: default + // CHECK-CC3: COMPLETION: delete + + A(A &&); + + A &operator=(const A &) = default; + // RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:19:29 -std=gnu++11 %s -o - | FileCheck -check-prefix=CHECK-CC4 %s + // CHECK-CC4: COMPLETION: default + // CHECK-CC4-NEXT: COMPLETION: delete + + bool operator==(const A &) const = delete; + // RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:24:38 -std=gnu++11 %s -o - | FileCheck -check-prefix=CHECK-CC5 %s + // CHECK-CC5-NOT: COMPLETION: default + // CHECK-CC5: COMPLETION: delete + + // RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:24:38 -std=gnu++20 %s -o - | FileCheck -check-prefix=CHECK-CC6 %s + // CHECK-CC6: COMPLETION: default + // CHECK-CC6-NEXT: COMPLETION: delete + + void test() = delete; + // RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:33:17 -std=gnu++11 %s -o - | FileCheck -check-prefix=CHECK-CC7 %s + // CHECK-CC7-NOT: COMPLETION: default + // CHECK-CC7: COMPLETION: delete +}; + +A::A(A &&) = default; +// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:39:14 -std=gnu++11 %s -o - | FileCheck -check-prefix=CHECK-CC8 %s +// CHECK-CC8: COMPLETION: default +// CHECK-CC8-NEXT: COMPLETION: delete + +void test() = delete; +// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:44:15 -std=gnu++11 %s -o - | FileCheck -check-prefix=CHECK-CC9 %s +// CHECK-CC9-NOT: COMPLETION: default +// CHECK-CC9: COMPLETION: delete \ No newline at end of file diff --git a/clang/test/CodeCompletion/ordinary-name-cxx11.cpp b/clang/test/CodeCompletion/ordinary-name-cxx11.cpp index e568ee1ee3d8d..7593d00210e7c 100644 --- a/clang/test/CodeCompletion/ordinary-name-cxx11.cpp +++ b/clang/test/CodeCompletion/ordinary-name-cxx11.cpp @@ -57,11 +57,12 @@ void foo() { // CHECK-CC1: COMPLETION: TYPEDEF : TYPEDEF // CHECK-CC1-NEXT: COMPLETION: Pattern : typedef <#type#> <#name#>; // CHECK-CC1-NEXT: COMPLETION: Pattern : [#std::type_info#]typeid(<#expression-or-type#>) - // CHECK-CC1-NEXT: COMPLETION: Pattern : typename <#qualifier#>::<#name#> + // CHECK-CC1-NEXT: COMPLETION: Pattern : typename <#name#> // CHECK-CC1-NEXT: COMPLETION: Pattern : typeof <#expression#> // CHECK-CC1-NEXT: COMPLETION: Pattern : typeof(<#type#>) // CHECK-CC1-NEXT: COMPLETION: union // CHECK-CC1-NEXT: COMPLETION: unsigned + // CHECK-CC1-NEXT: COMPLETION: Pattern : using <#name#> = <#type#>; // CHECK-CC1-NEXT: COMPLETION: Pattern : using namespace <#identifier#>; // CHECK-CC1-NEXT: COMPLETION: void // CHECK-CC1-NEXT: COMPLETION: volatile @@ -107,12 +108,13 @@ void foo() { // CHECK-CC2-NEXT: COMPLETION: thread_local // CHECK-CC2-NEXT: COMPLETION: TYPEDEF : TYPEDEF // CHECK-CC2-NEXT: COMPLETION: Pattern : typedef <#type#> <#name#>; - // CHECK-CC2-NEXT: COMPLETION: Pattern : typename <#qualifier#>::<#name#> + // CHECK-CC2-NEXT: COMPLETION: Pattern : typename <#name#> // CHECK-CC2-NEXT: COMPLETION: Pattern : typeof <#expression#> // CHECK-CC2-NEXT: COMPLETION: Pattern : typeof(<#type#>) // CHECK-CC2-NEXT: COMPLETION: union // CHECK-CC2-NEXT: COMPLETION: unsigned // CHECK-CC2-NEXT: COMPLETION: Pattern : using <#qualifier#>::<#name#>; + // CHECK-CC2-NEXT: COMPLETION: Pattern : using <#name#> = <#type#>; // CHECK-CC2-NEXT: COMPLETION: Pattern : using namespace <#identifier#>; // CHECK-CC2-NEXT: COMPLETION: void // CHECK-CC2-NEXT: COMPLETION: volatile @@ -150,12 +152,13 @@ void foo() { // CHECK-CC3-NEXT: COMPLETION: Pattern : template<<#parameters#>> // CHECK-CC3-NEXT: COMPLETION: thread_local // CHECK-CC3-NEXT: COMPLETION: Pattern : typedef <#type#> <#name#>; - // CHECK-CC3-NEXT: COMPLETION: Pattern : typename <#qualifier#>::<#name#> + // CHECK-CC3-NEXT: COMPLETION: Pattern : typename <#name#> // CHECK-CC3-NEXT: COMPLETION: Pattern : typeof <#expression#> // CHECK-CC3-NEXT: COMPLETION: Pattern : typeof(<#type#>) // CHECK-CC3-NEXT: COMPLETION: union // CHECK-CC3-NEXT: COMPLETION: unsigned // CHECK-CC3-NEXT: COMPLETION: Pattern : using <#qualifier#>::<#name#> + // CHECK-CC3-NEXT: COMPLETION: Pattern : using <#name#> = <#type#>; // CHECK-CC3-NEXT: COMPLETION: virtual // CHECK-CC3-NEXT: COMPLETION: void // CHECK-CC3-NEXT: COMPLETION: volatile @@ -198,7 +201,7 @@ void foo() { // CHECK-CC4-NEXT: COMPLETION: Pattern : [#bool#]true // CHECK-CC4-NEXT: COMPLETION: TYPEDEF : TYPEDEF // CHECK-CC4-NEXT: COMPLETION: Pattern : [#std::type_info#]typeid(<#expression-or-type#>) - // CHECK-CC4-NEXT: COMPLETION: Pattern : typename <#qualifier#>::<#name#> + // CHECK-CC4-NEXT: COMPLETION: Pattern : typename <#name#> // CHECK-CC4-NEXT: COMPLETION: Pattern : typeof <#expression#> // CHECK-CC4-NEXT: COMPLETION: Pattern : typeof(<#type#>) // CHECK-CC4-NEXT: COMPLETION: union @@ -259,11 +262,12 @@ void foo() { // CHECK-NO-RTTI: COMPLETION: TYPEDEF : TYPEDEF // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : typedef <#type#> <#name#>; // CHECK-NO-RTTI-NOT: typeid - // CHECK-NO-RTTI: COMPLETION: Pattern : typename <#qualifier#>::<#name#> + // CHECK-NO-RTTI: COMPLETION: Pattern : typename <#name#> // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : typeof <#expression#> // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : typeof(<#type#>) // CHECK-NO-RTTI-NEXT: COMPLETION: union // CHECK-NO-RTTI-NEXT: COMPLETION: unsigned + // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : using <#name#> = <#type#>; // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : using namespace <#identifier#>; // CHECK-NO-RTTI-NEXT: COMPLETION: void // CHECK-NO-RTTI-NEXT: COMPLETION: volatile diff --git a/clang/test/CodeCompletion/ordinary-name.cpp b/clang/test/CodeCompletion/ordinary-name.cpp index 3f891307bb74b..3c3d0c5d68831 100644 --- a/clang/test/CodeCompletion/ordinary-name.cpp +++ b/clang/test/CodeCompletion/ordinary-name.cpp @@ -54,11 +54,12 @@ void foo() { // CHECK-CC1: COMPLETION: TYPEDEF : TYPEDEF // CHECK-CC1-NEXT: COMPLETION: Pattern : typedef <#type#> <#name#>; // CHECK-CC1-NEXT: COMPLETION: Pattern : [#std::type_info#]typeid(<#expression-or-type#>) - // CHECK-CC1-NEXT: COMPLETION: Pattern : typename <#qualifier#>::<#name#> + // CHECK-CC1-NEXT: COMPLETION: Pattern : typename <#name#> // CHECK-CC1-NEXT: COMPLETION: Pattern : typeof <#expression#> // CHECK-CC1-NEXT: COMPLETION: Pattern : typeof(<#type#>) // CHECK-CC1-NEXT: COMPLETION: union // CHECK-CC1-NEXT: COMPLETION: unsigned + // CHECK-CC1-NOT: COMPLETION: Pattern : using <#name#> = <#type#>; // CHECK-CC1-NEXT: COMPLETION: Pattern : using namespace <#identifier#>; // CHECK-CC1-NEXT: COMPLETION: void // CHECK-CC1-NEXT: COMPLETION: volatile @@ -97,12 +98,13 @@ void foo() { // CHECK-CC2-NEXT: COMPLETION: Pattern : template<<#parameters#>> // CHECK-CC2-NEXT: COMPLETION: TYPEDEF : TYPEDEF // CHECK-CC2-NEXT: COMPLETION: Pattern : typedef <#type#> <#name#>; - // CHECK-CC2-NEXT: COMPLETION: Pattern : typename <#qualifier#>::<#name#> + // CHECK-CC2-NEXT: COMPLETION: Pattern : typename <#name#> // CHECK-CC2-NEXT: COMPLETION: Pattern : typeof <#expression#> // CHECK-CC2-NEXT: COMPLETION: Pattern : typeof(<#type#>) // CHECK-CC2-NEXT: COMPLETION: union // CHECK-CC2-NEXT: COMPLETION: unsigned // CHECK-CC2-NEXT: COMPLETION: Pattern : using <#qualifier#>::<#name#>; + // CHECK-CC2-NOT: COMPLETION: Pattern : using <#name#> = <#type#>; // CHECK-CC2-NEXT: COMPLETION: Pattern : using namespace <#identifier#>; // CHECK-CC2-NEXT: COMPLETION: void // CHECK-CC2-NEXT: COMPLETION: volatile @@ -134,12 +136,13 @@ void foo() { // CHECK-CC3-NEXT: COMPLETION: struct // CHECK-CC3-NEXT: COMPLETION: Pattern : template<<#parameters#>> // CHECK-CC3-NEXT: COMPLETION: Pattern : typedef <#type#> <#name#>; - // CHECK-CC3-NEXT: COMPLETION: Pattern : typename <#qualifier#>::<#name#> + // CHECK-CC3-NEXT: COMPLETION: Pattern : typename <#name#> // CHECK-CC3-NEXT: COMPLETION: Pattern : typeof <#expression#> // CHECK-CC3-NEXT: COMPLETION: Pattern : typeof(<#type#>) // CHECK-CC3-NEXT: COMPLETION: union // CHECK-CC3-NEXT: COMPLETION: unsigned // CHECK-CC3-NEXT: COMPLETION: Pattern : using <#qualifier#>::<#name#>; + // CHECK-CC3-NOT: COMPLETION: Pattern : using <#name#> = <#type#>; // CHECK-CC3-NEXT: COMPLETION: virtual // CHECK-CC3-NEXT: COMPLETION: void // CHECK-CC3-NEXT: COMPLETION: volatile @@ -176,7 +179,7 @@ void foo() { // CHECK-CC4-NEXT: COMPLETION: Pattern : [#bool#]true // CHECK-CC4-NEXT: COMPLETION: TYPEDEF : TYPEDEF // CHECK-CC4-NEXT: COMPLETION: Pattern : [#std::type_info#]typeid(<#expression-or-type#>) - // CHECK-CC4-NEXT: COMPLETION: Pattern : typename <#qualifier#>::<#name#> + // CHECK-CC4-NEXT: COMPLETION: Pattern : typename <#name#> // CHECK-CC4-NEXT: COMPLETION: Pattern : typeof <#expression#> // CHECK-CC4-NEXT: COMPLETION: Pattern : typeof(<#type#>) // CHECK-CC4-NEXT: COMPLETION: union @@ -227,11 +230,12 @@ void foo() { // CHECK-NO-RTTI: COMPLETION: TYPEDEF : TYPEDEF // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : typedef <#type#> <#name#>; // CHECK-NO-RTTI-NOT: typeid - // CHECK-NO-RTTI: COMPLETION: Pattern : typename <#qualifier#>::<#name#> + // CHECK-NO-RTTI: COMPLETION: Pattern : typename <#name#> // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : typeof <#expression#> // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : typeof(<#type#>) // CHECK-NO-RTTI-NEXT: COMPLETION: union // CHECK-NO-RTTI-NEXT: COMPLETION: unsigned + // CHECK-NO-RTTI-NOT: COMPLETION: Pattern : using <#name#> = <#type#>; // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : using namespace <#identifier#>; // CHECK-NO-RTTI-NEXT: COMPLETION: void // CHECK-NO-RTTI-NEXT: COMPLETION: volatile diff --git a/clang/test/CodeCompletion/patterns.cpp b/clang/test/CodeCompletion/patterns.cpp index 5189e3e636d5a..9d18ced8aa6d1 100644 --- a/clang/test/CodeCompletion/patterns.cpp +++ b/clang/test/CodeCompletion/patterns.cpp @@ -74,3 +74,30 @@ int Cls::*memptr_return() { // RUN: %clang_cc1 -fsyntax-only -std=c++03 -code-completion-patterns -code-completion-at=%s:37:1 %s -o - | FileCheck -check-prefix=RETURN-PTR-STD03 %s // RUN: %clang_cc1 -fsyntax-only -std=c++03 -code-completion-patterns -code-completion-at=%s:41:1 %s -o - | FileCheck -check-prefix=RETURN-PTR-STD03 %s // RETURN-PTR-STD03-NOT: COMPLETION: Pattern : return nullptr; + +void something(); + +void unbraced_if() { + if (true) + something(); + // line 83 +} +// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:83:3 %s -o - | FileCheck -check-prefix=UNBRACED-IF %s +// UNBRACED-IF: COMPLETION: Pattern : else +// UNBRACED-IF-NEXT: <#statement#>; +// UNBRACED-IF: COMPLETION: Pattern : else if (<#condition#>) +// UNBRACED-IF-NEXT: <#statement#>; + +void braced_if() { + if (true) { + something(); + } + // line 95 +} +// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:95:3 %s -o - | FileCheck -check-prefix=BRACED-IF %s +// BRACED-IF: COMPLETION: Pattern : else { +// BRACED-IF-NEXT: <#statements#> +// BRACED-IF-NEXT: } +// BRACED-IF: COMPLETION: Pattern : else if (<#condition#>) { +// BRACED-IF-NEXT: <#statements#> +// BRACED-IF-NEXT: } diff --git a/clang/test/CodeGen/AMX/amx.c b/clang/test/CodeGen/AMX/amx.c new file mode 100644 index 0000000000000..89b486f7a6010 --- /dev/null +++ b/clang/test/CodeGen/AMX/amx.c @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +amx-int8 \ +// RUN: -target-feature +amx-bf16 -emit-llvm -o - -Werror -pedantic | FileCheck %s --check-prefixes=CHECK + +#include + +void test_amx(void *data) { + //CHECK-LABEL: @test_amx + //CHECK: call void @llvm.x86.ldtilecfg(i8* %{{.*}}) + //CHECK: call void @llvm.x86.sttilecfg(i8* %{{.*}}) + //CHECK: call void @llvm.x86.tilerelease() + //CHECK: call void @llvm.x86.tilezero(i8 3) + //CHECK: call void @llvm.x86.tileloadd64(i8 4, i8* %{{.*}}, i64 8) + //CHECK: call void @llvm.x86.tileloaddt164(i8 0, i8* %{{.*}}, i64 1) + //CHECK: call void @llvm.x86.tilestored64(i8 0, i8* %{{.*}}, i64 1) + //CHECK: call void @llvm.x86.tdpbssd(i8 1, i8 2, i8 3) + //CHECK: call void @llvm.x86.tdpbsud(i8 1, i8 2, i8 3) + //CHECK: call void @llvm.x86.tdpbusd(i8 1, i8 2, i8 3) + //CHECK: call void @llvm.x86.tdpbuud(i8 1, i8 2, i8 3) + //CHECK: call void @llvm.x86.tdpbf16ps(i8 1, i8 2, i8 3) + _tile_loadconfig(data); + _tile_storeconfig(data); + _tile_release(); + _tile_zero(3); + _tile_loadd(4, data, 8); + _tile_stream_loadd(0, data, 1); + _tile_stored(0, data, 1); + _tile_dpbssd(1, 2, 3); + _tile_dpbsud(1, 2, 3); + _tile_dpbusd(1, 2, 3); + _tile_dpbuud(1, 2, 3); + _tile_dpbf16ps(1, 2, 3); +} diff --git a/clang/test/CodeGen/AMX/amx_errors.c b/clang/test/CodeGen/AMX/amx_errors.c new file mode 100644 index 0000000000000..13a2b33b5a0a2 --- /dev/null +++ b/clang/test/CodeGen/AMX/amx_errors.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +amx-tile -target-feature +amx-int8 -target-feature +amx-bf16 -emit-llvm -fsyntax-only -verify + +#include + +void test_amx(void *data) { + _tile_zero(16); // expected-error {{argument value 16 is outside the valid range [0, 7]}} + _tile_loadd(19, data, 16); // expected-error {{argument value 19 is outside the valid range [0, 7]}} + _tile_stream_loadd(23, data, 1); // expected-error {{argument value 23 is outside the valid range [0, 7]}} + _tile_stored(88, data, 1); // expected-error {{argument value 88 is outside the valid range [0, 7]}} + _tile_dpbssd(16, 2, 3); // expected-error {{argument value 16 is outside the valid range [0, 7]}} + _tile_dpbssd(0, 16, 3); // expected-error {{argument value 16 is outside the valid range [0, 7]}} + _tile_dpbuud(0, 2, 16); // expected-error {{argument value 16 is outside the valid range [0, 7]}} + _tile_dpbsud(1, 1, 3); // expected-error {{tile arguments must refer to different tiles}} + _tile_dpbsud(7, 1, 7); // expected-error {{tile arguments must refer to different tiles}} + _tile_dpbsud(4, 3, 3); // expected-error {{tile arguments must refer to different tiles}} + _tile_dpbf16ps(4, 3, 3); // expected-error {{tile arguments must refer to different tiles}} +} diff --git a/clang/test/CodeGen/AMX/amx_inline_asm.c b/clang/test/CodeGen/AMX/amx_inline_asm.c new file mode 100644 index 0000000000000..9d828f8ac94e3 --- /dev/null +++ b/clang/test/CodeGen/AMX/amx_inline_asm.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +amx-int8 -target-feature +amx-bf16 -emit-llvm -o - -Wall -Werror -pedantic | FileCheck %s --check-prefixes=CHECK,X86_64 + +void f_tilemul(short a) +{ + //CHECK: call void asm sideeffect "tileloadd 0(%rsi,%r13,4), %tmm0 \0A\09tileloadd 0(%rdx,%r14,4), %tmm6 \0A\09tdpbf16ps %tmm6, %tmm0, %tmm7 \0A\09tilestored %tmm7, 0(%r12,%r15,4) \0A\09", "~{memory},~{tmm0},~{tmm6},~{tmm7},~{dirflag},~{fpsr},~{flags}"() + __asm__ volatile ("tileloadd 0(%%rsi,%%r13,4), %%tmm0 \n\t" + "tileloadd 0(%%rdx,%%r14,4), %%tmm6 \n\t" + "tdpbf16ps %%tmm6, %%tmm0, %%tmm7 \n\t" + "tilestored %%tmm7, 0(%%r12,%%r15,4) \n\t" + ::: "memory", "tmm0", "tmm6", "tmm7"); +} diff --git a/clang/test/CodeGen/Atomics.c b/clang/test/CodeGen/Atomics.c index d960ac6df2f96..ebc9c139775a9 100644 --- a/clang/test/CodeGen/Atomics.c +++ b/clang/test/CodeGen/Atomics.c @@ -10,6 +10,8 @@ signed int si; unsigned int ui; signed long long sll; unsigned long long ull; +__int128 s128; +unsigned __int128 u128; void test_op_ignore (void) // CHECK-LABEL: define void @test_op_ignore { @@ -48,6 +50,8 @@ void test_op_ignore (void) // CHECK-LABEL: define void @test_op_ignore (void) __sync_fetch_and_xor (&ui, 1); // CHECK: atomicrmw xor i32 (void) __sync_fetch_and_xor (&sll, 1); // CHECK: atomicrmw xor i64 (void) __sync_fetch_and_xor (&ull, 1); // CHECK: atomicrmw xor i64 + (void) __sync_fetch_and_xor (&u128, 1); // CHECK: atomicrmw xor i128 + (void) __sync_fetch_and_xor (&s128, 1); // CHECK: atomicrmw xor i128 (void) __sync_fetch_and_nand (&sc, 1); // CHECK: atomicrmw nand i8 (void) __sync_fetch_and_nand (&uc, 1); // CHECK: atomicrmw nand i8 @@ -168,27 +172,43 @@ void test_op_and_fetch (void) sc = __sync_nand_and_fetch (&sc, uc); // CHECK: atomicrmw nand // CHECK: and // CHECK: xor + // CHECK: -1 uc = __sync_nand_and_fetch (&uc, uc); // CHECK: atomicrmw nand // CHECK: and // CHECK: xor + // CHECK: -1 ss = __sync_nand_and_fetch (&ss, uc); // CHECK: atomicrmw nand // CHECK: and // CHECK: xor + // CHECK: -1 us = __sync_nand_and_fetch (&us, uc); // CHECK: atomicrmw nand // CHECK: and // CHECK: xor + // CHECK: -1 si = __sync_nand_and_fetch (&si, uc); // CHECK: atomicrmw nand // CHECK: and // CHECK: xor + // CHECK: -1 ui = __sync_nand_and_fetch (&ui, uc); // CHECK: atomicrmw nand // CHECK: and // CHECK: xor + // CHECK: -1 sll = __sync_nand_and_fetch (&sll, uc); // CHECK: atomicrmw nand // CHECK: and // CHECK: xor + // CHECK: -1 ull = __sync_nand_and_fetch (&ull, uc); // CHECK: atomicrmw nand // CHECK: and // CHECK: xor + // CHECK: -1 + u128 = __sync_nand_and_fetch (&u128, uc); // CHECK: atomicrmw nand + // CHECK: and + // CHECK: xor + // CHECK: -1 + s128 = __sync_nand_and_fetch (&s128, uc); // CHECK: atomicrmw nand + // CHECK: and + // CHECK: xor + // CHECK: -1 sc = __sync_and_and_fetch (&sc, uc); // CHECK: atomicrmw and uc = __sync_and_and_fetch (&uc, uc); // CHECK: atomicrmw and diff --git a/clang/test/CodeGen/aarch64-bf16-lane-intrinsics.c b/clang/test/CodeGen/aarch64-bf16-lane-intrinsics.c new file mode 100644 index 0000000000000..8a8795cd8ad8b --- /dev/null +++ b/clang/test/CodeGen/aarch64-bf16-lane-intrinsics.c @@ -0,0 +1,145 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// RUN: %clang_cc1 -triple aarch64-arm-none-eabi -target-feature +neon -target-feature +bf16 \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg -instcombine | FileCheck --check-prefix=CHECK-LE %s +// RUN: %clang_cc1 -triple aarch64_be-arm-none-eabi -target-feature +neon -target-feature +bf16 \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg -instcombine | FileCheck --check-prefix=CHECK-BE %s + +#include + +// CHECK-LE-LABEL: @test_vcopy_lane_bf16_v1( +// CHECK-LE-NEXT: entry: +// CHECK-LE-NEXT: [[VSET_LANE:%.*]] = shufflevector <4 x bfloat> [[A:%.*]], <4 x bfloat> [[B:%.*]], <4 x i32> +// CHECK-LE-NEXT: ret <4 x bfloat> [[VSET_LANE]] +// +// CHECK-BE-LABEL: @test_vcopy_lane_bf16_v1( +// CHECK-BE-NEXT: entry: +// CHECK-BE-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x bfloat> [[A:%.*]], <4 x bfloat> undef, <4 x i32> +// CHECK-BE-NEXT: [[VSET_LANE:%.*]] = shufflevector <4 x bfloat> [[SHUFFLE]], <4 x bfloat> [[B:%.*]], <4 x i32> +// CHECK-BE-NEXT: [[SHUFFLE5:%.*]] = shufflevector <4 x bfloat> [[VSET_LANE]], <4 x bfloat> undef, <4 x i32> +// CHECK-BE-NEXT: ret <4 x bfloat> [[SHUFFLE5]] +// +bfloat16x4_t test_vcopy_lane_bf16_v1(bfloat16x4_t a, bfloat16x4_t b) { + return vcopy_lane_bf16(a, 1, b, 3); +} + +// CHECK-LE-LABEL: @test_vcopy_lane_bf16_v2( +// CHECK-LE-NEXT: entry: +// CHECK-LE-NEXT: [[VSET_LANE:%.*]] = shufflevector <4 x bfloat> [[A:%.*]], <4 x bfloat> [[B:%.*]], <4 x i32> +// CHECK-LE-NEXT: ret <4 x bfloat> [[VSET_LANE]] +// +// CHECK-BE-LABEL: @test_vcopy_lane_bf16_v2( +// CHECK-BE-NEXT: entry: +// CHECK-BE-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x bfloat> [[A:%.*]], <4 x bfloat> undef, <4 x i32> +// CHECK-BE-NEXT: [[VSET_LANE:%.*]] = shufflevector <4 x bfloat> [[SHUFFLE]], <4 x bfloat> [[B:%.*]], <4 x i32> +// CHECK-BE-NEXT: [[SHUFFLE5:%.*]] = shufflevector <4 x bfloat> [[VSET_LANE]], <4 x bfloat> undef, <4 x i32> +// CHECK-BE-NEXT: ret <4 x bfloat> [[SHUFFLE5]] +// +bfloat16x4_t test_vcopy_lane_bf16_v2(bfloat16x4_t a, bfloat16x4_t b) { + return vcopy_lane_bf16(a, 2, b, 0); +} + +// CHECK-LE-LABEL: @test_vcopyq_lane_bf16_v1( +// CHECK-LE-NEXT: entry: +// CHECK-LE-NEXT: [[TMP0:%.*]] = shufflevector <4 x bfloat> [[B:%.*]], <4 x bfloat> undef, <8 x i32> +// CHECK-LE-NEXT: [[VSET_LANE:%.*]] = shufflevector <8 x bfloat> [[A:%.*]], <8 x bfloat> [[TMP0]], <8 x i32> +// CHECK-LE-NEXT: ret <8 x bfloat> [[VSET_LANE]] +// +// CHECK-BE-LABEL: @test_vcopyq_lane_bf16_v1( +// CHECK-BE-NEXT: entry: +// CHECK-BE-NEXT: [[TMP0:%.*]] = shufflevector <4 x bfloat> [[B:%.*]], <4 x bfloat> undef, <8 x i32> +// CHECK-BE-NEXT: [[SHUFFLE:%.*]] = shufflevector <8 x bfloat> [[A:%.*]], <8 x bfloat> undef, <8 x i32> +// CHECK-BE-NEXT: [[VSET_LANE:%.*]] = shufflevector <8 x bfloat> [[SHUFFLE]], <8 x bfloat> [[TMP0]], <8 x i32> +// CHECK-BE-NEXT: [[SHUFFLE5:%.*]] = shufflevector <8 x bfloat> [[VSET_LANE]], <8 x bfloat> undef, <8 x i32> +// CHECK-BE-NEXT: ret <8 x bfloat> [[SHUFFLE5]] +// +bfloat16x8_t test_vcopyq_lane_bf16_v1(bfloat16x8_t a, bfloat16x4_t b) { + return vcopyq_lane_bf16(a, 0, b, 2); +} + +// CHECK-LE-LABEL: @test_vcopyq_lane_bf16_v2( +// CHECK-LE-NEXT: entry: +// CHECK-LE-NEXT: [[TMP0:%.*]] = shufflevector <4 x bfloat> [[B:%.*]], <4 x bfloat> undef, <8 x i32> +// CHECK-LE-NEXT: [[VSET_LANE:%.*]] = shufflevector <8 x bfloat> [[A:%.*]], <8 x bfloat> [[TMP0]], <8 x i32> +// CHECK-LE-NEXT: ret <8 x bfloat> [[VSET_LANE]] +// +// CHECK-BE-LABEL: @test_vcopyq_lane_bf16_v2( +// CHECK-BE-NEXT: entry: +// CHECK-BE-NEXT: [[TMP0:%.*]] = shufflevector <4 x bfloat> [[B:%.*]], <4 x bfloat> undef, <8 x i32> +// CHECK-BE-NEXT: [[SHUFFLE:%.*]] = shufflevector <8 x bfloat> [[A:%.*]], <8 x bfloat> undef, <8 x i32> +// CHECK-BE-NEXT: [[VSET_LANE:%.*]] = shufflevector <8 x bfloat> [[SHUFFLE]], <8 x bfloat> [[TMP0]], <8 x i32> +// CHECK-BE-NEXT: [[SHUFFLE5:%.*]] = shufflevector <8 x bfloat> [[VSET_LANE]], <8 x bfloat> undef, <8 x i32> +// CHECK-BE-NEXT: ret <8 x bfloat> [[SHUFFLE5]] +// +bfloat16x8_t test_vcopyq_lane_bf16_v2(bfloat16x8_t a, bfloat16x4_t b) { + return vcopyq_lane_bf16(a, 6, b, 0); +} + +// CHECK-LE-LABEL: @test_vcopy_laneq_bf16_v1( +// CHECK-LE-NEXT: entry: +// CHECK-LE-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x bfloat> [[B:%.*]], i32 7 +// CHECK-LE-NEXT: [[VSET_LANE:%.*]] = insertelement <4 x bfloat> [[A:%.*]], bfloat [[VGETQ_LANE]], i32 0 +// CHECK-LE-NEXT: ret <4 x bfloat> [[VSET_LANE]] +// +// CHECK-BE-LABEL: @test_vcopy_laneq_bf16_v1( +// CHECK-BE-NEXT: entry: +// CHECK-BE-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x bfloat> [[A:%.*]], <4 x bfloat> undef, <4 x i32> +// CHECK-BE-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x bfloat> [[B:%.*]], i32 0 +// CHECK-BE-NEXT: [[VSET_LANE:%.*]] = insertelement <4 x bfloat> [[SHUFFLE]], bfloat [[VGETQ_LANE]], i32 0 +// CHECK-BE-NEXT: [[SHUFFLE5:%.*]] = shufflevector <4 x bfloat> [[VSET_LANE]], <4 x bfloat> undef, <4 x i32> +// CHECK-BE-NEXT: ret <4 x bfloat> [[SHUFFLE5]] +// +bfloat16x4_t test_vcopy_laneq_bf16_v1(bfloat16x4_t a, bfloat16x8_t b) { + return vcopy_laneq_bf16(a, 0, b, 7); +} + +// CHECK-LE-LABEL: @test_vcopy_laneq_bf16_v2( +// CHECK-LE-NEXT: entry: +// CHECK-LE-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x bfloat> [[B:%.*]], i32 4 +// CHECK-LE-NEXT: [[VSET_LANE:%.*]] = insertelement <4 x bfloat> [[A:%.*]], bfloat [[VGETQ_LANE]], i32 3 +// CHECK-LE-NEXT: ret <4 x bfloat> [[VSET_LANE]] +// +// CHECK-BE-LABEL: @test_vcopy_laneq_bf16_v2( +// CHECK-BE-NEXT: entry: +// CHECK-BE-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x bfloat> [[A:%.*]], <4 x bfloat> undef, <4 x i32> +// CHECK-BE-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x bfloat> [[B:%.*]], i32 3 +// CHECK-BE-NEXT: [[VSET_LANE:%.*]] = insertelement <4 x bfloat> [[SHUFFLE]], bfloat [[VGETQ_LANE]], i32 3 +// CHECK-BE-NEXT: [[SHUFFLE5:%.*]] = shufflevector <4 x bfloat> [[VSET_LANE]], <4 x bfloat> undef, <4 x i32> +// CHECK-BE-NEXT: ret <4 x bfloat> [[SHUFFLE5]] +// +bfloat16x4_t test_vcopy_laneq_bf16_v2(bfloat16x4_t a, bfloat16x8_t b) { + return vcopy_laneq_bf16(a, 3, b, 4); +} + +// CHECK-LE-LABEL: @test_vcopyq_laneq_bf16_v1( +// CHECK-LE-NEXT: entry: +// CHECK-LE-NEXT: [[VSET_LANE:%.*]] = shufflevector <8 x bfloat> [[A:%.*]], <8 x bfloat> [[B:%.*]], <8 x i32> +// CHECK-LE-NEXT: ret <8 x bfloat> [[VSET_LANE]] +// +// CHECK-BE-LABEL: @test_vcopyq_laneq_bf16_v1( +// CHECK-BE-NEXT: entry: +// CHECK-BE-NEXT: [[SHUFFLE:%.*]] = shufflevector <8 x bfloat> [[A:%.*]], <8 x bfloat> undef, <8 x i32> +// CHECK-BE-NEXT: [[VSET_LANE:%.*]] = shufflevector <8 x bfloat> [[SHUFFLE]], <8 x bfloat> [[B:%.*]], <8 x i32> +// CHECK-BE-NEXT: [[SHUFFLE5:%.*]] = shufflevector <8 x bfloat> [[VSET_LANE]], <8 x bfloat> undef, <8 x i32> +// CHECK-BE-NEXT: ret <8 x bfloat> [[SHUFFLE5]] +// +bfloat16x8_t test_vcopyq_laneq_bf16_v1(bfloat16x8_t a, bfloat16x8_t b) { + return vcopyq_laneq_bf16(a, 3, b, 7); + +} + +// CHECK-LE-LABEL: @test_vcopyq_laneq_bf16_v2( +// CHECK-LE-NEXT: entry: +// CHECK-LE-NEXT: [[VSET_LANE:%.*]] = shufflevector <8 x bfloat> [[A:%.*]], <8 x bfloat> [[B:%.*]], <8 x i32> +// CHECK-LE-NEXT: ret <8 x bfloat> [[VSET_LANE]] +// +// CHECK-BE-LABEL: @test_vcopyq_laneq_bf16_v2( +// CHECK-BE-NEXT: entry: +// CHECK-BE-NEXT: [[SHUFFLE:%.*]] = shufflevector <8 x bfloat> [[A:%.*]], <8 x bfloat> undef, <8 x i32> +// CHECK-BE-NEXT: [[VSET_LANE:%.*]] = shufflevector <8 x bfloat> [[SHUFFLE]], <8 x bfloat> [[B:%.*]], <8 x i32> +// CHECK-BE-NEXT: [[SHUFFLE5:%.*]] = shufflevector <8 x bfloat> [[VSET_LANE]], <8 x bfloat> undef, <8 x i32> +// CHECK-BE-NEXT: ret <8 x bfloat> [[SHUFFLE5]] +// +bfloat16x8_t test_vcopyq_laneq_bf16_v2(bfloat16x8_t a, bfloat16x8_t b) { + return vcopyq_laneq_bf16(a, 6, b, 2); +} + diff --git a/clang/test/CodeGen/aarch64-neon-misc-constrained.c b/clang/test/CodeGen/aarch64-neon-misc-constrained.c index 0385358291c9b..a0a503df33754 100644 --- a/clang/test/CodeGen/aarch64-neon-misc-constrained.c +++ b/clang/test/CodeGen/aarch64-neon-misc-constrained.c @@ -3,6 +3,7 @@ // RUN: | opt -S -mem2reg | FileCheck --check-prefix=COMMON --check-prefix=COMMONIR --check-prefix=UNCONSTRAINED %s // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \ // RUN: -ffp-exception-behavior=strict \ +// RUN: -fexperimental-strict-floating-point \ // RUN: -disable-O0-optnone -fallow-half-arguments-and-returns -emit-llvm -o - %s \ // RUN: | opt -S -mem2reg | FileCheck --check-prefix=COMMON --check-prefix=COMMONIR --check-prefix=CONSTRAINED %s // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \ @@ -10,6 +11,7 @@ // RUN: | FileCheck --check-prefix=COMMON --check-prefix=CHECK-ASM %s // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \ // RUN: -ffp-exception-behavior=strict \ +// RUN: -fexperimental-strict-floating-point \ // RUN: -disable-O0-optnone -fallow-half-arguments-and-returns -S -o - %s \ // RUN: | FileCheck --check-prefix=COMMON --check-prefix=CHECK-ASM %s diff --git a/clang/test/CodeGen/aarch64-neon-scalar-x-indexed-elem-constrained.c b/clang/test/CodeGen/aarch64-neon-scalar-x-indexed-elem-constrained.c index cbe5627337fd9..311950362f332 100644 --- a/clang/test/CodeGen/aarch64-neon-scalar-x-indexed-elem-constrained.c +++ b/clang/test/CodeGen/aarch64-neon-scalar-x-indexed-elem-constrained.c @@ -3,6 +3,7 @@ // RUN: | FileCheck --check-prefix=COMMON --check-prefix=COMMONIR --check-prefix=UNCONSTRAINED %s // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -target-cpu cyclone \ // RUN: -ffp-exception-behavior=strict \ +// RUN: -fexperimental-strict-floating-point \ // RUN: -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg \ // RUN: | FileCheck --check-prefix=COMMON --check-prefix=COMMONIR --check-prefix=CONSTRAINED %s // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -target-cpu cyclone \ @@ -10,6 +11,7 @@ // RUN: | FileCheck --check-prefix=COMMON --check-prefix=CHECK-ASM %s // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -target-cpu cyclone \ // RUN: -ffp-exception-behavior=strict \ +// RUN: -fexperimental-strict-floating-point \ // RUN: -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | llc -o=- - \ // RUN: | FileCheck --check-prefix=COMMON --check-prefix=CHECK-ASM %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_abd.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_abd.c index dcaa5aa260295..96a814565981e 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_abd.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_abd.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_abs.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_abs.c index 2313b3c01a4d6..c880f25f49434 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_abs.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_abs.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_acge.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_acge.c index c5c3071225454..d1752815bcee5 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_acge.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_acge.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_acgt.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_acgt.c index 00e408ca4d941..0377105a1ff05 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_acgt.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_acgt.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_acle.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_acle.c index 6ba53d0bb8c3a..f411cd2cf6279 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_acle.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_acle.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_aclt.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_aclt.c index 781e6633f69f2..cbbd6ed947538 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_aclt.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_aclt.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_add.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_add.c index 0956efdebb13a..68c223f872f0e 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_add.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_add.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_adda.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_adda.c index 104d112cc046b..853da8783faa7 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_adda.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_adda.c @@ -1,8 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: rm -f -- %S/acle_sve_adda.s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_addv.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_addv.c index fc00f38196f62..eab8ba56411f7 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_addv.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_addv.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_adrb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_adrb.c index 4a5820aa52ef9..b70c3c0aca412 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_adrb.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_adrb.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_adrd.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_adrd.c index bd72564492210..5dc5aad81937e 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_adrd.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_adrd.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_adrh.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_adrh.c index 959a9f7ae7e89..7b11e478c1771 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_adrh.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_adrh.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_adrw.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_adrw.c index 6050e0502e15e..3d771a5fdf781 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_adrw.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_adrw.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_and.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_and.c index 2db91824ec2aa..61cc267702107 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_and.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_and.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_andv.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_andv.c index 4967a488e6bad..02e2069727483 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_andv.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_andv.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_asr.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_asr.c index ca0a97fb89491..6d973583f6ccc 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_asr.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_asr.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_asrd.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_asrd.c index b91784b08053f..8a6febba9a21b 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_asrd.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_asrd.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfdot.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfdot.c new file mode 100644 index 0000000000000..2d07f3419d739 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfdot.c @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4 +#endif + +svfloat32_t test_bfdot_f32(svfloat32_t x, svbfloat16_t y, svbfloat16_t z) { + // CHECK-LABEL: @test_bfdot_f32( + // CHECK: %[[RET:.*]] = call @llvm.aarch64.sve.bfdot( %x, %y, %z) + // CHECK: ret %[[RET]] + return SVE_ACLE_FUNC(svbfdot, _f32, , )(x, y, z); +} + +svfloat32_t test_bfdot_lane_0_f32(svfloat32_t x, svbfloat16_t y, svbfloat16_t z) { + // CHECK-LABEL: @test_bfdot_lane_0_f32( + // CHECK: %[[RET:.*]] = call @llvm.aarch64.sve.bfdot.lane( %x, %y, %z, i64 0) + // CHECK: ret %[[RET]] + return SVE_ACLE_FUNC(svbfdot_lane, _f32, , )(x, y, z, 0); +} + +svfloat32_t test_bfdot_lane_3_f32(svfloat32_t x, svbfloat16_t y, svbfloat16_t z) { + // CHECK-LABEL: @test_bfdot_lane_3_f32( + // CHECK: %[[RET:.*]] = call @llvm.aarch64.sve.bfdot.lane( %x, %y, %z, i64 3) + // CHECK: ret %[[RET]] + return SVE_ACLE_FUNC(svbfdot_lane, _f32, , )(x, y, z, 3); +} + +svfloat32_t test_bfdot_n_f32(svfloat32_t x, svbfloat16_t y, bfloat16_t z) { + // CHECK-LABEL: @test_bfdot_n_f32( + // CHECK: %[[SPLAT:.*]] = call @llvm.aarch64.sve.dup.x.nxv8bf16(bfloat %z) + // CHECK: %[[RET:.*]] = call @llvm.aarch64.sve.bfdot( %x, %y, %[[SPLAT]]) + // CHECK: ret %[[RET]] + return SVE_ACLE_FUNC(svbfdot, _n_f32, , )(x, y, z); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfmlalb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfmlalb.c new file mode 100644 index 0000000000000..dd88b486e57e1 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfmlalb.c @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4 +#endif + +svfloat32_t test_svbfmlalb_f32(svfloat32_t x, svbfloat16_t y, svbfloat16_t z) { + // CHECK-LABEL: @test_svbfmlalb_f32( + // CHECK: %[[RET:.*]] = call @llvm.aarch64.sve.bfmlalb( %x, %y, %z) + // CHECK: ret %[[RET]] + return SVE_ACLE_FUNC(svbfmlalb, _f32, , )(x, y, z); +} + +svfloat32_t test_bfmlalb_lane_0_f32(svfloat32_t x, svbfloat16_t y, svbfloat16_t z) { + // CHECK-LABEL: @test_bfmlalb_lane_0_f32( + // CHECK: %[[RET:.*]] = call @llvm.aarch64.sve.bfmlalb.lane( %x, %y, %z, i64 0) + // CHECK: ret %[[RET]] + return SVE_ACLE_FUNC(svbfmlalb_lane, _f32, , )(x, y, z, 0); +} + +svfloat32_t test_bfmlalb_lane_7_f32(svfloat32_t x, svbfloat16_t y, svbfloat16_t z) { + // CHECK-LABEL: @test_bfmlalb_lane_7_f32( + // CHECK: %[[RET:.*]] = call @llvm.aarch64.sve.bfmlalb.lane( %x, %y, %z, i64 7) + // CHECK: ret %[[RET]] + return SVE_ACLE_FUNC(svbfmlalb_lane, _f32, , )(x, y, z, 7); +} + +svfloat32_t test_bfmlalb_n_f32(svfloat32_t x, svbfloat16_t y, bfloat16_t z) { + // CHECK-LABEL: @test_bfmlalb_n_f32( + // CHECK: %[[SPLAT:.*]] = call @llvm.aarch64.sve.dup.x.nxv8bf16(bfloat %z) + // CHECK: %[[RET:.*]] = call @llvm.aarch64.sve.bfmlalb( %x, %y, %[[SPLAT]]) + // CHECK: ret %[[RET]] + return SVE_ACLE_FUNC(svbfmlalb, _n_f32, , )(x, y, z); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfmlalt.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfmlalt.c new file mode 100644 index 0000000000000..f68976458d56b --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfmlalt.c @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4 +#endif + +svfloat32_t test_svbfmlalt_f32(svfloat32_t x, svbfloat16_t y, svbfloat16_t z) { + // CHECK-LABEL: @test_svbfmlalt_f32( + // CHECK: %[[RET:.*]] = call @llvm.aarch64.sve.bfmlalt( %x, %y, %z) + // CHECK: ret %[[RET]] + return SVE_ACLE_FUNC(svbfmlalt, _f32, , )(x, y, z); +} + +svfloat32_t test_bfmlalt_lane_0_f32(svfloat32_t x, svbfloat16_t y, svbfloat16_t z) { + // CHECK-LABEL: @test_bfmlalt_lane_0_f32( + // CHECK: %[[RET:.*]] = call @llvm.aarch64.sve.bfmlalt.lane( %x, %y, %z, i64 0) + // CHECK: ret %[[RET]] + return SVE_ACLE_FUNC(svbfmlalt_lane, _f32, , )(x, y, z, 0); +} + +svfloat32_t test_bfmlalt_lane_7_f32(svfloat32_t x, svbfloat16_t y, svbfloat16_t z) { + // CHECK-LABEL: @test_bfmlalt_lane_7_f32( + // CHECK: %[[RET:.*]] = call @llvm.aarch64.sve.bfmlalt.lane( %x, %y, %z, i64 7) + // CHECK: ret %[[RET]] + return SVE_ACLE_FUNC(svbfmlalt_lane, _f32, , )(x, y, z, 7); +} + +svfloat32_t test_bfmlalt_n_f32(svfloat32_t x, svbfloat16_t y, bfloat16_t z) { + // CHECK-LABEL: @test_bfmlalt_n_f32( + // CHECK: %[[SPLAT:.*]] = call @llvm.aarch64.sve.dup.x.nxv8bf16(bfloat %z) + // CHECK: %[[RET:.*]] = call @llvm.aarch64.sve.bfmlalt( %x, %y, %[[SPLAT]]) + // CHECK: ret %[[RET]] + return SVE_ACLE_FUNC(svbfmlalt, _n_f32, , )(x, y, z); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfmmla.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfmmla.c new file mode 100644 index 0000000000000..e38baea73e709 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfmmla.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4 +#endif + +svfloat32_t test_bfmmla_f32(svfloat32_t x, svbfloat16_t y, svbfloat16_t z) { + // CHECK-LABEL: @test_bfmmla_f32( + // CHECK: %[[RET:.*]] = call @llvm.aarch64.sve.bfmmla( %x, %y, %z) + // CHECK: ret %[[RET]] + return SVE_ACLE_FUNC(svbfmmla, _f32, , )(x, y, z); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bic.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bic.c index d062d367fb601..7d5bb90ec41c4 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bic.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bic.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_brka.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_brka.c index b6bb5fe2e8ee8..71728997029a0 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_brka.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_brka.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_brkb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_brkb.c index 07dd782f71fde..e950a6db629e8 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_brkb.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_brkb.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_brkn.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_brkn.c index 539c34aa6e421..c84360962b023 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_brkn.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_brkn.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_brkpa.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_brkpa.c index bbcdead0a5614..b9b7d70f8f6d9 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_brkpa.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_brkpa.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_brkpb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_brkpb.c index ca6b543135694..7723cf264c7bc 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_brkpb.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_brkpb.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cadd.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cadd.c index 889f4af15e7a5..8f318f93a91a7 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cadd.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cadd.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_clasta-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_clasta-bfloat.c new file mode 100644 index 0000000000000..3e66d7d98b076 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_clasta-bfloat.c @@ -0,0 +1,36 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svclasta_bf16(svbool_t pg, svbfloat16_t fallback, svbfloat16_t data) { + // CHECK-LABEL: test_svclasta_bf16 + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.clasta.nxv8bf16( %[[PG]], %fallback, %data) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svclasta_bf16'}} + return SVE_ACLE_FUNC(svclasta, _bf16, , )(pg, fallback, data); +} + +bfloat16_t test_svclasta_n_bf16(svbool_t pg, bfloat16_t fallback, svbfloat16_t data) { + // CHECK-LABEL: test_svclasta_n_bf16 + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call bfloat @llvm.aarch64.sve.clasta.n.nxv8bf16( %[[PG]], bfloat %fallback, %data) + // CHECK: ret bfloat %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svclasta_n_bf16'}} + return SVE_ACLE_FUNC(svclasta, _n_bf16, , )(pg, fallback, data); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_clasta.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_clasta.c index 0f49a4447fe78..5c869a02f3715 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_clasta.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_clasta.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_clastb-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_clastb-bfloat.c new file mode 100644 index 0000000000000..0182f2e6775e7 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_clastb-bfloat.c @@ -0,0 +1,36 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svclastb_bf16(svbool_t pg, svbfloat16_t fallback, svbfloat16_t data) { + // CHECK-LABEL: test_svclastb_bf16 + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.clastb.nxv8bf16( %[[PG]], %fallback, %data) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svclastb_bf16'}} + return SVE_ACLE_FUNC(svclastb, _bf16, , )(pg, fallback, data); +} + +bfloat16_t test_svclastb_n_bf16(svbool_t pg, bfloat16_t fallback, svbfloat16_t data) { + // CHECK-LABEL: test_svclastb_n_bf16 + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call bfloat @llvm.aarch64.sve.clastb.n.nxv8bf16( %[[PG]], bfloat %fallback, %data) + // CHECK: ret bfloat %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svclastb_n_bf16'}} + return SVE_ACLE_FUNC(svclastb, _n_bf16, , )(pg, fallback, data); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_clastb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_clastb.c index 4ba3fbb1ff3a7..63bfc7c4c9ec9 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_clastb.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_clastb.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cls.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cls.c index 4538a9e7c57cd..92255b24cd515 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cls.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cls.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_clz.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_clz.c index 864711ef34552..72e55ce8855d1 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_clz.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_clz.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmla.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmla.c index a8207acb9b3a5..2c8062daeb8f6 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmla.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmla.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmpeq.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmpeq.c index b76bd8ee1bebf..269801c71fdc8 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmpeq.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmpeq.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmpge.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmpge.c index a5fed360db3db..56c761c773180 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmpge.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmpge.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s - +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmpgt.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmpgt.c index 76c0a63c2863a..f49520b3e360b 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmpgt.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmpgt.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s - +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmple.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmple.c index a6cf374346579..cb93f1ece5fb2 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmple.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmple.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s - +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmplt.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmplt.c index a5ed353609ee3..b19d515559569 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmplt.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmplt.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s - +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmpne.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmpne.c index c98c40a120bc4..272af486f8950 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmpne.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmpne.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmpuo.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmpuo.c index 1130d9812647b..bc9d506b5033a 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmpuo.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cmpuo.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cnot.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cnot.c index 3597cec12127d..1ef1ba8a7b28f 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cnot.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cnot.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cnt-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cnt-bfloat.c new file mode 100644 index 0000000000000..e3e07a1ef18e4 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cnt-bfloat.c @@ -0,0 +1,44 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4 +#endif + +svuint16_t test_svcnt_bf16_z(svbool_t pg, svbfloat16_t op) { + // CHECK-LABEL: test_svcnt_bf16_z + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.cnt.nxv8bf16( zeroinitializer, %[[PG]], %op) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svcnt_bf16_z'}} + return SVE_ACLE_FUNC(svcnt, _bf16, _z, )(pg, op); +} + +svuint16_t test_svcnt_bf16_m(svuint16_t inactive, svbool_t pg, svbfloat16_t op) { + // CHECK-LABEL: test_svcnt_bf16_m + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.cnt.nxv8bf16( %inactive, %[[PG]], %op) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svcnt_bf16_m'}} + return SVE_ACLE_FUNC(svcnt, _bf16, _m, )(inactive, pg, op); +} +svuint16_t test_svcnt_bf16_x(svbool_t pg, svbfloat16_t op) { + // CHECK-LABEL: test_svcnt_bf16_x + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.cnt.nxv8bf16( undef, %[[PG]], %op) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svcnt_bf16_x'}} + return SVE_ACLE_FUNC(svcnt, _bf16, _x, )(pg, op); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cnt.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cnt.c index c3ab491a0dee8..43c03cc46ef6a 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cnt.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cnt.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntb.c index 4e3febe41845d..f06ed67ecb2e3 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntb.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntb.c @@ -1,6 +1,6 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntd.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntd.c index aa6a024b9b1c8..1fe544e99c193 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntd.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntd.c @@ -1,6 +1,6 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cnth.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cnth.c index 8c2481f641192..0bd8b5b566c6d 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cnth.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cnth.c @@ -1,6 +1,6 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntp.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntp.c index 448ec9ba76852..cb9f2c7c6816a 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntp.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntp.c @@ -1,6 +1,6 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntw.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntw.c index 05bf30abb316c..40b00eb1bf25d 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntw.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cntw.c @@ -1,6 +1,6 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_compact.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_compact.c index 2ebc928c0beb9..67ac08921a257 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_compact.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_compact.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create2-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create2-bfloat.c new file mode 100644 index 0000000000000..52d92d04d6982 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create2-bfloat.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbfloat16x2_t test_svcreate2_bf16(svbfloat16_t x0, svbfloat16_t x1) +{ + // CHECK-LABEL: test_svcreate2_bf16 + // CHECK: %[[CREATE:.*]] = call @llvm.aarch64.sve.tuple.create2.nxv16bf16.nxv8bf16( %x0, %x1) + // CHECK-NEXT: ret %[[CREATE]] + // expected-warning@+1 {{implicit declaration of function 'svcreate2_bf16'}} + return SVE_ACLE_FUNC(svcreate2,_bf16,,)(x0, x1); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create2.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create2.c index 5f5de0a473e77..614f39c2bbfe9 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create2.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create2.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create3-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create3-bfloat.c new file mode 100644 index 0000000000000..28e14972f0981 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create3-bfloat.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbfloat16x3_t test_svcreate3_bf16(svbfloat16_t x0, svbfloat16_t x1, svbfloat16_t x2) +{ + // CHECK-LABEL: test_svcreate3_bf16 + // CHECK: %[[CREATE:.*]] = call @llvm.aarch64.sve.tuple.create3.nxv24bf16.nxv8bf16( %x0, %x1, %x2) + // CHECK-NEXT: ret %[[CREATE]] + // expected-warning@+1 {{implicit declaration of function 'svcreate3_bf16'}} + return SVE_ACLE_FUNC(svcreate3,_bf16,,)(x0, x1, x2); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create3.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create3.c index b08ce21f199c1..4c792b0b9e357 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create3.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create3.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create4-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create4-bfloat.c new file mode 100644 index 0000000000000..36bdf7c05fca0 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create4-bfloat.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbfloat16x4_t test_svcreate4_bf16(svbfloat16_t x0, svbfloat16_t x1, svbfloat16_t x2, svbfloat16_t x4) +{ + // CHECK-LABEL: test_svcreate4_bf16 + // CHECK: %[[CREATE:.*]] = call @llvm.aarch64.sve.tuple.create4.nxv32bf16.nxv8bf16( %x0, %x1, %x2, %x4) + // CHECK-NEXT: ret %[[CREATE]] + // expected-warning@+1 {{implicit declaration of function 'svcreate4_bf16'}} + return SVE_ACLE_FUNC(svcreate4,_bf16,,)(x0, x1, x2, x4); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create4.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create4.c index ff05e4ac99467..6f93c4c44184d 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create4.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create4.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cvt-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cvt-bfloat.c new file mode 100644 index 0000000000000..dea8e20dc267c --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cvt-bfloat.c @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svcvt_bf16_f32_x(svbool_t pg, svfloat32_t op) { + // CHECK-LABEL: test_svcvt_bf16_f32_x + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcvt.bf16f32( undef, %[[PG]], %op) + // CHECK: ret %[[INTRINSIC]] + return SVE_ACLE_FUNC(svcvt_bf16, _f32, _x, )(pg, op); +} + +svbfloat16_t test_svcvt_bf16_f32_z(svbool_t pg, svfloat32_t op) { + // CHECK-LABEL: test_svcvt_bf16_f32_z + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcvt.bf16f32( zeroinitializer, %[[PG]], %op) + // CHECK: ret %[[INTRINSIC]] + return SVE_ACLE_FUNC(svcvt_bf16, _f32, _z, )(pg, op); +} + +svbfloat16_t test_svcvt_bf16_f32_m(svbfloat16_t inactive, svbool_t pg, svfloat32_t op) { + // CHECK-LABEL: test_svcvt_bf16_f32_m + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcvt.bf16f32( %inactive, %[[PG]], %op) + // CHECK: ret %[[INTRINSIC]] + return SVE_ACLE_FUNC(svcvt_bf16, _f32, _m, )(inactive, pg, op); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cvt.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cvt.c index f6c01cd6bfe66..58ced24326b0e 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cvt.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cvt.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cvtnt.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cvtnt.c new file mode 100644 index 0000000000000..b5828227cac46 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cvtnt.c @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svcvtnt_bf16_f32_x(svbfloat16_t even, svbool_t pg, svfloat32_t op) { + // CHECK-LABEL: test_svcvtnt_bf16_f32_x + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcvtnt.bf16f32( %even, %[[PG]], %op) + // CHECK: ret %[[INTRINSIC]] + return SVE_ACLE_FUNC(svcvtnt_bf16, _f32, _x, )(even, pg, op); +} + +svbfloat16_t test_svcvtnt_bf16_f32_m(svbfloat16_t even, svbool_t pg, svfloat32_t op) { + // CHECK-LABEL: test_svcvtnt_bf16_f32_m + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.fcvtnt.bf16f32( %even, %[[PG]], %op) + // CHECK: ret %[[INTRINSIC]] + return SVE_ACLE_FUNC(svcvtnt_bf16, _f32, _m, )(even, pg, op); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_div.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_div.c index 0d8c1156a709b..e388e5c1271ca 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_div.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_div.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_divr.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_divr.c index 2239441295ffe..462099ba6398f 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_divr.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_divr.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_dot.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_dot.c index 7c5ee85afad30..2533662be82b2 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_dot.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_dot.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_dup-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_dup-bfloat.c new file mode 100644 index 0000000000000..7ef02c3330e97 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_dup-bfloat.c @@ -0,0 +1,63 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svdup_n_bf16(bfloat16_t op) { + // CHECK-LABEL: test_svdup_n_bf16 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.dup.x.nxv8bf16(bfloat %op) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svdup_n_bf16'}} + return SVE_ACLE_FUNC(svdup, _n, _bf16, )(op); +} + +svbfloat16_t test_svdup_n_bf16_z(svbool_t pg, bfloat16_t op) { + // CHECK-LABEL: test_svdup_n_bf16_z + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.dup.nxv8bf16( zeroinitializer, %[[PG]], bfloat %op) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svdup_n_bf16_z'}} + return SVE_ACLE_FUNC(svdup, _n, _bf16_z, )(pg, op); +} + +svbfloat16_t test_svdup_n_bf16_m(svbfloat16_t inactive, svbool_t pg, bfloat16_t op) { + // CHECK-LABEL: test_svdup_n_bf16_m + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.dup.nxv8bf16( %inactive, %[[PG]], bfloat %op) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svdup_n_bf16_m'}} + return SVE_ACLE_FUNC(svdup, _n, _bf16_m, )(inactive, pg, op); +} + +svbfloat16_t test_svdup_n_bf16_x(svbool_t pg, bfloat16_t op) { + // CHECK-LABEL: test_svdup_n_bf16_x + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.dup.nxv8bf16( undef, %[[PG]], bfloat %op) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svdup_n_bf16_x'}} + return SVE_ACLE_FUNC(svdup, _n, _bf16_x, )(pg, op); +} + +svbfloat16_t test_svdup_lane_bf16(svbfloat16_t data, uint16_t index) +{ + // CHECK-LABEL: test_svdup_lane_bf16 + // CHECK: %[[DUP:.*]] = call @llvm.aarch64.sve.dup.x.nxv8i16(i16 %index) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.tbl.nxv8bf16( %data, %[[DUP]]) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svdup_lane_bf16'}} + return SVE_ACLE_FUNC(svdup_lane,_bf16,,)(data, index); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_dup.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_dup.c index 9fb8cc6fabd19..5475d55564a63 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_dup.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_dup.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s - +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_dupq-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_dupq-bfloat.c new file mode 100644 index 0000000000000..66694789162c7 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_dupq-bfloat.c @@ -0,0 +1,42 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svdupq_lane_bf16(svbfloat16_t data, uint64_t index) { + // CHECK-LABEL: test_svdupq_lane_bf16 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.dupq.lane.nxv8bf16( %data, i64 %index) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svdupq_lane_bf16'}} + return SVE_ACLE_FUNC(svdupq_lane, _bf16, , )(data, index); +} +svbfloat16_t test_svdupq_n_bf16(bfloat16_t x0, bfloat16_t x1, bfloat16_t x2, bfloat16_t x3, + bfloat16_t x4, bfloat16_t x5, bfloat16_t x6, bfloat16_t x7) { + // CHECK-LABEL: test_svdupq_n_bf16 + // CHECK: %[[ALLOCA:.*]] = alloca [8 x bfloat], align 16 + // CHECK-DAG: %[[BASE:.*]] = getelementptr inbounds [8 x bfloat], [8 x bfloat]* %[[ALLOCA]], i64 0, i64 0 + // CHECK-DAG: store bfloat %x0, bfloat* %[[BASE]], align 16 + // + // CHECK-DAG: %[[GEP:.*]] = getelementptr inbounds [8 x bfloat], [8 x bfloat]* %[[ALLOCA]], i64 0, i64 7 + // CHECK: store bfloat %x7, bfloat* %[[GEP]], align 2 + // CHECK-NOT: store + // CHECK: call @llvm.aarch64.sve.ptrue.nxv8i1(i32 31) + // CHECK: %[[LOAD:.*]] = call @llvm.aarch64.sve.ld1rq.nxv8bf16( %{{.*}}, bfloat* nonnull %[[BASE]]) + // CHECK: ret %[[LOAD]] + // expected-warning@+1 {{implicit declaration of function 'svdupq_n_bf16'}} + return SVE_ACLE_FUNC(svdupq, _n, _bf16, )(x0, x1, x2, x3, x4, x5, x6, x7); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_dupq.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_dupq.c index 7393ef705e523..d604d13356e53 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_dupq.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_dupq.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_eor.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_eor.c index 88e1a1b38d092..bcc0333c67585 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_eor.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_eor.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_eorv.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_eorv.c index 3398c6611f40c..69db72c2c2ece 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_eorv.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_eorv.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_expa.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_expa.c index dfe56d5eadf10..96fbb9c705655 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_expa.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_expa.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ext-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ext-bfloat.c new file mode 100644 index 0000000000000..6ed1d36cf30ea --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ext-bfloat.c @@ -0,0 +1,26 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svext_bf16(svbfloat16_t op1, svbfloat16_t op2) +{ + // CHECK-LABEL: test_svext_bf16 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ext.nxv8bf16( %op1, %op2, i32 127) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svext_bf16'}} + return SVE_ACLE_FUNC(svext,_bf16,,)(op1, op2, 127); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ext.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ext.c index 7091e351fa817..7b970637eed08 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ext.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ext.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_extb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_extb.c index 2e9ce0006d840..4e07f241c799a 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_extb.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_extb.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_exth.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_exth.c index 28f5084892acf..074feed23e83a 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_exth.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_exth.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_extw.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_extw.c index 043f9ed4f468b..ec07bb59cf1d9 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_extw.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_extw.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get2-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get2-bfloat.c new file mode 100644 index 0000000000000..cd585cc867e4d --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get2-bfloat.c @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svget2_bf16_0(svbfloat16x2_t tuple) +{ + // CHECK-LABEL: test_svget2_bf16_0 + // CHECK: %[[EXT:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv16bf16( %tuple, i32 0) + // CHECK-NEXT: ret %[[EXT]] + // expected-warning@+1 {{implicit declaration of function 'svget2_bf16'}} + return SVE_ACLE_FUNC(svget2,_bf16,,)(tuple, 0); +} + +svbfloat16_t test_svget2_bf16_1(svbfloat16x2_t tuple) +{ + // CHECK-LABEL: test_svget2_bf16_1 + // CHECK: %[[EXT:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv16bf16( %tuple, i32 1) + // CHECK-NEXT: ret %[[EXT]] + // expected-warning@+1 {{implicit declaration of function 'svget2_bf16'}} + return SVE_ACLE_FUNC(svget2,_bf16,,)(tuple, 1); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get2.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get2.c index b05612bb7c607..7beb191cab30f 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get2.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get2.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get3-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get3-bfloat.c new file mode 100644 index 0000000000000..ae9bc08eac113 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get3-bfloat.c @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svget3_bf16_0(svbfloat16x3_t tuple) +{ + // CHECK-LABEL: test_svget3_bf16_0 + // CHECK: %[[EXT:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv24bf16( %tuple, i32 0) + // CHECK-NEXT: ret %[[EXT]] + // expected-warning@+1 {{implicit declaration of function 'svget3_bf16'}} + return SVE_ACLE_FUNC(svget3,_bf16,,)(tuple, 0); +} + +svbfloat16_t test_svget3_bf16_1(svbfloat16x3_t tuple) +{ + // CHECK-LABEL: test_svget3_bf16_1 + // CHECK: %[[EXT:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv24bf16( %tuple, i32 1) + // CHECK-NEXT: ret %[[EXT]] + // expected-warning@+1 {{implicit declaration of function 'svget3_bf16'}} + return SVE_ACLE_FUNC(svget3,_bf16,,)(tuple, 1); +} + +svbfloat16_t test_svget3_bf16_2(svbfloat16x3_t tuple) +{ + // CHECK-LABEL: test_svget3_bf16_2 + // CHECK: %[[EXT:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv24bf16( %tuple, i32 2) + // CHECK-NEXT: ret %[[EXT]] + // expected-warning@+1 {{implicit declaration of function 'svget3_bf16'}} + return SVE_ACLE_FUNC(svget3,_bf16,,)(tuple, 2); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get3.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get3.c index 4b788919055f8..63e17c3e1e0fd 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get3.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get3.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get4-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get4-bfloat.c new file mode 100644 index 0000000000000..4d5eb50e1b2ad --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get4-bfloat.c @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svget4_bf16_0(svbfloat16x4_t tuple) +{ + // CHECK-LABEL: test_svget4_bf16_0 + // CHECK: %[[EXT:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv32bf16( %tuple, i32 0) + // CHECK-NEXT: ret %[[EXT]] + // expected-warning@+1 {{implicit declaration of function 'svget4_bf16'}} + return SVE_ACLE_FUNC(svget4,_bf16,,)(tuple, 0); +} + +svbfloat16_t test_svget4_bf16_1(svbfloat16x4_t tuple) +{ + // CHECK-LABEL: test_svget4_bf16_1 + // CHECK: %[[EXT:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv32bf16( %tuple, i32 1) + // CHECK-NEXT: ret %[[EXT]] + // expected-warning@+1 {{implicit declaration of function 'svget4_bf16'}} + return SVE_ACLE_FUNC(svget4,_bf16,,)(tuple, 1); +} + +svbfloat16_t test_svget4_bf16_2(svbfloat16x4_t tuple) +{ + // CHECK-LABEL: test_svget4_bf16_2 + // CHECK: %[[EXT:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv32bf16( %tuple, i32 2) + // CHECK-NEXT: ret %[[EXT]] + // expected-warning@+1 {{implicit declaration of function 'svget4_bf16'}} + return SVE_ACLE_FUNC(svget4,_bf16,,)(tuple, 2); +} + +svbfloat16_t test_svget4_bf16_3(svbfloat16x4_t tuple) +{ + // CHECK-LABEL: test_svget4_bf16_3 + // CHECK: %[[EXT:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv32bf16( %tuple, i32 3) + // CHECK-NEXT: ret %[[EXT]] + // expected-warning@+1 {{implicit declaration of function 'svget4_bf16'}} + return SVE_ACLE_FUNC(svget4,_bf16,,)(tuple, 3); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get4.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get4.c index c4ce575eac424..a34f41ff3b40a 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get4.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get4.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_index.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_index.c index d7241d1c014d2..f4d8478ec83ea 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_index.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_index.c @@ -1,5 +1,10 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include svint8_t test_svindex_s8(int8_t base, int8_t step) diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_insr-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_insr-bfloat.c new file mode 100644 index 0000000000000..9d1b4672d587d --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_insr-bfloat.c @@ -0,0 +1,26 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svinsr_n_bf16(svbfloat16_t op1, bfloat16_t op2) { + // CHECK-LABEL: test_svinsr_n_bf16 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.insr.nxv8bf16( %op1, bfloat %op2) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svinsr_n_bf16'}} + return SVE_ACLE_FUNC(svinsr, _n_bf16, , )(op1, op2); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_insr.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_insr.c index ffa420b1ac5df..024b3a67d1c7a 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_insr.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_insr.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_lasta-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_lasta-bfloat.c new file mode 100644 index 0000000000000..d5cc626b9733d --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_lasta-bfloat.c @@ -0,0 +1,27 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4 +#endif + +bfloat16_t test_svlasta_bf16(svbool_t pg, svbfloat16_t op) { + // CHECK-LABEL: test_svlasta_bf16 + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call bfloat @llvm.aarch64.sve.lasta.nxv8bf16( %[[PG]], %op) + // CHECK: ret bfloat %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svlasta_bf16'}} + return SVE_ACLE_FUNC(svlasta, _bf16, , )(pg, op); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_lasta.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_lasta.c index 804b12a543b4c..fac57f7cde849 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_lasta.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_lasta.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_lastb-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_lastb-bfloat.c new file mode 100644 index 0000000000000..57f0e79424314 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_lastb-bfloat.c @@ -0,0 +1,27 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4 +#endif + +bfloat16_t test_svlastb_bf16(svbool_t pg, svbfloat16_t op) { + // CHECK-LABEL: test_svlastb_bf16 + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call bfloat @llvm.aarch64.sve.lastb.nxv8bf16( %[[PG]], %op) + // CHECK: ret bfloat %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svlastb_bf16'}} + return SVE_ACLE_FUNC(svlastb, _bf16, , )(pg, op); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_lastb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_lastb.c index 9cb60c49bacbd..cc16223f7de1b 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_lastb.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_lastb.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1-bfloat.c new file mode 100644 index 0000000000000..e85eced4b5a6b --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1-bfloat.c @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svld1_bf16(svbool_t pg, const bfloat16_t *base) +{ + // CHECK-LABEL: test_svld1_bf16 + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[LOAD:.*]] = call @llvm.aarch64.sve.ld1.nxv8bf16( %[[PG]], bfloat* %base) + // CHECK: ret %[[LOAD]] + // expected-warning@+1 {{implicit declaration of function 'svld1_bf16'}} + return SVE_ACLE_FUNC(svld1,_bf16,,)(pg, base); +} + +svbfloat16_t test_svld1_vnum_bf16(svbool_t pg, const bfloat16_t *base, int64_t vnum) +{ + // CHECK-LABEL: test_svld1_vnum_bf16 + // CHECK-DAG: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK-DAG: %[[BITCAST:.*]] = bitcast bfloat* %base to * + // CHECK-DAG: %[[GEP:.*]] = getelementptr , * %[[BITCAST]], i64 %vnum, i64 0 + // CHECK: %[[LOAD:.*]] = call @llvm.aarch64.sve.ld1.nxv8bf16( %[[PG]], bfloat* %[[GEP]]) + // CHECK: ret %[[LOAD]] + // expected-warning@+1 {{implicit declaration of function 'svld1_vnum_bf16'}} + return SVE_ACLE_FUNC(svld1_vnum,_bf16,,)(pg, base, vnum); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1.c index 690ae89c6459e..7b6d2f38b81dc 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1ro-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1ro-bfloat.c index 56137bd6c8a89..d9639a2c75b08 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1ro-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1ro-bfloat.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE_MATMUL_FP64 -D__ARM_FEATURE_BF16_SCALAR_ARITHMETIC -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE_MATMUL_FP64 -D__ARM_FEATURE_BF16_SCALAR_ARITHMETIC -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -target-feature +f64mm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -target-feature +f64mm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1ro.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1ro.c index 10608f2568320..bb4711943ad1e 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1ro.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1ro.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE_MATMUL_FP64 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE_MATMUL_FP64 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +f64mm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +f64mm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1rq-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1rq-bfloat.c new file mode 100644 index 0000000000000..bd5fdc6da7a97 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1rq-bfloat.c @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svld1rq_bf16(svbool_t pg, const bfloat16_t *base) +{ + // CHECK-LABEL: test_svld1rq_bf16 + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.ld1rq.nxv8bf16( %[[PG]], bfloat* %base) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svld1rq_bf16'}} + return SVE_ACLE_FUNC(svld1rq,_bf16,,)(pg, base); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1rq.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1rq.c index 2e143a5cf3c8e..51b703a041ab3 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1rq.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1rq.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1sb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1sb.c index 2bc64c714f0ed..7a108331c9404 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1sb.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1sb.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1sh.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1sh.c index 28d7ff448c90b..6475b19ab6533 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1sh.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1sh.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s - +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1sw.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1sw.c index 110af5122c78b..3f4db7aec2440 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1sw.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1sw.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s - +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1ub.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1ub.c index b0196a7066f0b..e3209fa8d9247 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1ub.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1ub.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1uh.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1uh.c index 9f371e795cf28..9219b687bd2cd 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1uh.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1uh.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s - +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1uw.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1uw.c index 28a0c94fa4a0e..1c2b48becbb93 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1uw.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1uw.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s - +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld2-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld2-bfloat.c new file mode 100644 index 0000000000000..171e320883223 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld2-bfloat.c @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbfloat16x2_t test_svld2_bf16(svbool_t pg, const bfloat16_t *base) +{ + // CHECK-LABEL: test_svld2_bf16 + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[LOAD:.*]] = call @llvm.aarch64.sve.ld2.nxv16bf16.nxv8i1( %[[PG]], bfloat* %base) + // CHECK-NEXT: ret %[[LOAD]] + return SVE_ACLE_FUNC(svld2,_bf16,,)(pg, base); +} + + +svbfloat16x2_t test_svld2_vnum_bf16(svbool_t pg, const bfloat16_t *base, int64_t vnum) +{ + // CHECK-LABEL: test_svld2_vnum_bf16 + // CHECK-DAG: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK-DAG: %[[BASE:.*]] = bitcast bfloat* %base to * + // CHECK-DAG: %[[GEP:.*]] = getelementptr , * %[[BASE]], i64 %vnum, i64 0 + // CHECK: %[[LOAD:.*]] = call @llvm.aarch64.sve.ld2.nxv16bf16.nxv8i1( %[[PG]], bfloat* %[[GEP]]) + // CHECK-NEXT: ret %[[LOAD]] + return SVE_ACLE_FUNC(svld2_vnum,_bf16,,)(pg, base, vnum); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld2.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld2.c index 96c298077cb65..e232366cf744d 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld2.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld2.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld3-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld3-bfloat.c new file mode 100644 index 0000000000000..94446e1041388 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld3-bfloat.c @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbfloat16x3_t test_svld3_bf16(svbool_t pg, const bfloat16_t *base) +{ + // CHECK-LABEL: test_svld3_bf16 + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[LOAD:.*]] = call @llvm.aarch64.sve.ld3.nxv24bf16.nxv8i1( %[[PG]], bfloat* %base) + // CHECK-NEXT: ret %[[LOAD]] + return SVE_ACLE_FUNC(svld3,_bf16,,)(pg, base); +} + +svbfloat16x3_t test_svld3_vnum_bf16(svbool_t pg, const bfloat16_t *base, int64_t vnum) +{ + // CHECK-LABEL: test_svld3_vnum_bf16 + // CHECK-DAG: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK-DAG: %[[BASE:.*]] = bitcast bfloat* %base to * + // CHECK-DAG: %[[GEP:.*]] = getelementptr , * %[[BASE]], i64 %vnum, i64 0 + // CHECK: %[[LOAD:.*]] = call @llvm.aarch64.sve.ld3.nxv24bf16.nxv8i1( %[[PG]], bfloat* %[[GEP]]) + // CHECK-NEXT: ret %[[LOAD]] + return SVE_ACLE_FUNC(svld3_vnum,_bf16,,)(pg, base, vnum); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld3.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld3.c index b9d72033844c5..c3251c9205826 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld3.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld3.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld4-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld4-bfloat.c new file mode 100644 index 0000000000000..953ebfb692262 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld4-bfloat.c @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbfloat16x4_t test_svld4_bf16(svbool_t pg, const bfloat16_t *base) +{ + // CHECK-LABEL: test_svld4_bf16 + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[LOAD:.*]] = call @llvm.aarch64.sve.ld4.nxv32bf16.nxv8i1( %[[PG]], bfloat* %base) + // CHECK-NEXT: ret %[[LOAD]] + return SVE_ACLE_FUNC(svld4,_bf16,,)(pg, base); +} + +svbfloat16x4_t test_svld4_vnum_bf16(svbool_t pg, const bfloat16_t *base, int64_t vnum) +{ + // CHECK-LABEL: test_svld4_vnum_bf16 + // CHECK-DAG: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK-DAG: %[[BASE:.*]] = bitcast bfloat* %base to * + // CHECK-DAG: %[[GEP:.*]] = getelementptr , * %[[BASE]], i64 %vnum, i64 0 + // CHECK: %[[LOAD:.*]] = call @llvm.aarch64.sve.ld4.nxv32bf16.nxv8i1( %[[PG]], bfloat* %[[GEP]]) + // CHECK-NEXT: ret %[[LOAD]] + return SVE_ACLE_FUNC(svld4_vnum,_bf16,,)(pg, base, vnum); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld4.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld4.c index 8d904b49dfdb6..60deeb3c08962 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld4.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld4.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1-bfloat.c new file mode 100644 index 0000000000000..7897a71ac2cc8 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1-bfloat.c @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svldff1_bf16(svbool_t pg, const bfloat16_t *base) +{ + // CHECK-LABEL: test_svldff1_bf16 + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[LOAD:.*]] = call @llvm.aarch64.sve.ldff1.nxv8bf16( %[[PG]], bfloat* %base) + // CHECK: ret %[[LOAD]] + // expected-warning@+1 {{implicit declaration of function 'svldff1_bf16'}} + return SVE_ACLE_FUNC(svldff1,_bf16,,)(pg, base); +} + +svbfloat16_t test_svldff1_vnum_bf16(svbool_t pg, const bfloat16_t *base, int64_t vnum) +{ + // CHECK-LABEL: test_svldff1_vnum_bf16 + // CHECK-DAG: %[[BITCAST:.*]] = bitcast bfloat* %base to * + // CHECK-DAG: %[[GEP:.*]] = getelementptr , * %[[BITCAST]], i64 %vnum, i64 0 + // CHECK-DAG: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[LOAD:.*]] = call @llvm.aarch64.sve.ldff1.nxv8bf16( %[[PG]], bfloat* %[[GEP]]) + // CHECK: ret %[[LOAD]] + // expected-warning@+1 {{implicit declaration of function 'svldff1_vnum_bf16'}} + return SVE_ACLE_FUNC(svldff1_vnum,_bf16,,)(pg, base, vnum); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1.c index 5363445a4f59b..0797cb3c7deba 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1sb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1sb.c index 6d5a964e1cf7e..0915a8ae49599 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1sb.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1sb.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1sh.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1sh.c index 3c60dcb8b2956..5c1fd27c3bbb9 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1sh.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1sh.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s - +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1sw.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1sw.c index 6c65979c32d40..b7892b96d0bbd 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1sw.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1sw.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s - +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1ub.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1ub.c index a6c117970877d..108980c190431 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1ub.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1ub.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1uh.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1uh.c index b335f3184d4c9..2a267e8301c83 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1uh.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1uh.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s - +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1uw.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1uw.c index 0b47a0630d58a..6865c3ee6258b 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1uw.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1uw.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s - +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1-bfloat.c new file mode 100644 index 0000000000000..438e5d196cf73 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1-bfloat.c @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svldnf1_bf16(svbool_t pg, const bfloat16_t *base) +{ + // CHECK-LABEL: test_svldnf1_bf16 + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[LOAD:.*]] = call @llvm.aarch64.sve.ldnf1.nxv8bf16( %[[PG]], bfloat* %base) + // CHECK: ret %[[LOAD]] + // expected-warning@+1 {{implicit declaration of function 'svldnf1_bf16'}} + return SVE_ACLE_FUNC(svldnf1,_bf16,,)(pg, base); +} + +svbfloat16_t test_svldnf1_vnum_bf16(svbool_t pg, const bfloat16_t *base, int64_t vnum) +{ + // CHECK-LABEL: test_svldnf1_vnum_bf16 + // CHECK-DAG: %[[BITCAST:.*]] = bitcast bfloat* %base to * + // CHECK-DAG: %[[GEP:.*]] = getelementptr , * %[[BITCAST]], i64 %vnum, i64 0 + // CHECK-DAG: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[LOAD:.*]] = call @llvm.aarch64.sve.ldnf1.nxv8bf16( %[[PG]], bfloat* %[[GEP]]) + // CHECK: ret %[[LOAD]] + // expected-warning@+1 {{implicit declaration of function 'svldnf1_vnum_bf16'}} + return SVE_ACLE_FUNC(svldnf1_vnum,_bf16,,)(pg, base, vnum); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1.c index bac5a26c249e4..55343bc803f13 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1sb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1sb.c index 274fe4249e355..841da37bc12f9 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1sb.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1sb.c @@ -1,5 +1,10 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include svint16_t test_svldnf1sb_s16(svbool_t pg, const int8_t *base) diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1sh.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1sh.c index d57fa1fd11104..e5a1666abd600 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1sh.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1sh.c @@ -1,5 +1,10 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include svint32_t test_svldnf1sh_s32(svbool_t pg, const int16_t *base) diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1sw.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1sw.c index 5c70e3068c62a..addb6825aa373 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1sw.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1sw.c @@ -1,5 +1,10 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include svint64_t test_svldnf1sw_s64(svbool_t pg, const int32_t *base) diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1ub.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1ub.c index 19b316d8774d0..63ea57c43c550 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1ub.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1ub.c @@ -1,5 +1,10 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include svint16_t test_svldnf1ub_s16(svbool_t pg, const uint8_t *base) diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1uh.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1uh.c index 260bcb2e81a7e..3d70bba7f7d49 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1uh.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1uh.c @@ -1,5 +1,10 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include svint32_t test_svldnf1uh_s32(svbool_t pg, const uint16_t *base) diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1uw.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1uw.c index 011440da933f9..685a563c99ffe 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1uw.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1uw.c @@ -1,5 +1,10 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include svint64_t test_svldnf1uw_s64(svbool_t pg, const uint32_t *base) diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnt1-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnt1-bfloat.c new file mode 100644 index 0000000000000..db61ea68308ea --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnt1-bfloat.c @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svldnt1_bf16(svbool_t pg, const bfloat16_t *base) +{ + // CHECK-LABEL: test_svldnt1_bf16 + // CHECK-DAG: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[LOAD:.*]] = call @llvm.aarch64.sve.ldnt1.nxv8bf16( %[[PG]], bfloat* %base) + // CHECK: ret %[[LOAD]] + // expected-warning@+1 {{implicit declaration of function 'svldnt1_bf16'}} + return SVE_ACLE_FUNC(svldnt1,_bf16,,)(pg, base); +} + +svbfloat16_t test_svldnt1_vnum_bf16(svbool_t pg, const bfloat16_t *base, int64_t vnum) +{ + // CHECK-LABEL: test_svldnt1_vnum_bf16 + // CHECK-DAG: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK-DAG: %[[BITCAST:.*]] = bitcast bfloat* %base to * + // CHECK-DAG: %[[GEP:.*]] = getelementptr , * %[[BITCAST]], i64 %vnum, i64 0 + // CHECK: %[[LOAD:.*]] = call @llvm.aarch64.sve.ldnt1.nxv8bf16( %[[PG]], bfloat* %[[GEP]]) + // CHECK: ret %[[LOAD]] + // expected-warning@+1 {{implicit declaration of function 'svldnt1_vnum_bf16'}} + return SVE_ACLE_FUNC(svldnt1_vnum,_bf16,,)(pg, base, vnum); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnt1.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnt1.c index 6806e2589bdfb..71685d899c034 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnt1.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnt1.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_len-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_len-bfloat.c new file mode 100644 index 0000000000000..c084590039b3f --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_len-bfloat.c @@ -0,0 +1,27 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +uint64_t test_svlen_bf16(svbfloat16_t op) +{ + // CHECK-LABEL: test_svlen_bf16 + // CHECK: %[[VSCALE:.*]] = call i64 @llvm.vscale.i64() + // CHECK: %[[SHL:.*]] = shl i64 %[[VSCALE]], 3 + // CHECK: ret i64 %[[SHL]] + // expected-warning@+1 {{implicit declaration of function 'svlen_bf16'}} + return SVE_ACLE_FUNC(svlen,_bf16,,)(op); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_len.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_len.c index 1d096dfd9cc7d..55fb6a4f5fea9 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_len.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_len.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_lsl.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_lsl.c index d44b79864bebd..dc0bf2587ac00 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_lsl.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_lsl.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_lsr.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_lsr.c index e64913a60670f..5271b38e4cf9b 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_lsr.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_lsr.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mad.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mad.c index d53382b98ffb8..0483884cb1343 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mad.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mad.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_matmul_fp32.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_matmul_fp32.c index 422115c7aba5e..4ad3ed39a6d4a 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_matmul_fp32.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_matmul_fp32.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE_MATMUL_FP32 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE_MATMUL_FP32 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +f32mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +f32mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_matmul_fp64.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_matmul_fp64.c index e918d271e53ba..e287734f1afe9 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_matmul_fp64.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_matmul_fp64.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE_MATMUL_FP64 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE_MATMUL_FP64 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_max.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_max.c index 8759057aed2ec..9526a37357d48 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_max.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_max.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_maxnm.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_maxnm.c index a6dd6eab6738e..0646356b40a8f 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_maxnm.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_maxnm.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_maxnmv.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_maxnmv.c index 3d057a887c225..ea79022775e13 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_maxnmv.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_maxnmv.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_maxv.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_maxv.c index a488c17e9df7f..8d33b78378d46 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_maxv.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_maxv.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_min.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_min.c index 4fccd76389733..7966b57d9edf2 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_min.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_min.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_minnm.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_minnm.c index 2aab3a138f92e..2957e8c5952de 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_minnm.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_minnm.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_minnmv.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_minnmv.c index ca414449c0010..273e197b1e098 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_minnmv.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_minnmv.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_minv.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_minv.c index 42b1462367746..466b90af12714 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_minv.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_minv.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mla.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mla.c index 301a49c5fdbea..d187b79cbcc7b 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mla.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mla.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mls.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mls.c index 2c2c99025ae8b..e50d4bceb4c02 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mls.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mls.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mmla.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mmla.c index 8259bc0aa9a29..642cb1ca3ffa3 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mmla.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mmla.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE_MATMUL_INT8 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE_MATMUL_INT8 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +i8mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +i8mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mov.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mov.c index 76ea092c38faf..88d4e9b5a2e77 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mov.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mov.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_msb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_msb.c index f3aa553bc0860..c4fef3a4439da 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_msb.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_msb.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mul.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mul.c index e44a7b3b1fc02..804eac56608dd 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mul.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mul.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mulh.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mulh.c index 0384edeb27b0a..c899a08f9ff31 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mulh.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mulh.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mulx.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mulx.c index 0cbf5fa20e9cc..2e8a9c78b0d7a 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mulx.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mulx.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_nand.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_nand.c index e2db5919db394..450a493ee52cc 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_nand.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_nand.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_neg.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_neg.c index 1e3a697733729..5cf52196c1d04 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_neg.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_neg.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_nmad.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_nmad.c index c9432b5a562fc..f9a96f5bdf683 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_nmad.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_nmad.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_nmla.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_nmla.c index 8613f7ba6a16b..7db8e950d8733 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_nmla.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_nmla.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_nmls.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_nmls.c index 4af2c079f45a5..892da2b9254a6 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_nmls.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_nmls.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_nmsb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_nmsb.c index 9b6149273099b..5792cb2e66e2d 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_nmsb.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_nmsb.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_nor.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_nor.c index 482b6ace99d50..ff2d8a67907e0 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_nor.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_nor.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_not.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_not.c index f6ba6b5fef299..43773ef21c9d9 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_not.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_not.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_orn.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_orn.c index 40b5dbd2ad0d0..21156ef6cbe50 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_orn.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_orn.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_orr.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_orr.c index 8a4c226e06dba..df64dce6aa57b 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_orr.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_orr.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_orv.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_orv.c index e0810eff8f198..be15713f374c3 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_orv.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_orv.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_pfalse.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_pfalse.c index 8702ea7c85b7f..1131978933278 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_pfalse.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_pfalse.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_pfirst.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_pfirst.c index 2de1daed744c8..1486e948fa95b 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_pfirst.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_pfirst.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_pnext.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_pnext.c index 2bc17afe12334..4d023fa34b8ff 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_pnext.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_pnext.c @@ -1,5 +1,10 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include svbool_t test_svpnext_b8(svbool_t pg, svbool_t op) diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfb.c index 4928ab87c070d..93aef4a5b4b06 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfb.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfb.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfd.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfd.c index d2bcb9b7f413d..454b149199556 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfd.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfd.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfh.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfh.c index ce0131f6ccb60..3b9f0b9050f11 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfh.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfh.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfw.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfw.c index 775ebeb7ef9f6..53151a4c4b183 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfw.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfw.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ptest.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ptest.c index 6290e47658253..b4ca9fa0000e9 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ptest.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ptest.c @@ -1,6 +1,6 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ptrue.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ptrue.c index f5a9ee8ec2825..98ea771ddf54f 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ptrue.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ptrue.c @@ -1,5 +1,10 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include svbool_t test_svptrue_b8() diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qadd.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qadd.c index 10e79ab7fa4cc..634be9daf3fb1 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qadd.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qadd.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qdecb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qdecb.c index 26f09adac4fb3..507db3aab27f3 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qdecb.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qdecb.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qdecd.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qdecd.c index d69102e34ef28..7aad6fa51e5e2 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qdecd.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qdecd.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qdech.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qdech.c index 1725cb4c8063c..6eb5e467f0f89 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qdech.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qdech.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qdecp.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qdecp.c index 08298f72c029a..2cd4f75f578fd 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qdecp.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qdecp.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qdecw.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qdecw.c index 3f318020228d9..532a57a6bae1d 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qdecw.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qdecw.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qincb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qincb.c index 2ae1c8aa1fd1e..7494af867da58 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qincb.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qincb.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qincd.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qincd.c index ac60f02c7d043..3780f5190d81b 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qincd.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qincd.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qinch.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qinch.c index a0ea4fa9c6496..25984e4d0b63f 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qinch.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qinch.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qincp.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qincp.c index 4052e309c00b6..2b1a0097eae94 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qincp.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qincp.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qincw.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qincw.c index 3f7cd70b64b0c..13787b5bf4ca0 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qincw.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qincw.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qsub.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qsub.c index b19bbf53d4330..48219a45e51a9 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qsub.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_qsub.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rbit.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rbit.c index b8a2973ddb2ec..a3e4f67a93ac4 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rbit.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rbit.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rdffr.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rdffr.c index 3e43b940402ff..dd4d6de5d6f7a 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rdffr.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rdffr.c @@ -1,6 +1,6 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_recpe.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_recpe.c index 7b4c5b8c7b864..644afb130195e 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_recpe.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_recpe.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_recps.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_recps.c index b35f3b5546e45..2e170fa506fb9 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_recps.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_recps.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_recpx.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_recpx.c index a375a2865d2a8..e9d19c8bf14fa 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_recpx.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_recpx.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret-bfloat.c new file mode 100644 index 0000000000000..90547a09b6e4e --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret-bfloat.c @@ -0,0 +1,177 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4 +#endif + +svint8_t test_svreinterpret_s8_bf16(svbfloat16_t op) { + // CHECK-LABEL: test_svreinterpret_s8_bf16 + // CHECK: %[[CAST:.*]] = bitcast %op to + // CHECK: ret %[[CAST]] + return SVE_ACLE_FUNC(svreinterpret_s8, _bf16, , )(op); +} + +svint16_t test_svreinterpret_s16_bf16(svbfloat16_t op) { + // CHECK-LABEL: test_svreinterpret_s16_bf16 + // CHECK: %[[CAST:.*]] = bitcast %op to + // CHECK: ret %[[CAST]] + return SVE_ACLE_FUNC(svreinterpret_s16, _bf16, , )(op); +} + +svint32_t test_svreinterpret_s32_bf16(svbfloat16_t op) { + // CHECK-LABEL: test_svreinterpret_s32_bf16 + // CHECK: %[[CAST:.*]] = bitcast %op to + // CHECK: ret %[[CAST]] + return SVE_ACLE_FUNC(svreinterpret_s32, _bf16, , )(op); +} +svint64_t test_svreinterpret_s64_bf16(svbfloat16_t op) { + // CHECK-LABEL: test_svreinterpret_s64_bf16 + // CHECK: %[[CAST:.*]] = bitcast %op to + // CHECK: ret %[[CAST]] + return SVE_ACLE_FUNC(svreinterpret_s64, _bf16, , )(op); +} + +svuint8_t test_svreinterpret_u8_bf16(svbfloat16_t op) { + // CHECK-LABEL: test_svreinterpret_u8_bf16 + // CHECK: %[[CAST:.*]] = bitcast %op to + // CHECK: ret %[[CAST]] + return SVE_ACLE_FUNC(svreinterpret_u8, _bf16, , )(op); +} + +svuint16_t test_svreinterpret_u16_bf16(svbfloat16_t op) { + // CHECK-LABEL: test_svreinterpret_u16_bf16 + // CHECK: %[[CAST:.*]] = bitcast %op to + // CHECK: ret %[[CAST]] + return SVE_ACLE_FUNC(svreinterpret_u16, _bf16, , )(op); +} + +svuint32_t test_svreinterpret_u32_bf16(svbfloat16_t op) { + // CHECK-LABEL: test_svreinterpret_u32_bf16 + // CHECK: %[[CAST:.*]] = bitcast %op to + // CHECK: ret %[[CAST]] + return SVE_ACLE_FUNC(svreinterpret_u32, _bf16, , )(op); +} + +svuint64_t test_svreinterpret_u64_bf16(svbfloat16_t op) { + // CHECK-LABEL: test_svreinterpret_u64_bf16 + // CHECK: %[[CAST:.*]] = bitcast %op to + // CHECK: ret %[[CAST]] + return SVE_ACLE_FUNC(svreinterpret_u64, _bf16, , )(op); +} + +svbfloat16_t test_svreinterpret_bf16_s8(svint8_t op) { + // CHECK-LABEL: test_svreinterpret_bf16_s8 + // CHECK: %[[CAST:.*]] = bitcast %op to + // CHECK: ret %[[CAST]] + return SVE_ACLE_FUNC(svreinterpret_bf16, _s8, , )(op); +} + +svbfloat16_t test_svreinterpret_bf16_s16(svint16_t op) { + // CHECK-LABEL: test_svreinterpret_bf16_s16 + // CHECK: %[[CAST:.*]] = bitcast %op to + // CHECK: ret %[[CAST]] + return SVE_ACLE_FUNC(svreinterpret_bf16, _s16, , )(op); +} + +svbfloat16_t test_svreinterpret_bf16_s32(svint32_t op) { + // CHECK-LABEL: test_svreinterpret_bf16_s32 + // CHECK: %[[CAST:.*]] = bitcast %op to + // CHECK: ret %[[CAST]] + return SVE_ACLE_FUNC(svreinterpret_bf16, _s32, , )(op); +} + +svbfloat16_t test_svreinterpret_bf16_s64(svint64_t op) { + // CHECK-LABEL: test_svreinterpret_bf16_s64 + // CHECK: %[[CAST:.*]] = bitcast %op to + // CHECK: ret %[[CAST]] + return SVE_ACLE_FUNC(svreinterpret_bf16, _s64, , )(op); +} + +svbfloat16_t test_svreinterpret_bf16_u8(svuint8_t op) { + // CHECK-LABEL: test_svreinterpret_bf16_u8 + // CHECK: %[[CAST:.*]] = bitcast %op to + // CHECK: ret %[[CAST]] + return SVE_ACLE_FUNC(svreinterpret_bf16, _u8, , )(op); +} + +svbfloat16_t test_svreinterpret_bf16_u16(svuint16_t op) { + // CHECK-LABEL: test_svreinterpret_bf16_u16 + // CHECK: %[[CAST:.*]] = bitcast %op to + // CHECK: ret %[[CAST]] + return SVE_ACLE_FUNC(svreinterpret_bf16, _u16, , )(op); +} + +svbfloat16_t test_svreinterpret_bf16_u32(svuint32_t op) { + // CHECK-LABEL: test_svreinterpret_bf16_u32 + // CHECK: %[[CAST:.*]] = bitcast %op to + // CHECK: ret %[[CAST]] + return SVE_ACLE_FUNC(svreinterpret_bf16, _u32, , )(op); +} + +svbfloat16_t test_svreinterpret_bf16_u64(svuint64_t op) { + // CHECK-LABEL: test_svreinterpret_bf16_u64 + // CHECK: %[[CAST:.*]] = bitcast %op to + // CHECK: ret %[[CAST]] + return SVE_ACLE_FUNC(svreinterpret_bf16, _u64, , )(op); +} + +svbfloat16_t test_svreinterpret_bf16_bf16(svbfloat16_t op) { + // CHECK-LABEL: test_svreinterpret_bf16_bf16 + // CHECK: ret %op + return SVE_ACLE_FUNC(svreinterpret_bf16, _bf16, , )(op); +} + +svbfloat16_t test_svreinterpret_bf16_f16(svfloat16_t op) { + // CHECK-LABEL: test_svreinterpret_bf16_f16 + // CHECK: %[[CAST:.*]] = bitcast %op to + // CHECK: ret %[[CAST]] + return SVE_ACLE_FUNC(svreinterpret_bf16, _f16, , )(op); +} + +svbfloat16_t test_svreinterpret_bf16_f32(svfloat32_t op) { + // CHECK-LABEL: test_svreinterpret_bf16_f32 + // CHECK: %[[CAST:.*]] = bitcast %op to + // CHECK: ret %[[CAST]] + return SVE_ACLE_FUNC(svreinterpret_bf16, _f32, , )(op); +} + +svbfloat16_t test_svreinterpret_bf16_f64(svfloat64_t op) { + // CHECK-LABEL: test_svreinterpret_bf16_f64 + // CHECK: %[[CAST:.*]] = bitcast %op to + // CHECK: ret %[[CAST]] + return SVE_ACLE_FUNC(svreinterpret_bf16, _f64, , )(op); +} + +svfloat32_t test_svreinterpret_f32_bf16(svbfloat16_t op) { + // CHECK-LABEL: test_svreinterpret_f32_bf16 + // CHECK: %[[CAST:.*]] = bitcast %op to + // CHECK: ret %[[CAST]] + return SVE_ACLE_FUNC(svreinterpret_f32, _bf16, , )(op); +} + +svfloat16_t test_svreinterpret_f16_bf16(svbfloat16_t op) { + // CHECK-LABEL: test_svreinterpret_f16_bf16 + // CHECK: %[[CAST:.*]] = bitcast %op to + // CHECK: ret %[[CAST]] + return SVE_ACLE_FUNC(svreinterpret_f16, _bf16, , )(op); +} + +svfloat64_t test_svreinterpret_f64_bf16(svbfloat16_t op) { + // CHECK-LABEL: test_svreinterpret_f64_bf16 + // CHECK: %[[CAST:.*]] = bitcast %op to + // CHECK: ret %[[CAST]] + return SVE_ACLE_FUNC(svreinterpret_f64, _bf16, , )(op); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret.c index 20abbabaeed22..0a50057fbc2a0 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_reinterpret.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rev-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rev-bfloat.c new file mode 100644 index 0000000000000..1feab6ed6ec90 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rev-bfloat.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svrev_bf16(svbfloat16_t op) +{ + // CHECK-LABEL: test_svrev_bf16 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.rev.nxv8bf16( %op) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svrev_bf16'}} + return SVE_ACLE_FUNC(svrev,_bf16,,)(op); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rev.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rev.c index fa275a8fab4ff..f48c6c71f4961 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rev.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rev.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s - +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_revb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_revb.c index 2cf1c211cab1b..a61519f2930f0 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_revb.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_revb.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_revh.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_revh.c index 1b72508cae859..aef91d64fcbdf 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_revh.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_revh.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_revw.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_revw.c index db8b596426374..99ed94f8854ba 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_revw.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_revw.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rinta.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rinta.c index bcee6301ef065..4cc978ed9fddf 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rinta.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rinta.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rinti.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rinti.c index febcb87e74d31..f595cdb13449b 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rinti.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rinti.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rintm.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rintm.c index d781a130204fa..40db460ea6e76 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rintm.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rintm.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rintn.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rintn.c index ba89f486190ca..73a7a2f68fab1 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rintn.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rintn.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rintp.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rintp.c index eefdaea5d93aa..f014b3d3549a8 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rintp.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rintp.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rintx.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rintx.c index a87be65edee2b..f54d704181041 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rintx.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rintx.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rintz.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rintz.c index 3a6b120e90573..328b8375748b5 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rintz.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rintz.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rsqrte.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rsqrte.c index ae2bb3c357133..fb56c377a8b50 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rsqrte.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rsqrte.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rsqrts.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rsqrts.c index 5dd5c909afb58..143461f235608 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rsqrts.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rsqrts.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_scale.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_scale.c index 74d70482ee0f7..2ff293bdd88c5 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_scale.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_scale.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_sel-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_sel-bfloat.c new file mode 100644 index 0000000000000..d803d2ffdf4d7 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_sel-bfloat.c @@ -0,0 +1,27 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svsel_bf16(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) +{ + // CHECK-LABEL: test_svsel_bf16 + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.sel.nxv8bf16( %[[PG]], %op1, %op2) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svsel_bf16'}} + return SVE_ACLE_FUNC(svsel,_bf16,,)(pg, op1, op2); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_sel.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_sel.c index aeedcdf970cfe..30b0d4dfa38a5 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_sel.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_sel.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set2-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set2-bfloat.c new file mode 100644 index 0000000000000..b44d6264a711e --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set2-bfloat.c @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbfloat16x2_t test_svset2_bf16_0(svbfloat16x2_t tuple, svbfloat16_t x) +{ + // CHECK-LABEL: test_svset2_bf16_0 + // CHECK: %[[INSERT:.*]] = call @llvm.aarch64.sve.tuple.set.nxv16bf16.nxv8bf16( %tuple, i32 0, %x) + // CHECK-NEXT: ret %[[INSERT]] + // expected-warning@+1 {{implicit declaration of function 'svset2_bf16'}} + return SVE_ACLE_FUNC(svset2,_bf16,,)(tuple, 0, x); +} + +svbfloat16x2_t test_svset2_bf16_1(svbfloat16x2_t tuple, svbfloat16_t x) +{ + // CHECK-LABEL: test_svset2_bf16_1 + // CHECK: %[[INSERT:.*]] = call @llvm.aarch64.sve.tuple.set.nxv16bf16.nxv8bf16( %tuple, i32 1, %x) + // CHECK-NEXT: ret %[[INSERT]] + // expected-warning@+1 {{implicit declaration of function 'svset2_bf16'}} + return SVE_ACLE_FUNC(svset2,_bf16,,)(tuple, 1, x); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set2.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set2.c index dc41543a4e835..9be45026d40c2 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set2.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set2.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set3-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set3-bfloat.c new file mode 100644 index 0000000000000..1d5881d074e76 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set3-bfloat.c @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + + +svbfloat16x3_t test_svset3_bf16_0(svbfloat16x3_t tuple, svbfloat16_t x) +{ + // CHECK-LABEL: test_svset3_bf16_0 + // CHECK: %[[INSERT:.*]] = call @llvm.aarch64.sve.tuple.set.nxv24bf16.nxv8bf16( %tuple, i32 0, %x) + // CHECK-NEXT: ret %[[INSERT]] + // expected-warning@+1 {{implicit declaration of function 'svset3_bf16'}} + return SVE_ACLE_FUNC(svset3,_bf16,,)(tuple, 0, x); +} + +svbfloat16x3_t test_svset3_bf16_1(svbfloat16x3_t tuple, svbfloat16_t x) +{ + // CHECK-LABEL: test_svset3_bf16_1 + // CHECK: %[[INSERT:.*]] = call @llvm.aarch64.sve.tuple.set.nxv24bf16.nxv8bf16( %tuple, i32 1, %x) + // CHECK-NEXT: ret %[[INSERT]] + // expected-warning@+1 {{implicit declaration of function 'svset3_bf16'}} + return SVE_ACLE_FUNC(svset3,_bf16,,)(tuple, 1, x); +} + +svbfloat16x3_t test_svset3_bf16_2(svbfloat16x3_t tuple, svbfloat16_t x) +{ + // CHECK-LABEL: test_svset3_bf16_2 + // CHECK: %[[INSERT:.*]] = call @llvm.aarch64.sve.tuple.set.nxv24bf16.nxv8bf16( %tuple, i32 2, %x) + // CHECK-NEXT: ret %[[INSERT]] + // expected-warning@+1 {{implicit declaration of function 'svset3_bf16'}} + return SVE_ACLE_FUNC(svset3,_bf16,,)(tuple, 2, x); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set3.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set3.c index 77fd69bbbbc2e..0f59a389e0d19 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set3.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set3.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set4-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set4-bfloat.c new file mode 100644 index 0000000000000..b824cace2b78b --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set4-bfloat.c @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + + +svbfloat16x4_t test_svset4_bf16_0(svbfloat16x4_t tuple, svbfloat16_t x) +{ + // CHECK-LABEL: test_svset4_bf16_0 + // CHECK: %[[INSERT:.*]] = call @llvm.aarch64.sve.tuple.set.nxv32bf16.nxv8bf16( %tuple, i32 0, %x) + // CHECK-NEXT: ret %[[INSERT]] + // expected-warning@+1 {{implicit declaration of function 'svset4_bf16'}} + return SVE_ACLE_FUNC(svset4,_bf16,,)(tuple, 0, x); +} + +svbfloat16x4_t test_svset4_bf16_1(svbfloat16x4_t tuple, svbfloat16_t x) +{ + // CHECK-LABEL: test_svset4_bf16_1 + // CHECK: %[[INSERT:.*]] = call @llvm.aarch64.sve.tuple.set.nxv32bf16.nxv8bf16( %tuple, i32 1, %x) + // CHECK-NEXT: ret %[[INSERT]] + // expected-warning@+1 {{implicit declaration of function 'svset4_bf16'}} + return SVE_ACLE_FUNC(svset4,_bf16,,)(tuple, 1, x); +} + +svbfloat16x4_t test_svset4_bf16_2(svbfloat16x4_t tuple, svbfloat16_t x) +{ + // CHECK-LABEL: test_svset4_bf16_2 + // CHECK: %[[INSERT:.*]] = call @llvm.aarch64.sve.tuple.set.nxv32bf16.nxv8bf16( %tuple, i32 2, %x) + // CHECK-NEXT: ret %[[INSERT]] + // expected-warning@+1 {{implicit declaration of function 'svset4_bf16'}} + return SVE_ACLE_FUNC(svset4,_bf16,,)(tuple, 2, x); +} + +svbfloat16x4_t test_svset4_bf16_3(svbfloat16x4_t tuple, svbfloat16_t x) +{ + // CHECK-LABEL: test_svset4_bf16_3 + // CHECK: %[[INSERT:.*]] = call @llvm.aarch64.sve.tuple.set.nxv32bf16.nxv8bf16( %tuple, i32 3, %x) + // CHECK-NEXT: ret %[[INSERT]] + // expected-warning@+1 {{implicit declaration of function 'svset4_bf16'}} + return SVE_ACLE_FUNC(svset4,_bf16,,)(tuple, 3, x); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set4.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set4.c index 6522948d8ba65..1e724d172d429 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set4.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set4.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_setffr.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_setffr.c index 4399e20e5351e..3a9dcf0c739f3 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_setffr.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_setffr.c @@ -1,7 +1,11 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // CHECK-NOT: warning +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include void test_svsetffr() diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_splice-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_splice-bfloat.c new file mode 100644 index 0000000000000..b9d0c7944ae40 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_splice-bfloat.c @@ -0,0 +1,27 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svsplice_bf16(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2) +{ + // CHECK-LABEL: test_svsplice_bf16 + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.splice.nxv8bf16( %[[PG]], %op1, %op2) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svsplice_bf16'}} + return SVE_ACLE_FUNC(svsplice,_bf16,,)(pg, op1, op2); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_splice.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_splice.c index c90b593396901..51212274903a0 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_splice.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_splice.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_sqrt.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_sqrt.c index 1081fd3ce2136..43b6e63214bd6 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_sqrt.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_sqrt.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1-bfloat.c new file mode 100644 index 0000000000000..feee5434e5431 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1-bfloat.c @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +void test_svst1_bf16(svbool_t pg, bfloat16_t *base, svbfloat16_t data) +{ + // CHECK-LABEL: test_svst1_bf16 + // CHECK: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: call void @llvm.aarch64.sve.st1.nxv8bf16( %data, %[[PG]], bfloat* %base) + // CHECK: ret void + // expected-warning@+1 {{implicit declaration of function 'svst1_bf16'}} + return SVE_ACLE_FUNC(svst1,_bf16,,)(pg, base, data); +} + +void test_svst1_vnum_bf16(svbool_t pg, bfloat16_t *base, int64_t vnum, svbfloat16_t data) +{ + // CHECK-LABEL: test_svst1_vnum_bf16 + // CHECK-DAG: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK-DAG: %[[BASE:.*]] = bitcast bfloat* %base to * + // CHECK-DAG: %[[GEP:.*]] = getelementptr , * %[[BASE]], i64 %vnum, i64 0 + // CHECK: call void @llvm.aarch64.sve.st1.nxv8bf16( %data, %[[PG]], bfloat* %[[GEP]]) + // CHECK: ret void + // expected-warning@+1 {{implicit declaration of function 'svst1_vnum_bf16'}} + return SVE_ACLE_FUNC(svst1_vnum,_bf16,,)(pg, base, vnum, data); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1.c index 160319fd65108..fe91a5c52c514 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1b.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1b.c index 25d7bf187ffc0..09731f7d6fe06 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1b.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1b.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - -emit-llvm %s 2>&1 | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - -emit-llvm %s 2>&1 | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - -emit-llvm %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - -emit-llvm %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1h.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1h.c index 129f678218296..35b5c8416a8e6 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1h.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1h.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - -emit-llvm %s 2>&1 | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - -emit-llvm %s 2>&1 | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - -emit-llvm %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - -emit-llvm %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1w.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1w.c index b4ddb5ed7e334..89adeb6f5da0b 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1w.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1w.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - -emit-llvm %s 2>&1 | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - -emit-llvm %s 2>&1 | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - -emit-llvm %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - -emit-llvm %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st2-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st2-bfloat.c new file mode 100644 index 0000000000000..4b2235e63afe7 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st2-bfloat.c @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif +void test_svst2_bf16(svbool_t pg, bfloat16_t *base, svbfloat16x2_t data) +{ + // CHECK-LABEL: test_svst2_bf16 + // CHECK-DAG: %[[V0:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv16bf16( %data, i32 0) + // CHECK-DAG: %[[V1:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv16bf16( %data, i32 1) + // CHECK-DAG: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: call void @llvm.aarch64.sve.st2.nxv8bf16( %[[V0]], %[[V1]], %[[PG]], bfloat* %base) + // CHECK-NEXT: ret + return SVE_ACLE_FUNC(svst2,_bf16,,)(pg, base, data); +} + +void test_svst2_vnum_bf16(svbool_t pg, bfloat16_t *base, int64_t vnum, svbfloat16x2_t data) +{ + // CHECK-LABEL: test_svst2_vnum_bf16 + // CHECK-DAG: %[[BITCAST:.*]] = bitcast bfloat* %base to * + // CHECK-DAG: %[[GEP:.*]] = getelementptr , * %[[BITCAST]], i64 %vnum, i64 0 + // CHECK-DAG: %[[V0:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv16bf16( %data, i32 0) + // CHECK-DAG: %[[V1:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv16bf16( %data, i32 1) + // CHECK-DAG: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: call void @llvm.aarch64.sve.st2.nxv8bf16( %[[V0]], %[[V1]], %[[PG]], bfloat* %[[GEP]]) + // CHECK-NEXT: ret + return SVE_ACLE_FUNC(svst2_vnum,_bf16,,)(pg, base, vnum, data); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st2.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st2.c index 042612d7e0a9e..de21c59bb3b70 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st2.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st2.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st3-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st3-bfloat.c new file mode 100644 index 0000000000000..37ec4af436468 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st3-bfloat.c @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +void test_svst3_bf16(svbool_t pg, bfloat16_t *base, svbfloat16x3_t data) +{ + // CHECK-LABEL: test_svst3_bf16 + // CHECK-DAG: %[[V0:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv24bf16( %data, i32 0) + // CHECK-DAG: %[[V1:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv24bf16( %data, i32 1) + // CHECK-DAG: %[[V2:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv24bf16( %data, i32 2) + // CHECK-DAG: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: call void @llvm.aarch64.sve.st3.nxv8bf16( %[[V0]], %[[V1]], %[[V2]], %[[PG]], bfloat* %base) + // CHECK-NEXT: ret + return SVE_ACLE_FUNC(svst3,_bf16,,)(pg, base, data); +} + +void test_svst3_vnum_bf16(svbool_t pg, bfloat16_t *base, int64_t vnum, svbfloat16x3_t data) +{ + // CHECK-LABEL: test_svst3_vnum_bf16 + // CHECK-DAG: %[[BITCAST:.*]] = bitcast bfloat* %base to * + // CHECK-DAG: %[[GEP:.*]] = getelementptr , * %[[BITCAST]], i64 %vnum, i64 0 + // CHECK-DAG: %[[V0:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv24bf16( %data, i32 0) + // CHECK-DAG: %[[V1:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv24bf16( %data, i32 1) + // CHECK-DAG: %[[V2:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv24bf16( %data, i32 2) + // CHECK-DAG: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: call void @llvm.aarch64.sve.st3.nxv8bf16( %[[V0]], %[[V1]], %[[V2]], %[[PG]], bfloat* %[[GEP]]) + // CHECK-NEXT: ret + return SVE_ACLE_FUNC(svst3_vnum,_bf16,,)(pg, base, vnum, data); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st3.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st3.c index 5fbff9c5ea408..e98b2e7cc8a2f 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st3.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st3.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st4-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st4-bfloat.c new file mode 100644 index 0000000000000..538331b107dcb --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st4-bfloat.c @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +void test_svst4_bf16(svbool_t pg, bfloat16_t *base, svbfloat16x4_t data) +{ + // CHECK-LABEL: test_svst4_bf16 + // CHECK-DAG: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK-DAG: %[[V0:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv32bf16( %data, i32 0) + // CHECK-DAG: %[[V1:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv32bf16( %data, i32 1) + // CHECK-DAG: %[[V2:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv32bf16( %data, i32 2) + // CHECK-DAG: %[[V3:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv32bf16( %data, i32 3) + // CHECK: call void @llvm.aarch64.sve.st4.nxv8bf16( %[[V0]], %[[V1]], %[[V2]], %[[V3]], %[[PG]], bfloat* %base) + // CHECK-NEXT: ret + return SVE_ACLE_FUNC(svst4,_bf16,,)(pg, base, data); +} + +void test_svst4_vnum_bf16(svbool_t pg, bfloat16_t *base, int64_t vnum, svbfloat16x4_t data) +{ + // CHECK-LABEL: test_svst4_vnum_bf16 + // CHECK-DAG: %[[BITCAST:.*]] = bitcast bfloat* %base to * + // CHECK-DAG: %[[GEP:.*]] = getelementptr , * %[[BITCAST]], i64 %vnum, i64 0 + // CHECK-DAG: %[[V0:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv32bf16( %data, i32 0) + // CHECK-DAG: %[[V1:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv32bf16( %data, i32 1) + // CHECK-DAG: %[[V2:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv32bf16( %data, i32 2) + // CHECK-DAG: %[[V3:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv32bf16( %data, i32 3) + // CHECK-DAG: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: call void @llvm.aarch64.sve.st4.nxv8bf16( %[[V0]], %[[V1]], %[[V2]], %[[V3]], %[[PG]], bfloat* %[[GEP]]) + // CHECK-NEXT: ret + return SVE_ACLE_FUNC(svst4_vnum,_bf16,,)(pg, base, vnum, data); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st4.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st4.c index e2f315e83c24b..2ea1ae655ee81 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st4.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st4.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_stnt1-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_stnt1-bfloat.c new file mode 100644 index 0000000000000..78ddddc6b1b7a --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_stnt1-bfloat.c @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +void test_svstnt1_bf16(svbool_t pg, bfloat16_t *base, svbfloat16_t data) +{ + // CHECK-LABEL: test_svstnt1_bf16 + // CHECK-DAG: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: call void @llvm.aarch64.sve.stnt1.nxv8bf16( %data, %[[PG]], bfloat* %base) + // CHECK-NEXT: ret + // expected-warning@+1 {{implicit declaration of function 'svstnt1_bf16'}} + return SVE_ACLE_FUNC(svstnt1,_bf16,,)(pg, base, data); +} + +void test_svstnt1_vnum_bf16(svbool_t pg, bfloat16_t *base, int64_t vnum, svbfloat16_t data) +{ + // CHECK-LABEL: test_svstnt1_vnum_bf16 + // CHECK-DAG: %[[BITCAST:.*]] = bitcast bfloat* %base to * + // CHECK-DAG: %[[GEP:.*]] = getelementptr , * %[[BITCAST]], i64 %vnum, i64 0 + // CHECK-DAG: %[[PG:.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg) + // CHECK: call void @llvm.aarch64.sve.stnt1.nxv8bf16( %data, %[[PG]], bfloat* %[[GEP]]) + // CHECK-NEXT: ret + // expected-warning@+1 {{implicit declaration of function 'svstnt1_vnum_bf16'}} + return SVE_ACLE_FUNC(svstnt1_vnum,_bf16,,)(pg, base, vnum, data); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_stnt1.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_stnt1.c index 32f222b5d47ec..0c5980808ba46 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_stnt1.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_stnt1.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_sub.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_sub.c index d3f7da5862ff2..f4185179ba31e 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_sub.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_sub.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_subr.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_subr.c index 81ef2839e347c..523171f8bf01d 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_subr.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_subr.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_sudot.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_sudot.c index d678851bad586..70904c3fb8fd7 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_sudot.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_sudot.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE_MATMUL_INT8 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE_MATMUL_INT8 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +i8mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +i8mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_tbl-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_tbl-bfloat.c new file mode 100644 index 0000000000000..1c68586d2fed5 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_tbl-bfloat.c @@ -0,0 +1,26 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svtbl_bf16(svbfloat16_t data, svuint16_t indices) { + // CHECK-LABEL: test_svtbl_bf16 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.tbl.nxv8bf16( %data, %indices) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svtbl_bf16'}} + return SVE_ACLE_FUNC(svtbl, _bf16, , )(data, indices); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_tbl.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_tbl.c index 14f36ca89c247..05e5fe98b79f8 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_tbl.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_tbl.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_tmad.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_tmad.c index 70787cd634960..fa7139fa6e049 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_tmad.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_tmad.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1-bfloat.c new file mode 100644 index 0000000000000..fb60ce3e15b92 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1-bfloat.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svtrn1_bf16(svbfloat16_t op1, svbfloat16_t op2) +{ + // CHECK-LABEL: test_svtrn1_bf16 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.trn1.nxv8bf16( %op1, %op2) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svtrn1_bf16'}} + return SVE_ACLE_FUNC(svtrn1,_bf16,,)(op1, op2); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1-fp64-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1-fp64-bfloat.c new file mode 100644 index 0000000000000..c6f8e4a92c742 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1-fp64-bfloat.c @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svtrn1_bf16(svbfloat16_t op1, svbfloat16_t op2) { + // CHECK-LABEL: test_svtrn1_bf16 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.trn1q.nxv8bf16( %op1, %op2) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svtrn1q_bf16'}} + return SVE_ACLE_FUNC(svtrn1q, _bf16, , )(op1, op2); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1-fp64.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1-fp64.c index f968c1524a8b6..a8cbbc660b23a 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1-fp64.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1-fp64.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE_MATMUL_FP64 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE_MATMUL_FP64 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1.c index 6e7cbed5350e9..7e2e8e133bda0 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s - +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2-bfloat.c new file mode 100644 index 0000000000000..62c9a7daf9ee3 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2-bfloat.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svtrn2_bf16(svbfloat16_t op1, svbfloat16_t op2) +{ + // CHECK-LABEL: test_svtrn2_bf16 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.trn2.nxv8bf16( %op1, %op2) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svtrn2_bf16'}} + return SVE_ACLE_FUNC(svtrn2,_bf16,,)(op1, op2); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2-fp64-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2-fp64-bfloat.c new file mode 100644 index 0000000000000..16f4bce584611 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2-fp64-bfloat.c @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svtrn2_bf16(svbfloat16_t op1, svbfloat16_t op2) { + // CHECK-LABEL: test_svtrn2_bf16 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.trn2q.nxv8bf16( %op1, %op2) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svtrn2q_bf16'}} + return SVE_ACLE_FUNC(svtrn2q, _bf16, , )(op1, op2); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2-fp64.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2-fp64.c index fc26ec2b5658f..21ea2cbc17a1f 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2-fp64.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2-fp64.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE_MATMUL_FP64 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE_MATMUL_FP64 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2.c index 432370bb459f9..704b8d10f715d 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s - +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_tsmul.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_tsmul.c index 11094fe61f4d1..698f5213fb626 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_tsmul.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_tsmul.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_tssel.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_tssel.c index 69ab555908008..e130d836e5375 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_tssel.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_tssel.c @@ -1,7 +1,7 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef-bfloat.c new file mode 100644 index 0000000000000..16b789ca84035 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef-bfloat.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +svbfloat16_t test_svundef_bf16() +{ + // CHECK-LABEL: test_svundef_bf16 + // CHECK: ret undef + // expected-warning@+1 {{implicit declaration of function 'svundef_bf16'}} + return svundef_bf16(); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef.c index 731f740846d03..581ea7a050d32 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef.c @@ -1,5 +1,10 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include svint8_t test_svundef_s8() diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef2-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef2-bfloat.c new file mode 100644 index 0000000000000..a65560d837b0f --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef2-bfloat.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +svbfloat16x2_t test_svundef2_bf16() +{ + // CHECK-LABEL: test_svundef2_bf16 + // CHECK: ret undef + // expected-warning@+1 {{implicit declaration of function 'svundef2_bf16'}} + return svundef2_bf16(); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef2.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef2.c index ab5fb1cc691c8..8259cfe307507 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef2.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef2.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O2 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O2 -Werror -Wall -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef3-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef3-bfloat.c new file mode 100644 index 0000000000000..6e0ae7ce1ce73 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef3-bfloat.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +svbfloat16x3_t test_svundef3_bf16() +{ + // CHECK-LABEL: test_svundef3_bf16 + // CHECK: ret undef + // expected-warning@+1 {{implicit declaration of function 'svundef3_bf16'}} + return svundef3_bf16(); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef3.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef3.c index 925e5aa43779e..929983a3ccde9 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef3.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef3.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O2 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O2 -Werror -Wall -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef4-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef4-bfloat.c new file mode 100644 index 0000000000000..6907451d2475f --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef4-bfloat.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +svbfloat16x4_t test_svundef4_bf16() +{ + // CHECK-LABEL: test_svundef4_bf16 + // CHECK: ret undef + // expected-warning@+1 {{implicit declaration of function 'svundef4_bf16'}} + return svundef4_bf16(); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef4.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef4.c index 7dc854f33159b..9c45a8936d1b6 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef4.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef4.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O2 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O2 -Werror -Wall -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_unpkhi.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_unpkhi.c index 5bab85658561f..cae68a3e0a858 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_unpkhi.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_unpkhi.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_unpklo.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_unpklo.c index 343f61c5257f6..a73419779a281 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_unpklo.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_unpklo.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_usdot.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_usdot.c index 1639cbb2b86f3..0c361bac167fd 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_usdot.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_usdot.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE_MATMUL_INT8 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE_MATMUL_INT8 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +i8mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +i8mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1-bfloat.c new file mode 100644 index 0000000000000..ffc98e9745b1d --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1-bfloat.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svuzp1_bf16(svbfloat16_t op1, svbfloat16_t op2) +{ + // CHECK-LABEL: test_svuzp1_bf16 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.uzp1.nxv8bf16( %op1, %op2) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svuzp1_bf16'}} + return SVE_ACLE_FUNC(svuzp1,_bf16,,)(op1, op2); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1-fp64-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1-fp64-bfloat.c new file mode 100644 index 0000000000000..4aa8833073a43 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1-fp64-bfloat.c @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svuzp1_bf16(svbfloat16_t op1, svbfloat16_t op2) { + // CHECK-LABEL: test_svuzp1_bf16 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.uzp1q.nxv8bf16( %op1, %op2) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svuzp1q_bf16'}} + return SVE_ACLE_FUNC(svuzp1q, _bf16, , )(op1, op2); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1-fp64.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1-fp64.c index cb96efa7f519a..ab63a5fd07144 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1-fp64.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1-fp64.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE_MATMUL_FP64 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE_MATMUL_FP64 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1.c index d95cb5ec9bf89..6eea3bc17d98f 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s - +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2-bfloat.c new file mode 100644 index 0000000000000..bf3dd928c4fe3 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2-bfloat.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svuzp2_bf16(svbfloat16_t op1, svbfloat16_t op2) +{ + // CHECK-LABEL: test_svuzp2_bf16 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.uzp2.nxv8bf16( %op1, %op2) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svuzp2_bf16'}} + return SVE_ACLE_FUNC(svuzp2,_bf16,,)(op1, op2); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2-fp64-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2-fp64-bfloat.c new file mode 100644 index 0000000000000..aaca01a5105dc --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2-fp64-bfloat.c @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svuzp2_bf16(svbfloat16_t op1, svbfloat16_t op2) { + // CHECK-LABEL: test_svuzp2_bf16 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.uzp2q.nxv8bf16( %op1, %op2) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svuzp2q_bf16'}} + return SVE_ACLE_FUNC(svuzp2q, _bf16, , )(op1, op2); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2-fp64.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2-fp64.c index 122d5c536cc08..5b3b1b5443dea 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2-fp64.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2-fp64.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE_MATMUL_FP64 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE_MATMUL_FP64 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2.c index b359aa68e8c06..645e96c4e55fe 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s - +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_whilele.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_whilele.c index fc06fed94b015..6aa30f2ef59b7 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_whilele.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_whilele.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s - +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_whilelt.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_whilelt.c index 1d2480c0a8092..6904dbc079b70 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_whilelt.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_whilelt.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s - +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_wrffr.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_wrffr.c index 72ffe7ac2f954..c7d04db916e5d 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_wrffr.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_wrffr.c @@ -1,6 +1,6 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -o - %s >/dev/null 2>%t // RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t // If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1-bfloat.c new file mode 100644 index 0000000000000..d9c6581e11f07 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1-bfloat.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svzip1_bf16(svbfloat16_t op1, svbfloat16_t op2) +{ + // CHECK-LABEL: test_svzip1_bf16 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.zip1.nxv8bf16( %op1, %op2) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svzip1_bf16'}} + return SVE_ACLE_FUNC(svzip1,_bf16,,)(op1, op2); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1-fp64-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1-fp64-bfloat.c new file mode 100644 index 0000000000000..36ec40f5b91ea --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1-fp64-bfloat.c @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svzip1_bf16(svbfloat16_t op1, svbfloat16_t op2) { + // CHECK-LABEL: test_svzip1_bf16 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.zip1q.nxv8bf16( %op1, %op2) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svzip1q_bf16'}} + return SVE_ACLE_FUNC(svzip1q, _bf16, , )(op1, op2); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1-fp64.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1-fp64.c index 1e9e81dc45bbe..47ced73fd8601 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1-fp64.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1-fp64.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE_MATMUL_FP64 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE_MATMUL_FP64 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1.c index 3444ac9aa1abb..218f63764becc 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s - +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2-bfloat.c new file mode 100644 index 0000000000000..bde8800a57ca7 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2-bfloat.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svzip2_bf16(svbfloat16_t op1, svbfloat16_t op2) +{ + // CHECK-LABEL: test_svzip2_bf16 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.zip2.nxv8bf16( %op1, %op2) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svzip2_bf16'}} + return SVE_ACLE_FUNC(svzip2,_bf16,,)(op1, op2); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2-fp64-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2-fp64-bfloat.c new file mode 100644 index 0000000000000..a3b04e6d67256 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2-fp64-bfloat.c @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svzip2_bf16(svbfloat16_t op1, svbfloat16_t op2) { + // CHECK-LABEL: test_svzip2_bf16 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.zip2q.nxv8bf16( %op1, %op2) + // CHECK: ret %[[INTRINSIC]] + // expected-warning@+1 {{implicit declaration of function 'svzip2q_bf16'}} + return SVE_ACLE_FUNC(svzip2q, _bf16, , )(op1, op2); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2-fp64.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2-fp64.c index ad33f565af89a..20a12479e8b7c 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2-fp64.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2-fp64.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE_MATMUL_FP64 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE_MATMUL_FP64 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2.c index bba3aca2502a3..099d789586972 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2.c @@ -1,6 +1,11 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s - +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -o - %s >/dev/null 2>%t +// RUN: FileCheck --check-prefix=ASM --allow-empty %s <%t + +// If this check fails please read test/CodeGen/aarch64-sve-intrinsics/README for instructions on how to resolve it. +// ASM-NOT: warning #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_asrd.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_asrd.c index f57b94393096b..0df6a9b7b4507 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_asrd.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_asrd.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_cadd.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_cadd.c index 39b1ac318ffd7..7d83addc05335 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_cadd.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_cadd.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_cmla.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_cmla.c index ae507be463560..cafdd638b23e6 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_cmla.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_cmla.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_dot.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_dot.c index 9ea5abfcb4108..29e5eba397750 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_dot.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_dot.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_ext.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_ext.c index f8706d4e7590a..cce61cfd2b046 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_ext.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_ext.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get2.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get2.c index 7bd084490c2b1..1c334cfe17cd4 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get2.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get2.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get3.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get3.c index 91b91eb07a427..05f35f20a614f 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get3.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get3.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get4.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get4.c index 10e5175fd6ab8..37c5d1838acb2 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get4.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get4.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_mla.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_mla.c index 62249694f23e9..e107e02c7e8b2 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_mla.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_mla.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_mul.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_mul.c index b8cb87dab9990..528999a5c1b1f 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_mul.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_mul.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfb.c index 48fea8c540b7a..e8815a05c3a57 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfb.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfb.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfd.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfd.c index 2efa9b6c9e138..cd15ac58d9614 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfd.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfd.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfh.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfh.c index 16b19203cdc55..c18b66f06529b 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfh.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfh.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfw.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfw.c index ea1d6e24419b5..6e3c27a488599 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfw.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfw.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecb.c index b8ac4ac5aa6a5..2878a6fa35b68 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecb.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecb.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecd.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecd.c index db380e7dc83ce..ac01ce0b770da 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecd.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecd.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdech.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdech.c index daa87e1c2df79..adfc966363ede 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdech.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdech.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecw.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecw.c index 23705457131fb..316914fad06a5 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecw.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecw.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincb.c index c4d9b473ebd5a..e2687e19240fa 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincb.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincb.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincd.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincd.c index 1905778e97acb..9ad619207647d 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincd.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincd.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qinch.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qinch.c index b67c5ccdc88af..269ab07242f49 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qinch.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qinch.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincw.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincw.c index 7180f8bbd1649..f123b39a47f38 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincw.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincw.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set2.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set2.c index 621e0c89926cc..5a3131b2da6b6 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set2.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set2.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set3.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set3.c index 3b624588616bd..c4bb8cb880f27 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set3.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set3.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set4.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set4.c index 8cc19246d620c..6036bcd159c07 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set4.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set4.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_tmad.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_tmad.c index da85cb726257d..25f15402988ac 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_tmad.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_tmad.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/big_endian.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/big_endian.c index fc44481c94c70..f7fdd76114af9 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/big_endian.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/big_endian.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64_be-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64_be-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s // expected-error@* {{Big endian is currently not supported for arm_sve.h}} #include diff --git a/clang/test/CodeGen/aarch64-sve.c b/clang/test/CodeGen/aarch64-sve.c index 790b3a176182b..d21af74319f99 100644 --- a/clang/test/CodeGen/aarch64-sve.c +++ b/clang/test/CodeGen/aarch64-sve.c @@ -14,6 +14,7 @@ // CHECK-DEBUG: cannot yet generate debug info for SVE type '__SVFloat16_t' // CHECK-DEBUG: cannot yet generate debug info for SVE type '__SVFloat32_t' // CHECK-DEBUG: cannot yet generate debug info for SVE type '__SVFloat64_t' +// CHECK-DEBUG: cannot yet generate debug info for SVE type '__SVBFloat16_t' // CHECK-DEBUG: cannot yet generate debug info for SVE type '__SVBool_t' // CHECK: @ptr = global * null, align 8 @@ -28,6 +29,7 @@ // CHECK: %f16 = alloca , align 16 // CHECK: %f32 = alloca , align 16 // CHECK: %f64 = alloca , align 16 +// CHECK: %bf16 = alloca , align 16 // CHECK: %b8 = alloca , align 2 __SVInt8_t *ptr; @@ -47,5 +49,7 @@ void test_locals(void) { __SVFloat32_t f32; __SVFloat64_t f64; + __SVBFloat16_t bf16; + __SVBool_t b8; } diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aba.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aba.c index 5ba165faf48fd..26aafead5cefe 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aba.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aba.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abalb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abalb.c index 850a6722f645f..c50916c4e1316 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abalb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abalb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abalt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abalt.c index 34a2cb915c5d7..b7480a5d89aa8 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abalt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abalt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abdlb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abdlb.c index 2453fd99ca1ed..49d89ada0793d 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abdlb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abdlb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abdlt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abdlt.c index dbd333ab764bb..b5bb45d1e2f9d 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abdlt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abdlt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adalp.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adalp.c index 5d68f81099860..fa30a301b30a0 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adalp.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adalp.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adclb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adclb.c index a02ecaaad5afb..215949fe15459 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adclb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adclb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adclt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adclt.c index 2cee8a9dd5b3d..687574ed5d58d 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adclt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adclt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addhnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addhnb.c index 27efc36efedc6..24fdd559bf81f 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addhnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addhnb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addhnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addhnt.c index 700c59d6b82a4..95137ad33a772 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addhnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addhnt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlb.c index 39096523b223d..168a2c2bd0660 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlbt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlbt.c index 3d47de8421871..c5d96fae7a325 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlbt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlbt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlt.c index 5d5806361e044..71cf4d7edac9c 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addp.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addp.c index 0fd97cedb2013..a04ed5becc1cc 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addp.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addp.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addwb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addwb.c index 85ec2f09aeb4c..00e3be0111abd 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addwb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addwb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addwt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addwt.c index c4c40d295285b..57392da45022b 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addwt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addwt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesd.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesd.c index d037f452ce76d..a170585dd58a0 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesd.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesd.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2_AES -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2_AES -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aese.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aese.c index 19235555e5e7f..d9b5f3eef2df8 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aese.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aese.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2_AES -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2_AES -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesimc.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesimc.c index e3b1952e484dd..a79317c37f569 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesimc.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesimc.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2_AES -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2_AES -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesmc.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesmc.c index fa53d5a51e760..5af2a29302ecf 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesmc.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesmc.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2_AES -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2_AES -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bcax.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bcax.c index 3cde14ad65df1..8547ff4d3fdd0 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bcax.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bcax.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bdep.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bdep.c index eb5890b3f65f7..6543b30b417f8 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bdep.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bdep.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2_BITPERM -triple aarch64-none-linux-gnu -target-feature +sve2-bitperm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2_BITPERM -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-bitperm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-bitperm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-bitperm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bext.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bext.c index 8178506c37650..714364b6b4cbb 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bext.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bext.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2_BITPERM -triple aarch64-none-linux-gnu -target-feature +sve2-bitperm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2_BITPERM -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-bitperm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-bitperm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-bitperm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bgrp.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bgrp.c index aebfa11663d00..10d9fa85fa9f6 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bgrp.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bgrp.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2_BITPERM -triple aarch64-none-linux-gnu -target-feature +sve2-bitperm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2_BITPERM -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-bitperm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-bitperm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-bitperm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl.c index 982d04b7d7cf1..fae32cbc9ba01 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl1n.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl1n.c index 85c0951693e92..787a3f2ec9631 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl1n.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl1n.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl2n.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl2n.c index a47dc2d190fed..d9771e31db874 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl2n.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl2n.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cadd.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cadd.c index 01c14f8636663..aada5acbd9e69 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cadd.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cadd.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cdot.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cdot.c index c8094c8948924..bfbbee64eb3c8 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cdot.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cdot.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cmla.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cmla.c index 4ce43feb61147..b9089aacb4d89 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cmla.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cmla.c @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtlt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtlt.c index 99344a3ece2e2..e54128107c868 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtlt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtlt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtnt.c index ee57e8de12b50..fd64108463b81 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtnt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtx.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtx.c index a499a87ee2737..ba2cc769ebca7 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtx.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtx.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtxnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtxnt.c index a006c8e0c5502..d4ef80781a4da 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtxnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtxnt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eor3.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eor3.c index 634cb65375952..79cccc7dc441e 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eor3.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eor3.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eorbt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eorbt.c index 865ac2e444e57..586fea961439e 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eorbt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eorbt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eortb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eortb.c index 6734d9fa0c6da..81abf27cf5e50 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eortb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eortb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hadd.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hadd.c index 6a9f3f347f633..37d9dba6b6a57 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hadd.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hadd.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_histcnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_histcnt.c index 3f2138bc48c43..2572376fe5c48 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_histcnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_histcnt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_histseg.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_histseg.c index 230075fe7c6f4..b38c82a75911f 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_histseg.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_histseg.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hsub.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hsub.c index 386bae82e07be..8bb1cdb46be83 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hsub.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hsub.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hsubr.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hsubr.c index efc1544c6e3a1..f2fe38fc392af 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hsubr.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hsubr.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1.c index 1f00744afe51b..fa055476f87d7 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sb.c index cd87d4491bc23..cb52acf5df9cc 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sh.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sh.c index a595f70a9572d..0ffe8e337ffee 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sh.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sh.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sw.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sw.c index 921861e4bcffa..e1e244ef56209 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sw.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sw.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1ub.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1ub.c index 05fbfebb9a973..47b14d08657f9 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1ub.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1ub.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1uh.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1uh.c index 5627060b878b5..cf3c8afd4caa9 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1uh.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1uh.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1uw.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1uw.c index e64ec26be8dee..b90c0802406b6 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1uw.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1uw.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_logb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_logb.c index ab0a508b5a27f..92b4c4a18ba17 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_logb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_logb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_match.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_match.c index 79591ad7b7365..456e1e05af7e6 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_match.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_match.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_maxnmp.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_maxnmp.c index 66e4c9db60eae..5b7d487f70f80 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_maxnmp.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_maxnmp.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_maxp.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_maxp.c index 3f09a62e28fc2..59bb50e695ffc 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_maxp.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_maxp.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_minnmp.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_minnmp.c index 75d9319ce01a5..3480e7cf1a1ac 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_minnmp.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_minnmp.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_minp.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_minp.c index 9f8c34bd21b5b..3a687870839c8 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_minp.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_minp.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mla.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mla.c index b130780648c4e..e2585dbecc6b4 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mla.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mla.c @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlalb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlalb.c index e4f80eb639dec..1e566a9bd9277 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlalb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlalb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlalt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlalt.c index 49f67536d1767..2de60cd819f74 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlalt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlalt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mls.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mls.c index 13ecb1fadfea5..b52cdd2efbaab 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mls.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mls.c @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlslb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlslb.c index 429569e306d82..8f10ae47340ec 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlslb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlslb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlslt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlslt.c index 4bca3ae5aefb0..e9cf85a739624 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlslt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlslt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlb.c index ba0d80deaf8af..f3ec86b843068 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlt.c index 71a3ea179a914..de9cb692ac80c 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mul.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mul.c index fff05ca585fec..dca5752dee8a8 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mul.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mul.c @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mullb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mullb.c index fca203bb60b91..a9bd191407450 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mullb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mullb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mullt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mullt.c index 9590d4aa895c8..04055adfb431e 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mullt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mullt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_nbsl.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_nbsl.c index e20ca82990558..ce4072a27382e 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_nbsl.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_nbsl.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_nmatch.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_nmatch.c index d55e7e6db1be0..2b3be07b96054 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_nmatch.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_nmatch.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmul.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmul.c index 05dca4ecc4200..edca8a90d7ebe 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmul.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmul.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullb.c index a12d1fd09ffd0..647ad310aa511 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullb_128.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullb_128.c index 2c8ff2cb000eb..5268cf80cf125 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullb_128.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullb_128.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2_AES -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2_AES -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullt.c index 5b4b05aa72fb5..3b7c443a8ae1e 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullt_128.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullt_128.c index 69726c90d10cd..e9947f486ed40 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullt_128.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullt_128.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2_AES -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2_AES -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qabs.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qabs.c index 94442807d49cc..02dd525839a56 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qabs.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qabs.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qadd.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qadd.c index 2c035b6a77d0b..8099471d8edec 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qadd.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qadd.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qcadd.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qcadd.c index 028283b1e3c89..c6cd3428136f9 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qcadd.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qcadd.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalb.c index f1658279f15f8..2b237aa473504 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalbt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalbt.c index 88f141838938e..3123182cad31e 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalbt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalbt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalt.c index f1554f37c8767..aeb9b083d14b6 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslb.c index 29e1fcbb2c793..bd072342d478c 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslbt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslbt.c index 0bcc24e57022f..cd521d76a75f2 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslbt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslbt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslt.c index f3d78c06b3a47..e8398784b621b 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmulh.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmulh.c index 0de2aad076a60..f9a964940020c 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmulh.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmulh.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmullb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmullb.c index e7101e43ad20a..e3b21aee8c976 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmullb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmullb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmullt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmullt.c index 4943b503c6a8c..b8b3144c8cbdb 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmullt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmullt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qneg.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qneg.c index a734f741d780b..195e8c4bbf426 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qneg.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qneg.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdcmlah.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdcmlah.c index 33853acc600ff..9f125868143ab 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdcmlah.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdcmlah.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmlah.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmlah.c index a142609407a6a..3f2c8369db3ac 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmlah.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmlah.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmlsh.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmlsh.c index 921bca4c76699..a944719c46db4 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmlsh.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmlsh.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmulh.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmulh.c index 07efb8ff0f8cd..57a26d4f9acf8 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmulh.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmulh.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshl.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshl.c index e9233ab9804c8..dbfbc3f8d47aa 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshl.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshl.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrnb.c index 991739d2ddc0d..de5e76b410e23 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrnb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrnt.c index 33686277aa2fe..42ac313a86131 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrnt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrunb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrunb.c index 7e3777819e0ee..dc84be5365d74 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrunb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrunb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrunt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrunt.c index 5e96435b265b6..857079c7392ce 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrunt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrunt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshl.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshl.c index d8c9e19afcd06..1527fd80e1a7e 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshl.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshl.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshlu.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshlu.c index d61959573632e..8f7110a70890d 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshlu.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshlu.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrnb.c index d4c1719bc0362..794301ee0600c 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrnb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrnt.c index 5a68834978aa4..669a52f8ce4f8 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrnt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrunb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrunb.c index e012484e86c57..f9a2843dcf7c5 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrunb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrunb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrunt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrunt.c index d6db3fb8d8f60..07d68ebf3f13d 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrunt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrunt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qsub.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qsub.c index 63bbb8c0390eb..6aa030e01d3a6 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qsub.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qsub.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qsubr.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qsubr.c index c0146876d648d..9f8f5cd24ff70 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qsubr.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qsubr.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtnb.c index 1586d22fb86e5..c8a75a70f2970 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtnb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtnt.c index 68c99bcda1d43..f7beb72880c55 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtnt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtunb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtunb.c index 138fb51d85ba4..5c2ea3d163b81 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtunb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtunb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtunt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtunt.c index 6f7a96e3b243d..49020b868c81a 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtunt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtunt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_raddhnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_raddhnb.c index b8504b794d489..5a642a14eb959 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_raddhnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_raddhnb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_raddhnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_raddhnt.c index fa313ef9cbabd..47c76d9209cb3 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_raddhnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_raddhnt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rax1.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rax1.c index 01ce8ba78b6d6..666ec9378bab6 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rax1.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rax1.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2_SHA3 -triple aarch64-none-linux-gnu -target-feature +sve2-sha3 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2_SHA3 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-sha3 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-sha3 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-sha3 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_recpe.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_recpe.c index 7f9c804746c11..a068e15301331 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_recpe.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_recpe.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rhadd.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rhadd.c index e3731e5215689..b8f300d6ed1b2 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rhadd.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rhadd.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshl.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshl.c index c17ab16632551..cfb2b058bc6db 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshl.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshl.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshr.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshr.c index be46241417532..2c351cebf9558 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshr.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshr.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshrnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshrnb.c index 06cb1745d5418..8dcb355a138b5 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshrnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshrnb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshrnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshrnt.c index 559d6c912c47e..ceb11ec9abf68 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshrnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshrnt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsqrte.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsqrte.c index 02fb5f61e9d27..19d1cbd14bc43 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsqrte.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsqrte.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsra.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsra.c index 9e42b76032310..3196775cbfd3d 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsra.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsra.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsubhnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsubhnb.c index e424bef582188..f92817198b921 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsubhnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsubhnb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsubhnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsubhnt.c index 8a3fc54a4a9b2..36bf0225f4098 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsubhnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsubhnt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sbclb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sbclb.c index 37f4ae268c976..e40ab98212a0d 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sbclb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sbclb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sbclt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sbclt.c index 0fcc4f4f94d17..2c05ae860eba8 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sbclt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sbclt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shllb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shllb.c index e0b10d0959287..0e1d348bcba7a 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shllb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shllb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shllt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shllt.c index 6faf3c819c7f9..313ad9aa8c381 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shllt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shllt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shrnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shrnb.c index 88403c5ede584..8c8ee83da4567 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shrnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shrnb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shrnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shrnt.c index 35b0c23d26c8d..69eafcf7200be 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shrnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shrnt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sli.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sli.c index e25c9abf6e1d9..19361c6ab6099 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sli.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sli.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sm4e.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sm4e.c index aab77947db3e5..b7f343bfd7f34 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sm4e.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sm4e.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2_SM4 -triple aarch64-none-linux-gnu -target-feature +sve2-sm4 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2_SM4 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-sm4 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-sm4 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-sm4 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sm4ekey.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sm4ekey.c index d2eb88bbda9f4..c2b72406de84f 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sm4ekey.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sm4ekey.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2_SM4 -triple aarch64-none-linux-gnu -target-feature +sve2-sm4 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2_SM4 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-sm4 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-sm4 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-sm4 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sqadd.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sqadd.c index 78f77adc33788..ae84e010c89af 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sqadd.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sqadd.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sra.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sra.c index d6535a463430b..6a5f4ddc83c0c 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sra.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sra.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sri.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sri.c index 7abb04d291c4a..276ceb2c8e285 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sri.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sri.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1.c index e088836648c12..665d1f2720bcc 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1b.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1b.c index d94d6b4f34e37..a367406548ae8 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1b.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1b.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1h.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1h.c index f457ada228f3c..9db44153732a6 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1h.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1h.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1w.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1w.c index 98f1ecd544071..6b7ec77c6902c 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1w.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1w.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subhnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subhnb.c index 63bc103ce5135..388caf852183a 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subhnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subhnb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subhnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subhnt.c index a2c8d1cd36a9a..42783c2d90fbc 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subhnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subhnt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublb.c index e9b7b286fd912..0e0069051d43f 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublbt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublbt.c index 36c414293b558..1b84cd1046e05 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublbt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublbt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublt.c index 02cc433ac2183..c21f03b76e1b2 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subltb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subltb.c index a3ad6db87a230..4b4a62e13f82d 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subltb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subltb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subwb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subwb.c index e73e3481d6c9c..410e5f79bec50 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subwb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subwb.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subwt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subwt.c index 08b9e97ed9a07..d927b1b6231aa 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subwt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subwt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_tbl2-bfloat.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_tbl2-bfloat.c new file mode 100644 index 0000000000000..e3169988466df --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_tbl2-bfloat.c @@ -0,0 +1,26 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +bf16 -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svtbl2_bf16(svbfloat16x2_t data, svuint16_t indices) { + // CHECK-LABEL: test_svtbl2_bf16 + // CHECK-DAG: %[[V0:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv16bf16( %data, i32 0) + // CHECK-DAG: %[[V1:.*]] = call @llvm.aarch64.sve.tuple.get.nxv8bf16.nxv16bf16( %data, i32 1) + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.tbl2.nxv8bf16( %[[V0]], %[[V1]], %indices) + // CHECK-NEXT: ret %[[INTRINSIC]] + // overload-warning@+2 {{implicit declaration of function 'svtbl2'}} + // expected-warning@+1 {{implicit declaration of function 'svtbl2_bf16'}} + return SVE_ACLE_FUNC(svtbl2, _bf16, , )(data, indices); +} diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_tbl2.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_tbl2.c index d74b17f726630..4e4f70cb47a04 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_tbl2.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_tbl2.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_tbx-bfloat.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_tbx-bfloat.c new file mode 100644 index 0000000000000..1b8cac3656f1c --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_tbx-bfloat.c @@ -0,0 +1,24 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +bf16 -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3, A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1, A2, A3, A4) A1##A2##A3##A4 +#endif + +svbfloat16_t test_svtbx_bf16(svbfloat16_t fallback, svbfloat16_t data, svuint16_t indices) { + // CHECK-LABEL: @test_svtbx_bf16( + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.tbx.nxv8bf16( %fallback, %data, %indices) + // CHECK: ret %[[INTRINSIC]] + // overload-warning@+2 {{implicit declaration of function 'svtbx'}} + // expected-warning@+1 {{implicit declaration of function 'svtbx_bf16'}} + return SVE_ACLE_FUNC(svtbx, _bf16, , )(fallback, data, indices); +} diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_tbx.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_tbx.c index 78cc1b016417f..c3c6f5f0447b6 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_tbx.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_tbx.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_uqadd.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_uqadd.c index 19245bd0425e5..090df7318edd2 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_uqadd.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_uqadd.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include #ifdef SVE_OVERLOADED_FORMS diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilege.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilege.c index 72f331609b8fa..bbfcdce54a85e 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilege.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilege.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilegt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilegt.c index 464f7c111e343..ea263e4ad1036 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilegt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilegt.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilerw-bfloat.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilerw-bfloat.c new file mode 100644 index 0000000000000..9ea4ebc9ddceb --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilerw-bfloat.c @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -D__ARM_FEATURE_BF16_SCALAR_ARITHMETIC -triple aarch64-none-linux-gnu -target-feature +sve2 -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -D__ARM_FEATURE_BF16_SCALAR_ARITHMETIC -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_BF16_SCALAR_ARITHMETIC -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_BF16_SCALAR_ARITHMETIC -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbool_t test_svwhilerw_bf16(const bfloat16_t *op1, const bfloat16_t *op2) +{ + // CHECK-LABEL: test_svwhilerw_bf16 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.whilerw.h.nxv8i1.p0bf16(bfloat* %op1, bfloat* %op2) + // CHECK: %[[INTRINSIC_REINT:.*]] = call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( %[[INTRINSIC]]) + // CHECK: ret %[[INTRINSIC_REINT]] + // overload-warning@+2 {{implicit declaration of function 'svwhilerw'}} + // expected-warning@+1 {{implicit declaration of function 'svwhilerw_bf16'}} + return SVE_ACLE_FUNC(svwhilerw,_bf16,,)(op1, op2); +} diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilerw.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilerw.c index cfb2600aaf05d..0fcd6be3043d1 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilerw.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilerw.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilewr-bfloat.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilewr-bfloat.c new file mode 100644 index 0000000000000..a8d09379b7163 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilewr-bfloat.c @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -D__ARM_FEATURE_BF16_SCALAR_ARITHMETIC -triple aarch64-none-linux-gnu -target-feature +sve2 -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -D__ARM_FEATURE_BF16_SCALAR_ARITHMETIC -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_BF16_SCALAR_ARITHMETIC -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_BF16_SCALAR_ARITHMETIC -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +svbool_t test_svwhilewr_bf16(const bfloat16_t *op1, const bfloat16_t *op2) +{ + // CHECK-LABEL: test_svwhilewr_bf16 + // CHECK: %[[INTRINSIC:.*]] = call @llvm.aarch64.sve.whilewr.h.nxv8i1.p0bf16(bfloat* %op1, bfloat* %op2) + // CHECK: %[[INTRINSIC_REINT:.*]] = call @llvm.aarch64.sve.convert.to.svbool.nxv8i1( %[[INTRINSIC]]) + // CHECK: ret %[[INTRINSIC_REINT]] + // overload-warning@+2 {{implicit declaration of function 'svwhilewr'}} + // expected-warning@+1 {{implicit declaration of function 'svwhilewr_bf16'}} + return SVE_ACLE_FUNC(svwhilewr,_bf16,,)(op1, op2); +} diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilewr.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilewr.c index 8495a30cd801c..4541c31971485 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilewr.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilewr.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_xar.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_xar.c index 5cd7cf0c4fd47..95542c07a44c6 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_xar.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_xar.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify=overload -verify-ignore-unexpected=error %s #include diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cadd.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cadd.c index 70e8f3192a82f..12d695d1a4a7b 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cadd.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cadd.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cdot.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cdot.c index cb177b943cd5b..88b662d089f9d 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cdot.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cdot.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=warning %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=warning %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=warning %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=warning %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cmla.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cmla.c index 338e1f10f8dc3..4c0592addb5d8 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cmla.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cmla.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mla.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mla.c index 969317db8a0b0..ee679750b9f6b 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mla.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mla.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlalb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlalb.c index 17b8282c60010..da67b6de26bbf 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlalb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlalb.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlalt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlalt.c index f93de7cdf8d23..8f2b4e4897c07 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlalt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlalt.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mls.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mls.c index 1467931a4b312..e727f5745bd66 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mls.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mls.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlslb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlslb.c index d6c44447dd02d..cda90d870b687 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlslb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlslb.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlslt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlslt.c index 5ac82f7c48d7b..c51ccff08b792 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlslt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlslt.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mul.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mul.c index 73d7d6f79d345..fe407224e4dfb 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mul.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mul.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mullb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mullb.c index 010e969d5a580..9902a4a89618d 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mullb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mullb.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mullt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mullt.c index 3dca8dd37e34b..f29b01d278738 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mullt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mullt.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qcadd.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qcadd.c index adf04c9928468..8dea17f829a8f 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qcadd.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qcadd.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlalb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlalb.c index fc40b7010ceb6..24adade56741d 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlalb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlalb.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlalt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlalt.c index 32d28bfaf87a7..b3dd7bd940dc1 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlalt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlalt.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlslb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlslb.c index 6e5203d3c45d5..250e6755794e6 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlslb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlslb.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlslt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlslt.c index f47dc027c00d1..9d38a7849cfdd 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlslt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlslt.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmulh.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmulh.c index 60207813d8a39..58401229adaae 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmulh.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmulh.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmullb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmullb.c index f40c221f286ab..5b22db2f8ed09 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmullb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmullb.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmullt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmullt.c index 85b96b4ef7772..597ac7e08a679 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmullt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmullt.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdcmlah.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdcmlah.c index 547da4c17ed99..ce1bafe877559 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdcmlah.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdcmlah.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdmlah.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdmlah.c index 94a5f351d6e80..266d658af31bc 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdmlah.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdmlah.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdmlsh.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdmlsh.c index 5ca6e6e1917a9..8074a605041b4 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdmlsh.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdmlsh.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdmulh.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdmulh.c index ead75193692d1..14834aa42596b 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdmulh.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdmulh.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrnb.c index bbbbfc418cc96..f92fe6011e7d5 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrnb.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrnt.c index 4a323b56c1b37..0c791e005bfdc 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrnt.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrunb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrunb.c index ff45e95c5d520..541ae62837d1b 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrunb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrunb.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrunt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrunt.c index 849500d3a4cb3..4b6dc9e7f164f 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrunt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrunt.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshlu.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshlu.c index 6b7e5a5f69376..ca26aec41bdb4 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshlu.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshlu.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrnb.c index dc7189583b8ca..19d4d8a97a60b 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrnb.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrnt.c index 0e05ce5093237..18d9ccc04a425 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrnt.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrunb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrunb.c index e4da43cb607b4..bee61489d4d61 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrunb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrunb.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrunt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrunt.c index 4caf7bc3c6d2c..8b7c202fba80e 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrunt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrunt.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshr.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshr.c index 2f7513db3a347..9da56a0163ce0 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshr.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshr.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshrnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshrnb.c index 4c9fd97eca03f..dfba6aeb1d760 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshrnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshrnb.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshrnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshrnt.c index 99c751fafbe6c..c859022738528 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshrnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshrnt.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rsra.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rsra.c index e279a384e01d9..acf5065a9348f 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rsra.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rsra.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shllb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shllb.c index 79a7b59299371..5e4af80a5bb9d 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shllb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shllb.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shllt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shllt.c index e989544048f57..6b67e2dd45c34 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shllt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shllt.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shrnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shrnb.c index 60cf3a1154ed0..f783779ac2232 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shrnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shrnb.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shrnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shrnt.c index d6d0a23ae5049..8bca15b643170 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shrnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shrnt.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sli.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sli.c index f8846952dd4a6..ce159bcf679ab 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sli.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sli.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sra.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sra.c index efd4a70c37ec5..b70d4351ad887 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sra.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sra.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sri.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sri.c index 48aea5c124276..19acfebc661a7 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sri.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sri.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_xar.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_xar.c index 2d96ab558781f..d0d7f5d0dc133 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_xar.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_xar.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s -// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s #ifdef SVE_OVERLOADED_FORMS // A simple used,unused... macro, long enough to represent any SVE builtin. diff --git a/clang/test/CodeGen/aarch64-v8.2a-fp16-intrinsics-constrained.c b/clang/test/CodeGen/aarch64-v8.2a-fp16-intrinsics-constrained.c index 473d3ba53e968..d42fb1e02cade 100644 --- a/clang/test/CodeGen/aarch64-v8.2a-fp16-intrinsics-constrained.c +++ b/clang/test/CodeGen/aarch64-v8.2a-fp16-intrinsics-constrained.c @@ -12,7 +12,7 @@ // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +fullfp16 \ // RUN: -ffp-exception-behavior=strict \ // RUN: -fallow-half-arguments-and-returns -S -disable-O0-optnone -o - %s \ -// RUN: | FileCheck -vv --check-prefix=COMMON --check-prefix=CHECK-ASM %s +// RUN: | FileCheck --check-prefix=COMMON --check-prefix=CHECK-ASM %s // REQUIRES: aarch64-registered-target diff --git a/clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics-constrained.c b/clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics-constrained.c index 6058e6f92832f..478c4a27c3e7a 100644 --- a/clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics-constrained.c +++ b/clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics-constrained.c @@ -4,6 +4,7 @@ // RUN: | FileCheck --check-prefix=COMMON --check-prefix=COMMONIR --check-prefix=UNCONSTRAINED %s // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -target-feature +fullfp16 -target-feature +v8.2a\ // RUN: -ffp-exception-behavior=strict \ +// RUN: -fexperimental-strict-floating-point \ // RUN: -fallow-half-arguments-and-returns -flax-vector-conversions=none -S -disable-O0-optnone -emit-llvm -o - %s \ // RUN: | opt -S -mem2reg \ // RUN: | FileCheck --check-prefix=COMMON --check-prefix=COMMONIR --check-prefix=CONSTRAINED %s @@ -13,6 +14,7 @@ // RUN: | FileCheck --check-prefix=COMMON --check-prefix=CHECK-ASM %s // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -target-feature +fullfp16 -target-feature +v8.2a\ // RUN: -ffp-exception-behavior=strict \ +// RUN: -fexperimental-strict-floating-point \ // RUN: -fallow-half-arguments-and-returns -flax-vector-conversions=none -S -disable-O0-optnone -emit-llvm -o - %s \ // RUN: | opt -S -mem2reg | llc -o=- - \ // RUN: | FileCheck --check-prefix=COMMON --check-prefix=CHECK-ASM %s diff --git a/clang/test/CodeGen/align_value.cpp b/clang/test/CodeGen/align_value.cpp index 3badcd74f46d6..acbfbaf2ba5c7 100644 --- a/clang/test/CodeGen/align_value.cpp +++ b/clang/test/CodeGen/align_value.cpp @@ -1,103 +1,192 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s typedef double * __attribute__((align_value(64))) aligned_double; +// CHECK-LABEL: define {{[^@]+}}@_Z3fooPdS_Rd +// CHECK-SAME: (double* align 64 [[X:%.*]], double* align 32 [[Y:%.*]], double* nonnull align 128 dereferenceable(8) [[Z:%.*]]) #0 +// CHECK-NEXT: entry: +// CHECK-NEXT: [[X_ADDR:%.*]] = alloca double*, align 8 +// CHECK-NEXT: [[Y_ADDR:%.*]] = alloca double*, align 8 +// CHECK-NEXT: [[Z_ADDR:%.*]] = alloca double*, align 8 +// CHECK-NEXT: store double* [[X]], double** [[X_ADDR]], align 8 +// CHECK-NEXT: store double* [[Y]], double** [[Y_ADDR]], align 8 +// CHECK-NEXT: store double* [[Z]], double** [[Z_ADDR]], align 8 +// CHECK-NEXT: ret void +// void foo(aligned_double x, double * y __attribute__((align_value(32))), double & z __attribute__((align_value(128)))) { }; -// CHECK: define void @_Z3fooPdS_Rd(double* align 64 %x, double* align 32 %y, double* nonnull align 128 dereferenceable(8) %z) struct ad_struct { aligned_double a; }; +// CHECK-LABEL: define {{[^@]+}}@_Z3fooR9ad_struct +// CHECK-SAME: (%struct.ad_struct* nonnull align 8 dereferenceable(8) [[X:%.*]]) #0 +// CHECK-NEXT: entry: +// CHECK-NEXT: [[X_ADDR:%.*]] = alloca %struct.ad_struct*, align 8 +// CHECK-NEXT: store %struct.ad_struct* [[X]], %struct.ad_struct** [[X_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load %struct.ad_struct*, %struct.ad_struct** [[X_ADDR]], align 8 +// CHECK-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_AD_STRUCT:%.*]], %struct.ad_struct* [[TMP0]], i32 0, i32 0 +// CHECK-NEXT: [[TMP1:%.*]] = load double*, double** [[A]], align 8 +// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint double* [[TMP1]] to i64 +// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 63 +// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]]) +// CHECK-NEXT: ret double* [[TMP1]] +// double *foo(ad_struct& x) { -// CHECK-LABEL: @_Z3fooR9ad_struct -// CHECK: [[PTRINT1:%.+]] = ptrtoint -// CHECK: [[MASKEDPTR1:%.+]] = and i64 [[PTRINT1]], 63 -// CHECK: [[MASKCOND1:%.+]] = icmp eq i64 [[MASKEDPTR1]], 0 -// CHECK: call void @llvm.assume(i1 [[MASKCOND1]]) return x.a; } +// CHECK-LABEL: define {{[^@]+}}@_Z3gooP9ad_struct +// CHECK-SAME: (%struct.ad_struct* [[X:%.*]]) #0 +// CHECK-NEXT: entry: +// CHECK-NEXT: [[X_ADDR:%.*]] = alloca %struct.ad_struct*, align 8 +// CHECK-NEXT: store %struct.ad_struct* [[X]], %struct.ad_struct** [[X_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load %struct.ad_struct*, %struct.ad_struct** [[X_ADDR]], align 8 +// CHECK-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_AD_STRUCT:%.*]], %struct.ad_struct* [[TMP0]], i32 0, i32 0 +// CHECK-NEXT: [[TMP1:%.*]] = load double*, double** [[A]], align 8 +// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint double* [[TMP1]] to i64 +// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 63 +// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]]) +// CHECK-NEXT: ret double* [[TMP1]] +// double *goo(ad_struct *x) { -// CHECK-LABEL: @_Z3gooP9ad_struct -// CHECK: [[PTRINT2:%.+]] = ptrtoint -// CHECK: [[MASKEDPTR2:%.+]] = and i64 [[PTRINT2]], 63 -// CHECK: [[MASKCOND2:%.+]] = icmp eq i64 [[MASKEDPTR2]], 0 -// CHECK: call void @llvm.assume(i1 [[MASKCOND2]]) return x->a; } +// CHECK-LABEL: define {{[^@]+}}@_Z3barPPd +// CHECK-SAME: (double** [[X:%.*]]) #0 +// CHECK-NEXT: entry: +// CHECK-NEXT: [[X_ADDR:%.*]] = alloca double**, align 8 +// CHECK-NEXT: store double** [[X]], double*** [[X_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load double**, double*** [[X_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load double*, double** [[TMP0]], align 8 +// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint double* [[TMP1]] to i64 +// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 63 +// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]]) +// CHECK-NEXT: ret double* [[TMP1]] +// double *bar(aligned_double *x) { -// CHECK-LABEL: @_Z3barPPd -// CHECK: [[PTRINT3:%.+]] = ptrtoint -// CHECK: [[MASKEDPTR3:%.+]] = and i64 [[PTRINT3]], 63 -// CHECK: [[MASKCOND3:%.+]] = icmp eq i64 [[MASKEDPTR3]], 0 -// CHECK: call void @llvm.assume(i1 [[MASKCOND3]]) return *x; } +// CHECK-LABEL: define {{[^@]+}}@_Z3carRPd +// CHECK-SAME: (double** nonnull align 8 dereferenceable(8) [[X:%.*]]) #0 +// CHECK-NEXT: entry: +// CHECK-NEXT: [[X_ADDR:%.*]] = alloca double**, align 8 +// CHECK-NEXT: store double** [[X]], double*** [[X_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load double**, double*** [[X_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load double*, double** [[TMP0]], align 8 +// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint double* [[TMP1]] to i64 +// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 63 +// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]]) +// CHECK-NEXT: ret double* [[TMP1]] +// double *car(aligned_double &x) { -// CHECK-LABEL: @_Z3carRPd -// CHECK: [[PTRINT4:%.+]] = ptrtoint -// CHECK: [[MASKEDPTR4:%.+]] = and i64 [[PTRINT4]], 63 -// CHECK: [[MASKCOND4:%.+]] = icmp eq i64 [[MASKEDPTR4]], 0 -// CHECK: call void @llvm.assume(i1 [[MASKCOND4]]) return x; } +// CHECK-LABEL: define {{[^@]+}}@_Z3darPPd +// CHECK-SAME: (double** [[X:%.*]]) #0 +// CHECK-NEXT: entry: +// CHECK-NEXT: [[X_ADDR:%.*]] = alloca double**, align 8 +// CHECK-NEXT: store double** [[X]], double*** [[X_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load double**, double*** [[X_ADDR]], align 8 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds double*, double** [[TMP0]], i64 5 +// CHECK-NEXT: [[TMP1:%.*]] = load double*, double** [[ARRAYIDX]], align 8 +// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint double* [[TMP1]] to i64 +// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 63 +// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]]) +// CHECK-NEXT: ret double* [[TMP1]] +// double *dar(aligned_double *x) { -// CHECK-LABEL: @_Z3darPPd -// CHECK: [[PTRINT5:%.+]] = ptrtoint -// CHECK: [[MASKEDPTR5:%.+]] = and i64 [[PTRINT5]], 63 -// CHECK: [[MASKCOND5:%.+]] = icmp eq i64 [[MASKEDPTR5]], 0 -// CHECK: call void @llvm.assume(i1 [[MASKCOND5]]) return x[5]; } aligned_double eep(); +// CHECK-LABEL: define {{[^@]+}}@_Z3retv() #0 +// CHECK-NEXT: entry: +// CHECK-NEXT: [[CALL:%.*]] = call double* @_Z3eepv() +// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint double* [[CALL]] to i64 +// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 63 +// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]]) +// CHECK-NEXT: ret double* [[CALL]] +// double *ret() { -// CHECK-LABEL: @_Z3retv -// CHECK: [[PTRINT6:%.+]] = ptrtoint -// CHECK: [[MASKEDPTR6:%.+]] = and i64 [[PTRINT6]], 63 -// CHECK: [[MASKCOND6:%.+]] = icmp eq i64 [[MASKEDPTR6]], 0 -// CHECK: call void @llvm.assume(i1 [[MASKCOND6]]) return eep(); } +// CHECK-LABEL: define {{[^@]+}}@_Z3no1PPd +// CHECK-SAME: (double** [[X:%.*]]) #0 +// CHECK-NEXT: entry: +// CHECK-NEXT: [[X_ADDR:%.*]] = alloca double**, align 8 +// CHECK-NEXT: store double** [[X]], double*** [[X_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load double**, double*** [[X_ADDR]], align 8 +// CHECK-NEXT: ret double** [[TMP0]] +// double **no1(aligned_double *x) { -// CHECK-LABEL: @_Z3no1PPd return x; -// CHECK-NOT: call void @llvm.assume } +// CHECK-LABEL: define {{[^@]+}}@_Z3no2RPd +// CHECK-SAME: (double** nonnull align 8 dereferenceable(8) [[X:%.*]]) #0 +// CHECK-NEXT: entry: +// CHECK-NEXT: [[X_ADDR:%.*]] = alloca double**, align 8 +// CHECK-NEXT: store double** [[X]], double*** [[X_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load double**, double*** [[X_ADDR]], align 8 +// CHECK-NEXT: ret double** [[TMP0]] +// double *&no2(aligned_double &x) { -// CHECK-LABEL: @_Z3no2RPd return x; -// CHECK-NOT: call void @llvm.assume } +// CHECK-LABEL: define {{[^@]+}}@_Z3no3RPd +// CHECK-SAME: (double** nonnull align 8 dereferenceable(8) [[X:%.*]]) #0 +// CHECK-NEXT: entry: +// CHECK-NEXT: [[X_ADDR:%.*]] = alloca double**, align 8 +// CHECK-NEXT: store double** [[X]], double*** [[X_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load double**, double*** [[X_ADDR]], align 8 +// CHECK-NEXT: ret double** [[TMP0]] +// double **no3(aligned_double &x) { -// CHECK-LABEL: @_Z3no3RPd return &x; -// CHECK-NOT: call void @llvm.assume } +// CHECK-LABEL: define {{[^@]+}}@_Z3no3Pd +// CHECK-SAME: (double* align 64 [[X:%.*]]) #0 +// CHECK-NEXT: entry: +// CHECK-NEXT: [[X_ADDR:%.*]] = alloca double*, align 8 +// CHECK-NEXT: store double* [[X]], double** [[X_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load double*, double** [[X_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load double, double* [[TMP0]], align 8 +// CHECK-NEXT: ret double [[TMP1]] +// double no3(aligned_double x) { -// CHECK-LABEL: @_Z3no3Pd return *x; -// CHECK-NOT: call void @llvm.assume } +// CHECK-LABEL: define {{[^@]+}}@_Z3no4Pd +// CHECK-SAME: (double* align 64 [[X:%.*]]) #0 +// CHECK-NEXT: entry: +// CHECK-NEXT: [[X_ADDR:%.*]] = alloca double*, align 8 +// CHECK-NEXT: store double* [[X]], double** [[X_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load double*, double** [[X_ADDR]], align 8 +// CHECK-NEXT: ret double* [[TMP0]] +// double *no4(aligned_double x) { -// CHECK-LABEL: @_Z3no4Pd return x; -// CHECK-NOT: call void @llvm.assume } diff --git a/clang/test/CodeGen/alloc-align-attr.c b/clang/test/CodeGen/alloc-align-attr.c index 6294450d04445..9517c50dbb1db 100644 --- a/clang/test/CodeGen/alloc-align-attr.c +++ b/clang/test/CodeGen/alloc-align-attr.c @@ -1,57 +1,90 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s __INT32_TYPE__*m1(__INT32_TYPE__ i) __attribute__((alloc_align(1))); // Condition where parameter to m1 is not size_t. +// CHECK-LABEL: define {{[^@]+}}@test1 +// CHECK-SAME: (i32 [[A:%.*]]) #0 +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 [[A]], i32* [[A_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A_ADDR]], align 4 +// CHECK-NEXT: [[CALL:%.*]] = call i32* @m1(i32 [[TMP0]]) +// CHECK-NEXT: [[ALIGNMENTCAST:%.*]] = zext i32 [[TMP0]] to i64 +// CHECK-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENTCAST]], 1 +// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[CALL]] to i64 +// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], [[MASK]] +// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]]) +// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[CALL]], align 4 +// CHECK-NEXT: ret i32 [[TMP1]] +// __INT32_TYPE__ test1(__INT32_TYPE__ a) { -// CHECK: define i32 @test1 return *m1(a); -// CHECK: call i32* @m1(i32 [[PARAM1:%[^\)]+]]) -// CHECK: [[ALIGNCAST1:%.+]] = zext i32 [[PARAM1]] to i64 -// CHECK: [[MASK1:%.+]] = sub i64 [[ALIGNCAST1]], 1 -// CHECK: [[PTRINT1:%.+]] = ptrtoint -// CHECK: [[MASKEDPTR1:%.+]] = and i64 [[PTRINT1]], [[MASK1]] -// CHECK: [[MASKCOND1:%.+]] = icmp eq i64 [[MASKEDPTR1]], 0 -// CHECK: call void @llvm.assume(i1 [[MASKCOND1]]) } // Condition where test2 param needs casting. +// CHECK-LABEL: define {{[^@]+}}@test2 +// CHECK-SAME: (i64 [[A:%.*]]) #0 +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8 +// CHECK-NEXT: store i64 [[A]], i64* [[A_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A_ADDR]], align 8 +// CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK-NEXT: [[CALL:%.*]] = call i32* @m1(i32 [[CONV]]) +// CHECK-NEXT: [[ALIGNMENTCAST:%.*]] = zext i32 [[CONV]] to i64 +// CHECK-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENTCAST]], 1 +// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[CALL]] to i64 +// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], [[MASK]] +// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]]) +// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[CALL]], align 4 +// CHECK-NEXT: ret i32 [[TMP1]] +// __INT32_TYPE__ test2(__SIZE_TYPE__ a) { -// CHECK: define i32 @test2 return *m1(a); -// CHECK: [[CONV2:%.+]] = trunc i64 %{{.+}} to i32 -// CHECK: call i32* @m1(i32 [[CONV2]]) -// CHECK: [[ALIGNCAST2:%.+]] = zext i32 [[CONV2]] to i64 -// CHECK: [[MASK2:%.+]] = sub i64 [[ALIGNCAST2]], 1 -// CHECK: [[PTRINT2:%.+]] = ptrtoint -// CHECK: [[MASKEDPTR2:%.+]] = and i64 [[PTRINT2]], [[MASK2]] -// CHECK: [[MASKCOND2:%.+]] = icmp eq i64 [[MASKEDPTR2]], 0 -// CHECK: call void @llvm.assume(i1 [[MASKCOND2]]) } __INT32_TYPE__ *m2(__SIZE_TYPE__ i) __attribute__((alloc_align(1))); // test3 param needs casting, but 'm2' is correct. +// CHECK-LABEL: define {{[^@]+}}@test3 +// CHECK-SAME: (i32 [[A:%.*]]) #0 +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 [[A]], i32* [[A_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A_ADDR]], align 4 +// CHECK-NEXT: [[CONV:%.*]] = sext i32 [[TMP0]] to i64 +// CHECK-NEXT: [[CALL:%.*]] = call i32* @m2(i64 [[CONV]]) +// CHECK-NEXT: [[MASK:%.*]] = sub i64 [[CONV]], 1 +// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[CALL]] to i64 +// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], [[MASK]] +// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]]) +// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[CALL]], align 4 +// CHECK-NEXT: ret i32 [[TMP1]] +// __INT32_TYPE__ test3(__INT32_TYPE__ a) { -// CHECK: define i32 @test3 return *m2(a); -// CHECK: [[CONV3:%.+]] = sext i32 %{{.+}} to i64 -// CHECK: call i32* @m2(i64 [[CONV3]]) -// CHECK: [[MASK3:%.+]] = sub i64 [[CONV3]], 1 -// CHECK: [[PTRINT3:%.+]] = ptrtoint -// CHECK: [[MASKEDPTR3:%.+]] = and i64 [[PTRINT3]], [[MASK3]] -// CHECK: [[MASKCOND3:%.+]] = icmp eq i64 [[MASKEDPTR3]], 0 -// CHECK: call void @llvm.assume(i1 [[MASKCOND3]]) } // Every type matches, canonical example. +// CHECK-LABEL: define {{[^@]+}}@test4 +// CHECK-SAME: (i64 [[A:%.*]]) #0 +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8 +// CHECK-NEXT: store i64 [[A]], i64* [[A_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A_ADDR]], align 8 +// CHECK-NEXT: [[CALL:%.*]] = call i32* @m2(i64 [[TMP0]]) +// CHECK-NEXT: [[MASK:%.*]] = sub i64 [[TMP0]], 1 +// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[CALL]] to i64 +// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], [[MASK]] +// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]]) +// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[CALL]], align 4 +// CHECK-NEXT: ret i32 [[TMP1]] +// __INT32_TYPE__ test4(__SIZE_TYPE__ a) { -// CHECK: define i32 @test4 return *m2(a); -// CHECK: call i32* @m2(i64 [[PARAM4:%[^\)]+]]) -// CHECK: [[MASK4:%.+]] = sub i64 [[PARAM4]], 1 -// CHECK: [[PTRINT4:%.+]] = ptrtoint -// CHECK: [[MASKEDPTR4:%.+]] = and i64 [[PTRINT4]], [[MASK4]] -// CHECK: [[MASKCOND4:%.+]] = icmp eq i64 [[MASKEDPTR4]], 0 -// CHECK: call void @llvm.assume(i1 [[MASKCOND4]]) } @@ -60,30 +93,81 @@ struct MultiArgs { __INT64_TYPE__ a, b;}; // Struct parameter doesn't take up an IR parameter, 'i' takes up 2. // Truncation to i64 is permissible, since alignments of greater than 2^64 are insane. __INT32_TYPE__ *m3(struct Empty s, __int128_t i) __attribute__((alloc_align(2))); +// CHECK-LABEL: define {{[^@]+}}@test5 +// CHECK-SAME: (i64 [[A_COERCE0:%.*]], i64 [[A_COERCE1:%.*]]) #0 +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A:%.*]] = alloca i128, align 16 +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i128, align 16 +// CHECK-NEXT: [[E:%.*]] = alloca [[STRUCT_EMPTY:%.*]], align 1 +// CHECK-NEXT: [[COERCE:%.*]] = alloca i128, align 16 +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128* [[A]] to { i64, i64 }* +// CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[TMP0]], i32 0, i32 0 +// CHECK-NEXT: store i64 [[A_COERCE0]], i64* [[TMP1]], align 16 +// CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[TMP0]], i32 0, i32 1 +// CHECK-NEXT: store i64 [[A_COERCE1]], i64* [[TMP2]], align 8 +// CHECK-NEXT: [[A1:%.*]] = load i128, i128* [[A]], align 16 +// CHECK-NEXT: store i128 [[A1]], i128* [[A_ADDR]], align 16 +// CHECK-NEXT: [[TMP3:%.*]] = load i128, i128* [[A_ADDR]], align 16 +// CHECK-NEXT: store i128 [[TMP3]], i128* [[COERCE]], align 16 +// CHECK-NEXT: [[TMP4:%.*]] = bitcast i128* [[COERCE]] to { i64, i64 }* +// CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[TMP4]], i32 0, i32 0 +// CHECK-NEXT: [[TMP6:%.*]] = load i64, i64* [[TMP5]], align 16 +// CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[TMP4]], i32 0, i32 1 +// CHECK-NEXT: [[TMP8:%.*]] = load i64, i64* [[TMP7]], align 8 +// CHECK-NEXT: [[CALL:%.*]] = call i32* @m3(i64 [[TMP6]], i64 [[TMP8]]) +// CHECK-NEXT: [[ALIGNMENTCAST:%.*]] = trunc i128 [[TMP3]] to i64 +// CHECK-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENTCAST]], 1 +// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[CALL]] to i64 +// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], [[MASK]] +// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]]) +// CHECK-NEXT: [[TMP9:%.*]] = load i32, i32* [[CALL]], align 4 +// CHECK-NEXT: ret i32 [[TMP9]] +// __INT32_TYPE__ test5(__int128_t a) { -// CHECK: define i32 @test5 struct Empty e; return *m3(e, a); -// CHECK: call i32* @m3(i64 %{{.*}}, i64 %{{.*}}) -// CHECK: [[ALIGNCAST5:%.+]] = trunc i128 %{{.*}} to i64 -// CHECK: [[MASK5:%.+]] = sub i64 [[ALIGNCAST5]], 1 -// CHECK: [[PTRINT5:%.+]] = ptrtoint -// CHECK: [[MASKEDPTR5:%.+]] = and i64 [[PTRINT5]], [[MASK5]] -// CHECK: [[MASKCOND5:%.+]] = icmp eq i64 [[MASKEDPTR5]], 0 -// CHECK: call void @llvm.assume(i1 [[MASKCOND5]]) } // Struct parameter takes up 2 parameters, 'i' takes up 2. __INT32_TYPE__ *m4(struct MultiArgs s, __int128_t i) __attribute__((alloc_align(2))); +// CHECK-LABEL: define {{[^@]+}}@test6 +// CHECK-SAME: (i64 [[A_COERCE0:%.*]], i64 [[A_COERCE1:%.*]]) #0 +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A:%.*]] = alloca i128, align 16 +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i128, align 16 +// CHECK-NEXT: [[E:%.*]] = alloca [[STRUCT_MULTIARGS:%.*]], align 8 +// CHECK-NEXT: [[COERCE:%.*]] = alloca i128, align 16 +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128* [[A]] to { i64, i64 }* +// CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[TMP0]], i32 0, i32 0 +// CHECK-NEXT: store i64 [[A_COERCE0]], i64* [[TMP1]], align 16 +// CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[TMP0]], i32 0, i32 1 +// CHECK-NEXT: store i64 [[A_COERCE1]], i64* [[TMP2]], align 8 +// CHECK-NEXT: [[A1:%.*]] = load i128, i128* [[A]], align 16 +// CHECK-NEXT: store i128 [[A1]], i128* [[A_ADDR]], align 16 +// CHECK-NEXT: [[TMP3:%.*]] = load i128, i128* [[A_ADDR]], align 16 +// CHECK-NEXT: [[TMP4:%.*]] = bitcast %struct.MultiArgs* [[E]] to { i64, i64 }* +// CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[TMP4]], i32 0, i32 0 +// CHECK-NEXT: [[TMP6:%.*]] = load i64, i64* [[TMP5]], align 8 +// CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[TMP4]], i32 0, i32 1 +// CHECK-NEXT: [[TMP8:%.*]] = load i64, i64* [[TMP7]], align 8 +// CHECK-NEXT: store i128 [[TMP3]], i128* [[COERCE]], align 16 +// CHECK-NEXT: [[TMP9:%.*]] = bitcast i128* [[COERCE]] to { i64, i64 }* +// CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[TMP9]], i32 0, i32 0 +// CHECK-NEXT: [[TMP11:%.*]] = load i64, i64* [[TMP10]], align 16 +// CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* [[TMP9]], i32 0, i32 1 +// CHECK-NEXT: [[TMP13:%.*]] = load i64, i64* [[TMP12]], align 8 +// CHECK-NEXT: [[CALL:%.*]] = call i32* @m4(i64 [[TMP6]], i64 [[TMP8]], i64 [[TMP11]], i64 [[TMP13]]) +// CHECK-NEXT: [[ALIGNMENTCAST:%.*]] = trunc i128 [[TMP3]] to i64 +// CHECK-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENTCAST]], 1 +// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[CALL]] to i64 +// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], [[MASK]] +// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]]) +// CHECK-NEXT: [[TMP14:%.*]] = load i32, i32* [[CALL]], align 4 +// CHECK-NEXT: ret i32 [[TMP14]] +// __INT32_TYPE__ test6(__int128_t a) { -// CHECK: define i32 @test6 struct MultiArgs e; return *m4(e, a); -// CHECK: call i32* @m4(i64 %{{.*}}, i64 %{{.*}}, i64 %{{.*}}) -// CHECK: [[ALIGNCAST6:%.+]] = trunc i128 %{{.*}} to i64 -// CHECK: [[MASK6:%.+]] = sub i64 [[ALIGNCAST6]], 1 -// CHECK: [[PTRINT6:%.+]] = ptrtoint -// CHECK: [[MASKEDPTR6:%.+]] = and i64 [[PTRINT6]], [[MASK6]] -// CHECK: [[MASKCOND6:%.+]] = icmp eq i64 [[MASKEDPTR6]], 0 -// CHECK: call void @llvm.assume(i1 [[MASKCOND6]]) } diff --git a/clang/test/CodeGen/arm-bf16-convert-intrinsics.c b/clang/test/CodeGen/arm-bf16-convert-intrinsics.c new file mode 100644 index 0000000000000..d36d8def70dea --- /dev/null +++ b/clang/test/CodeGen/arm-bf16-convert-intrinsics.c @@ -0,0 +1,88 @@ +// RUN: %clang_cc1 \ +// RUN: -triple aarch64-arm-none-eabi -target-feature +neon -target-feature +bf16 \ +// RUN: -disable-O0-optnone -emit-llvm -o - %s \ +// RUN: | opt -S -mem2reg -instcombine \ +// RUN: | FileCheck --check-prefixes=CHECK,CHECK-A64 %s +// RUN: %clang_cc1 \ +// RUN: -triple armv8.6a-arm-none-eabi -target-feature +neon \ +// RUN: -target-feature +bf16 -mfloat-abi hard \ +// RUN: -disable-O0-optnone -emit-llvm -o - %s \ +// RUN: | opt -S -mem2reg -instcombine \ +// RUN: | FileCheck --check-prefixes=CHECK,CHECK-A32-HARDFP %s +// RUN: %clang_cc1 \ +// RUN: -triple armv8.6a-arm-none-eabi -target-feature +neon \ +// RUN: -target-feature +bf16 -mfloat-abi softfp \ +// RUN: -disable-O0-optnone -emit-llvm -o - %s \ +// RUN: | opt -S -mem2reg -instcombine \ +// RUN: | FileCheck --check-prefixes=CHECK,CHECK-A32-SOFTFP %s + +#include + +// CHECK-LABEL: test_vcvt_f32_bf16 +// CHECK: %[[EXT:.*]] = zext <4 x i16> %{{.*}} to <4 x i32> +// CHECK: shl nuw <4 x i32> %[[EXT]], +float32x4_t test_vcvt_f32_bf16(bfloat16x4_t a) { + return vcvt_f32_bf16(a); +} + +// CHECK-LABEL: test_vcvtq_low_f32_bf16 +// CHECK: shufflevector <8 x bfloat> %{{.*}}, <8 x bfloat> undef, <4 x i32> +// CHECK: %[[EXT:.*]] = zext <4 x i16> %{{.*}} to <4 x i32> +// CHECK: shl nuw <4 x i32> %[[EXT]], +float32x4_t test_vcvtq_low_f32_bf16(bfloat16x8_t a) { + return vcvtq_low_f32_bf16(a); +} + +// CHECK-LABEL: test_vcvtq_high_f32_bf16 +// CHECK: shufflevector <8 x bfloat> %{{.*}}, <8 x bfloat> undef, <4 x i32> +// CHECK: %[[EXT:.*]] = zext <4 x i16> %{{.*}} to <4 x i32> +// CHECK: shl nuw <4 x i32> %[[EXT]], +float32x4_t test_vcvtq_high_f32_bf16(bfloat16x8_t a) { + return vcvtq_high_f32_bf16(a); +} + +// CHECK-LABEL: test_vcvt_bf16_f32 +// CHECK-A64: %[[CVT:.*]] = call <8 x bfloat> @llvm.aarch64.neon.bfcvtn(<4 x float> %a) +// CHECK-A64: shufflevector <8 x bfloat> %[[CVT]], <8 x bfloat> undef, <4 x i32> +// CHECK-A32-HARDFP: call <4 x bfloat> @llvm.arm.neon.vcvtfp2bf.v4bf16(<4 x float> %a) +// CHECK-A32-SOFTFP: call <4 x i16> @llvm.arm.neon.vcvtfp2bf.v4i16(<4 x float> %a) +bfloat16x4_t test_vcvt_bf16_f32(float32x4_t a) { + return vcvt_bf16_f32(a); +} + +// CHECK-LABEL: test_vcvtq_low_bf16_f32 +// CHECK-A64: call <8 x bfloat> @llvm.aarch64.neon.bfcvtn(<4 x float> %a) +// CHECK-A32-HARDFP: %[[CVT:.*]] = call <4 x bfloat> @llvm.arm.neon.vcvtfp2bf.v4bf16 +// CHECK-A32-HARDFP: shufflevector <4 x bfloat> zeroinitializer, <4 x bfloat> %[[CVT]], <8 x i32> +// CHECK-A32-SOFTFP: call <4 x i16> @llvm.arm.neon.vcvtfp2bf.v4i16 +// CHECK-A32-SOFTFP: shufflevector <4 x bfloat> zeroinitializer, <4 x bfloat> %{{.*}}, <8 x i32> +bfloat16x8_t test_vcvtq_low_bf16_f32(float32x4_t a) { + return vcvtq_low_bf16_f32(a); +} + +// CHECK-LABEL: test_vcvtq_high_bf16_f32 +// CHECK-A64: call <8 x bfloat> @llvm.aarch64.neon.bfcvtn2(<8 x bfloat> %inactive, <4 x float> %a) +// CHECK-A32-HARDFP: %[[CVT:.*]] = call <4 x bfloat> @llvm.arm.neon.vcvtfp2bf.v4bf16(<4 x float> %a) +// CHECK-A32-HARDFP: %[[INACT:.*]] = shufflevector <8 x bfloat> %inactive, <8 x bfloat> undef, <4 x i32> +// CHECK-A32-HARDFP: shufflevector <4 x bfloat> %[[CVT]], <4 x bfloat> %[[INACT]], <8 x i32> +// CHECK-A32-SOFTFP: call <4 x i16> @llvm.arm.neon.vcvtfp2bf.v4i16(<4 x float> %a) +// CHECK-A32-SOFTFP: shufflevector <8 x bfloat> %{{.*}}, <8 x bfloat> undef, <4 x i32> +// CHECK-A32-SOFTFP: shufflevector <4 x bfloat> %{{.*}}, <4 x bfloat> %{{.*}}, <8 x i32> +bfloat16x8_t test_vcvtq_high_bf16_f32(bfloat16x8_t inactive, float32x4_t a) { + return vcvtq_high_bf16_f32(inactive, a); +} + +// CHECK-LABEL: test_vcvth_bf16_f32 +// CHECK-A64: call bfloat @llvm.aarch64.neon.bfcvt(float %a) +// CHECK-A32-HARDFP: call bfloat @llvm.arm.neon.vcvtbfp2bf(float %a) +// CHECK-A32-SOFTFP: call bfloat @llvm.arm.neon.vcvtbfp2bf(float %a) +bfloat16_t test_vcvth_bf16_f32(float32_t a) { + return vcvth_bf16_f32(a); +} + +// CHECK-LABEL: test_vcvtah_f32_bf16 +// CHECK: shl i32 %{{.*}}, 16 +float32_t test_vcvtah_f32_bf16(bfloat16_t a) { + return vcvtah_f32_bf16(a); +} + diff --git a/clang/test/CodeGen/arm-bf16-dotprod-intrinsics.c b/clang/test/CodeGen/arm-bf16-dotprod-intrinsics.c new file mode 100644 index 0000000000000..0eb130a377bdd --- /dev/null +++ b/clang/test/CodeGen/arm-bf16-dotprod-intrinsics.c @@ -0,0 +1,166 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// RUN: %clang_cc1 -triple armv8-arm-none-eabi \ +// RUN: -target-feature +neon -target-feature +bf16 -mfloat-abi soft \ +// RUN: -disable-O0-optnone -S -emit-llvm -o - %s \ +// RUN: | opt -S -mem2reg -instcombine | FileCheck %s +// RUN: %clang_cc1 -triple armv8-arm-none-eabi \ +// RUN: -target-feature +neon -target-feature +bf16 -mfloat-abi hard \ +// RUN: -disable-O0-optnone -S -emit-llvm -o - %s \ +// RUN: | opt -S -mem2reg -instcombine | FileCheck %s + +#include + +// CHECK-LABEL: @test_vbfdot_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x bfloat> [[A:%.*]] to <8 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x bfloat> [[B:%.*]] to <8 x i8> +// CHECK-NEXT: [[VBFDOT1_I:%.*]] = call <2 x float> @llvm.arm.neon.bfdot.v2f32.v8i8(<2 x float> [[R:%.*]], <8 x i8> [[TMP0]], <8 x i8> [[TMP1]]) #3 +// CHECK-NEXT: ret <2 x float> [[VBFDOT1_I]] +// +float32x2_t test_vbfdot_f32(float32x2_t r, bfloat16x4_t a, bfloat16x4_t b) { + return vbfdot_f32(r, a, b); +} + +// CHECK-LABEL: @test_vbfdotq_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x bfloat> [[B:%.*]] to <16 x i8> +// CHECK-NEXT: [[VBFDOT1_I:%.*]] = call <4 x float> @llvm.arm.neon.bfdot.v4f32.v16i8(<4 x float> [[R:%.*]], <16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) #3 +// CHECK-NEXT: ret <4 x float> [[VBFDOT1_I]] +// +float32x4_t test_vbfdotq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b){ + return vbfdotq_f32(r, a, b); +} + +// CHECK-LABEL: @test_vbfdot_lane_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[DOTCAST:%.*]] = bitcast <4 x bfloat> [[B:%.*]] to <2 x float> +// CHECK-NEXT: [[LANE:%.*]] = shufflevector <2 x float> [[DOTCAST]], <2 x float> undef, <2 x i32> zeroinitializer +// CHECK-NEXT: [[DOTCAST1:%.*]] = bitcast <2 x float> [[LANE]] to <8 x i8> +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x bfloat> [[A:%.*]] to <8 x i8> +// CHECK-NEXT: [[VBFDOT1_I:%.*]] = call <2 x float> @llvm.arm.neon.bfdot.v2f32.v8i8(<2 x float> [[R:%.*]], <8 x i8> [[TMP0]], <8 x i8> [[DOTCAST1]]) #3 +// CHECK-NEXT: ret <2 x float> [[VBFDOT1_I]] +// +float32x2_t test_vbfdot_lane_f32(float32x2_t r, bfloat16x4_t a, bfloat16x4_t b){ + return vbfdot_lane_f32(r, a, b, 0); +} + +// CHECK-LABEL: @test_vbfdotq_laneq_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[DOTCAST:%.*]] = bitcast <8 x bfloat> [[B:%.*]] to <4 x float> +// CHECK-NEXT: [[LANE:%.*]] = shufflevector <4 x float> [[DOTCAST]], <4 x float> undef, <4 x i32> +// CHECK-NEXT: [[DOTCAST1:%.*]] = bitcast <4 x float> [[LANE]] to <16 x i8> +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> +// CHECK-NEXT: [[VBFDOT1_I:%.*]] = call <4 x float> @llvm.arm.neon.bfdot.v4f32.v16i8(<4 x float> [[R:%.*]], <16 x i8> [[TMP0]], <16 x i8> [[DOTCAST1]]) #3 +// CHECK-NEXT: ret <4 x float> [[VBFDOT1_I]] +// +float32x4_t test_vbfdotq_laneq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { + return vbfdotq_laneq_f32(r, a, b, 3); +} + +// CHECK-LABEL: @test_vbfdot_laneq_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[DOTCAST:%.*]] = bitcast <8 x bfloat> [[B:%.*]] to <4 x float> +// CHECK-NEXT: [[LANE:%.*]] = shufflevector <4 x float> [[DOTCAST]], <4 x float> undef, <2 x i32> +// CHECK-NEXT: [[DOTCAST1:%.*]] = bitcast <2 x float> [[LANE]] to <8 x i8> +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x bfloat> [[A:%.*]] to <8 x i8> +// CHECK-NEXT: [[VBFDOT1_I:%.*]] = call <2 x float> @llvm.arm.neon.bfdot.v2f32.v8i8(<2 x float> [[R:%.*]], <8 x i8> [[TMP0]], <8 x i8> [[DOTCAST1]]) #3 +// CHECK-NEXT: ret <2 x float> [[VBFDOT1_I]] +// +float32x2_t test_vbfdot_laneq_f32(float32x2_t r, bfloat16x4_t a, bfloat16x8_t b) { + return vbfdot_laneq_f32(r, a, b, 3); +} + +// CHECK-LABEL: @test_vbfdotq_lane_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[DOTCAST:%.*]] = bitcast <4 x bfloat> [[B:%.*]] to <2 x float> +// CHECK-NEXT: [[LANE:%.*]] = shufflevector <2 x float> [[DOTCAST]], <2 x float> undef, <4 x i32> zeroinitializer +// CHECK-NEXT: [[DOTCAST1:%.*]] = bitcast <4 x float> [[LANE]] to <16 x i8> +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> +// CHECK-NEXT: [[VBFDOT1_I:%.*]] = call <4 x float> @llvm.arm.neon.bfdot.v4f32.v16i8(<4 x float> [[R:%.*]], <16 x i8> [[TMP0]], <16 x i8> [[DOTCAST1]]) #3 +// CHECK-NEXT: ret <4 x float> [[VBFDOT1_I]] +// +float32x4_t test_vbfdotq_lane_f32(float32x4_t r, bfloat16x8_t a, bfloat16x4_t b) { + return vbfdotq_lane_f32(r, a, b, 0); +} + +// CHECK-LABEL: @test_vbfmmlaq_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x bfloat> [[B:%.*]] to <16 x i8> +// CHECK-NEXT: [[VBFMMLA1_I:%.*]] = call <4 x float> @llvm.arm.neon.bfmmla.v4f32.v16i8(<4 x float> [[R:%.*]], <16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) #3 +// CHECK-NEXT: ret <4 x float> [[VBFMMLA1_I]] +// +float32x4_t test_vbfmmlaq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { + return vbfmmlaq_f32(r, a, b); +} + +// CHECK-LABEL: @test_vbfmlalbq_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x bfloat> [[B:%.*]] to <16 x i8> +// CHECK-NEXT: [[VBFMLALB1_I:%.*]] = call <4 x float> @llvm.arm.neon.bfmlalb.v4f32.v16i8(<4 x float> [[R:%.*]], <16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) #3 +// CHECK-NEXT: ret <4 x float> [[VBFMLALB1_I]] +// +float32x4_t test_vbfmlalbq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { + return vbfmlalbq_f32(r, a, b); +} + +// CHECK-LABEL: @test_vbfmlaltq_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x bfloat> [[B:%.*]] to <16 x i8> +// CHECK-NEXT: [[VBFMLALT1_I:%.*]] = call <4 x float> @llvm.arm.neon.bfmlalt.v4f32.v16i8(<4 x float> [[R:%.*]], <16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) #3 +// CHECK-NEXT: ret <4 x float> [[VBFMLALT1_I]] +// +float32x4_t test_vbfmlaltq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { + return vbfmlaltq_f32(r, a, b); +} + +// CHECK-LABEL: @test_vbfmlalbq_lane_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VECINIT35:%.*]] = shufflevector <4 x bfloat> [[B:%.*]], <4 x bfloat> undef, <8 x i32> zeroinitializer +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x bfloat> [[VECINIT35]] to <16 x i8> +// CHECK-NEXT: [[VBFMLALB1_I:%.*]] = call <4 x float> @llvm.arm.neon.bfmlalb.v4f32.v16i8(<4 x float> [[R:%.*]], <16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) #3 +// CHECK-NEXT: ret <4 x float> [[VBFMLALB1_I]] +// +float32x4_t test_vbfmlalbq_lane_f32(float32x4_t r, bfloat16x8_t a, bfloat16x4_t b) { + return vbfmlalbq_lane_f32(r, a, b, 0); +} + +// CHECK-LABEL: @test_vbfmlalbq_laneq_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VECINIT35:%.*]] = shufflevector <8 x bfloat> [[B:%.*]], <8 x bfloat> undef, <8 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x bfloat> [[VECINIT35]] to <16 x i8> +// CHECK-NEXT: [[VBFMLALB1_I:%.*]] = call <4 x float> @llvm.arm.neon.bfmlalb.v4f32.v16i8(<4 x float> [[R:%.*]], <16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) #3 +// CHECK-NEXT: ret <4 x float> [[VBFMLALB1_I]] +// +float32x4_t test_vbfmlalbq_laneq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { + return vbfmlalbq_laneq_f32(r, a, b, 3); +} + +// CHECK-LABEL: @test_vbfmlaltq_lane_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VECINIT35:%.*]] = shufflevector <4 x bfloat> [[B:%.*]], <4 x bfloat> undef, <8 x i32> zeroinitializer +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x bfloat> [[VECINIT35]] to <16 x i8> +// CHECK-NEXT: [[VBFMLALT1_I:%.*]] = call <4 x float> @llvm.arm.neon.bfmlalt.v4f32.v16i8(<4 x float> [[R:%.*]], <16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) #3 +// CHECK-NEXT: ret <4 x float> [[VBFMLALT1_I]] +// +float32x4_t test_vbfmlaltq_lane_f32(float32x4_t r, bfloat16x8_t a, bfloat16x4_t b) { + return vbfmlaltq_lane_f32(r, a, b, 0); +} + +// CHECK-LABEL: @test_vbfmlaltq_laneq_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[VECINIT35:%.*]] = shufflevector <8 x bfloat> [[B:%.*]], <8 x bfloat> undef, <8 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x bfloat> [[A:%.*]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x bfloat> [[VECINIT35]] to <16 x i8> +// CHECK-NEXT: [[VBFMLALT1_I:%.*]] = call <4 x float> @llvm.arm.neon.bfmlalt.v4f32.v16i8(<4 x float> [[R:%.*]], <16 x i8> [[TMP0]], <16 x i8> [[TMP1]]) #3 +// CHECK-NEXT: ret <4 x float> [[VBFMLALT1_I]] +// +float32x4_t test_vbfmlaltq_laneq_f32(float32x4_t r, bfloat16x8_t a, bfloat16x8_t b) { + return vbfmlaltq_laneq_f32(r, a, b, 3); +} diff --git a/clang/test/CodeGen/arm-bf16-getset-intrinsics.c b/clang/test/CodeGen/arm-bf16-getset-intrinsics.c index ed35f810d18fc..a1a5b7b54f3ed 100644 --- a/clang/test/CodeGen/arm-bf16-getset-intrinsics.c +++ b/clang/test/CodeGen/arm-bf16-getset-intrinsics.c @@ -1,6 +1,8 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple armv8.6a-arm-none-eabi -target-feature +neon -target-feature +bf16 -mfloat-abi hard \ // RUN: -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg -instcombine | FileCheck %s +// RUN: %clang_cc1 -triple armv8.6a-arm-none-eabi -target-feature +neon -target-feature +bf16 -mfloat-abi soft \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg -instcombine | FileCheck %s #include @@ -98,8 +100,8 @@ bfloat16x4_t test_vget_low_bf16(bfloat16x8_t a) { // CHECK-LABEL: @test_vget_lane_bf16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[DOTCAST1:%.*]] = extractelement <4 x bfloat> [[V:%.*]], i32 1 -// CHECK-NEXT: ret bfloat [[DOTCAST1]] +// CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <4 x bfloat> [[V:%.*]], i32 1 +// CHECK-NEXT: ret bfloat [[VGET_LANE]] // bfloat16_t test_vget_lane_bf16(bfloat16x4_t v) { return vget_lane_bf16(v, 1); @@ -107,8 +109,8 @@ bfloat16_t test_vget_lane_bf16(bfloat16x4_t v) { // CHECK-LABEL: @test_vgetq_lane_bf16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[DOTCAST1:%.*]] = extractelement <8 x bfloat> [[V:%.*]], i32 7 -// CHECK-NEXT: ret bfloat [[DOTCAST1]] +// CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <8 x bfloat> [[V:%.*]], i32 7 +// CHECK-NEXT: ret bfloat [[VGET_LANE]] // bfloat16_t test_vgetq_lane_bf16(bfloat16x8_t v) { return vgetq_lane_bf16(v, 7); @@ -116,8 +118,8 @@ bfloat16_t test_vgetq_lane_bf16(bfloat16x8_t v) { // CHECK-LABEL: @test_vset_lane_bf16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = insertelement <4 x bfloat> [[V:%.*]], bfloat [[A:%.*]], i32 1 -// CHECK-NEXT: ret <4 x bfloat> [[TMP0]] +// CHECK-NEXT: [[VSET_LANE:%.*]] = insertelement <4 x bfloat> [[V:%.*]], bfloat [[A:%.*]], i32 1 +// CHECK-NEXT: ret <4 x bfloat> [[VSET_LANE]] // bfloat16x4_t test_vset_lane_bf16(bfloat16_t a, bfloat16x4_t v) { return vset_lane_bf16(a, v, 1); @@ -125,8 +127,8 @@ bfloat16x4_t test_vset_lane_bf16(bfloat16_t a, bfloat16x4_t v) { // CHECK-LABEL: @test_vsetq_lane_bf16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = insertelement <8 x bfloat> [[V:%.*]], bfloat [[A:%.*]], i32 7 -// CHECK-NEXT: ret <8 x bfloat> [[TMP0]] +// CHECK-NEXT: [[VSET_LANE:%.*]] = insertelement <8 x bfloat> [[V:%.*]], bfloat [[A:%.*]], i32 7 +// CHECK-NEXT: ret <8 x bfloat> [[VSET_LANE]] // bfloat16x8_t test_vsetq_lane_bf16(bfloat16_t a, bfloat16x8_t v) { return vsetq_lane_bf16(a, v, 7); @@ -143,8 +145,8 @@ bfloat16_t test_vduph_lane_bf16(bfloat16x4_t v) { // CHECK-LABEL: @test_vduph_laneq_bf16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[VGETQ_LANE:%.*]] = extractelement <8 x bfloat> [[V:%.*]], i32 7 -// CHECK-NEXT: ret bfloat [[VGETQ_LANE]] +// CHECK-NEXT: [[VGET_LANE:%.*]] = extractelement <8 x bfloat> [[V:%.*]], i32 7 +// CHECK-NEXT: ret bfloat [[VGET_LANE]] // bfloat16_t test_vduph_laneq_bf16(bfloat16x8_t v) { return vduph_laneq_bf16(v, 7); diff --git a/clang/test/CodeGen/arm-mve-intrinsics/dup.c b/clang/test/CodeGen/arm-mve-intrinsics/dup.c index 283c082570056..b443917cb2582 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/dup.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/dup.c @@ -242,7 +242,8 @@ uint32x4_t test_vdupq_m_n_u32(uint32x4_t inactive, uint32_t a, mve_pred16_t p) // CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) // CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <8 x half> undef, half [[A:%.*]], i32 0 // CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <8 x half> [[DOTSPLATINSERT]], <8 x half> undef, <8 x i32> zeroinitializer -// CHECK-NEXT: ret <8 x half> [[DOTSPLAT]] +// CHECK-NEXT: [[TMP2:%.*]] = select <8 x i1> [[TMP1]], <8 x half> [[DOTSPLAT]], <8 x half> undef +// CHECK-NEXT: ret <8 x half> [[TMP2]] // float16x8_t test_vdupq_x_n_f16(float16_t a, mve_pred16_t p) { @@ -255,7 +256,8 @@ float16x8_t test_vdupq_x_n_f16(float16_t a, mve_pred16_t p) // CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) // CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x float> undef, float [[A:%.*]], i32 0 // CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <4 x float> [[DOTSPLATINSERT]], <4 x float> undef, <4 x i32> zeroinitializer -// CHECK-NEXT: ret <4 x float> [[DOTSPLAT]] +// CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x float> [[DOTSPLAT]], <4 x float> undef +// CHECK-NEXT: ret <4 x float> [[TMP2]] // float32x4_t test_vdupq_x_n_f32(float32_t a, mve_pred16_t p) { @@ -268,7 +270,8 @@ float32x4_t test_vdupq_x_n_f32(float32_t a, mve_pred16_t p) // CHECK-NEXT: [[TMP1:%.*]] = call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[TMP0]]) // CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <16 x i8> undef, i8 [[A:%.*]], i32 0 // CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <16 x i8> [[DOTSPLATINSERT]], <16 x i8> undef, <16 x i32> zeroinitializer -// CHECK-NEXT: ret <16 x i8> [[DOTSPLAT]] +// CHECK-NEXT: [[TMP2:%.*]] = select <16 x i1> [[TMP1]], <16 x i8> [[DOTSPLAT]], <16 x i8> undef +// CHECK-NEXT: ret <16 x i8> [[TMP2]] // int8x16_t test_vdupq_x_n_s8(int8_t a, mve_pred16_t p) { @@ -281,7 +284,8 @@ int8x16_t test_vdupq_x_n_s8(int8_t a, mve_pred16_t p) // CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) // CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <8 x i16> undef, i16 [[A:%.*]], i32 0 // CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <8 x i16> [[DOTSPLATINSERT]], <8 x i16> undef, <8 x i32> zeroinitializer -// CHECK-NEXT: ret <8 x i16> [[DOTSPLAT]] +// CHECK-NEXT: [[TMP2:%.*]] = select <8 x i1> [[TMP1]], <8 x i16> [[DOTSPLAT]], <8 x i16> undef +// CHECK-NEXT: ret <8 x i16> [[TMP2]] // int16x8_t test_vdupq_x_n_s16(int16_t a, mve_pred16_t p) { @@ -294,7 +298,8 @@ int16x8_t test_vdupq_x_n_s16(int16_t a, mve_pred16_t p) // CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) // CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x i32> undef, i32 [[A:%.*]], i32 0 // CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <4 x i32> [[DOTSPLATINSERT]], <4 x i32> undef, <4 x i32> zeroinitializer -// CHECK-NEXT: ret <4 x i32> [[DOTSPLAT]] +// CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[DOTSPLAT]], <4 x i32> undef +// CHECK-NEXT: ret <4 x i32> [[TMP2]] // int32x4_t test_vdupq_x_n_s32(int32_t a, mve_pred16_t p) { @@ -307,7 +312,8 @@ int32x4_t test_vdupq_x_n_s32(int32_t a, mve_pred16_t p) // CHECK-NEXT: [[TMP1:%.*]] = call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[TMP0]]) // CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <16 x i8> undef, i8 [[A:%.*]], i32 0 // CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <16 x i8> [[DOTSPLATINSERT]], <16 x i8> undef, <16 x i32> zeroinitializer -// CHECK-NEXT: ret <16 x i8> [[DOTSPLAT]] +// CHECK-NEXT: [[TMP2:%.*]] = select <16 x i1> [[TMP1]], <16 x i8> [[DOTSPLAT]], <16 x i8> undef +// CHECK-NEXT: ret <16 x i8> [[TMP2]] // uint8x16_t test_vdupq_x_n_u8(uint8_t a, mve_pred16_t p) { @@ -320,7 +326,8 @@ uint8x16_t test_vdupq_x_n_u8(uint8_t a, mve_pred16_t p) // CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]]) // CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <8 x i16> undef, i16 [[A:%.*]], i32 0 // CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <8 x i16> [[DOTSPLATINSERT]], <8 x i16> undef, <8 x i32> zeroinitializer -// CHECK-NEXT: ret <8 x i16> [[DOTSPLAT]] +// CHECK-NEXT: [[TMP2:%.*]] = select <8 x i1> [[TMP1]], <8 x i16> [[DOTSPLAT]], <8 x i16> undef +// CHECK-NEXT: ret <8 x i16> [[TMP2]] // uint16x8_t test_vdupq_x_n_u16(uint16_t a, mve_pred16_t p) { @@ -333,7 +340,8 @@ uint16x8_t test_vdupq_x_n_u16(uint16_t a, mve_pred16_t p) // CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) // CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x i32> undef, i32 [[A:%.*]], i32 0 // CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <4 x i32> [[DOTSPLATINSERT]], <4 x i32> undef, <4 x i32> zeroinitializer -// CHECK-NEXT: ret <4 x i32> [[DOTSPLAT]] +// CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[DOTSPLAT]], <4 x i32> undef +// CHECK-NEXT: ret <4 x i32> [[TMP2]] // uint32x4_t test_vdupq_x_n_u32(uint32_t a, mve_pred16_t p) { diff --git a/clang/test/CodeGen/arm-neon-directed-rounding-constrained.c b/clang/test/CodeGen/arm-neon-directed-rounding-constrained.c index 5246993173f83..7dedab375c81e 100644 --- a/clang/test/CodeGen/arm-neon-directed-rounding-constrained.c +++ b/clang/test/CodeGen/arm-neon-directed-rounding-constrained.c @@ -7,10 +7,12 @@ // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a57 \ // RUN: -ffp-exception-behavior=strict \ +// RUN: -fexperimental-strict-floating-point \ // RUN: -ffreestanding -disable-O0-optnone -emit-llvm %s -o - | \ // RUN: opt -S -mem2reg | FileCheck -check-prefixes=COMMON,COMMONIR,CONSTRAINED %s // RUN: %clang_cc1 -triple arm64-linux-gnueabihf -target-feature +neon \ // RUN: -ffp-exception-behavior=strict \ +// RUN: -fexperimental-strict-floating-point \ // RUN: -ffreestanding -disable-O0-optnone -emit-llvm %s -o - | \ // RUN: opt -S -mem2reg | FileCheck -check-prefixes=COMMON,COMMONIR,CONSTRAINED %s @@ -23,10 +25,12 @@ // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a57 \ // RUN: -ffp-exception-behavior=strict \ +// RUN: -fexperimental-strict-floating-point \ // RUN: -ffreestanding -disable-O0-optnone -emit-llvm %s -o - | \ // RUN: opt -S -mem2reg | llc -o=- - | FileCheck -check-prefixes=COMMON,CHECK-ASM32 %s // RUN: %clang_cc1 -triple arm64-linux-gnueabihf -target-feature +neon \ // RUN: -ffp-exception-behavior=strict \ +// RUN: -fexperimental-strict-floating-point \ // RUN: -ffreestanding -disable-O0-optnone -emit-llvm %s -o - | \ // RUN: opt -S -mem2reg | llc -o=- - | FileCheck -check-prefixes=COMMON,CHECK-ASM64 %s diff --git a/clang/test/CodeGen/arm64-vrnd-constrained.c b/clang/test/CodeGen/arm64-vrnd-constrained.c index bbded8f2c7f66..ee2edbcbd0964 100644 --- a/clang/test/CodeGen/arm64-vrnd-constrained.c +++ b/clang/test/CodeGen/arm64-vrnd-constrained.c @@ -1,10 +1,10 @@ // RUN: %clang_cc1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -flax-vector-conversions=none -emit-llvm -o - %s \ // RUN: | FileCheck --check-prefix=COMMON --check-prefix=COMMONIR --check-prefix=UNCONSTRAINED %s -// RUN: %clang_cc1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -flax-vector-conversions=none -ffp-exception-behavior=strict -emit-llvm -o - %s \ +// RUN: %clang_cc1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -flax-vector-conversions=none -fexperimental-strict-floating-point -ffp-exception-behavior=strict -emit-llvm -o - %s \ // RUN: | FileCheck --check-prefix=COMMON --check-prefix=COMMONIR --check-prefix=CONSTRAINED %s // RUN: %clang_cc1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -flax-vector-conversions=none -emit-llvm -o - %s | llc -o=- - \ // RUN: | FileCheck --check-prefix=COMMON --check-prefix=CHECK-ASM %s -// RUN: %clang_cc1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -flax-vector-conversions=none -ffp-exception-behavior=strict -emit-llvm -o - %s | llc -o=- - \ +// RUN: %clang_cc1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -flax-vector-conversions=none -fexperimental-strict-floating-point -ffp-exception-behavior=strict -emit-llvm -o - %s | llc -o=- - \ // RUN: | FileCheck --check-prefix=COMMON --check-prefix=CHECK-ASM %s // REQUIRES: aarch64-registered-target diff --git a/clang/test/CodeGen/attr-target-x86.c b/clang/test/CodeGen/attr-target-x86.c index 73486e5ee1fe7..feed175cce0bc 100644 --- a/clang/test/CodeGen/attr-target-x86.c +++ b/clang/test/CodeGen/attr-target-x86.c @@ -50,9 +50,9 @@ int __attribute__((target("arch=lakemont,mmx"))) use_before_def(void) { // CHECK: use_before_def{{.*}} #7 // CHECK: #0 = {{.*}}"target-cpu"="i686" "target-features"="+cx8,+x87" // CHECK: #1 = {{.*}}"target-cpu"="ivybridge" "target-features"="+avx,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" -// CHECK: #2 = {{.*}}"target-cpu"="i686" "target-features"="+cx8,+x87,-aes,-avx,-avx2,-avx512bf16,-avx512bitalg,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512ifma,-avx512pf,-avx512vbmi,-avx512vbmi2,-avx512vl,-avx512vnni,-avx512vp2intersect,-avx512vpopcntdq,-f16c,-fma,-fma4,-gfni,-pclmul,-sha,-sse2,-sse3,-sse4.1,-sse4.2,-sse4a,-ssse3,-vaes,-vpclmulqdq,-xop,-xsave,-xsaveopt" +// CHECK: #2 = {{.*}}"target-cpu"="i686" "target-features"="+cx8,+x87,-aes,-avx,-avx2,-avx512bf16,-avx512bitalg,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512ifma,-avx512pf,-avx512vbmi,-avx512vbmi2,-avx512vl,-avx512vnni,-avx512vp2intersect,-avx512vpopcntdq,-f16c,-fma,-fma4,-gfni,-pclmul,-sha,-sse2,-sse3,-sse4.1,-sse4.2,-sse4a,-ssse3,-vaes,-vpclmulqdq,-xop" // CHECK: #3 = {{.*}}"target-cpu"="i686" "target-features"="+cx8,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87" -// CHECK: #4 = {{.*}}"target-cpu"="i686" "target-features"="+cx8,+x87,-avx,-avx2,-avx512bf16,-avx512bitalg,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512ifma,-avx512pf,-avx512vbmi,-avx512vbmi2,-avx512vl,-avx512vnni,-avx512vp2intersect,-avx512vpopcntdq,-f16c,-fma,-fma4,-sse4.1,-sse4.2,-vaes,-vpclmulqdq,-xop,-xsave,-xsaveopt" +// CHECK: #4 = {{.*}}"target-cpu"="i686" "target-features"="+cx8,+x87,-avx,-avx2,-avx512bf16,-avx512bitalg,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512ifma,-avx512pf,-avx512vbmi,-avx512vbmi2,-avx512vl,-avx512vnni,-avx512vp2intersect,-avx512vpopcntdq,-f16c,-fma,-fma4,-sse4.1,-sse4.2,-vaes,-vpclmulqdq,-xop" // CHECK: #5 = {{.*}}"target-cpu"="ivybridge" "target-features"="+avx,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt,-aes,-vaes" // CHECK: #6 = {{.*}}"target-cpu"="i686" "target-features"="+cx8,+x87,-3dnow,-3dnowa,-mmx" // CHECK: #7 = {{.*}}"target-cpu"="lakemont" "target-features"="+cx8,+mmx" diff --git a/clang/test/CodeGen/builtin-align.c b/clang/test/CodeGen/builtin-align.c index 8fb51822164d0..7e66e2b5c0b9b 100644 --- a/clang/test/CodeGen/builtin-align.c +++ b/clang/test/CodeGen/builtin-align.c @@ -1,21 +1,22 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py /// Check the code generation for the alignment builtins /// To make the test case easier to read, run SROA after generating IR to remove the alloca instructions. // RUN: %clang_cc1 -triple=x86_64-unknown-unknown -DTEST_VOID_PTR \ // RUN: -o - -emit-llvm %s -disable-O0-optnone | opt -S -sroa | \ -// RUN: FileCheck %s -check-prefixes CHECK,POINTER,ALIGNMENT_EXT \ +// RUN: FileCheck %s -check-prefixes CHECK,CHECK-VOID_PTR \ // RUN: -enable-var-scope '-D$PTRTYPE=i8' // RUN: %clang_cc1 -triple=x86_64-unknown-unknown -DTEST_FLOAT_PTR \ // RUN: -o - -emit-llvm %s -disable-O0-optnone | opt -S -sroa | \ -// RUN: FileCheck %s -check-prefixes CHECK,POINTER,NON_I8_POINTER,ALIGNMENT_EXT \ +// RUN: FileCheck %s -check-prefixes CHECK,CHECK-FLOAT_PTR \ // RUN: -enable-var-scope '-D$PTRTYPE=f32' // RUN: %clang_cc1 -triple=x86_64-unknown-unknown -DTEST_LONG \ // RUN: -o - -emit-llvm %s -disable-O0-optnone | opt -S -sroa | \ -// RUN: FileCheck %s -check-prefixes CHECK,INTEGER,ALIGNMENT_EXT -enable-var-scope +// RUN: FileCheck %s -check-prefixes CHECK,CHECK-LONG -enable-var-scope /// Check that we can handle the case where the alignment parameter is wider /// than the source type (generate a trunc on alignment instead of zext) // RUN: %clang_cc1 -triple=x86_64-unknown-unknown -DTEST_USHORT \ // RUN: -o - -emit-llvm %s -disable-O0-optnone | opt -S -sroa | \ -// RUN: FileCheck %s -check-prefixes CHECK,INTEGER,ALIGNMENT_TRUNC -enable-var-scope +// RUN: FileCheck %s -check-prefixes CHECK,CHECK-USHORT -enable-var-scope #ifdef TEST_VOID_PTR @@ -24,8 +25,6 @@ #define TYPE float * #elif defined(TEST_LONG) #define TYPE long -#elif defined(TEST_CAP) -#define TYPE void *__capability #elif defined(TEST_USHORT) #define TYPE unsigned short #else @@ -49,78 +48,185 @@ int up_2 = __builtin_align_up(256, 32); // CHECK: @up_2 = global i32 256, align 4 /// Capture the IR type here to use in the remaining FileCheck captures: -// CHECK: define {{[^@]+}}@get_type() #0 -// CHECK-NEXT: entry: -// POINTER-NEXT: ret [[$TYPE:.+]] null -// INTEGER-NEXT: ret [[$TYPE:.+]] 0 +// CHECK-VOID_PTR-LABEL: define {{[^@]+}}@get_type() #0 +// CHECK-VOID_PTR-NEXT: entry: +// CHECK-VOID_PTR-NEXT: ret i8* null +// +// CHECK-FLOAT_PTR-LABEL: define {{[^@]+}}@get_type() #0 +// CHECK-FLOAT_PTR-NEXT: entry: +// CHECK-FLOAT_PTR-NEXT: ret float* null +// +// CHECK-LONG-LABEL: define {{[^@]+}}@get_type() #0 +// CHECK-LONG-NEXT: entry: +// CHECK-LONG-NEXT: ret i64 0 +// +// CHECK-USHORT-LABEL: define {{[^@]+}}@get_type() #0 +// CHECK-USHORT-NEXT: entry: +// CHECK-USHORT-NEXT: ret i16 0 // TYPE get_type(void) { return (TYPE)0; } -// CHECK-LABEL: define {{[^@]+}}@is_aligned -// CHECK-SAME: ([[$TYPE]] {{[^%]*}}[[PTR:%.*]], i32 [[ALIGN:%.*]]) #0 -// CHECK-NEXT: entry: -// ALIGNMENT_EXT-NEXT: [[ALIGNMENT:%.*]] = zext i32 [[ALIGN]] to [[ALIGN_TYPE:i64]] -// ALIGNMENT_TRUNC-NEXT: [[ALIGNMENT:%.*]] = trunc i32 [[ALIGN]] to [[ALIGN_TYPE:i16]] -// CHECK-NEXT: [[MASK:%.*]] = sub [[ALIGN_TYPE]] [[ALIGNMENT]], 1 -// POINTER-NEXT: [[PTR:%.*]] = ptrtoint [[$TYPE]] %ptr to i64 -// CHECK-NEXT: [[SET_BITS:%.*]] = and [[ALIGN_TYPE]] [[PTR]], [[MASK]] -// CHECK-NEXT: [[IS_ALIGNED:%.*]] = icmp eq [[ALIGN_TYPE]] [[SET_BITS]], 0 -// CHECK-NEXT: ret i1 [[IS_ALIGNED]] +// CHECK-VOID_PTR-LABEL: define {{[^@]+}}@is_aligned +// CHECK-VOID_PTR-SAME: (i8* [[PTR:%.*]], i32 [[ALIGN:%.*]]) #0 +// CHECK-VOID_PTR-NEXT: entry: +// CHECK-VOID_PTR-NEXT: [[ALIGNMENT:%.*]] = zext i32 [[ALIGN]] to i64 +// CHECK-VOID_PTR-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENT]], 1 +// CHECK-VOID_PTR-NEXT: [[SRC_ADDR:%.*]] = ptrtoint i8* [[PTR]] to i64 +// CHECK-VOID_PTR-NEXT: [[SET_BITS:%.*]] = and i64 [[SRC_ADDR]], [[MASK]] +// CHECK-VOID_PTR-NEXT: [[IS_ALIGNED:%.*]] = icmp eq i64 [[SET_BITS]], 0 +// CHECK-VOID_PTR-NEXT: ret i1 [[IS_ALIGNED]] +// +// CHECK-FLOAT_PTR-LABEL: define {{[^@]+}}@is_aligned +// CHECK-FLOAT_PTR-SAME: (float* [[PTR:%.*]], i32 [[ALIGN:%.*]]) #0 +// CHECK-FLOAT_PTR-NEXT: entry: +// CHECK-FLOAT_PTR-NEXT: [[ALIGNMENT:%.*]] = zext i32 [[ALIGN]] to i64 +// CHECK-FLOAT_PTR-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENT]], 1 +// CHECK-FLOAT_PTR-NEXT: [[SRC_ADDR:%.*]] = ptrtoint float* [[PTR]] to i64 +// CHECK-FLOAT_PTR-NEXT: [[SET_BITS:%.*]] = and i64 [[SRC_ADDR]], [[MASK]] +// CHECK-FLOAT_PTR-NEXT: [[IS_ALIGNED:%.*]] = icmp eq i64 [[SET_BITS]], 0 +// CHECK-FLOAT_PTR-NEXT: ret i1 [[IS_ALIGNED]] +// +// CHECK-LONG-LABEL: define {{[^@]+}}@is_aligned +// CHECK-LONG-SAME: (i64 [[PTR:%.*]], i32 [[ALIGN:%.*]]) #0 +// CHECK-LONG-NEXT: entry: +// CHECK-LONG-NEXT: [[ALIGNMENT:%.*]] = zext i32 [[ALIGN]] to i64 +// CHECK-LONG-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENT]], 1 +// CHECK-LONG-NEXT: [[SET_BITS:%.*]] = and i64 [[PTR]], [[MASK]] +// CHECK-LONG-NEXT: [[IS_ALIGNED:%.*]] = icmp eq i64 [[SET_BITS]], 0 +// CHECK-LONG-NEXT: ret i1 [[IS_ALIGNED]] +// +// CHECK-USHORT-LABEL: define {{[^@]+}}@is_aligned +// CHECK-USHORT-SAME: (i16 zeroext [[PTR:%.*]], i32 [[ALIGN:%.*]]) #0 +// CHECK-USHORT-NEXT: entry: +// CHECK-USHORT-NEXT: [[ALIGNMENT:%.*]] = trunc i32 [[ALIGN]] to i16 +// CHECK-USHORT-NEXT: [[MASK:%.*]] = sub i16 [[ALIGNMENT]], 1 +// CHECK-USHORT-NEXT: [[SET_BITS:%.*]] = and i16 [[PTR]], [[MASK]] +// CHECK-USHORT-NEXT: [[IS_ALIGNED:%.*]] = icmp eq i16 [[SET_BITS]], 0 +// CHECK-USHORT-NEXT: ret i1 [[IS_ALIGNED]] // _Bool is_aligned(TYPE ptr, unsigned align) { return __builtin_is_aligned(ptr, align); } -// CHECK-LABEL: define {{[^@]+}}@align_up -// CHECK-SAME: ([[$TYPE]] {{[^%]*}}[[PTR:%.*]], i32 [[ALIGN:%.*]]) #0 -// CHECK-NEXT: entry: -// ALIGNMENT_EXT-NEXT: [[ALIGNMENT:%.*]] = zext i32 [[ALIGN]] to [[ALIGN_TYPE:i64]] -// ALIGNMENT_TRUNC-NEXT: [[ALIGNMENT:%.*]] = trunc i32 [[ALIGN]] to [[ALIGN_TYPE:i16]] -// CHECK-NEXT: [[MASK:%.*]] = sub [[ALIGN_TYPE]] [[ALIGNMENT]], 1 -// INTEGER-NEXT: [[OVER_BOUNDARY:%.*]] = add [[$TYPE]] [[PTR]], [[MASK]] // NOTYET-POINTER-NEXT: [[ALIGNED_RESULT:%.*]] = call [[$TYPE]] @llvm.ptrmask.p0[[$PTRTYPE]].p0i8.i64(i8* [[OVER_BOUNDARY]], [[ALIGN_TYPE]] [[INVERTED_MASK]]) -// POINTER-NEXT: [[INTPTR:%.*]] = ptrtoint [[$TYPE]] [[PTR]] to [[ALIGN_TYPE]] -// POINTER-NEXT: [[OVER_BOUNDARY:%.*]] = add [[ALIGN_TYPE]] [[INTPTR]], [[MASK]] -// CHECK-NEXT: [[INVERTED_MASK:%.*]] = xor [[ALIGN_TYPE]] [[MASK]], -1 -// CHECK-NEXT: [[ALIGNED_RESULT:%.*]] = and [[ALIGN_TYPE]] [[OVER_BOUNDARY]], [[INVERTED_MASK]] -// POINTER-NEXT: [[DIFF:%.*]] = sub i64 [[ALIGNED_RESULT]], [[INTPTR]] -// NON_I8_POINTER-NEXT: [[PTR:%.*]] = bitcast [[$TYPE]] {{%.*}} to i8* -// POINTER-NEXT: [[ALIGNED_RESULT:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[DIFF]] -// NON_I8_POINTER-NEXT: [[ALIGNED_RESULT:%.*]] = bitcast i8* {{%.*}} to [[$TYPE]] -// POINTER-NEXT: [[ASSUME_MASK:%.*]] = sub i64 %alignment, 1 -// POINTER-NEXT: [[ASSUME_INTPTR:%.*]]= ptrtoint [[$TYPE]] [[ALIGNED_RESULT]] to i64 -// POINTER-NEXT: [[MASKEDPTR:%.*]] = and i64 %ptrint, [[ASSUME_MASK]] -// POINTER-NEXT: [[MASKEDCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 -// POINTER-NEXT: call void @llvm.assume(i1 [[MASKEDCOND]]) -// CHECK-NEXT: ret [[$TYPE]] [[ALIGNED_RESULT]] +// CHECK-VOID_PTR-LABEL: define {{[^@]+}}@align_up +// CHECK-VOID_PTR-SAME: (i8* [[PTR:%.*]], i32 [[ALIGN:%.*]]) #0 +// CHECK-VOID_PTR-NEXT: entry: +// CHECK-VOID_PTR-NEXT: [[ALIGNMENT:%.*]] = zext i32 [[ALIGN]] to i64 +// CHECK-VOID_PTR-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENT]], 1 +// CHECK-VOID_PTR-NEXT: [[INTPTR:%.*]] = ptrtoint i8* [[PTR]] to i64 +// CHECK-VOID_PTR-NEXT: [[OVER_BOUNDARY:%.*]] = add i64 [[INTPTR]], [[MASK]] +// CHECK-VOID_PTR-NEXT: [[INVERTED_MASK:%.*]] = xor i64 [[MASK]], -1 +// CHECK-VOID_PTR-NEXT: [[ALIGNED_INTPTR:%.*]] = and i64 [[OVER_BOUNDARY]], [[INVERTED_MASK]] +// CHECK-VOID_PTR-NEXT: [[DIFF:%.*]] = sub i64 [[ALIGNED_INTPTR]], [[INTPTR]] +// CHECK-VOID_PTR-NEXT: [[ALIGNED_RESULT:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[DIFF]] +// CHECK-VOID_PTR-NEXT: [[MASK1:%.*]] = sub i64 [[ALIGNMENT]], 1 +// CHECK-VOID_PTR-NEXT: [[PTRINT:%.*]] = ptrtoint i8* [[ALIGNED_RESULT]] to i64 +// CHECK-VOID_PTR-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], [[MASK1]] +// CHECK-VOID_PTR-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +// CHECK-VOID_PTR-NEXT: call void @llvm.assume(i1 [[MASKCOND]]) +// CHECK-VOID_PTR-NEXT: ret i8* [[ALIGNED_RESULT]] +// +// CHECK-FLOAT_PTR-LABEL: define {{[^@]+}}@align_up +// CHECK-FLOAT_PTR-SAME: (float* [[PTR:%.*]], i32 [[ALIGN:%.*]]) #0 +// CHECK-FLOAT_PTR-NEXT: entry: +// CHECK-FLOAT_PTR-NEXT: [[ALIGNMENT:%.*]] = zext i32 [[ALIGN]] to i64 +// CHECK-FLOAT_PTR-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENT]], 1 +// CHECK-FLOAT_PTR-NEXT: [[INTPTR:%.*]] = ptrtoint float* [[PTR]] to i64 +// CHECK-FLOAT_PTR-NEXT: [[OVER_BOUNDARY:%.*]] = add i64 [[INTPTR]], [[MASK]] +// CHECK-FLOAT_PTR-NEXT: [[INVERTED_MASK:%.*]] = xor i64 [[MASK]], -1 +// CHECK-FLOAT_PTR-NEXT: [[ALIGNED_INTPTR:%.*]] = and i64 [[OVER_BOUNDARY]], [[INVERTED_MASK]] +// CHECK-FLOAT_PTR-NEXT: [[DIFF:%.*]] = sub i64 [[ALIGNED_INTPTR]], [[INTPTR]] +// CHECK-FLOAT_PTR-NEXT: [[TMP0:%.*]] = bitcast float* [[PTR]] to i8* +// CHECK-FLOAT_PTR-NEXT: [[ALIGNED_RESULT:%.*]] = getelementptr inbounds i8, i8* [[TMP0]], i64 [[DIFF]] +// CHECK-FLOAT_PTR-NEXT: [[TMP1:%.*]] = bitcast i8* [[ALIGNED_RESULT]] to float* +// CHECK-FLOAT_PTR-NEXT: [[MASK1:%.*]] = sub i64 [[ALIGNMENT]], 1 +// CHECK-FLOAT_PTR-NEXT: [[PTRINT:%.*]] = ptrtoint float* [[TMP1]] to i64 +// CHECK-FLOAT_PTR-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], [[MASK1]] +// CHECK-FLOAT_PTR-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +// CHECK-FLOAT_PTR-NEXT: call void @llvm.assume(i1 [[MASKCOND]]) +// CHECK-FLOAT_PTR-NEXT: ret float* [[TMP1]] +// +// CHECK-LONG-LABEL: define {{[^@]+}}@align_up +// CHECK-LONG-SAME: (i64 [[PTR:%.*]], i32 [[ALIGN:%.*]]) #0 +// CHECK-LONG-NEXT: entry: +// CHECK-LONG-NEXT: [[ALIGNMENT:%.*]] = zext i32 [[ALIGN]] to i64 +// CHECK-LONG-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENT]], 1 +// CHECK-LONG-NEXT: [[OVER_BOUNDARY:%.*]] = add i64 [[PTR]], [[MASK]] +// CHECK-LONG-NEXT: [[INVERTED_MASK:%.*]] = xor i64 [[MASK]], -1 +// CHECK-LONG-NEXT: [[ALIGNED_RESULT:%.*]] = and i64 [[OVER_BOUNDARY]], [[INVERTED_MASK]] +// CHECK-LONG-NEXT: ret i64 [[ALIGNED_RESULT]] +// +// CHECK-USHORT-LABEL: define {{[^@]+}}@align_up +// CHECK-USHORT-SAME: (i16 zeroext [[PTR:%.*]], i32 [[ALIGN:%.*]]) #0 +// CHECK-USHORT-NEXT: entry: +// CHECK-USHORT-NEXT: [[ALIGNMENT:%.*]] = trunc i32 [[ALIGN]] to i16 +// CHECK-USHORT-NEXT: [[MASK:%.*]] = sub i16 [[ALIGNMENT]], 1 +// CHECK-USHORT-NEXT: [[OVER_BOUNDARY:%.*]] = add i16 [[PTR]], [[MASK]] +// CHECK-USHORT-NEXT: [[INVERTED_MASK:%.*]] = xor i16 [[MASK]], -1 +// CHECK-USHORT-NEXT: [[ALIGNED_RESULT:%.*]] = and i16 [[OVER_BOUNDARY]], [[INVERTED_MASK]] +// CHECK-USHORT-NEXT: ret i16 [[ALIGNED_RESULT]] // TYPE align_up(TYPE ptr, unsigned align) { return __builtin_align_up(ptr, align); } -// CHECK-LABEL: define {{[^@]+}}@align_down -// CHECK-SAME: ([[$TYPE]] {{[^%]*}}[[PTR:%.*]], i32 [[ALIGN:%.*]]) #0 -// CHECK-NEXT: entry: -// ALIGNMENT_EXT-NEXT: [[ALIGNMENT:%.*]] = zext i32 [[ALIGN]] to [[ALIGN_TYPE:i64]] -// ALIGNMENT_TRUNC-NEXT: [[ALIGNMENT:%.*]] = trunc i32 [[ALIGN]] to [[ALIGN_TYPE:i16]] -// CHECK-NEXT: [[MASK:%.*]] = sub [[ALIGN_TYPE]] [[ALIGNMENT]], 1 // NOTYET-POINTER-NEXT: [[ALIGNED_RESULT:%.*]] = call [[$TYPE]] @llvm.ptrmask.p0[[$PTRTYPE]].p0[[$PTRTYPE]].i64([[$TYPE]] [[PTR]], [[ALIGN_TYPE]] [[INVERTED_MASK]]) -// POINTER-NEXT: [[INTPTR:%.*]] = ptrtoint [[$TYPE]] [[PTR]] to [[ALIGN_TYPE]] -// CHECK-NEXT: [[INVERTED_MASK:%.*]] = xor [[ALIGN_TYPE]] [[MASK]], -1 -// POINTER-NEXT: [[ALIGNED_INTPTR:%.*]] = and [[ALIGN_TYPE]] [[INTPTR]], [[INVERTED_MASK]] -// POINTER-NEXT: [[DIFF:%.*]] = sub i64 [[ALIGNED_INTPTR]], [[INTPTR]] -// NON_I8_POINTER-NEXT: [[PTR:%.*]] = bitcast [[$TYPE]] {{%.*}} to i8* -// POINTER-NEXT: [[ALIGNED_RESULT:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[DIFF]] -// NON_I8_POINTER-NEXT: [[ALIGNED_RESULT:%.*]] = bitcast i8* {{%.*}} to [[$TYPE]] -// INTEGER-NEXT: [[ALIGNED_RESULT:%.*]] = and [[ALIGN_TYPE]] [[PTR]], [[INVERTED_MASK]] -// POINTER-NEXT: [[ASSUME_MASK:%.*]] = sub i64 %alignment, 1 -// POINTER-NEXT: [[ASSUME_INTPTR:%.*]]= ptrtoint [[$TYPE]] [[ALIGNED_RESULT]] to i64 -// POINTER-NEXT: [[MASKEDPTR:%.*]] = and i64 %ptrint, [[ASSUME_MASK]] -// POINTER-NEXT: [[MASKEDCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 -// POINTER-NEXT: call void @llvm.assume(i1 [[MASKEDCOND]]) -// CHECK-NEXT: ret [[$TYPE]] [[ALIGNED_RESULT]] +// CHECK-VOID_PTR-LABEL: define {{[^@]+}}@align_down +// CHECK-VOID_PTR-SAME: (i8* [[PTR:%.*]], i32 [[ALIGN:%.*]]) #0 +// CHECK-VOID_PTR-NEXT: entry: +// CHECK-VOID_PTR-NEXT: [[ALIGNMENT:%.*]] = zext i32 [[ALIGN]] to i64 +// CHECK-VOID_PTR-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENT]], 1 +// CHECK-VOID_PTR-NEXT: [[INTPTR:%.*]] = ptrtoint i8* [[PTR]] to i64 +// CHECK-VOID_PTR-NEXT: [[INVERTED_MASK:%.*]] = xor i64 [[MASK]], -1 +// CHECK-VOID_PTR-NEXT: [[ALIGNED_INTPTR:%.*]] = and i64 [[INTPTR]], [[INVERTED_MASK]] +// CHECK-VOID_PTR-NEXT: [[DIFF:%.*]] = sub i64 [[ALIGNED_INTPTR]], [[INTPTR]] +// CHECK-VOID_PTR-NEXT: [[ALIGNED_RESULT:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[DIFF]] +// CHECK-VOID_PTR-NEXT: [[MASK1:%.*]] = sub i64 [[ALIGNMENT]], 1 +// CHECK-VOID_PTR-NEXT: [[PTRINT:%.*]] = ptrtoint i8* [[ALIGNED_RESULT]] to i64 +// CHECK-VOID_PTR-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], [[MASK1]] +// CHECK-VOID_PTR-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +// CHECK-VOID_PTR-NEXT: call void @llvm.assume(i1 [[MASKCOND]]) +// CHECK-VOID_PTR-NEXT: ret i8* [[ALIGNED_RESULT]] +// +// CHECK-FLOAT_PTR-LABEL: define {{[^@]+}}@align_down +// CHECK-FLOAT_PTR-SAME: (float* [[PTR:%.*]], i32 [[ALIGN:%.*]]) #0 +// CHECK-FLOAT_PTR-NEXT: entry: +// CHECK-FLOAT_PTR-NEXT: [[ALIGNMENT:%.*]] = zext i32 [[ALIGN]] to i64 +// CHECK-FLOAT_PTR-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENT]], 1 +// CHECK-FLOAT_PTR-NEXT: [[INTPTR:%.*]] = ptrtoint float* [[PTR]] to i64 +// CHECK-FLOAT_PTR-NEXT: [[INVERTED_MASK:%.*]] = xor i64 [[MASK]], -1 +// CHECK-FLOAT_PTR-NEXT: [[ALIGNED_INTPTR:%.*]] = and i64 [[INTPTR]], [[INVERTED_MASK]] +// CHECK-FLOAT_PTR-NEXT: [[DIFF:%.*]] = sub i64 [[ALIGNED_INTPTR]], [[INTPTR]] +// CHECK-FLOAT_PTR-NEXT: [[TMP0:%.*]] = bitcast float* [[PTR]] to i8* +// CHECK-FLOAT_PTR-NEXT: [[ALIGNED_RESULT:%.*]] = getelementptr inbounds i8, i8* [[TMP0]], i64 [[DIFF]] +// CHECK-FLOAT_PTR-NEXT: [[TMP1:%.*]] = bitcast i8* [[ALIGNED_RESULT]] to float* +// CHECK-FLOAT_PTR-NEXT: [[MASK1:%.*]] = sub i64 [[ALIGNMENT]], 1 +// CHECK-FLOAT_PTR-NEXT: [[PTRINT:%.*]] = ptrtoint float* [[TMP1]] to i64 +// CHECK-FLOAT_PTR-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], [[MASK1]] +// CHECK-FLOAT_PTR-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +// CHECK-FLOAT_PTR-NEXT: call void @llvm.assume(i1 [[MASKCOND]]) +// CHECK-FLOAT_PTR-NEXT: ret float* [[TMP1]] +// +// CHECK-LONG-LABEL: define {{[^@]+}}@align_down +// CHECK-LONG-SAME: (i64 [[PTR:%.*]], i32 [[ALIGN:%.*]]) #0 +// CHECK-LONG-NEXT: entry: +// CHECK-LONG-NEXT: [[ALIGNMENT:%.*]] = zext i32 [[ALIGN]] to i64 +// CHECK-LONG-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENT]], 1 +// CHECK-LONG-NEXT: [[INVERTED_MASK:%.*]] = xor i64 [[MASK]], -1 +// CHECK-LONG-NEXT: [[ALIGNED_RESULT:%.*]] = and i64 [[PTR]], [[INVERTED_MASK]] +// CHECK-LONG-NEXT: ret i64 [[ALIGNED_RESULT]] +// +// CHECK-USHORT-LABEL: define {{[^@]+}}@align_down +// CHECK-USHORT-SAME: (i16 zeroext [[PTR:%.*]], i32 [[ALIGN:%.*]]) #0 +// CHECK-USHORT-NEXT: entry: +// CHECK-USHORT-NEXT: [[ALIGNMENT:%.*]] = trunc i32 [[ALIGN]] to i16 +// CHECK-USHORT-NEXT: [[MASK:%.*]] = sub i16 [[ALIGNMENT]], 1 +// CHECK-USHORT-NEXT: [[INVERTED_MASK:%.*]] = xor i16 [[MASK]], -1 +// CHECK-USHORT-NEXT: [[ALIGNED_RESULT:%.*]] = and i16 [[PTR]], [[INVERTED_MASK]] +// CHECK-USHORT-NEXT: ret i16 [[ALIGNED_RESULT]] // TYPE align_down(TYPE ptr, unsigned align) { return __builtin_align_down(ptr, align); diff --git a/clang/test/CodeGen/builtin-assume-aligned.c b/clang/test/CodeGen/builtin-assume-aligned.c index 40532d914f7a1..90693cc215200 100644 --- a/clang/test/CodeGen/builtin-assume-aligned.c +++ b/clang/test/CodeGen/builtin-assume-aligned.c @@ -1,50 +1,106 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s -// CHECK-LABEL: @test1 +// CHECK-LABEL: define {{[^@]+}}@test1 +// CHECK-SAME: (i32* [[A:%.*]]) #0 +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32*, align 8 +// CHECK-NEXT: store i32* [[A]], i32** [[A_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load i32*, i32** [[A_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[TMP0]] to i8* +// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i8* [[TMP1]] to i64 +// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31 +// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +// CHECK-NEXT: store i32* [[TMP2]], i32** [[A_ADDR]], align 8 +// CHECK-NEXT: [[TMP3:%.*]] = load i32*, i32** [[A_ADDR]], align 8 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP3]], i64 0 +// CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +// CHECK-NEXT: ret i32 [[TMP4]] +// int test1(int *a) { -// CHECK: [[PTRINT1:%.+]] = ptrtoint -// CHECK: [[MASKEDPTR1:%.+]] = and i64 [[PTRINT1]], 31 -// CHECK: [[MASKCOND1:%.+]] = icmp eq i64 [[MASKEDPTR1]], 0 -// CHECK: call void @llvm.assume(i1 [[MASKCOND1]]) a = __builtin_assume_aligned(a, 32, 0ull); return a[0]; } -// CHECK-LABEL: @test2 +// CHECK-LABEL: define {{[^@]+}}@test2 +// CHECK-SAME: (i32* [[A:%.*]]) #0 +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32*, align 8 +// CHECK-NEXT: store i32* [[A]], i32** [[A_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load i32*, i32** [[A_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[TMP0]] to i8* +// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i8* [[TMP1]] to i64 +// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31 +// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +// CHECK-NEXT: store i32* [[TMP2]], i32** [[A_ADDR]], align 8 +// CHECK-NEXT: [[TMP3:%.*]] = load i32*, i32** [[A_ADDR]], align 8 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP3]], i64 0 +// CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +// CHECK-NEXT: ret i32 [[TMP4]] +// int test2(int *a) { -// CHECK: [[PTRINT2:%.+]] = ptrtoint -// CHECK: [[MASKEDPTR2:%.+]] = and i64 [[PTRINT2]], 31 -// CHECK: [[MASKCOND2:%.+]] = icmp eq i64 [[MASKEDPTR2]], 0 -// CHECK: call void @llvm.assume(i1 [[MASKCOND2]]) a = __builtin_assume_aligned(a, 32, 0); return a[0]; } -// CHECK-LABEL: @test3 +// CHECK-LABEL: define {{[^@]+}}@test3 +// CHECK-SAME: (i32* [[A:%.*]]) #0 +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32*, align 8 +// CHECK-NEXT: store i32* [[A]], i32** [[A_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load i32*, i32** [[A_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[TMP0]] to i8* +// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i8* [[TMP1]] to i64 +// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31 +// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +// CHECK-NEXT: store i32* [[TMP2]], i32** [[A_ADDR]], align 8 +// CHECK-NEXT: [[TMP3:%.*]] = load i32*, i32** [[A_ADDR]], align 8 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP3]], i64 0 +// CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +// CHECK-NEXT: ret i32 [[TMP4]] +// int test3(int *a) { -// CHECK: [[PTRINT3:%.+]] = ptrtoint -// CHECK: [[MASKEDPTR3:%.+]] = and i64 [[PTRINT3]], 31 -// CHECK: [[MASKCOND3:%.+]] = icmp eq i64 [[MASKEDPTR3]], 0 -// CHECK: call void @llvm.assume(i1 [[MASKCOND3]]) a = __builtin_assume_aligned(a, 32); return a[0]; } -// CHECK-LABEL: @test4 +// CHECK-LABEL: define {{[^@]+}}@test4 +// CHECK-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #0 +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32*, align 8 +// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32* [[A]], i32** [[A_ADDR]], align 8 +// CHECK-NEXT: store i32 [[B]], i32* [[B_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load i32*, i32** [[A_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[TMP0]] to i8* +// CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[B_ADDR]], align 4 +// CHECK-NEXT: [[CONV:%.*]] = sext i32 [[TMP2]] to i64 +// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i8* [[TMP1]] to i64 +// CHECK-NEXT: [[OFFSETPTR:%.*]] = sub i64 [[PTRINT]], [[CONV]] +// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[OFFSETPTR]], 31 +// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]]) +// CHECK-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP1]] to i32* +// CHECK-NEXT: store i32* [[TMP3]], i32** [[A_ADDR]], align 8 +// CHECK-NEXT: [[TMP4:%.*]] = load i32*, i32** [[A_ADDR]], align 8 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP4]], i64 0 +// CHECK-NEXT: [[TMP5:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +// CHECK-NEXT: ret i32 [[TMP5]] +// int test4(int *a, int b) { -// CHECK-DAG: [[PTRINT4:%.+]] = ptrtoint -// CHECK-DAG: [[CONV4:%.+]] = sext i32 -// CHECK: [[OFFSETPTR4:%.+]] = sub i64 [[PTRINT4]], [[CONV4]] -// CHECK: [[MASKEDPTR4:%.+]] = and i64 [[OFFSETPTR4]], 31 -// CHECK: [[MASKCOND4:%.+]] = icmp eq i64 [[MASKEDPTR4]], 0 -// CHECK: call void @llvm.assume(i1 [[MASKCOND4]]) a = __builtin_assume_aligned(a, 32, b); return a[0]; } int *m1() __attribute__((assume_aligned(64))); -// CHECK-LABEL: @test5( +// CHECK-LABEL: define {{[^@]+}}@test5() #0 // CHECK-NEXT: entry: // CHECK-NEXT: [[CALL:%.*]] = call align 64 i32* (...) @m1() // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 @@ -56,22 +112,40 @@ int test5() { int *m2() __attribute__((assume_aligned(64, 12))); -// CHECK-LABEL: @test6 +// CHECK-LABEL: define {{[^@]+}}@test6() #0 +// CHECK-NEXT: entry: +// CHECK-NEXT: [[CALL:%.*]] = call i32* (...) @m2() +// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i32* [[CALL]] to i64 +// CHECK-NEXT: [[OFFSETPTR:%.*]] = sub i64 [[PTRINT]], 12 +// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[OFFSETPTR]], 63 +// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]]) +// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 +// CHECK-NEXT: ret i32 [[TMP0]] +// int test6() { return *m2(); -// CHECK: [[PTRINT6:%.+]] = ptrtoint -// CHECK: [[OFFSETPTR6:%.+]] = sub i64 [[PTRINT6]], 12 -// CHECK: [[MASKEDPTR6:%.+]] = and i64 [[OFFSETPTR6]], 63 -// CHECK: [[MASKCOND6:%.+]] = icmp eq i64 [[MASKEDPTR6]], 0 -// CHECK: call void @llvm.assume(i1 [[MASKCOND6]]) } -// CHECK-LABEL: @pr43638 +// CHECK-LABEL: define {{[^@]+}}@pr43638 +// CHECK-SAME: (i32* [[A:%.*]]) #0 +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32*, align 8 +// CHECK-NEXT: store i32* [[A]], i32** [[A_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load i32*, i32** [[A_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[TMP0]] to i8* +// CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint i8* [[TMP1]] to i64 +// CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 536870911 +// CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0 +// CHECK-NEXT: call void @llvm.assume(i1 [[MASKCOND]]) +// CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +// CHECK-NEXT: store i32* [[TMP2]], i32** [[A_ADDR]], align 8 +// CHECK-NEXT: [[TMP3:%.*]] = load i32*, i32** [[A_ADDR]], align 8 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP3]], i64 0 +// CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +// CHECK-NEXT: ret i32 [[TMP4]] +// int pr43638(int *a) { a = __builtin_assume_aligned(a, 4294967296); return a[0]; -// CHECK: [[PTRINT7:%.+]] = ptrtoint -// CHECK: [[MASKEDPTR7:%.+]] = and i64 [[PTRINT7]], 536870911 -// CHECK: [[MASKCOND7:%.+]] = icmp eq i64 [[MASKEDPTR7]], 0 -// CHECK: call void @llvm.assume(i1 [[MASKCOND7]]) } diff --git a/clang/test/CodeGen/builtin-expect-with-probability.cpp b/clang/test/CodeGen/builtin-expect-with-probability.cpp new file mode 100644 index 0000000000000..ba1d71321a3ff --- /dev/null +++ b/clang/test/CodeGen/builtin-expect-with-probability.cpp @@ -0,0 +1,101 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -O1 -disable-llvm-passes | FileCheck %s --check-prefix=ALL --check-prefix=O1 +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -O0 | FileCheck %s --check-prefix=ALL --check-prefix=O0 +extern int global; + +int expect_taken(int x) { +// ALL-LABEL: expect_taken +// O1: call i64 @llvm.expect.with.probability.i64(i64 {{%.*}}, i64 1, double 9.000000e-01) +// O0-NOT: @llvm.expect.with.probability + + if (__builtin_expect_with_probability(x == 100, 1, 0.9)) { + return 0; + } + return x; +} + +int expect_not_taken(int x) { +// ALL-LABEL: expect_not_taken +// O1: call i64 @llvm.expect.with.probability.i64(i64 {{%.*}}, i64 0, double 9.000000e-01) +// O0-NOT: @llvm.expect.with.probability + + if (__builtin_expect_with_probability(x == 100, 0, 0.9)) { + return 0; + } + return x; +} + +struct S { + static constexpr int prob = 1; +}; + +template +int expect_taken_template(int x) { +// ALL-LABEL: expect_taken_template +// O1: call i64 @llvm.expect.with.probability.i64(i64 {{%.*}}, i64 1, double 1.000000e+00) +// O0-NOT: @llvm.expect.with.probability + + if (__builtin_expect_with_probability (x == 100, 1, T::prob)) { + return 0; + } + return x; +} + +int f() { + return expect_taken_template(global); +} + +int x; +extern "C" { + int y(void); +} +void foo(); + +void expect_value_side_effects() { +// ALL-LABEL: expect_value_side_effects +// ALL: [[CALL:%.*]] = call i32 @y +// O1: [[SEXT:%.*]] = sext i32 [[CALL]] to i64 +// O1: call i64 @llvm.expect.with.probability.i64(i64 {{%.*}}, i64 [[SEXT]], double 6.000000e-01) +// O0-NOT: @llvm.expect.with.probability + + if (__builtin_expect_with_probability(x, y(), 0.6)) + foo(); +} + +int switch_cond(int x) { +// ALL-LABEL: switch_cond +// O1: call i64 @llvm.expect.with.probability.i64(i64 {{%.*}}, i64 1, double 8.000000e-01) +// O0-NOT: @llvm.expect.with.probability + + switch (__builtin_expect_with_probability(x, 1, 0.8)) { + case 0: + x = x + 0; + case 1: + x = x + 1; + case 2: + x = x + 2; + case 5: + x = x + 5; + default: + x = x + 6; + } + return x; +} + +constexpr double prob = 0.8; + +int variable_expected(int stuff) { +// ALL-LABEL: variable_expected +// O1: call i64 @llvm.expect.with.probability.i64(i64 {{%.*}}, i64 {{%.*}}, double 8.000000e-01) +// O0-NOT: @llvm.expect.with.probability + + int res = 0; + + switch(__builtin_expect_with_probability(stuff, stuff, prob)) { + case 0: + res = 1; + break; + default: + break; + } + return res; +} diff --git a/clang/test/CodeGen/builtins-ppc-fpconstrained.c b/clang/test/CodeGen/builtins-ppc-fpconstrained.c new file mode 100644 index 0000000000000..c8b08c3fb5d4a --- /dev/null +++ b/clang/test/CodeGen/builtins-ppc-fpconstrained.c @@ -0,0 +1,161 @@ +// REQUIRES: powerpc-registered-target +// RUN: %clang_cc1 -triple powerpc64le-gnu-linux -target-feature +vsx \ +// RUN: -emit-llvm %s -o - | FileCheck --check-prefix=CHECK-UNCONSTRAINED %s +// RUN: %clang_cc1 -triple powerpc64le-gnu-linux -target-feature +vsx \ +// RUN: -fexperimental-strict-floating-point \ +// RUN: -ffp-exception-behavior=strict -emit-llvm %s -o - | FileCheck \ +// RUN: --check-prefix=CHECK-CONSTRAINED -vv %s +// RUN: %clang_cc1 -triple powerpc64le-gnu-linux -target-feature +vsx \ +// RUN: -fallow-half-arguments-and-returns -S -o - %s | \ +// RUN: FileCheck --check-prefix=CHECK-ASM --check-prefix=NOT-FIXME-CHECK %s +// RUN: %clang_cc1 -triple powerpc64le-gnu-linux -target-feature +vsx \ +// RUN: -fexperimental-strict-floating-point \ +// RUN: -fallow-half-arguments-and-returns -S -ffp-exception-behavior=strict \ +// RUN: -o - %s | FileCheck --check-prefix=CHECK-ASM \ +// RUN: --check-prefix=FIXME-CHECK %s + +typedef __attribute__((vector_size(4 * sizeof(float)))) float vec_float; +typedef __attribute__((vector_size(2 * sizeof(double)))) double vec_double; + +volatile vec_double vd; +volatile vec_float vf; + +void test_float(void) { + vf = __builtin_vsx_xvsqrtsp(vf); + // CHECK-LABEL: try-xvsqrtsp + // CHECK-UNCONSTRAINED: @llvm.sqrt.v4f32(<4 x float> %{{.*}}) + // CHECK-CONSTRAINED: @llvm.experimental.constrained.sqrt.v4f32(<4 x float> %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") + // CHECK-ASM: xvsqrtsp + + vd = __builtin_vsx_xvsqrtdp(vd); + // CHECK-LABEL: try-xvsqrtdp + // CHECK-UNCONSTRAINED: @llvm.sqrt.v2f64(<2 x double> %{{.*}}) + // CHECK-CONSTRAINED: @llvm.experimental.constrained.sqrt.v2f64(<2 x double> %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") + // CHECK-ASM: xvsqrtdp + + vf = __builtin_vsx_xvrspim(vf); + // CHECK-LABEL: try-xvrspim + // CHECK-UNCONSTRAINED: @llvm.floor.v4f32(<4 x float> %{{.*}}) + // CHECK-CONSTRAINED: @llvm.experimental.constrained.floor.v4f32(<4 x float> %{{.*}}, metadata !"fpexcept.strict") + // CHECK-ASM: xvrspim + + vd = __builtin_vsx_xvrdpim(vd); + // CHECK-LABEL: try-xvrdpim + // CHECK-UNCONSTRAINED: @llvm.floor.v2f64(<2 x double> %{{.*}}) + // CHECK-CONSTRAINED: @llvm.experimental.constrained.floor.v2f64(<2 x double> %{{.*}}, metadata !"fpexcept.strict") + // CHECK-ASM: xvrdpim + + vf = __builtin_vsx_xvrspi(vf); + // CHECK-LABEL: try-xvrspi + // CHECK-UNCONSTRAINED: @llvm.round.v4f32(<4 x float> %{{.*}}) + // CHECK-CONSTRAINED: @llvm.experimental.constrained.round.v4f32(<4 x float> %{{.*}}, metadata !"fpexcept.strict") + // CHECK-ASM: xvrspi + + vd = __builtin_vsx_xvrdpi(vd); + // CHECK-LABEL: try-xvrdpi + // CHECK-UNCONSTRAINED: @llvm.round.v2f64(<2 x double> %{{.*}}) + // CHECK-CONSTRAINED: @llvm.experimental.constrained.round.v2f64(<2 x double> %{{.*}}, metadata !"fpexcept.strict") + // CHECK-ASM: xvrdpi + + vf = __builtin_vsx_xvrspic(vf); + // CHECK-LABEL: try-xvrspic + // CHECK-UNCONSTRAINED: @llvm.nearbyint.v4f32(<4 x float> %{{.*}}) + // CHECK-CONSTRAINED: @llvm.experimental.constrained.nearbyint.v4f32(<4 x float> %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") + // CHECK-ASM: xvrspic + + vd = __builtin_vsx_xvrdpic(vd); + // CHECK-LABEL: try-xvrdpic + // CHECK-UNCONSTRAINED: @llvm.nearbyint.v2f64(<2 x double> %{{.*}}) + // CHECK-CONSTRAINED: @llvm.experimental.constrained.nearbyint.v2f64(<2 x double> %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") + // CHECK-ASM: xvrdpic + + vf = __builtin_vsx_xvrspip(vf); + // CHECK-LABEL: try-xvrspip + // CHECK-UNCONSTRAINED: @llvm.ceil.v4f32(<4 x float> %{{.*}}) + // CHECK-CONSTRAINED: @llvm.experimental.constrained.ceil.v4f32(<4 x float> %{{.*}}, metadata !"fpexcept.strict") + // CHECK-ASM: xvrspip + + vd = __builtin_vsx_xvrdpip(vd); + // CHECK-LABEL: try-xvrdpip + // CHECK-UNCONSTRAINED: @llvm.ceil.v2f64(<2 x double> %{{.*}}) + // CHECK-CONSTRAINED: @llvm.experimental.constrained.ceil.v2f64(<2 x double> %{{.*}}, metadata !"fpexcept.strict") + // CHECK-ASM: xvrdpip + + vf = __builtin_vsx_xvrspiz(vf); + // CHECK-LABEL: try-xvrspiz + // CHECK-UNCONSTRAINED: @llvm.trunc.v4f32(<4 x float> %{{.*}}) + // CHECK-CONSTRAINED: @llvm.experimental.constrained.trunc.v4f32(<4 x float> %{{.*}}, metadata !"fpexcept.strict") + // CHECK-ASM: xvrspiz + + vd = __builtin_vsx_xvrdpiz(vd); + // CHECK-LABEL: try-xvrdpiz + // CHECK-UNCONSTRAINED: @llvm.trunc.v2f64(<2 x double> %{{.*}}) + // CHECK-CONSTRAINED: @llvm.experimental.constrained.trunc.v2f64(<2 x double> %{{.*}}, metadata !"fpexcept.strict") + // CHECK-ASM: xvrdpiz + + vf = __builtin_vsx_xvmaddasp(vf, vf, vf); + // CHECK-LABEL: try-xvmaddasp + // CHECK-UNCONSTRAINED: @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK-CONSTRAINED: @llvm.experimental.constrained.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") + // CHECK-ASM: xvmaddasp + + vd = __builtin_vsx_xvmaddadp(vd, vd, vd); + // CHECK-LABEL: try-xvmaddadp + // CHECK-UNCONSTRAINED: @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-CONSTRAINED: @llvm.experimental.constrained.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") + // CHECK-ASM: xvmaddadp + + vf = __builtin_vsx_xvnmaddasp(vf, vf, vf); + // CHECK-LABEL: try-xvnmaddasp + // CHECK-UNCONSTRAINED: [[RESULT:%[^ ]+]] = call <4 x float> @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK-UNCONSTRAINED: fneg <4 x float> [[RESULT]] + // CHECK-CONSTRAINED: [[RESULT:%[^ ]+]] = call <4 x float> @llvm.experimental.constrained.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") + // CHECK-CONSTRAINED: fneg <4 x float> [[RESULT]] + // NOT-FIXME-CHECK: xvnmaddasp + // FIXME-CHECK: xvmaddasp + // FIXME-CHECK: xvnegsp + + vd = __builtin_vsx_xvnmaddadp(vd, vd, vd); + // CHECK-LABEL: try-xvnmaddadp + // CHECK-UNCONSTRAINED: [[RESULT:%[^ ]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK-UNCONSTRAINED: fneg <2 x double> [[RESULT]] + // CHECK-CONSTRAINED: [[RESULT:%[^ ]+]] = call <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") + // CHECK-CONSTRAINED: fneg <2 x double> [[RESULT]] + // CHECK-ASM: xvnmaddadp + + vf = __builtin_vsx_xvmsubasp(vf, vf, vf); + // CHECK-LABEL: try-xvmsubasp + // CHECK-UNCONSTRAINED: [[RESULT:%[^ ]+]] = fneg <4 x float> %{{.*}} + // CHECK-UNCONSTRAINED: @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> [[RESULT]]) + // CHECK-CONSTRAINED: [[RESULT:%[^ ]+]] = fneg <4 x float> %{{.*}} + // CHECK-CONSTRAINED: @llvm.experimental.constrained.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> [[RESULT]], metadata !"round.tonearest", metadata !"fpexcept.strict") + // CHECK-ASM: xvmsubasp + + vd = __builtin_vsx_xvmsubadp(vd, vd, vd); + // CHECK-LABEL: try-xvmsubadp + // CHECK-UNCONSTRAINED: [[RESULT:%[^ ]+]] = fneg <2 x double> %{{.*}} + // CHECK-UNCONSTRAINED: @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> [[RESULT]]) + // CHECK-CONSTRAINED: [[RESULT:%[^ ]+]] = fneg <2 x double> %{{.*}} + // CHECK-CONSTRAINED: @llvm.experimental.constrained.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> [[RESULT]], metadata !"round.tonearest", metadata !"fpexcept.strict") + // CHECK-ASM: xvmsubadp + + vf = __builtin_vsx_xvnmsubasp(vf, vf, vf); + // CHECK-LABEL: try-xvnmsubasp + // CHECK-UNCONSTRAINED: [[RESULT0:%[^ ]+]] = fneg <4 x float> %{{.*}} + // CHECK-UNCONSTRAINED: [[RESULT1:%[^ ]+]] = call <4 x float> @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> [[RESULT0]]) + // CHECK-UNCONSTRAINED: fneg <4 x float> [[RESULT1]] + // CHECK-CONSTRAINED: [[RESULT0:%[^ ]+]] = fneg <4 x float> %{{.*}} + // CHECK-CONSTRAINED: [[RESULT1:%[^ ]+]] = call <4 x float> @llvm.experimental.constrained.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> [[RESULT0]], metadata !"round.tonearest", metadata !"fpexcept.strict") + // CHECK-CONSTRAINED: fneg <4 x float> [[RESULT1]] + // CHECK-ASM: xvnmsubasp + + vd = __builtin_vsx_xvnmsubadp(vd, vd, vd); + // CHECK-LABEL: try-xvnmsubadp + // CHECK-UNCONSTRAINED: [[RESULT0:%[^ ]+]] = fneg <2 x double> %{{.*}} + // CHECK-UNCONSTRAINED: [[RESULT1:%[^ ]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> [[RESULT0]]) + // CHECK-UNCONSTRAINED: fneg <2 x double> [[RESULT1]] + // CHECK-CONSTRAINED: [[RESULT0:%[^ ]+]] = fneg <2 x double> %{{.*}} + // CHECK-CONSTRAINED: [[RESULT1:%[^ ]+]] = call <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> [[RESULT0]], metadata !"round.tonearest", metadata !"fpexcept.strict") + // CHECK-CONSTRAINED: fneg <2 x double> [[RESULT1]] + // CHECK-ASM: xvnmsubadp +} diff --git a/clang/test/CodeGen/builtins-ppc-p10.c b/clang/test/CodeGen/builtins-ppc-p10.c index c21e8026d0c9a..38c8988a3e37c 100644 --- a/clang/test/CodeGen/builtins-ppc-p10.c +++ b/clang/test/CodeGen/builtins-ppc-p10.c @@ -13,3 +13,18 @@ unsigned long long test_pextd(void) { // CHECK: @llvm.ppc.pextd return __builtin_pextd(ulla, ullb); } + +unsigned long long test_cfuged(void) { + // CHECK: @llvm.ppc.cfuged + return __builtin_cfuged(ulla, ullb); +} + +unsigned long long test_cntlzdm(void) { + // CHECK: @llvm.ppc.cntlzdm + return __builtin_cntlzdm(ulla, ullb); +} + +unsigned long long test_cnttzdm(void) { + // CHECK: @llvm.ppc.cnttzdm + return __builtin_cnttzdm(ulla, ullb); +} diff --git a/clang/test/CodeGen/builtins-ppc-p10vector.c b/clang/test/CodeGen/builtins-ppc-p10vector.c index 829ef97435eb4..22b4e7a6f3ecf 100644 --- a/clang/test/CodeGen/builtins-ppc-p10vector.c +++ b/clang/test/CodeGen/builtins-ppc-p10vector.c @@ -3,12 +3,31 @@ // RUN: -target-cpu pwr10 -triple powerpc64le-unknown-unknown -emit-llvm %s \ // RUN: -o - | FileCheck %s +// RUN: %clang_cc1 -target-feature +vsx -target-feature +altivec \ +// RUN: -target-cpu pwr10 -triple powerpc64-unknown-unknown -emit-llvm %s \ +// RUN: -o - | FileCheck %s -check-prefix=CHECK-BE + +// RUN: %clang_cc1 -target-feature +vsx -target-feature +altivec \ +// RUN: -target-cpu pwr10 -triple powerpc64le-unknown-unknown -emit-llvm %s \ +// RUN: -o - | FileCheck %s -check-prefix=CHECK-LE + #include -vector signed char vsca; -vector unsigned char vuca; -vector unsigned long long vulla, vullb; -unsigned int uia; +vector signed char vsca, vscb; +vector unsigned char vuca, vucb, vucc; +vector signed short vssa, vssb; +vector unsigned short vusa, vusb, vusc; +vector signed int vsia, vsib; +vector unsigned int vuia, vuib, vuic; +vector signed long long vslla, vsllb; +vector unsigned long long vulla, vullb, vullc; +vector unsigned __int128 vui128a, vui128b, vui128c; +vector float vfa, vfb; +vector double vda, vdb; +unsigned int uia, uib; +unsigned char uca; +unsigned short usa; +unsigned long long ulla; vector unsigned long long test_vpdepd(void) { // CHECK: @llvm.ppc.altivec.vpdepd(<2 x i64> @@ -22,6 +41,84 @@ vector unsigned long long test_vpextd(void) { return vec_pext(vulla, vullb); } +vector unsigned long long test_vcfuged(void) { + // CHECK: @llvm.ppc.altivec.vcfuged(<2 x i64> + // CHECK-NEXT: ret <2 x i64> + return vec_cfuge(vulla, vullb); +} + +unsigned long long test_vgnb_1(void) { + // CHECK: @llvm.ppc.altivec.vgnb(<1 x i128> %{{.+}}, i32 2) + // CHECK-NEXT: ret i64 + return vec_gnb(vui128a, 2); +} + +unsigned long long test_vgnb_2(void) { + // CHECK: @llvm.ppc.altivec.vgnb(<1 x i128> %{{.+}}, i32 7) + // CHECK-NEXT: ret i64 + return vec_gnb(vui128a, 7); +} + +unsigned long long test_vgnb_3(void) { + // CHECK: @llvm.ppc.altivec.vgnb(<1 x i128> %{{.+}}, i32 5) + // CHECK-NEXT: ret i64 + return vec_gnb(vui128a, 5); +} + +vector unsigned char test_xxeval_uc(void) { + // CHECK: @llvm.ppc.vsx.xxeval(<2 x i64> %{{.+}}, <2 x i64> %{{.+}}, <2 x i64> %{{.+}}, i32 0) + // CHECK: ret <16 x i8> + return vec_ternarylogic(vuca, vucb, vucc, 0); +} + +vector unsigned short test_xxeval_us(void) { + // CHECK: @llvm.ppc.vsx.xxeval(<2 x i64> %{{.+}}, <2 x i64> %{{.+}}, <2 x i64> %{{.+}}, i32 255) + // CHECK: ret <8 x i16> + return vec_ternarylogic(vusa, vusb, vusc, 255); +} + +vector unsigned int test_xxeval_ui(void) { + // CHECK: @llvm.ppc.vsx.xxeval(<2 x i64> %{{.+}}, <2 x i64> %{{.+}}, <2 x i64> %{{.+}}, i32 150) + // CHECK: ret <4 x i32> + return vec_ternarylogic(vuia, vuib, vuic, 150); +} + +vector unsigned long long test_xxeval_ull(void) { + // CHECK: @llvm.ppc.vsx.xxeval(<2 x i64> %{{.+}}, <2 x i64> %{{.+}}, <2 x i64> %{{.+}}, i32 1) + // CHECK: ret <2 x i64> + return vec_ternarylogic(vulla, vullb, vullc, 1); +} + +vector unsigned __int128 test_xxeval_ui128(void) { + // CHECK: @llvm.ppc.vsx.xxeval(<2 x i64> %{{.+}}, <2 x i64> %{{.+}}, <2 x i64> %{{.+}}, i32 246) + // CHECK: ret <1 x i128> + return vec_ternarylogic(vui128a, vui128b, vui128c, 246); +} + +vector unsigned char test_xxgenpcvbm(void) { + // CHECK: @llvm.ppc.vsx.xxgenpcvbm(<16 x i8> %{{.+}}, i32 + // CHECK-NEXT: ret <16 x i8> + return vec_genpcvm(vuca, 0); +} + +vector unsigned short test_xxgenpcvhm(void) { + // CHECK: @llvm.ppc.vsx.xxgenpcvhm(<8 x i16> %{{.+}}, i32 + // CHECK-NEXT: ret <8 x i16> + return vec_genpcvm(vusa, 0); +} + +vector unsigned int test_xxgenpcvwm(void) { + // CHECK: @llvm.ppc.vsx.xxgenpcvwm(<4 x i32> %{{.+}}, i32 + // CHECK-NEXT: ret <4 x i32> + return vec_genpcvm(vuia, 0); +} + +vector unsigned long long test_xxgenpcvdm(void) { + // CHECK: @llvm.ppc.vsx.xxgenpcvdm(<2 x i64> %{{.+}}, i32 + // CHECK-NEXT: ret <2 x i64> + return vec_genpcvm(vulla, 0); +} + vector signed char test_vec_vclrl_sc(void) { // CHECK-BE: @llvm.ppc.altivec.vclrlb(<16 x i8> // CHECK-BE-NEXT: ret <16 x i8> @@ -53,3 +150,434 @@ vector unsigned char test_vec_clrr_uc(void) { // CHECK-LE-NEXT: ret <16 x i8> return vec_clrr(vuca, uia); } + +vector unsigned long long test_vclzdm(void) { + // CHECK: @llvm.ppc.altivec.vclzdm(<2 x i64> + // CHECK-NEXT: ret <2 x i64> + return vec_cntlzm(vulla, vullb); +} + +vector unsigned long long test_vctzdm(void) { + // CHECK: @llvm.ppc.altivec.vctzdm(<2 x i64> + // CHECK-NEXT: ret <2 x i64> + return vec_cnttzm(vulla, vullb); +} + +vector signed char test_vec_sldb_sc(void) { + // CHECK: @llvm.ppc.altivec.vsldbi(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 0 + // CHECK-NEXT: ret <16 x i8> + return vec_sldb(vsca, vscb, 0); + } + +vector unsigned char test_vec_sldb_uc(void) { + // CHECK: @llvm.ppc.altivec.vsldbi(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 1 + // CHECK-NEXT: ret <16 x i8> + return vec_sldb(vuca, vucb, 1); +} + +vector signed short test_vec_sldb_ss(void) { + // CHECK: @llvm.ppc.altivec.vsldbi(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 2 + // CHECK-NEXT: bitcast <16 x i8> %{{.*}} to <8 x i16> + // CHECK-NEXT: ret <8 x i16> + return vec_sldb(vssa, vssb, 2); +} + +vector unsigned short test_vec_sldb_us(void) { + // CHECK: @llvm.ppc.altivec.vsldbi(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 3 + // CHECK-NEXT: bitcast <16 x i8> %{{.*}} to <8 x i16> + // CHECK-NEXT: ret <8 x i16> + return vec_sldb(vusa, vusb, 3); +} + +vector signed int test_vec_sldb_si(void) { + // CHECK: @llvm.ppc.altivec.vsldbi(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 4 + // CHECK-NEXT: bitcast <16 x i8> %{{.*}} to <4 x i32> + // CHECK-NEXT: ret <4 x i32> + return vec_sldb(vsia, vsib, 4); +} + +vector unsigned int test_vec_sldb_ui(void) { + // CHECK: @llvm.ppc.altivec.vsldbi(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 5 + // CHECK-NEXT: bitcast <16 x i8> %{{.*}} to <4 x i32> + // CHECK-NEXT: ret <4 x i32> + return vec_sldb(vuia, vuib, 5); +} + +vector signed long long test_vec_sldb_sll(void) { + // CHECK: @llvm.ppc.altivec.vsldbi(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 6 + // CHECK-NEXT: bitcast <16 x i8> %{{.*}} to <2 x i64> + // CHECK-NEXT: ret <2 x i64> + return vec_sldb(vslla, vsllb, 6); +} + +vector unsigned long long test_vec_sldb_ull(void) { + // CHECK: @llvm.ppc.altivec.vsldbi(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 7 + // CHECK-NEXT: bitcast <16 x i8> %{{.*}} to <2 x i64> + // CHECK-NEXT: ret <2 x i64> + return vec_sldb(vulla, vullb, 7); +} + +vector signed char test_vec_srdb_sc(void) { + // CHECK: @llvm.ppc.altivec.vsrdbi(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 0 + // CHECK-NEXT: ret <16 x i8> + return vec_srdb(vsca, vscb, 8); +} + +vector unsigned char test_vec_srdb_uc(void) { + // CHECK: @llvm.ppc.altivec.vsrdbi(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 1 + // CHECK-NEXT: ret <16 x i8> + return vec_srdb(vuca, vucb, 9); +} + +vector signed short test_vec_srdb_ss(void) { + // CHECK: @llvm.ppc.altivec.vsrdbi(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 2 + // CHECK-NEXT: bitcast <16 x i8> %{{.*}} to <8 x i16> + // CHECK-NEXT: ret <8 x i16> + return vec_srdb(vssa, vssb, 10); +} + +vector unsigned short test_vec_srdb_us(void) { + // CHECK: @llvm.ppc.altivec.vsrdbi(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 3 + // CHECK-NEXT: bitcast <16 x i8> %{{.*}} to <8 x i16> + // CHECK-NEXT: ret <8 x i16> + return vec_srdb(vusa, vusb, 3); +} + +vector signed int test_vec_srdb_si(void) { + // CHECK: @llvm.ppc.altivec.vsrdbi(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 4 + // CHECK-NEXT: bitcast <16 x i8> %{{.*}} to <4 x i32> + // CHECK-NEXT: ret <4 x i32> + return vec_srdb(vsia, vsib, 4); +} + +vector unsigned int test_vec_srdb_ui(void) { + // CHECK: @llvm.ppc.altivec.vsrdbi(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 5 + // CHECK-NEXT: bitcast <16 x i8> %{{.*}} to <4 x i32> + // CHECK-NEXT: ret <4 x i32> + return vec_srdb(vuia, vuib, 5); +} + +vector signed long long test_vec_srdb_sll(void) { + // CHECK: @llvm.ppc.altivec.vsrdbi(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 6 + // CHECK-NEXT: bitcast <16 x i8> %{{.*}} to <2 x i64> + // CHECK-NEXT: ret <2 x i64> + return vec_srdb(vslla, vsllb, 6); +} + +vector unsigned long long test_vec_srdb_ull(void) { + // CHECK: @llvm.ppc.altivec.vsrdbi(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 7 + // CHECK-NEXT: bitcast <16 x i8> %{{.*}} to <2 x i64> + // CHECK-NEXT: ret <2 x i64> + return vec_srdb(vulla, vullb, 7); +} + +vector signed char test_vec_permx_sc(void) { + // CHECK: @llvm.ppc.vsx.xxpermx(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 + // CHECK-NEXT: ret <16 x i8> + return vec_permx(vsca, vscb, vucc, 0); +} + +vector unsigned char test_vec_permx_uc(void) { + // CHECK: @llvm.ppc.vsx.xxpermx(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 + // CHECK-NEXT: ret <16 x i8> + return vec_permx(vuca, vucb, vucc, 1); +} + +vector signed short test_vec_permx_ss(void) { + // CHECK: @llvm.ppc.vsx.xxpermx(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 + // CHECK-NEXT: bitcast <16 x i8> %{{.*}} to <8 x i16> + // CHECK-NEXT: ret <8 x i16> + return vec_permx(vssa, vssb, vucc, 2); +} + +vector unsigned short test_vec_permx_us(void) { + // CHECK: @llvm.ppc.vsx.xxpermx(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 + // CHECK-NEXT: bitcast <16 x i8> %{{.*}} to <8 x i16> + // CHECK-NEXT: ret <8 x i16> + return vec_permx(vusa, vusb, vucc, 3); +} + +vector signed int test_vec_permx_si(void) { + // CHECK: @llvm.ppc.vsx.xxpermx(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 + // CHECK-NEXT: bitcast <16 x i8> %{{.*}} to <4 x i32> + // CHECK-NEXT: ret <4 x i32> + return vec_permx(vsia, vsib, vucc, 4); +} + +vector unsigned int test_vec_permx_ui(void) { + // CHECK: @llvm.ppc.vsx.xxpermx(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 + // CHECK-NEXT: bitcast <16 x i8> %{{.*}} to <4 x i32> + // CHECK-NEXT: ret <4 x i32> + return vec_permx(vuia, vuib, vucc, 5); +} + +vector signed long long test_vec_permx_sll(void) { + // CHECK: @llvm.ppc.vsx.xxpermx(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 + // CHECK-NEXT: bitcast <16 x i8> %{{.*}} to <2 x i64> + // CHECK-NEXT: ret <2 x i64> + return vec_permx(vslla, vsllb, vucc, 6); +} + +vector unsigned long long test_vec_permx_ull(void) { + // CHECK: @llvm.ppc.vsx.xxpermx(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 + // CHECK-NEXT: bitcast <16 x i8> %{{.*}} to <2 x i64> + // CHECK-NEXT: ret <2 x i64> + return vec_permx(vulla, vullb, vucc, 7); +} + +vector float test_vec_permx_f(void) { + // CHECK: @llvm.ppc.vsx.xxpermx(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 + // CHECK-NEXT: bitcast <16 x i8> %{{.*}} to <4 x float> + // CHECK-NEXT: ret <4 x float> + return vec_permx(vfa, vfb, vucc, 0); +} + +vector double test_vec_permx_d(void) { + // CHECK: @llvm.ppc.vsx.xxpermx(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, <16 x i8> %{{.+}}, i32 + // CHECK-NEXT: bitcast <16 x i8> %{{.*}} to <2 x double> + // CHECK-NEXT: ret <2 x double> + return vec_permx(vda, vdb, vucc, 1); +} + +vector signed char test_vec_blend_sc(void) { + // CHECK: @llvm.ppc.vsx.xxblendvb(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, <16 x i8> + // CHECK-NEXT: ret <16 x i8> + return vec_blendv(vsca, vscb, vucc); +} + +vector unsigned char test_vec_blend_uc(void) { + // CHECK: @llvm.ppc.vsx.xxblendvb(<16 x i8> %{{.+}}, <16 x i8> %{{.+}}, <16 x i8> + // CHECK-NEXT: ret <16 x i8> + return vec_blendv(vuca, vucb, vucc); +} + +vector signed short test_vec_blend_ss(void) { + // CHECK: @llvm.ppc.vsx.xxblendvh(<8 x i16> %{{.+}}, <8 x i16> %{{.+}}, <8 x i16> + // CHECK-NEXT: ret <8 x i16> + return vec_blendv(vssa, vssb, vusc); +} + +vector unsigned short test_vec_blend_us(void) { + // CHECK: @llvm.ppc.vsx.xxblendvh(<8 x i16> %{{.+}}, <8 x i16> %{{.+}}, <8 x i16> + // CHECK-NEXT: ret <8 x i16> + return vec_blendv(vusa, vusb, vusc); +} + +vector signed int test_vec_blend_si(void) { + // CHECK: @llvm.ppc.vsx.xxblendvw(<4 x i32> %{{.+}}, <4 x i32> %{{.+}}, <4 x i32> + // CHECK-NEXT: ret <4 x i32> + return vec_blendv(vsia, vsib, vuic); +} + +vector unsigned int test_vec_blend_ui(void) { + // CHECK: @llvm.ppc.vsx.xxblendvw(<4 x i32> %{{.+}}, <4 x i32> %{{.+}}, <4 x i32> + // CHECK-NEXT: ret <4 x i32> + return vec_blendv(vuia, vuib, vuic); +} + +vector signed long long test_vec_blend_sll(void) { + // CHECK: @llvm.ppc.vsx.xxblendvd(<2 x i64> %{{.+}}, <2 x i64> %{{.+}}, <2 x i64> + // CHECK-NEXT: ret <2 x i64> + return vec_blendv(vslla, vsllb, vullc); +} + +vector unsigned long long test_vec_blend_ull(void) { + // CHECK: @llvm.ppc.vsx.xxblendvd(<2 x i64> %{{.+}}, <2 x i64> %{{.+}}, <2 x i64> + // CHECK-NEXT: ret <2 x i64> + return vec_blendv(vulla, vullb, vullc); +} + +vector float test_vec_blend_f(void) { + // CHECK: @llvm.ppc.vsx.xxblendvw(<4 x i32> %{{.+}}, <4 x i32> %{{.+}}, <4 x i32> + // CHECK-NEXT: bitcast <4 x i32> %{{.*}} to <4 x float> + // CHECK-NEXT: ret <4 x float> + return vec_blendv(vfa, vfb, vuic); +} + +vector double test_vec_blend_d(void) { + // CHECK: @llvm.ppc.vsx.xxblendvd(<2 x i64> %{{.+}}, <2 x i64> %{{.+}}, <2 x i64> + // CHECK-NEXT: bitcast <2 x i64> %{{.*}} to <2 x double> + // CHECK-NEXT: ret <2 x double> + return vec_blendv(vda, vdb, vullc); +} + +vector unsigned char test_vec_insertl_uc(void) { + // CHECK-BE: @llvm.ppc.altivec.vinsblx(<16 x i8> %{{.+}}, i64 %{{.+}}, i64 + // CHECK-BE-NEXT: ret <16 x i8> + // CHECK-LE: @llvm.ppc.altivec.vinsbrx(<16 x i8> %{{.+}}, i64 %{{.+}}, i64 + // CHECK-LE-NEXT: ret <16 x i8> + return vec_insertl(uca, vuca, uia); +} + +vector unsigned short test_vec_insertl_us(void) { + // CHECK-BE: @llvm.ppc.altivec.vinshlx(<8 x i16> %{{.+}}, i64 %{{.+}}, i64 + // CHECK-BE-NEXT: ret <8 x i16> + // CHECK-LE: @llvm.ppc.altivec.vinshrx(<8 x i16> %{{.+}}, i64 %{{.+}}, i64 + // CHECK-LE-NEXT: ret <8 x i16> + return vec_insertl(usa, vusa, uia); +} + +vector unsigned int test_vec_insertl_ui(void) { + // CHECK-BE: @llvm.ppc.altivec.vinswlx(<4 x i32> %{{.+}}, i64 %{{.+}}, i64 + // CHECK-BE-NEXT: ret <4 x i32> + // CHECK-LE: @llvm.ppc.altivec.vinswrx(<4 x i32> %{{.+}}, i64 %{{.+}}, i64 + // CHECK-LE-NEXT: ret <4 x i32> + return vec_insertl(uib, vuia, uia); +} + +vector unsigned long long test_vec_insertl_ul(void) { + // CHECK-BE: @llvm.ppc.altivec.vinsdlx(<2 x i64> %{{.+}}, i64 %{{.+}}, i64 + // CHECK-BE-NEXT: ret <2 x i64> + // CHECK-LE: @llvm.ppc.altivec.vinsdrx(<2 x i64> %{{.+}}, i64 %{{.+}}, i64 + // CHECK-LE-NEXT: ret <2 x i64> + return vec_insertl(ulla, vulla, uia); +} + +vector unsigned char test_vec_insertl_ucv(void) { + // CHECK-BE: @llvm.ppc.altivec.vinsbvlx(<16 x i8> %{{.+}}, i64 %{{.+}}, <16 x i8> + // CHECK-BE-NEXT: ret <16 x i8> + // CHECK-LE: @llvm.ppc.altivec.vinsbvrx(<16 x i8> %{{.+}}, i64 %{{.+}}, <16 x i8> + // CHECK-LE-NEXT: ret <16 x i8> + return vec_insertl(vuca, vucb, uia); +} + +vector unsigned short test_vec_insertl_usv(void) { + // CHECK-BE: @llvm.ppc.altivec.vinshvlx(<8 x i16> %{{.+}}, i64 %{{.+}}, <8 x i16> + // CHECK-BE-NEXT: ret <8 x i16> + // CHECK-LE: @llvm.ppc.altivec.vinshvrx(<8 x i16> %{{.+}}, i64 %{{.+}}, <8 x i16> + // CHECK-LE-NEXT: ret <8 x i16> + return vec_insertl(vusa, vusb, uia); +} + +vector unsigned int test_vec_insertl_uiv(void) { + // CHECK-BE: @llvm.ppc.altivec.vinswvlx(<4 x i32> %{{.+}}, i64 %{{.+}}, <4 x i32> + // CHECK-BE-NEXT: ret <4 x i32> + // CHECK-LE: @llvm.ppc.altivec.vinswvrx(<4 x i32> %{{.+}}, i64 %{{.+}}, <4 x i32> + // CHECK-LE-NEXT: ret <4 x i32> + return vec_insertl(vuia, vuib, uia); +} + +vector unsigned char test_vec_inserth_uc(void) { + // CHECK-BE: @llvm.ppc.altivec.vinsbrx(<16 x i8> %{{.+}}, i64 %{{.+}}, i64 + // CHECK-BE-NEXT: ret <16 x i8> + // CHECK-LE: @llvm.ppc.altivec.vinsblx(<16 x i8> %{{.+}}, i64 %{{.+}}, i64 + // CHECK-LE-NEXT: ret <16 x i8> + return vec_inserth(uca, vuca, uia); +} + +vector unsigned short test_vec_inserth_us(void) { + // CHECK-BE: @llvm.ppc.altivec.vinshrx(<8 x i16> %{{.+}}, i64 %{{.+}}, i64 + // CHECK-BE-NEXT: ret <8 x i16> + // CHECK-LE: @llvm.ppc.altivec.vinshlx(<8 x i16> %{{.+}}, i64 %{{.+}}, i64 + // CHECK-LE-NEXT: ret <8 x i16> + return vec_inserth(usa, vusa, uia); +} + +vector unsigned int test_vec_inserth_ui(void) { + // CHECK-BE: @llvm.ppc.altivec.vinswrx(<4 x i32> %{{.+}}, i64 %{{.+}}, i64 + // CHECK-BE-NEXT: ret <4 x i32> + // CHECK-LE: @llvm.ppc.altivec.vinswlx(<4 x i32> %{{.+}}, i64 %{{.+}}, i64 + // CHECK-LE-NEXT: ret <4 x i32> + return vec_inserth(uib, vuia, uia); +} + +vector unsigned long long test_vec_inserth_ul(void) { + // CHECK-BE: @llvm.ppc.altivec.vinsdrx(<2 x i64> %{{.+}}, i64 %{{.+}}, i64 + // CHECK-BE-NEXT: ret <2 x i64> + // CHECK-LE: @llvm.ppc.altivec.vinsdlx(<2 x i64> %{{.+}}, i64 %{{.+}}, i64 + // CHECK-LE-NEXT: ret <2 x i64> + return vec_inserth(ulla, vulla, uia); +} + +vector unsigned char test_vec_inserth_ucv(void) { + // CHECK-BE: @llvm.ppc.altivec.vinsbvrx(<16 x i8> %{{.+}}, i64 %{{.+}}, <16 x i8> + // CHECK-BE-NEXT: ret <16 x i8> + // CHECK-LE: @llvm.ppc.altivec.vinsbvlx(<16 x i8> %{{.+}}, i64 %{{.+}}, <16 x i8> + // CHECK-LE-NEXT: ret <16 x i8> + return vec_inserth(vuca, vucb, uia); +} + +vector unsigned short test_vec_inserth_usv(void) { + // CHECK-BE: @llvm.ppc.altivec.vinshvrx(<8 x i16> %{{.+}}, i64 %{{.+}}, <8 x i16> + // CHECK-BE-NEXT: ret <8 x i16> + // CHECK-LE: @llvm.ppc.altivec.vinshvlx(<8 x i16> %{{.+}}, i64 %{{.+}}, <8 x i16> + // CHECK-LE-NEXT: ret <8 x i16> + return vec_inserth(vusa, vusb, uia); +} + +vector unsigned int test_vec_inserth_uiv(void) { + // CHECK-BE: @llvm.ppc.altivec.vinswvrx(<4 x i32> %{{.+}}, i64 %{{.+}}, <4 x i32> + // CHECK-BE-NEXT: ret <4 x i32> + // CHECK-LE: @llvm.ppc.altivec.vinswvlx(<4 x i32> %{{.+}}, i64 %{{.+}}, <4 x i32> + // CHECK-LE-NEXT: ret <4 x i32> + return vec_inserth(vuia, vuib, uia); +} + +vector signed int test_vec_vec_splati_si(void) { + // CHECK-BE: ret <4 x i32> + // CHECK: ret <4 x i32> + return vec_splati(-17); +} + +vector unsigned int test_vec_vec_splati_ui(void) { + // CHECK-BE: ret <4 x i32> + // CHECK: ret <4 x i32> + return vec_splati(16U); +} + +vector float test_vec_vec_splati_f(void) { + // CHECK-BE: ret <4 x float> + // CHECK: ret <4 x float> + return vec_splati(1.0f); +} + +vector double test_vec_vec_splatid(void) { + // CHECK-BE: [[T1:%.+]] = fpext float %{{.+}} to double + // CHECK-BE-NEXT: [[T2:%.+]] = insertelement <2 x double> undef, double [[T1:%.+]], i32 0 + // CHECK-BE-NEXT: [[T3:%.+]] = shufflevector <2 x double> [[T2:%.+]], <2 x double> undef, <2 x i32> zeroinitialize + // CHECK-BE-NEXT: ret <2 x double> [[T3:%.+]] + // CHECK: [[T1:%.+]] = fpext float %{{.+}} to double + // CHECK-NEXT: [[T2:%.+]] = insertelement <2 x double> undef, double [[T1:%.+]], i32 0 + // CHECK-NEXT: [[T3:%.+]] = shufflevector <2 x double> [[T2:%.+]], <2 x double> undef, <2 x i32> zeroinitialize + // CHECK-NEXT: ret <2 x double> [[T3:%.+]] + return vec_splatid(1.0); +} + +vector signed int test_vec_vec_splati_ins_si(void) { + // CHECK-BE: insertelement <4 x i32> %{{.+}}, i32 %{{.+}}, i32 %{{.+}} + // CHECK-BE: [[T1:%.+]] = add i32 2, %{{.+}} + // CHECK-BE: insertelement <4 x i32> %{{.+}}, i32 %{{.+}}, i32 [[T1]] + // CHECK-BE: ret <4 x i32> + // CHECK: [[T1:%.+]] = sub i32 1, %{{.+}} + // CHECK: insertelement <4 x i32> %{{.+}}, i32 %{{.+}}, i32 [[T1]] + // CHECK: [[T2:%.+]] = sub i32 3, %{{.+}} + // CHECK: insertelement <4 x i32> %{{.+}}, i32 %{{.+}}, i32 [[T2]] + // CHECK: ret <4 x i32> + return vec_splati_ins(vsia, 0, -17); +} + +vector unsigned int test_vec_vec_splati_ins_ui(void) { + // CHECK-BE: insertelement <4 x i32> %{{.+}}, i32 %{{.+}}, i32 %{{.+}} + // CHECK-BE: [[T1:%.+]] = add i32 2, %{{.+}} + // CHECK-BE: insertelement <4 x i32> %{{.+}}, i32 %{{.+}}, i32 [[T1]] + // CHECK-BE: ret <4 x i32> + // CHECK: [[T1:%.+]] = sub i32 1, %{{.+}} + // CHECK: insertelement <4 x i32> %{{.+}}, i32 %{{.+}}, i32 [[T1]] + // CHECK: [[T2:%.+]] = sub i32 3, %{{.+}} + // CHECK: insertelement <4 x i32> %{{.+}}, i32 %{{.+}}, i32 [[T2]] + // CHECK: ret <4 x i32> + return vec_splati_ins(vuia, 1, 16U); +} + +vector float test_vec_vec_splati_ins_f(void) { + // CHECK-BE: insertelement <4 x float> %{{.+}}, float %{{.+}}, i32 %{{.+}} + // CHECK-BE: [[T1:%.+]] = add i32 2, %{{.+}} + // CHECK-BE: insertelement <4 x float> %{{.+}}, float %{{.+}}, i32 [[T1]] + // CHECK-BE: ret <4 x float> + // CHECK: [[T1:%.+]] = sub i32 1, %{{.+}} + // CHECK: insertelement <4 x float> %{{.+}}, float %{{.+}}, i32 [[T1]] + // CHECK: [[T2:%.+]] = sub i32 3, %{{.+}} + // CHECK: insertelement <4 x float> %{{.+}}, float %{{.+}}, i32 [[T2]] + // CHECK: ret <4 x float> + return vec_splati_ins(vfa, 0, 1.0f); +} diff --git a/clang/test/CodeGen/builtins-wasm.c b/clang/test/CodeGen/builtins-wasm.c index 36d259f7405d7..f7e3dc1ea5e7a 100644 --- a/clang/test/CodeGen/builtins-wasm.c +++ b/clang/test/CodeGen/builtins-wasm.c @@ -26,18 +26,6 @@ __SIZE_TYPE__ memory_grow(__SIZE_TYPE__ delta) { // WEBASSEMBLY64: call i64 @llvm.wasm.memory.grow.i64(i32 0, i64 %{{.*}}) } -void memory_init(void *dest, int offset, int size) { - __builtin_wasm_memory_init(3, 0, dest, offset, size); - // WEBASSEMBLY32: call void @llvm.wasm.memory.init(i32 3, i32 0, i8* %{{.*}}, i32 %{{.*}}, i32 %{{.*}}) - // WEBASSEMBLY64: call void @llvm.wasm.memory.init(i32 3, i32 0, i8* %{{.*}}, i32 %{{.*}}, i32 %{{.*}}) -} - -void data_drop() { - __builtin_wasm_data_drop(3); - // WEBASSEMBLY32: call void @llvm.wasm.data.drop(i32 3) - // WEBASSEMBLY64: call void @llvm.wasm.data.drop(i32 3) -} - __SIZE_TYPE__ tls_size() { return __builtin_wasm_tls_size(); // WEBASSEMBLY32: call i32 @llvm.wasm.tls.size.i32() diff --git a/clang/test/CodeGen/code-coverage.c b/clang/test/CodeGen/code-coverage.c index 251e8bc77b312..34ba3554f5b54 100644 --- a/clang/test/CodeGen/code-coverage.c +++ b/clang/test/CodeGen/code-coverage.c @@ -9,7 +9,7 @@ // RUN: %clang_cc1 -emit-llvm -disable-red-zone -femit-coverage-data %s -o - | \ // RUN: FileCheck --check-prefixes=CHECK,408 %s -// RUN: %clang_cc1 -emit-llvm -disable-red-zone -femit-coverage-data -coverage-notes-file=aaa.gcno -coverage-data-file=bbb.gcda -dwarf-column-info -debug-info-kind=limited -dwarf-version=4 %s -o - | FileCheck %s --check-prefix GCOV_FILE_INFO +// RUN: %clang_cc1 -emit-llvm -disable-red-zone -femit-coverage-data -coverage-notes-file=aaa.gcno -coverage-data-file=bbb.gcda -debug-info-kind=limited -dwarf-version=4 %s -o - | FileCheck %s --check-prefix GCOV_FILE_INFO // RUN: %clang_cc1 -emit-llvm-bc -o /dev/null -fexperimental-new-pass-manager -fdebug-pass-manager -femit-coverage-data %s 2>&1 | FileCheck --check-prefix=NEWPM %s // RUN: %clang_cc1 -emit-llvm-bc -o /dev/null -fexperimental-new-pass-manager -fdebug-pass-manager -femit-coverage-data -O3 %s 2>&1 | FileCheck --check-prefix=NEWPM-O3 %s diff --git a/clang/test/CodeGen/fp-floatcontrol-pragma.cpp b/clang/test/CodeGen/fp-floatcontrol-pragma.cpp index 7d8843220f44d..548809521f7f2 100644 --- a/clang/test/CodeGen/fp-floatcontrol-pragma.cpp +++ b/clang/test/CodeGen/fp-floatcontrol-pragma.cpp @@ -119,6 +119,24 @@ float fma_test1(float a, float b, float c) { return x; } +#pragma float_control(push) +#pragma float_control(precise, on) +struct Distance {}; +Distance operator+(Distance, Distance); + +template +T add(T lhs, T rhs) { +#pragma float_control(except, on) + return lhs + rhs; +} +#pragma float_control(pop) + +float test_OperatorCall() { + return add(1.0f, 2.0f); + //CHECK: llvm.experimental.constrained.fadd{{.*}}fpexcept.strict +} +// CHECK-LABEL define float {{.*}}test_OperatorCall{{.*}} + #if FENV_ON // expected-warning@+1{{pragma STDC FENV_ACCESS ON is not supported, ignoring pragma}} #pragma STDC FENV_ACCESS ON diff --git a/clang/test/CodeGen/fp-strictfp-exp.cpp b/clang/test/CodeGen/fp-strictfp-exp.cpp new file mode 100644 index 0000000000000..7b9718a50ff2b --- /dev/null +++ b/clang/test/CodeGen/fp-strictfp-exp.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -triple mips64-linux-gnu -fexperimental-strict-floating-point -frounding-math -ffp-exception-behavior=strict -O2 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple mips64-linux-gnu -fexperimental-strict-floating-point -ffp-exception-behavior=strict -O2 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple mips64-linux-gnu -fexperimental-strict-floating-point -frounding-math -O2 -emit-llvm -o - %s | FileCheck %s +// +// Verify that constrained intrinsics are used due to the experimental flag. +// As more targets gain support for constrained intrinsics the triple +// in this test will need to change. + +float fp_precise_1(float a, float b, float c) { +// CHECK-LABEL: define float @_Z12fp_precise_1fff +// CHECK: %[[M:.+]] = tail call float @llvm.experimental.constrained.fmul.f32(float {{.*}}, float {{.*}}, metadata {{.*}}) +// CHECK: tail call float @llvm.experimental.constrained.fadd.f32(float %[[M]], float %c, metadata {{.*}}) + return a * b + c; +} diff --git a/clang/test/CodeGen/fp-strictfp.cpp b/clang/test/CodeGen/fp-strictfp.cpp new file mode 100644 index 0000000000000..bfa13b4dd3545 --- /dev/null +++ b/clang/test/CodeGen/fp-strictfp.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -triple mips64-linux-gnu -frounding-math -ffp-exception-behavior=strict -O2 -verify=rounding,exception -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple mips64-linux-gnu -ffp-exception-behavior=strict -O2 -verify=exception -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple mips64-linux-gnu -frounding-math -O2 -verify=rounding -emit-llvm -o - %s | FileCheck %s +// +// Verify that constrained intrinsics are not used. +// As more targets gain support for constrained intrinsics the triple +// in this test will need to change. + +// rounding-warning@* {{overriding currently unsupported rounding mode on this target}} +// exception-warning@* {{overriding currently unsupported use of floating point exceptions on this target}} +float fp_precise_1(float a, float b, float c) { +// CHECK: define float @_Z12fp_precise_1fff +// CHECK: %[[M:.+]] = fmul float{{.*}} +// CHECK: fadd float %[[M]], %c + return a * b + c; +} diff --git a/clang/test/CodeGen/fpconstrained-cmp-double.c b/clang/test/CodeGen/fpconstrained-cmp-double.c index 2819970a3fcff..335b7e49b01df 100644 --- a/clang/test/CodeGen/fpconstrained-cmp-double.c +++ b/clang/test/CodeGen/fpconstrained-cmp-double.c @@ -1,9 +1,9 @@ // RUN: %clang_cc1 -ffp-exception-behavior=ignore -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=FCMP -// RUN: %clang_cc1 -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=EXCEPT -// RUN: %clang_cc1 -ffp-exception-behavior=maytrap -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=MAYTRAP -// RUN: %clang_cc1 -frounding-math -ffp-exception-behavior=ignore -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=IGNORE -// RUN: %clang_cc1 -frounding-math -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=EXCEPT -// RUN: %clang_cc1 -frounding-math -ffp-exception-behavior=maytrap -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=MAYTRAP +// RUN: %clang_cc1 -ffp-exception-behavior=strict -fexperimental-strict-floating-point -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=EXCEPT +// RUN: %clang_cc1 -ffp-exception-behavior=maytrap -fexperimental-strict-floating-point -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=MAYTRAP +// RUN: %clang_cc1 -frounding-math -ffp-exception-behavior=ignore -fexperimental-strict-floating-point -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=IGNORE +// RUN: %clang_cc1 -frounding-math -ffp-exception-behavior=strict -fexperimental-strict-floating-point -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=EXCEPT +// RUN: %clang_cc1 -frounding-math -ffp-exception-behavior=maytrap -fexperimental-strict-floating-point -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=MAYTRAP _Bool QuietEqual(double f1, double f2) { // CHECK-LABEL: define {{.*}}i1 @QuietEqual(double %f1, double %f2) diff --git a/clang/test/CodeGen/fpconstrained-cmp-float.c b/clang/test/CodeGen/fpconstrained-cmp-float.c index 0265fc54c02b5..e9667904122ba 100644 --- a/clang/test/CodeGen/fpconstrained-cmp-float.c +++ b/clang/test/CodeGen/fpconstrained-cmp-float.c @@ -1,9 +1,9 @@ -// RUN: %clang_cc1 -ffp-exception-behavior=ignore -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=FCMP -// RUN: %clang_cc1 -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=EXCEPT -// RUN: %clang_cc1 -ffp-exception-behavior=maytrap -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=MAYTRAP -// RUN: %clang_cc1 -frounding-math -ffp-exception-behavior=ignore -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=IGNORE -// RUN: %clang_cc1 -frounding-math -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=EXCEPT -// RUN: %clang_cc1 -frounding-math -ffp-exception-behavior=maytrap -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=MAYTRAP +// RUN: %clang_cc1 -ffp-exception-behavior=ignore -fexperimental-strict-floating-point -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=FCMP +// RUN: %clang_cc1 -ffp-exception-behavior=strict -fexperimental-strict-floating-point -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=EXCEPT +// RUN: %clang_cc1 -ffp-exception-behavior=maytrap -fexperimental-strict-floating-point -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=MAYTRAP +// RUN: %clang_cc1 -frounding-math -ffp-exception-behavior=ignore -fexperimental-strict-floating-point -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=IGNORE +// RUN: %clang_cc1 -frounding-math -ffp-exception-behavior=strict -fexperimental-strict-floating-point -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=EXCEPT +// RUN: %clang_cc1 -frounding-math -ffp-exception-behavior=maytrap -fexperimental-strict-floating-point -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=MAYTRAP _Bool QuietEqual(float f1, float f2) { // CHECK-LABEL: define {{.*}}i1 @QuietEqual(float %f1, float %f2) diff --git a/clang/test/CodeGen/fpconstrained.c b/clang/test/CodeGen/fpconstrained.c index 902d6b5baf490..0307ebbd357f5 100644 --- a/clang/test/CodeGen/fpconstrained.c +++ b/clang/test/CodeGen/fpconstrained.c @@ -1,10 +1,11 @@ -// RUN: %clang_cc1 -ftrapping-math -frounding-math -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck %s -check-prefix=FPMODELSTRICT +// RUN: %clang_cc1 -ftrapping-math -frounding-math -ffp-exception-behavior=strict -fexperimental-strict-floating-point -emit-llvm -o - %s | FileCheck %s -check-prefix=FPMODELSTRICT // RUN: %clang_cc1 -ffp-contract=fast -emit-llvm -o - %s | FileCheck %s -check-prefix=PRECISE // RUN: %clang_cc1 -ffast-math -ffp-contract=fast -emit-llvm -o - %s | FileCheck %s -check-prefix=FAST // RUN: %clang_cc1 -ffast-math -emit-llvm -o - %s | FileCheck %s -check-prefix=FASTNOCONTRACT // RUN: %clang_cc1 -ffast-math -ffp-contract=fast -ffp-exception-behavior=ignore -emit-llvm -o - %s | FileCheck %s -check-prefix=FAST -// RUN: %clang_cc1 -ffast-math -ffp-contract=fast -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck %s -check-prefix=EXCEPT -// RUN: %clang_cc1 -ffast-math -ffp-contract=fast -ffp-exception-behavior=maytrap -emit-llvm -o - %s | FileCheck %s -check-prefix=MAYTRAP +// RUN: %clang_cc1 -ffast-math -ffp-contract=fast -ffp-exception-behavior=strict -fexperimental-strict-floating-point -emit-llvm -o - %s | FileCheck %s -check-prefix=EXCEPT +// RUN: %clang_cc1 -ffast-math -ffp-contract=fast -ffp-exception-behavior=maytrap -fexperimental-strict-floating-point -emit-llvm -o - %s | FileCheck %s -check-prefix=MAYTRAP + float f0, f1, f2; void foo() { diff --git a/clang/test/CodeGen/fpconstrained.cpp b/clang/test/CodeGen/fpconstrained.cpp index e914abcc69268..305c3684486d9 100644 --- a/clang/test/CodeGen/fpconstrained.cpp +++ b/clang/test/CodeGen/fpconstrained.cpp @@ -1,10 +1,11 @@ -// RUN: %clang_cc1 -x c++ -ftrapping-math -fexceptions -fcxx-exceptions -frounding-math -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck %s -check-prefix=FPMODELSTRICT +// RUN: %clang_cc1 -x c++ -ftrapping-math -fexceptions -fcxx-exceptions -frounding-math -ffp-exception-behavior=strict -fexperimental-strict-floating-point -emit-llvm -o - %s | FileCheck %s -check-prefix=FPMODELSTRICT // RUN: %clang_cc1 -x c++ -ffp-contract=fast -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix=PRECISE // RUN: %clang_cc1 -x c++ -ffast-math -fexceptions -fcxx-exceptions -ffp-contract=fast -emit-llvm -o - %s | FileCheck %s -check-prefix=FAST // RUN: %clang_cc1 -x c++ -ffast-math -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix=FASTNOCONTRACT // RUN: %clang_cc1 -x c++ -ffast-math -fexceptions -fcxx-exceptions -ffp-contract=fast -ffp-exception-behavior=ignore -emit-llvm -o - %s | FileCheck %s -check-prefix=FAST -// RUN: %clang_cc1 -x c++ -ffast-math -fexceptions -fcxx-exceptions -ffp-contract=fast -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck %s -check-prefix=EXCEPT -// RUN: %clang_cc1 -x c++ -ffast-math -fexceptions -fcxx-exceptions -ffp-contract=fast -ffp-exception-behavior=maytrap -emit-llvm -o - %s | FileCheck %s -check-prefix=MAYTRAP +// RUN: %clang_cc1 -x c++ -ffast-math -fexceptions -fcxx-exceptions -ffp-contract=fast -ffp-exception-behavior=strict -fexperimental-strict-floating-point -emit-llvm -o - %s | FileCheck %s -check-prefix=EXCEPT +// RUN: %clang_cc1 -x c++ -ffast-math -fexceptions -fcxx-exceptions -ffp-contract=fast -ffp-exception-behavior=maytrap -fexperimental-strict-floating-point -emit-llvm -o - %s | FileCheck %s -check-prefix=MAYTRAP + float f0, f1, f2; template diff --git a/clang/test/CodeGen/linetable-endscope.c b/clang/test/CodeGen/linetable-endscope.c index 6eefbea2fc667..03291a2ea4aa9 100644 --- a/clang/test/CodeGen/linetable-endscope.c +++ b/clang/test/CodeGen/linetable-endscope.c @@ -11,7 +11,7 @@ void foo(char c) { int i; - // CHECK: ![[CONV]] = !DILocation(line: [[@LINE+1]], scope: !{{.*}}) + // CHECK: ![[CONV]] = !DILocation(line: [[@LINE+1]], column: 5, scope: !{{.*}}) i = c; - // CHECK: ![[RET]] = !DILocation(line: [[@LINE+1]], scope: !{{.*}}) + // CHECK: ![[RET]] = !DILocation(line: [[@LINE+1]], column: 1, scope: !{{.*}}) } diff --git a/clang/test/CodeGen/ms-intrinsics.c b/clang/test/CodeGen/ms-intrinsics.c index fed789e60d373..5182ae4039849 100644 --- a/clang/test/CodeGen/ms-intrinsics.c +++ b/clang/test/CodeGen/ms-intrinsics.c @@ -523,72 +523,72 @@ void test_iso_volatile_store64(__int64 volatile *p, __int64 v) { __iso_volatile_ // CHECK: store volatile i64 %v, i64* %p -#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) +#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) __int64 test_InterlockedExchange64(__int64 volatile *value, __int64 mask) { return _InterlockedExchange64(value, mask); } -// CHECK-ARM-X64: define{{.*}}i64 @test_InterlockedExchange64(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ -// CHECK-ARM-X64: [[RESULT:%[0-9]+]] = atomicrmw xchg i64* %value, i64 %mask seq_cst -// CHECK-ARM-X64: ret i64 [[RESULT:%[0-9]+]] -// CHECK-ARM-X64: } +// CHECK: define{{.*}}i64 @test_InterlockedExchange64(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: [[RESULT:%[0-9]+]] = atomicrmw xchg i64* %value, i64 %mask seq_cst +// CHECK: ret i64 [[RESULT:%[0-9]+]] +// CHECK: } __int64 test_InterlockedExchangeAdd64(__int64 volatile *value, __int64 mask) { return _InterlockedExchangeAdd64(value, mask); } -// CHECK-ARM-X64: define{{.*}}i64 @test_InterlockedExchangeAdd64(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ -// CHECK-ARM-X64: [[RESULT:%[0-9]+]] = atomicrmw add i64* %value, i64 %mask seq_cst -// CHECK-ARM-X64: ret i64 [[RESULT:%[0-9]+]] -// CHECK-ARM-X64: } +// CHECK: define{{.*}}i64 @test_InterlockedExchangeAdd64(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: [[RESULT:%[0-9]+]] = atomicrmw add i64* %value, i64 %mask seq_cst +// CHECK: ret i64 [[RESULT:%[0-9]+]] +// CHECK: } __int64 test_InterlockedExchangeSub64(__int64 volatile *value, __int64 mask) { return _InterlockedExchangeSub64(value, mask); } -// CHECK-ARM-X64: define{{.*}}i64 @test_InterlockedExchangeSub64(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ -// CHECK-ARM-X64: [[RESULT:%[0-9]+]] = atomicrmw sub i64* %value, i64 %mask seq_cst -// CHECK-ARM-X64: ret i64 [[RESULT:%[0-9]+]] -// CHECK-ARM-X64: } +// CHECK: define{{.*}}i64 @test_InterlockedExchangeSub64(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: [[RESULT:%[0-9]+]] = atomicrmw sub i64* %value, i64 %mask seq_cst +// CHECK: ret i64 [[RESULT:%[0-9]+]] +// CHECK: } __int64 test_InterlockedOr64(__int64 volatile *value, __int64 mask) { return _InterlockedOr64(value, mask); } -// CHECK-ARM-X64: define{{.*}}i64 @test_InterlockedOr64(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ -// CHECK-ARM-X64: [[RESULT:%[0-9]+]] = atomicrmw or i64* %value, i64 %mask seq_cst -// CHECK-ARM-X64: ret i64 [[RESULT:%[0-9]+]] -// CHECK-ARM-X64: } +// CHECK: define{{.*}}i64 @test_InterlockedOr64(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: [[RESULT:%[0-9]+]] = atomicrmw or i64* %value, i64 %mask seq_cst +// CHECK: ret i64 [[RESULT:%[0-9]+]] +// CHECK: } __int64 test_InterlockedXor64(__int64 volatile *value, __int64 mask) { return _InterlockedXor64(value, mask); } -// CHECK-ARM-X64: define{{.*}}i64 @test_InterlockedXor64(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ -// CHECK-ARM-X64: [[RESULT:%[0-9]+]] = atomicrmw xor i64* %value, i64 %mask seq_cst -// CHECK-ARM-X64: ret i64 [[RESULT:%[0-9]+]] -// CHECK-ARM-X64: } +// CHECK: define{{.*}}i64 @test_InterlockedXor64(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: [[RESULT:%[0-9]+]] = atomicrmw xor i64* %value, i64 %mask seq_cst +// CHECK: ret i64 [[RESULT:%[0-9]+]] +// CHECK: } __int64 test_InterlockedAnd64(__int64 volatile *value, __int64 mask) { return _InterlockedAnd64(value, mask); } -// CHECK-ARM-X64: define{{.*}}i64 @test_InterlockedAnd64(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ -// CHECK-ARM-X64: [[RESULT:%[0-9]+]] = atomicrmw and i64* %value, i64 %mask seq_cst -// CHECK-ARM-X64: ret i64 [[RESULT:%[0-9]+]] -// CHECK-ARM-X64: } +// CHECK: define{{.*}}i64 @test_InterlockedAnd64(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: [[RESULT:%[0-9]+]] = atomicrmw and i64* %value, i64 %mask seq_cst +// CHECK: ret i64 [[RESULT:%[0-9]+]] +// CHECK: } __int64 test_InterlockedIncrement64(__int64 volatile *Addend) { return _InterlockedIncrement64(Addend); } -// CHECK-ARM-X64: define{{.*}}i64 @test_InterlockedIncrement64(i64*{{[a-z_ ]*}}%Addend){{.*}}{ -// CHECK-ARM-X64: [[TMP:%[0-9]+]] = atomicrmw add i64* %Addend, i64 1 seq_cst -// CHECK-ARM-X64: [[RESULT:%[0-9]+]] = add i64 [[TMP]], 1 -// CHECK-ARM-X64: ret i64 [[RESULT]] -// CHECK-ARM-X64: } +// CHECK: define{{.*}}i64 @test_InterlockedIncrement64(i64*{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK: [[TMP:%[0-9]+]] = atomicrmw add i64* %Addend, i64 1 seq_cst +// CHECK: [[RESULT:%[0-9]+]] = add i64 [[TMP]], 1 +// CHECK: ret i64 [[RESULT]] +// CHECK: } __int64 test_InterlockedDecrement64(__int64 volatile *Addend) { return _InterlockedDecrement64(Addend); } -// CHECK-ARM-X64: define{{.*}}i64 @test_InterlockedDecrement64(i64*{{[a-z_ ]*}}%Addend){{.*}}{ -// CHECK-ARM-X64: [[TMP:%[0-9]+]] = atomicrmw sub i64* %Addend, i64 1 seq_cst -// CHECK-ARM-X64: [[RESULT:%[0-9]+]] = add i64 [[TMP]], -1 -// CHECK-ARM-X64: ret i64 [[RESULT]] -// CHECK-ARM-X64: } +// CHECK: define{{.*}}i64 @test_InterlockedDecrement64(i64*{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK: [[TMP:%[0-9]+]] = atomicrmw sub i64* %Addend, i64 1 seq_cst +// CHECK: [[RESULT:%[0-9]+]] = add i64 [[TMP]], -1 +// CHECK: ret i64 [[RESULT]] +// CHECK: } #endif diff --git a/clang/test/CodeGen/msp430-abi-complex.c b/clang/test/CodeGen/msp430-abi-complex.c new file mode 100644 index 0000000000000..faafcd2cde3f8 --- /dev/null +++ b/clang/test/CodeGen/msp430-abi-complex.c @@ -0,0 +1,226 @@ +// REQUIRES: msp430-registered-target +// RUN: %clang -target msp430 -Os -S -o- %s | FileCheck %s + +volatile int N; +volatile int i16_1, i16_2; +volatile long i32_1, i32_2; +volatile long long i64_1, i64_2; +volatile float f1, f2; +volatile double d1, d2; + +_Static_assert(sizeof(int) == 2, "Assumption failed"); +_Static_assert(sizeof(long) == 4, "Assumption failed"); +_Static_assert(sizeof(long long) == 8, "Assumption failed"); + +void complex_i16_arg_first(int _Complex x, int n) { +// CHECK-LABEL: @complex_i16_arg_first + i16_1 = __real__ x; +// CHECK-DAG: mov r12, &i16_1 + i16_2 = __imag__ x; +// CHECK-DAG: mov r13, &i16_2 + N = n; +// CHECK-DAG: mov r14, &N +// CHECK: ret +} + +void complex_i16_arg_second(int n, int _Complex x) { +// CHECK-LABEL: @complex_i16_arg_second + N = n; +// CHECK-DAG: mov r12, &N + i16_1 = __real__ x; +// CHECK-DAG: mov r13, &i16_1 + i16_2 = __imag__ x; +// CHECK-DAG: mov r14, &i16_2 +// CHECK: ret +} + +void complex_i32_arg_first(long _Complex x, int n) { +// CHECK-LABEL: @complex_i32_arg_first + i32_1 = __real__ x; +// CHECK-DAG: mov r12, &i32_1 +// CHECK-DAG: mov r13, &i32_1+2 + i32_2 = __imag__ x; +// CHECK-DAG: mov r14, &i32_2 +// CHECK-DAG: mov r15, &i32_2+2 + N = n; +// CHECK-DAG: mov 2(r1), &N +// CHECK: ret +} + +void complex_i32_arg_second(int n, long _Complex x) { +// CHECK-LABEL: @complex_i32_arg_second + N = n; +// CHECK-DAG: mov r12, &N + i32_1 = __real__ x; +// CHECK-DAG: mov 2(r1), &i32_1 +// CHECK-DAG: mov 4(r1), &i32_1+2 + i32_2 = __imag__ x; +// CHECK-DAG: mov 6(r1), &i32_2 +// CHECK-DAG: mov 8(r1), &i32_2+2 +// CHECK: ret +} + +void complex_i64_arg_first(long long _Complex x, int n) { +// CHECK-LABEL: @complex_i64_arg_first + i64_1 = __real__ x; +// CHECK-DAG: mov 2(r1), &i64_1 +// CHECK-DAG: mov 4(r1), &i64_1+2 +// CHECK-DAG: mov 6(r1), &i64_1+4 +// CHECK-DAG: mov 8(r1), &i64_1+6 + i64_2 = __imag__ x; +// CHECK-DAG: mov 10(r1), &i64_2 +// CHECK-DAG: mov 12(r1), &i64_2+2 +// CHECK-DAG: mov 14(r1), &i64_2+4 +// CHECK-DAG: mov 16(r1), &i64_2+6 + N = n; +// CHECK-DAG: mov r12, &N +// CHECK: ret +} + +void complex_i64_arg_second(int n, long long _Complex x) { +// CHECK-LABEL: @complex_i64_arg_second + N = n; +// CHECK-DAG: mov r12, &N + i64_1 = __real__ x; +// CHECK-DAG: mov 2(r1), &i64_1 +// CHECK-DAG: mov 4(r1), &i64_1+2 +// CHECK-DAG: mov 6(r1), &i64_1+4 +// CHECK-DAG: mov 8(r1), &i64_1+6 + i64_2 = __imag__ x; +// CHECK-DAG: mov 10(r1), &i64_2 +// CHECK-DAG: mov 12(r1), &i64_2+2 +// CHECK-DAG: mov 14(r1), &i64_2+4 +// CHECK-DAG: mov 16(r1), &i64_2+6 +// CHECK: ret +} + +void complex_float_arg_first(float _Complex x, int n) { +// CHECK-LABEL: @complex_float_arg_first + f1 = __real__ x; +// CHECK-DAG: mov r12, &f1 +// CHECK-DAG: mov r13, &f1+2 + f2 = __imag__ x; +// CHECK-DAG: mov r14, &f2 +// CHECK-DAG: mov r15, &f2+2 + N = n; +// CHECK-DAG: mov 2(r1), &N +// CHECK: ret +} + +void complex_float_arg_second(int n, float _Complex x) { +// CHECK-LABEL: @complex_float_arg_second + N = n; +// CHECK-DAG: mov r12, &N + f1 = __real__ x; +// CHECK-DAG: mov 2(r1), &f1 +// CHECK-DAG: mov 4(r1), &f1+2 + f2 = __imag__ x; +// CHECK-DAG: mov 6(r1), &f2 +// CHECK-DAG: mov 8(r1), &f2+2 +// CHECK: ret +} + +void complex_double_arg_first(double _Complex x, int n) { +// CHECK-LABEL: @complex_double_arg_first + d1 = __real__ x; +// CHECK-DAG: mov 2(r1), &d1 +// CHECK-DAG: mov 4(r1), &d1+2 +// CHECK-DAG: mov 6(r1), &d1+4 +// CHECK-DAG: mov 8(r1), &d1+6 + d2 = __imag__ x; +// CHECK-DAG: mov 10(r1), &d2 +// CHECK-DAG: mov 12(r1), &d2+2 +// CHECK-DAG: mov 14(r1), &d2+4 +// CHECK-DAG: mov 16(r1), &d2+6 + N = n; +// CHECK-DAG: mov r12, &N +// CHECK: ret +} + +void complex_double_arg_second(int n, double _Complex x) { +// CHECK-LABEL: @complex_double_arg_second + d1 = __real__ x; +// CHECK-DAG: mov 2(r1), &d1 +// CHECK-DAG: mov 4(r1), &d1+2 +// CHECK-DAG: mov 6(r1), &d1+4 +// CHECK-DAG: mov 8(r1), &d1+6 + d2 = __imag__ x; +// CHECK-DAG: mov 10(r1), &d2 +// CHECK-DAG: mov 12(r1), &d2+2 +// CHECK-DAG: mov 14(r1), &d2+4 +// CHECK-DAG: mov 16(r1), &d2+6 + N = n; +// CHECK-DAG: mov r12, &N +// CHECK: ret +} + +int _Complex complex_i16_res(void) { +// CHECK-LABEL: @complex_i16_res + int _Complex res; + __real__ res = 0x1122; +// CHECK-DAG: mov #4386, r12 + __imag__ res = 0x3344; +// CHECK-DAG: mov #13124, r13 + return res; +// CHECK: ret +} + +long _Complex complex_i32_res(void) { +// CHECK-LABEL: @complex_i32_res + long _Complex res; + __real__ res = 0x11223344; +// CHECK-DAG: mov #13124, r12 +// CHECK-DAG: mov #4386, r13 + __imag__ res = 0x55667788; +// CHECK-DAG: mov #30600, r14 +// CHECK-DAG: mov #21862, r15 + return res; +// CHECK: ret +} + +long long _Complex complex_i64_res(void) { +// CHECK-LABEL: @complex_i64_res + long long _Complex res; + __real__ res = 0x1122334455667788; +// CHECK-DAG: mov #30600, 0(r12) +// CHECK-DAG: mov #21862, 2(r12) +// CHECK-DAG: mov #13124, 4(r12) +// CHECK-DAG: mov #4386, 6(r12) + __imag__ res = 0x99aabbccddeeff00; +// CHECK-DAG: mov #-256, 8(r12) +// CHECK-DAG: mov #-8722, 10(r12) +// CHECK-DAG: mov #-17460, 12(r12) +// CHECK-DAG: mov #-26198, 14(r12) + return res; +// CHECK: ret +} + +float _Complex complex_float_res(void) { +// CHECK-LABEL: @complex_float_res + float _Complex res; + __real__ res = 1; +// CHECK-DAG: clr r12 +// CHECK-DAG: mov #16256, r13 + __imag__ res = -1; +// CHECK-DAG: clr r14 +// CHECK-DAG: mov #-16512, r15 + return res; +// CHECK: ret +} + +double _Complex complex_double_res(void) { +// CHECK-LABEL: @complex_double_res + double _Complex res; + __real__ res = 1; +// CHECK-DAG: clr 0(r12) +// CHECK-DAG: clr 2(r12) +// CHECK-DAG: clr 4(r12) +// CHECK-DAG: mov #16368, 6(r12) + __imag__ res = -1; +// CHECK-DAG: clr 8(r12) +// CHECK-DAG: clr 10(r12) +// CHECK-DAG: clr 12(r12) +// CHECK-DAG: mov #-16400, 14(r12) + return res; +// CHECK: ret +} diff --git a/clang/test/CodeGen/msp430-register-names.c b/clang/test/CodeGen/msp430-register-names.c new file mode 100644 index 0000000000000..106b6c933a49b --- /dev/null +++ b/clang/test/CodeGen/msp430-register-names.c @@ -0,0 +1,105 @@ +// Registers R0 - R3 have different names inside the LLVM MSP430 target code. +// Test that they are handled properly when used inside clobber lists. +// At the time of writing, llc silently ignores unknown register names. + +// REQUIRES: msp430-registered-target +// RUN: %clang -target msp430 -c %s -mllvm -stop-after=finalize-isel -o- | FileCheck %s + +void test_function(void) { + asm volatile("" + : + : + : "r0"); + asm volatile("" + : + : + : "r1"); + asm volatile("" + : + : + : "r2"); + asm volatile("" + : + : + : "r3"); + asm volatile("" + : + : + : "r4"); + asm volatile("" + : + : + : "r5"); + asm volatile("" + : + : + : "r6"); + asm volatile("" + : + : + : "r7"); + asm volatile("" + : + : + : "r8"); + asm volatile("" + : + : + : "r9"); + asm volatile("" + : + : + : "r10"); + asm volatile("" + : + : + : "r11"); + asm volatile("" + : + : + : "r12"); + asm volatile("" + : + : + : "r13"); + asm volatile("" + : + : + : "r14"); + asm volatile("" + : + : + : "r15"); + // CHECK: call void asm sideeffect "", "~{pc}"() + // CHECK: call void asm sideeffect "", "~{sp}"() + // CHECK: call void asm sideeffect "", "~{sr}"() + // CHECK: call void asm sideeffect "", "~{cg}"() + // CHECK: call void asm sideeffect "", "~{r4}"() + // CHECK: call void asm sideeffect "", "~{r5}"() + // CHECK: call void asm sideeffect "", "~{r6}"() + // CHECK: call void asm sideeffect "", "~{r7}"() + // CHECK: call void asm sideeffect "", "~{r8}"() + // CHECK: call void asm sideeffect "", "~{r9}"() + // CHECK: call void asm sideeffect "", "~{r10}"() + // CHECK: call void asm sideeffect "", "~{r11}"() + // CHECK: call void asm sideeffect "", "~{r12}"() + // CHECK: call void asm sideeffect "", "~{r13}"() + // CHECK: call void asm sideeffect "", "~{r14}"() + // CHECK: call void asm sideeffect "", "~{r15}"() + // CHECK: INLINEASM &"", {{.*}} implicit-def early-clobber $pc + // CHECK: INLINEASM &"", {{.*}} implicit-def early-clobber $sp + // CHECK: INLINEASM &"", {{.*}} implicit-def early-clobber $sr + // CHECK: INLINEASM &"", {{.*}} implicit-def early-clobber $cg + // CHECK: INLINEASM &"", {{.*}} implicit-def early-clobber $r4 + // CHECK: INLINEASM &"", {{.*}} implicit-def early-clobber $r5 + // CHECK: INLINEASM &"", {{.*}} implicit-def early-clobber $r6 + // CHECK: INLINEASM &"", {{.*}} implicit-def early-clobber $r7 + // CHECK: INLINEASM &"", {{.*}} implicit-def early-clobber $r8 + // CHECK: INLINEASM &"", {{.*}} implicit-def early-clobber $r9 + // CHECK: INLINEASM &"", {{.*}} implicit-def early-clobber $r10 + // CHECK: INLINEASM &"", {{.*}} implicit-def early-clobber $r11 + // CHECK: INLINEASM &"", {{.*}} implicit-def early-clobber $r12 + // CHECK: INLINEASM &"", {{.*}} implicit-def early-clobber $r13 + // CHECK: INLINEASM &"", {{.*}} implicit-def early-clobber $r14 + // CHECK: INLINEASM &"", {{.*}} implicit-def early-clobber $r15 +} diff --git a/clang/test/CodeGen/opt-record-MIR.c b/clang/test/CodeGen/opt-record-MIR.c index 731c6591c2372..40832d6e776a7 100644 --- a/clang/test/CodeGen/opt-record-MIR.c +++ b/clang/test/CodeGen/opt-record-MIR.c @@ -1,11 +1,11 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -triple arm64-apple-ios -S -o /dev/null %s -O2 -dwarf-column-info -Rpass-missed=regalloc 2>&1 | FileCheck -check-prefix=REMARK %s -// RUN: %clang_cc1 -triple arm64-apple-ios -S -o /dev/null %s -O2 -dwarf-column-info 2>&1 | FileCheck -allow-empty -check-prefix=NO_REMARK %s -// RUN: %clang_cc1 -triple arm64-apple-ios -S -o /dev/null %s -O2 -dwarf-column-info -opt-record-file %t.yaml +// RUN: %clang_cc1 -triple arm64-apple-ios -S -o /dev/null %s -O2 -Rpass-missed=regalloc 2>&1 | FileCheck -check-prefix=REMARK %s +// RUN: %clang_cc1 -triple arm64-apple-ios -S -o /dev/null %s -O2 2>&1 | FileCheck -allow-empty -check-prefix=NO_REMARK %s +// RUN: %clang_cc1 -triple arm64-apple-ios -S -o /dev/null %s -O2 -opt-record-file %t.yaml // RUN: cat %t.yaml | FileCheck -check-prefix=YAML %s -// RUN: %clang_cc1 -triple arm64-apple-ios -S -o /dev/null %s -O2 -dwarf-column-info -opt-record-file %t.yaml -opt-record-passes asm-printer +// RUN: %clang_cc1 -triple arm64-apple-ios -S -o /dev/null %s -O2 -opt-record-file %t.yaml -opt-record-passes asm-printer // RUN: cat %t.yaml | FileCheck -check-prefix=PASSES %s -// RUN: %clang_cc1 -triple arm64-apple-ios -S -o /dev/null %s -O2 -dwarf-column-info -opt-record-file %t.yaml -opt-record-format yaml +// RUN: %clang_cc1 -triple arm64-apple-ios -S -o /dev/null %s -O2 -opt-record-file %t.yaml -opt-record-format yaml // RUN: cat %t.yaml | FileCheck -check-prefix=YAML %s void bar(float); diff --git a/clang/test/CodeGen/opt-record.c b/clang/test/CodeGen/opt-record.c index 481b45d9e9589..243d05d26e318 100644 --- a/clang/test/CodeGen/opt-record.c +++ b/clang/test/CodeGen/opt-record.c @@ -1,14 +1,14 @@ -// RUN: %clang_cc1 -O3 -triple x86_64-unknown-linux-gnu -target-cpu x86-64 %s -o %t -dwarf-column-info -opt-record-file %t.yaml -emit-obj +// RUN: %clang_cc1 -O3 -triple x86_64-unknown-linux-gnu -target-cpu x86-64 %s -o %t -opt-record-file %t.yaml -emit-obj // RUN: cat %t.yaml | FileCheck %s // RUN: llvm-profdata merge %S/Inputs/opt-record.proftext -o %t.profdata -// RUN: %clang_cc1 -O3 -triple x86_64-unknown-linux-gnu -target-cpu x86-64 -fprofile-instrument-use-path=%t.profdata %s -o %t -dwarf-column-info -opt-record-file %t.yaml -emit-obj +// RUN: %clang_cc1 -O3 -triple x86_64-unknown-linux-gnu -target-cpu x86-64 -fprofile-instrument-use-path=%t.profdata %s -o %t -opt-record-file %t.yaml -emit-obj // RUN: cat %t.yaml | FileCheck -check-prefix=CHECK -check-prefix=CHECK-PGO %s -// RUN: %clang_cc1 -O3 -triple x86_64-unknown-linux-gnu -target-cpu x86-64 %s -o %t -dwarf-column-info -opt-record-file %t.yaml -opt-record-passes inline -emit-obj +// RUN: %clang_cc1 -O3 -triple x86_64-unknown-linux-gnu -target-cpu x86-64 %s -o %t -opt-record-file %t.yaml -opt-record-passes inline -emit-obj // RUN: cat %t.yaml | FileCheck -check-prefix=CHECK-PASSES %s -// RUN: not %clang_cc1 -O3 -triple x86_64-unknown-linux-gnu -target-cpu x86-64 %s -o %t -dwarf-column-info -opt-record-file %t.yaml -opt-record-passes "(foo" -emit-obj 2>&1 | FileCheck -check-prefix=CHECK-PATTERN-ERROR %s -// RUN: %clang_cc1 -O3 -triple x86_64-unknown-linux-gnu -target-cpu x86-64 %s -o %t -dwarf-column-info -opt-record-file %t.yaml -opt-record-format yaml -emit-obj +// RUN: not %clang_cc1 -O3 -triple x86_64-unknown-linux-gnu -target-cpu x86-64 %s -o %t -opt-record-file %t.yaml -opt-record-passes "(foo" -emit-obj 2>&1 | FileCheck -check-prefix=CHECK-PATTERN-ERROR %s +// RUN: %clang_cc1 -O3 -triple x86_64-unknown-linux-gnu -target-cpu x86-64 %s -o %t -opt-record-file %t.yaml -opt-record-format yaml -emit-obj // RUN: cat %t.yaml | FileCheck %s -// RUN: not %clang_cc1 -O3 -triple x86_64-unknown-linux-gnu -target-cpu x86-64 %s -o %t -dwarf-column-info -opt-record-file %t.yaml -opt-record-format "unknown-format" -emit-obj 2>&1 | FileCheck -check-prefix=CHECK-FORMAT-ERROR %s +// RUN: not %clang_cc1 -O3 -triple x86_64-unknown-linux-gnu -target-cpu x86-64 %s -o %t -opt-record-file %t.yaml -opt-record-format "unknown-format" -emit-obj 2>&1 | FileCheck -check-prefix=CHECK-FORMAT-ERROR %s // REQUIRES: x86-registered-target void bar(); diff --git a/clang/test/CodeGen/stack-clash-protection.c b/clang/test/CodeGen/stack-clash-protection.c index eb48da8ff9e9a..54699f044ae48 100644 --- a/clang/test/CodeGen/stack-clash-protection.c +++ b/clang/test/CodeGen/stack-clash-protection.c @@ -1,6 +1,8 @@ // Check the correct function attributes are generated // RUN: %clang_cc1 -triple x86_64-linux -O0 -S -emit-llvm -o- %s -fstack-clash-protection | FileCheck %s // RUN: %clang_cc1 -triple s390x-linux-gnu -O0 -S -emit-llvm -o- %s -fstack-clash-protection | FileCheck %s +// RUN: %clang_cc1 -triple powerpc64le-linux-gnu -O0 -S -emit-llvm -o- %s -fstack-clash-protection | FileCheck %s +// RUN: %clang_cc1 -triple powerpc64-linux-gnu -O0 -S -emit-llvm -o- %s -fstack-clash-protection | FileCheck %s // CHECK: define void @large_stack() #[[A:.*]] { void large_stack() { diff --git a/clang/test/CodeGen/systemz-abi.c b/clang/test/CodeGen/systemz-abi.c index 35adbbe301c47..9f9cb2275bfa4 100644 --- a/clang/test/CodeGen/systemz-abi.c +++ b/clang/test/CodeGen/systemz-abi.c @@ -155,6 +155,17 @@ struct agg_nofloat3 pass_agg_nofloat3(struct agg_nofloat3 arg) { return arg; } // CHECK-LABEL: define void @pass_agg_nofloat3(%struct.agg_nofloat3* noalias sret align 4 %{{.*}}, i32 %{{.*}}) +// Union types likewise are *not* float-like aggregate types + +union union_float { float a; }; +union union_float pass_union_float(union union_float arg) { return arg; } +// CHECK-LABEL: define void @pass_union_float(%union.union_float* noalias sret align 4 %{{.*}}, i32 %{{.*}}) + +union union_double { double a; }; +union union_double pass_union_double(union union_double arg) { return arg; } +// CHECK-LABEL: define void @pass_union_double(%union.union_double* noalias sret align 8 %{{.*}}, i64 %{{.*}}) + + // Accessing variable argument lists int va_int(__builtin_va_list l) { return __builtin_va_arg(l, int); } diff --git a/clang/test/CodeGen/systemz-abi.cpp b/clang/test/CodeGen/systemz-abi.cpp index cb381e88dd8f1..a91cb72ae33e2 100644 --- a/clang/test/CodeGen/systemz-abi.cpp +++ b/clang/test/CodeGen/systemz-abi.cpp @@ -2,10 +2,58 @@ // RUN: %clang_cc1 -triple s390x-linux-gnu -emit-llvm -x c++ -o - %s -mfloat-abi soft \ // RUN: | FileCheck %s --check-prefix=SOFT-FLOAT +// Verify that class types are also recognized as float-like aggregate types + +class agg_float_class { float a; }; +class agg_float_class pass_agg_float_class(class agg_float_class arg) { return arg; } +// CHECK-LABEL: define void @_Z20pass_agg_float_class15agg_float_class(%class.agg_float_class* noalias sret align 4 %{{.*}}, float %{{.*}}) +// SOFT-FLOAT-LABEL: define void @_Z20pass_agg_float_class15agg_float_class(%class.agg_float_class* noalias sret align 4 %{{.*}}, i32 %{{.*}}) + +class agg_double_class { double a; }; +class agg_double_class pass_agg_double_class(class agg_double_class arg) { return arg; } +// CHECK-LABEL: define void @_Z21pass_agg_double_class16agg_double_class(%class.agg_double_class* noalias sret align 8 %{{.*}}, double %{{.*}}) +// SOFT-FLOAT-LABEL: define void @_Z21pass_agg_double_class16agg_double_class(%class.agg_double_class* noalias sret align 8 %{{.*}}, i64 %{{.*}}) + + // For compatibility with GCC, this structure is passed in an FPR in C++, // but passed in a GPR in C (checked in systemz-abi.c). struct agg_float_cpp { float a; int : 0; }; struct agg_float_cpp pass_agg_float_cpp(struct agg_float_cpp arg) { return arg; } // CHECK-LABEL: define void @_Z18pass_agg_float_cpp13agg_float_cpp(%struct.agg_float_cpp* noalias sret align 4 %{{.*}}, float %{{.*}}) -// SOFT-FLOAT: define void @_Z18pass_agg_float_cpp13agg_float_cpp(%struct.agg_float_cpp* noalias sret align 4 %{{.*}}, i32 %{{.*}}) +// SOFT-FLOAT-LABEL: define void @_Z18pass_agg_float_cpp13agg_float_cpp(%struct.agg_float_cpp* noalias sret align 4 %{{.*}}, i32 %{{.*}}) + + +// A field member of empty class type in C++ makes the record nonhomogeneous, +// unless it is marked as [[no_unique_address]]. This does not apply to arrays. +struct empty { }; +struct agg_nofloat_empty { float a; empty dummy; }; +struct agg_nofloat_empty pass_agg_nofloat_empty(struct agg_nofloat_empty arg) { return arg; } +// CHECK-LABEL: define void @_Z22pass_agg_nofloat_empty17agg_nofloat_empty(%struct.agg_nofloat_empty* noalias sret align 4 %{{.*}}, i64 %{{.*}}) +// SOFT-FLOAT-LABEL: define void @_Z22pass_agg_nofloat_empty17agg_nofloat_empty(%struct.agg_nofloat_empty* noalias sret align 4 %{{.*}}, i64 %{{.*}}) +struct agg_float_empty { float a; [[no_unique_address]] empty dummy; }; +struct agg_float_empty pass_agg_float_empty(struct agg_float_empty arg) { return arg; } +// CHECK-LABEL: define void @_Z20pass_agg_float_empty15agg_float_empty(%struct.agg_float_empty* noalias sret align 4 %{{.*}}, float %{{.*}}) +// SOFT-FLOAT-LABEL: define void @_Z20pass_agg_float_empty15agg_float_empty(%struct.agg_float_empty* noalias sret align 4 %{{.*}}, i32 %{{.*}}) +struct agg_nofloat_emptyarray { float a; [[no_unique_address]] empty dummy[3]; }; +struct agg_nofloat_emptyarray pass_agg_nofloat_emptyarray(struct agg_nofloat_emptyarray arg) { return arg; } +// CHECK-LABEL: define void @_Z27pass_agg_nofloat_emptyarray22agg_nofloat_emptyarray(%struct.agg_nofloat_emptyarray* noalias sret align 4 %{{.*}}, i64 %{{.*}}) +// SOFT-FLOAT-LABEL: define void @_Z27pass_agg_nofloat_emptyarray22agg_nofloat_emptyarray(%struct.agg_nofloat_emptyarray* noalias sret align 4 %{{.*}}, i64 %{{.*}}) + +// And likewise for members of base classes. +struct noemptybase { empty dummy; }; +struct agg_nofloat_emptybase : noemptybase { float a; }; +struct agg_nofloat_emptybase pass_agg_nofloat_emptybase(struct agg_nofloat_emptybase arg) { return arg; } +// CHECK-LABEL: define void @_Z26pass_agg_nofloat_emptybase21agg_nofloat_emptybase(%struct.agg_nofloat_emptybase* noalias sret align 4 %{{.*}}, i64 %{{.*}}) +// SOFT-FLOAT-LABEL: define void @_Z26pass_agg_nofloat_emptybase21agg_nofloat_emptybase(%struct.agg_nofloat_emptybase* noalias sret align 4 %{{.*}}, i64 %{{.*}}) +struct emptybase { [[no_unique_address]] empty dummy; }; +struct agg_float_emptybase : emptybase { float a; }; +struct agg_float_emptybase pass_agg_float_emptybase(struct agg_float_emptybase arg) { return arg; } +// CHECK-LABEL: define void @_Z24pass_agg_float_emptybase19agg_float_emptybase(%struct.agg_float_emptybase* noalias sret align 4 %{{.*}}, float %{{.*}}) +// SOFT-FLOAT-LABEL: define void @_Z24pass_agg_float_emptybase19agg_float_emptybase(%struct.agg_float_emptybase* noalias sret align 4 %{{.*}}, i32 %{{.*}}) +struct noemptybasearray { [[no_unique_address]] empty dummy[3]; }; +struct agg_nofloat_emptybasearray : noemptybasearray { float a; }; +struct agg_nofloat_emptybasearray pass_agg_nofloat_emptybasearray(struct agg_nofloat_emptybasearray arg) { return arg; } +// CHECK-LABEL: define void @_Z31pass_agg_nofloat_emptybasearray26agg_nofloat_emptybasearray(%struct.agg_nofloat_emptybasearray* noalias sret align 4 %{{.*}}, i64 %{{.*}}) +// SOFT-FLOAT-LABEL: define void @_Z31pass_agg_nofloat_emptybasearray26agg_nofloat_emptybasearray(%struct.agg_nofloat_emptybasearray* noalias sret align 4 %{{.*}}, i64 %{{.*}}) + diff --git a/clang/test/CodeGen/target-avx-abi-diag.c b/clang/test/CodeGen/target-avx-abi-diag.c new file mode 100644 index 0000000000000..f3d4462a552d2 --- /dev/null +++ b/clang/test/CodeGen/target-avx-abi-diag.c @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -verify=no256,no512 -o - -S +// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -target-feature +avx -verify=no512 -o - -S +// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -target-feature +avx512f -verify=both -o - -S +// REQUIRES: x86-registered-target + +// both-no-diagnostics + +typedef short avx512fType __attribute__((vector_size(64))); +typedef short avx256Type __attribute__((vector_size(32))); + +__attribute__((target("avx"))) void takesAvx256(avx256Type t); +__attribute__((target("avx512f"))) void takesAvx512(avx512fType t); +void takesAvx256_no_target(avx256Type t); +void takesAvx512_no_target(avx512fType t); + +void variadic(int i, ...); +__attribute__((target("avx512f"))) void variadic_err(int i, ...); + +// If neither side has an attribute, warn. +void call_warn(void) { + avx256Type t1; + takesAvx256_no_target(t1); // no256-warning {{AVX vector argument of type 'avx256Type' (vector of 16 'short' values) without 'avx' enabled changes the ABI}} + + avx512fType t2; + takesAvx512_no_target(t2); // no512-warning {{AVX vector argument of type 'avx512fType' (vector of 32 'short' values) without 'avx512f' enabled changes the ABI}} + + variadic(1, t1); // no256-warning {{AVX vector argument of type 'avx256Type' (vector of 16 'short' values) without 'avx' enabled changes the ABI}} + variadic(3, t2); // no512-warning {{AVX vector argument of type 'avx512fType' (vector of 32 'short' values) without 'avx512f' enabled changes the ABI}} +} + +// If only 1 side has an attribute, error. +void call_errors(void) { + avx256Type t1; + takesAvx256(t1); // no256-error {{AVX vector argument of type 'avx256Type' (vector of 16 'short' values) without 'avx' enabled changes the ABI}} + avx512fType t2; + takesAvx512(t2); // no512-error {{AVX vector argument of type 'avx512fType' (vector of 32 'short' values) without 'avx512f' enabled changes the ABI}} + + variadic_err(1, t1); // no256-error {{AVX vector argument of type 'avx256Type' (vector of 16 'short' values) without 'avx' enabled changes the ABI}} + variadic_err(3, t2); // no512-error {{AVX vector argument of type 'avx512fType' (vector of 32 'short' values) without 'avx512f' enabled changes the ABI}} +} + +// These two don't diagnose anything, since these are valid calls. +__attribute__((target("avx"))) void call_avx256_ok(void) { + avx256Type t; + takesAvx256(t); +} + +__attribute__((target("avx512f"))) void call_avx512_ok(void) { + avx512fType t; + takesAvx512(t); +} diff --git a/clang/test/CodeGen/target-builtin-error-3.c b/clang/test/CodeGen/target-builtin-error-3.c index 5beb474befe07..3de76e253d9b1 100644 --- a/clang/test/CodeGen/target-builtin-error-3.c +++ b/clang/test/CodeGen/target-builtin-error-3.c @@ -18,11 +18,12 @@ static inline half8 __attribute__((__overloadable__)) convert_half( float8 a ) { return __extension__ ({ __m256 __a = (a); (__m128i)__builtin_ia32_vcvtps2ph256((__v8sf)__a, (0x00)); }); // expected-error {{'__builtin_ia32_vcvtps2ph256' needs target feature f16c}} } static inline half16 __attribute__((__overloadable__)) convert_half( float16 a ) { - half16 r; - r.lo = convert_half( a.lo); + half16 r; + r.lo = convert_half(a.lo); return r; } void avx_test( uint16_t *destData, float16 argbF) { - ((half16U*)destData)[0] = convert_half(argbF); + // expected-warning@+1{{AVX vector argument of type 'float16' (vector of 16 'float' values) without 'avx512f' enabled changes the ABI}} + ((half16U *)destData)[0] = convert_half(argbF); } diff --git a/clang/test/CodeGen/target-builtin-noerror.c b/clang/test/CodeGen/target-builtin-noerror.c index b2d18fa0b2c00..339e5b15c88d7 100644 --- a/clang/test/CodeGen/target-builtin-noerror.c +++ b/clang/test/CodeGen/target-builtin-noerror.c @@ -6,15 +6,15 @@ // No warnings. extern __m256i a; -int __attribute__((target("avx"))) bar(__m256i a) { +int __attribute__((target("avx"))) bar() { return _mm256_extract_epi32(a, 3); } int baz() { - return bar(a); + return bar(); } -int __attribute__((target("avx"))) qq_avx(__m256i a) { +int __attribute__((target("avx"))) qq_avx() { return _mm256_extract_epi32(a, 3); } @@ -25,7 +25,7 @@ int qq_noavx() { extern __m256i a; int qq() { if (__builtin_cpu_supports("avx")) - return qq_avx(a); + return qq_avx(); else return qq_noavx(); } diff --git a/clang/test/CodeGen/target-data.c b/clang/test/CodeGen/target-data.c index e619843f4bdbd..8c740119cd1ba 100644 --- a/clang/test/CodeGen/target-data.c +++ b/clang/test/CodeGen/target-data.c @@ -250,3 +250,7 @@ // RUN: %clang_cc1 -triple bpfeb -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=BPFEB // BPFEB: target datalayout = "E-m:e-p:64:64-i64:64-i128:128-n32:64-S128" + +// RUN: %clang_cc1 -triple ve -o - -emit-llvm %s | \ +// RUN: FileCheck %s -check-prefix=VE +// VE: target datalayout = "e-m:e-i64:64-n32:64-S128" diff --git a/clang/test/CodeGen/thinlto-distributed-cfi-devirt.ll b/clang/test/CodeGen/thinlto-distributed-cfi-devirt.ll index b46845afba26b..5c753ba6f93c3 100644 --- a/clang/test/CodeGen/thinlto-distributed-cfi-devirt.ll +++ b/clang/test/CodeGen/thinlto-distributed-cfi-devirt.ll @@ -93,7 +93,7 @@ cont2: ; CHECK-IR: br i1 {{.*}}, label %trap ; We still have to call it as virtual. - ; CHECK-IR: %call3 = tail call i32 %8 + ; CHECK-IR: %call3 = tail call i32 %7 %call3 = tail call i32 %8(%struct.A* nonnull %obj, i32 %call) ret i32 %call3 } diff --git a/clang/test/CodeGen/thinlto-inline-asm.c b/clang/test/CodeGen/thinlto-inline-asm.c new file mode 100644 index 0000000000000..a41cba6fadc1c --- /dev/null +++ b/clang/test/CodeGen/thinlto-inline-asm.c @@ -0,0 +1,21 @@ +// REQUIRES: x86-registered-target + +// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc19.11.0 -emit-llvm-bc \ +// RUN: -flto=thin -mllvm -x86-asm-syntax=intel -v \ +// RUN: -o %t.obj %s 2>&1 | FileCheck --check-prefix=CLANG %s +// +// RUN: llvm-lto2 dump-symtab %t.obj | FileCheck --check-prefix=SYMTAB %s + +// Module-level inline asm is parsed with At&t syntax. Test that the +// -x86-asm-syntax flag does not affect this. + +// CLANG-NOT: unknown token in expression +// SYMTAB: D------X foo +// SYMTAB: D------X bar + +void foo() {} + +asm(".globl bar \n" + "bar: \n" + " xor %eax, %eax\n" + " ret \n"); diff --git a/clang/test/CodeGen/ve-abi.c b/clang/test/CodeGen/ve-abi.c new file mode 100644 index 0000000000000..aa35095d5dea0 --- /dev/null +++ b/clang/test/CodeGen/ve-abi.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -triple ve-linux-gnu -emit-llvm %s -o - | FileCheck %s + +// CHECK-LABEL: define { float, float } @p(float %a.coerce0, float %a.coerce1, float %b.coerce0, float %b.coerce1) #0 { +float __complex__ p(float __complex__ a, float __complex__ b) { +} + +// CHECK-LABEL: define { double, double } @q(double %a.coerce0, double %a.coerce1, double %b.coerce0, double %b.coerce1) #0 { +double __complex__ q(double __complex__ a, double __complex__ b) { +} + +void func() { + // CHECK-LABEL: %call = call i32 (i32, i32, i32, i32, i32, i32, i32, ...) bitcast (i32 (...)* @hoge to i32 (i32, i32, i32, i32, i32, i32, i32, ...)*)(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7) + hoge(1, 2, 3, 4, 5, 6, 7); +} diff --git a/clang/test/CodeGen/vla.c b/clang/test/CodeGen/vla.c index 37243cd172905..16b82f4acc7d3 100644 --- a/clang/test/CodeGen/vla.c +++ b/clang/test/CodeGen/vla.c @@ -206,3 +206,7 @@ void test9(int n, int a[static n]) { } // NULL-INVALID: define void @test9(i32 %n, i32* nonnull %a) // NULL-VALID: define void @test9(i32 %n, i32* %a) +// Make sure a zero-sized static array extent is still required to be nonnull. +void test10(int a[static 0]) {} +// NULL-INVALID: define void @test10(i32* nonnull %a) +// NULL-VALID: define void @test10(i32* %a) diff --git a/clang/test/CodeGen/windows-seh-filter-inFinally.c b/clang/test/CodeGen/windows-seh-filter-inFinally.c new file mode 100644 index 0000000000000..f9dfca14f0209 --- /dev/null +++ b/clang/test/CodeGen/windows-seh-filter-inFinally.c @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -triple x86_64-windows -fms-extensions -Wno-implicit-function-declaration -S -emit-llvm %s -o - | FileCheck %s + +// CHECK: %[[dst:[0-9-]+]] = call i8* @llvm.eh.recoverfp(i8* bitcast (void (i8, i8*)* @"?fin$0@0@main@@" to i8*), i8* %frame_pointer) +// CHECK-NEXT: %[[dst1:[0-9-]+]] = call i8* @llvm.localrecover(i8* bitcast (void (i8, i8*)* @"?fin$0@0@main@@" to i8*), i8* %[[dst]], i32 0) +// CHECK-NEXT: %[[dst2:[0-9-]+]] = bitcast i8* %[[dst1]] to i8** +// CHECK-NEXT: = load i8*, i8** %[[dst2]], align 8 + +int +main(int argc, char *argv[]) +{ + int Counter = 0; + // + // Try/except within the finally clause of a try/finally. + // + __try { + Counter -= 1; + } + __finally { + __try { + Counter += 2; + // RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); + } __except(Counter) { + __try { + Counter += 3; + } + __finally { + if (abnormal_termination() == 1) { + Counter += 5; + } + } + } + } + // expect Counter == 9 + return 1; +} + diff --git a/clang/test/CodeGen/xcore-unused-inline.c b/clang/test/CodeGen/xcore-unused-inline.c new file mode 100644 index 0000000000000..8b5bdbf2ed6de --- /dev/null +++ b/clang/test/CodeGen/xcore-unused-inline.c @@ -0,0 +1,9 @@ +// REQUIRES: xcore-registered-target +// RUN: %clang_cc1 -triple xcore-unknown-unknown -emit-llvm -o - %s + +// D77068 fixes a segmentation fault and assertion failure "Unexpected null +// Value" in the case of an unused inline function, when targeting xcore. This +// test verifies that clang does not crash and does not produce code for such a +// function. + +inline void dead_function(void) {} diff --git a/clang/test/CodeGenCUDA/amdgpu-kernel-arg-pointer-type.cu b/clang/test/CodeGenCUDA/amdgpu-kernel-arg-pointer-type.cu index 73ab9edf318e5..2660a5f14f90d 100644 --- a/clang/test/CodeGenCUDA/amdgpu-kernel-arg-pointer-type.cu +++ b/clang/test/CodeGenCUDA/amdgpu-kernel-arg-pointer-type.cu @@ -1,37 +1,55 @@ -// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -fcuda-is-device -emit-llvm -x hip %s -o - | FileCheck %s +// REQUIRES: x86-registered-target +// REQUIRES: amdgpu-registered-target + +// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -fcuda-is-device -emit-llvm -x hip %s -o - | FileCheck --check-prefixes=COMMON,CHECK %s +// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -fcuda-is-device -emit-llvm -x hip %s -disable-O0-optnone -o - | opt -S -O2 | FileCheck %s --check-prefixes=COMMON,OPT // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -x hip %s -o - | FileCheck -check-prefix=HOST %s #include "Inputs/cuda.h" // Coerced struct from `struct S` without all generic pointers lowered into // global ones. -// CHECK: %struct.S.coerce = type { i32 addrspace(1)*, float addrspace(1)* } -// CHECK: %struct.T.coerce = type { [2 x float addrspace(1)*] } +// COMMON: %struct.S.coerce = type { i32 addrspace(1)*, float addrspace(1)* } +// COMMON: %struct.T.coerce = type { [2 x float addrspace(1)*] } // On the host-side compilation, generic pointer won't be coerced. // HOST-NOT: %struct.S.coerce // HOST-NOT: %struct.T.coerce -// CHECK: define amdgpu_kernel void @_Z7kernel1Pi(i32 addrspace(1)* %x.coerce) // HOST: define void @_Z22__device_stub__kernel1Pi(i32* %x) +// COMMON-LABEL: define amdgpu_kernel void @_Z7kernel1Pi(i32 addrspace(1)*{{.*}} %x.coerce) +// CHECK: = addrspacecast [[TYPE:.*]] addrspace(1)* %{{.*}} to [[TYPE]]* +// CHECK-NOT: = addrspacecast [[TYPE:.*]] addrspace(1)* %{{.*}} to [[TYPE]]* +// OPT: [[VAL:%.*]] = load i32, i32 addrspace(1)* %x.coerce, align 4 +// OPT: [[INC:%.*]] = add nsw i32 [[VAL]], 1 +// OPT: store i32 [[INC]], i32 addrspace(1)* %x.coerce, align 4 +// OPT: ret void __global__ void kernel1(int *x) { x[0]++; } -// CHECK: define amdgpu_kernel void @_Z7kernel2Ri(i32 addrspace(1)* nonnull align 4 dereferenceable(4) %x.coerce) // HOST: define void @_Z22__device_stub__kernel2Ri(i32* nonnull align 4 dereferenceable(4) %x) +// COMMON-LABEL: define amdgpu_kernel void @_Z7kernel2Ri(i32 addrspace(1)*{{.*}} nonnull align 4 dereferenceable(4) %x.coerce) +// CHECK: = addrspacecast [[TYPE:.*]] addrspace(1)* %{{.*}} to [[TYPE]]* +// CHECK-NOT: = addrspacecast [[TYPE:.*]] addrspace(1)* %{{.*}} to [[TYPE]]* +// OPT: [[VAL:%.*]] = load i32, i32 addrspace(1)* %x.coerce, align 4 +// OPT: [[INC:%.*]] = add nsw i32 [[VAL]], 1 +// OPT: store i32 [[INC]], i32 addrspace(1)* %x.coerce, align 4 +// OPT: ret void __global__ void kernel2(int &x) { x++; } -// CHECK: define amdgpu_kernel void @_Z7kernel3PU3AS2iPU3AS1i(i32 addrspace(2)* %x, i32 addrspace(1)* %y) // HOST: define void @_Z22__device_stub__kernel3PU3AS2iPU3AS1i(i32 addrspace(2)* %x, i32 addrspace(1)* %y) +// CHECK-LABEL: define amdgpu_kernel void @_Z7kernel3PU3AS2iPU3AS1i(i32 addrspace(2)*{{.*}} %x, i32 addrspace(1)*{{.*}} %y) +// CHECK-NOT: = addrspacecast [[TYPE:.*]] addrspace(1)* %{{.*}} to [[TYPE]]* __global__ void kernel3(__attribute__((address_space(2))) int *x, __attribute__((address_space(1))) int *y) { y[0] = x[0]; } -// CHECK: define void @_Z4funcPi(i32* %x) +// COMMON-LABEL: define void @_Z4funcPi(i32*{{.*}} %x) +// CHECK-NOT: = addrspacecast [[TYPE:.*]] addrspace(1)* %{{.*}} to [[TYPE]]* __device__ void func(int *x) { x[0]++; } @@ -42,16 +60,25 @@ struct S { }; // `by-val` struct will be coerced into a similar struct with all generic // pointers lowerd into global ones. -// CHECK: define amdgpu_kernel void @_Z7kernel41S(%struct.S.coerce %s.coerce) // HOST: define void @_Z22__device_stub__kernel41S(i32* %s.coerce0, float* %s.coerce1) +// COMMON-LABEL: define amdgpu_kernel void @_Z7kernel41S(%struct.S.coerce %s.coerce) +// OPT: [[P0:%.*]] = extractvalue %struct.S.coerce %s.coerce, 0 +// OPT: [[P1:%.*]] = extractvalue %struct.S.coerce %s.coerce, 1 +// OPT: [[V0:%.*]] = load i32, i32 addrspace(1)* [[P0]], align 4 +// OPT: [[INC:%.*]] = add nsw i32 [[V0]], 1 +// OPT: store i32 [[INC]], i32 addrspace(1)* [[P0]], align 4 +// OPT: [[V1:%.*]] = load float, float addrspace(1)* [[P1]], align 4 +// OPT: [[ADD:%.*]] = fadd contract float [[V1]], 1.000000e+00 +// OPT: store float [[ADD]], float addrspace(1)* [[P1]], align 4 +// OPT: ret void __global__ void kernel4(struct S s) { s.x[0]++; s.y[0] += 1.f; } // If a pointer to struct is passed, only the pointer itself is coerced into the global one. -// CHECK: define amdgpu_kernel void @_Z7kernel5P1S(%struct.S addrspace(1)* %s.coerce) // HOST: define void @_Z22__device_stub__kernel5P1S(%struct.S* %s) +// COMMON-LABEL: define amdgpu_kernel void @_Z7kernel5P1S(%struct.S addrspace(1)*{{.*}} %s.coerce) __global__ void kernel5(struct S *s) { s->x[0]++; s->y[0] += 1.f; @@ -61,16 +88,26 @@ struct T { float *x[2]; }; // `by-val` array is also coerced. -// CHECK: define amdgpu_kernel void @_Z7kernel61T(%struct.T.coerce %t.coerce) // HOST: define void @_Z22__device_stub__kernel61T(float* %t.coerce0, float* %t.coerce1) +// COMMON-LABEL: define amdgpu_kernel void @_Z7kernel61T(%struct.T.coerce %t.coerce) +// OPT: [[ARR:%.*]] = extractvalue %struct.T.coerce %t.coerce, 0 +// OPT: [[P0:%.*]] = extractvalue [2 x float addrspace(1)*] [[ARR]], 0 +// OPT: [[P1:%.*]] = extractvalue [2 x float addrspace(1)*] [[ARR]], 1 +// OPT: [[V0:%.*]] = load float, float addrspace(1)* [[P0]], align 4 +// OPT: [[ADD0:%.*]] = fadd contract float [[V0]], 1.000000e+00 +// OPT: store float [[ADD0]], float addrspace(1)* [[P0]], align 4 +// OPT: [[V1:%.*]] = load float, float addrspace(1)* [[P1]], align 4 +// OPT: [[ADD1:%.*]] = fadd contract float [[V1]], 2.000000e+00 +// OPT: store float [[ADD1]], float addrspace(1)* [[P1]], align 4 +// OPT: ret void __global__ void kernel6(struct T t) { t.x[0][0] += 1.f; t.x[1][0] += 2.f; } // Check that coerced pointers retain the noalias attribute when qualified with __restrict. -// CHECK: define amdgpu_kernel void @_Z7kernel7Pi(i32 addrspace(1)* noalias %x.coerce) // HOST: define void @_Z22__device_stub__kernel7Pi(i32* noalias %x) +// COMMON-LABEL: define amdgpu_kernel void @_Z7kernel7Pi(i32 addrspace(1)* noalias{{.*}} %x.coerce) __global__ void kernel7(int *__restrict x) { x[0]++; } diff --git a/clang/test/CodeGenCUDA/lambda.cu b/clang/test/CodeGenCUDA/lambda.cu new file mode 100644 index 0000000000000..8a639c90f2668 --- /dev/null +++ b/clang/test/CodeGenCUDA/lambda.cu @@ -0,0 +1,85 @@ +// RUN: %clang_cc1 -x hip -emit-llvm -std=c++11 %s -o - \ +// RUN: -triple x86_64-linux-gnu \ +// RUN: | FileCheck -check-prefix=HOST %s +// RUN: %clang_cc1 -x hip -emit-llvm -std=c++11 %s -o - \ +// RUN: -triple amdgcn-amd-amdhsa -fcuda-is-device \ +// RUN: | FileCheck -check-prefix=DEV %s + +#include "Inputs/cuda.h" + +// Device side kernel name. +// HOST: @[[KERN_CAPTURE:[0-9]+]] = {{.*}} c"_Z1gIZ12test_capturevEUlvE_EvT_\00" +// HOST: @[[KERN_RESOLVE:[0-9]+]] = {{.*}} c"_Z1gIZ12test_resolvevEUlvE_EvT_\00" + +// Check functions emitted for test_capture in host compilation. +// Check lambda is not emitted in host compilation. +// HOST-LABEL: define void @_Z12test_capturev +// HOST: call void @_Z19test_capture_helperIZ12test_capturevEUlvE_EvT_ +// HOST-LABEL: define internal void @_Z19test_capture_helperIZ12test_capturevEUlvE_EvT_ +// HOST: call void @_Z16__device_stub__gIZ12test_capturevEUlvE_EvT_ +// HOST-NOT: define{{.*}}@_ZZ4mainENKUlvE_clEv + +// Check functions emitted for test_resolve in host compilation. +// Check host version of template function 'overloaded' is emitted and called +// by the lambda function. +// HOST-LABEL: define void @_Z12test_resolvev +// HOST: call void @_Z19test_resolve_helperIZ12test_resolvevEUlvE_EvT_() +// HOST-LABEL: define internal void @_Z19test_resolve_helperIZ12test_resolvevEUlvE_EvT_ +// HOST: call void @_Z16__device_stub__gIZ12test_resolvevEUlvE_EvT_ +// HOST: call void @_ZZ12test_resolvevENKUlvE_clEv +// HOST-LABEL: define internal void @_ZZ12test_resolvevENKUlvE_clEv +// HOST: call i32 @_Z10overloadedIiET_v +// HOST-LABEL: define linkonce_odr i32 @_Z10overloadedIiET_v +// HOST: ret i32 2 + +// Check kernel is registered with correct device side kernel name. +// HOST: @__hipRegisterFunction({{.*}}@[[KERN_CAPTURE]] +// HOST: @__hipRegisterFunction({{.*}}@[[KERN_RESOLVE]] + +// DEV: @a = addrspace(1) externally_initialized global i32 0 + +// Check functions emitted for test_capture in device compilation. +// Check lambda is emitted in device compilation and accessing device variable. +// DEV-LABEL: define amdgpu_kernel void @_Z1gIZ12test_capturevEUlvE_EvT_ +// DEV: call void @_ZZ12test_capturevENKUlvE_clEv +// DEV-LABEL: define internal void @_ZZ12test_capturevENKUlvE_clEv +// DEV: store i32 1, i32* addrspacecast (i32 addrspace(1)* @a to i32*) + +// Check functions emitted for test_resolve in device compilation. +// Check device version of template function 'overloaded' is emitted and called +// by the lambda function. +// DEV-LABEL: define amdgpu_kernel void @_Z1gIZ12test_resolvevEUlvE_EvT_ +// DEV: call void @_ZZ12test_resolvevENKUlvE_clEv +// DEV-LABEL: define internal void @_ZZ12test_resolvevENKUlvE_clEv +// DEV: call i32 @_Z10overloadedIiET_v +// DEV-LABEL: define linkonce_odr i32 @_Z10overloadedIiET_v +// DEV: ret i32 1 + +__device__ int a; + +template +__device__ T overloaded() { return 1; } + +template +__host__ T overloaded() { return 2; } + +template +__global__ void g(F f) { f(); } + +template +void test_capture_helper(F f) { g<<<1,1>>>(f); } + +template +void test_resolve_helper(F f) { g<<<1,1>>>(f); f(); } + +// Test capture of device variable in lambda function. +void test_capture(void) { + test_capture_helper([](){ a = 1;}); +} + +// Test resolving host/device function in lambda function. +// Callee should resolve to correct host/device function based on where +// the lambda function is called, not where it is defined. +void test_resolve(void) { + test_resolve_helper([](){ overloaded();}); +} diff --git a/clang/test/CodeGenCXX/PR20038.cpp b/clang/test/CodeGenCXX/PR20038.cpp index 195e4e521240b..b6d12f6603127 100644 --- a/clang/test/CodeGenCXX/PR20038.cpp +++ b/clang/test/CodeGenCXX/PR20038.cpp @@ -7,8 +7,8 @@ extern bool b; // CHECK: call {{.*}}, !dbg [[DTOR_CALL1_LOC:![0-9]*]] // CHECK: call {{.*}}, !dbg [[DTOR_CALL2_LOC:![0-9]*]] // CHECK: [[FUN1:.*]] = distinct !DISubprogram(name: "fun1",{{.*}} DISPFlagDefinition -// CHECK: [[DTOR_CALL1_LOC]] = !DILocation(line: [[@LINE+1]], scope: [[FUN1]]) +// CHECK: [[DTOR_CALL1_LOC]] = !DILocation(line: [[@LINE+1]], column: 15, scope: [[FUN1]]) void fun1() { b && (C(), 1); } // CHECK: [[FUN2:.*]] = distinct !DISubprogram(name: "fun2",{{.*}} DISPFlagDefinition -// CHECK: [[DTOR_CALL2_LOC]] = !DILocation(line: [[@LINE+1]], scope: [[FUN2]]) +// CHECK: [[DTOR_CALL2_LOC]] = !DILocation(line: [[@LINE+1]], column: 15, scope: [[FUN2]]) bool fun2() { return (C(), b) && 0; } diff --git a/clang/test/CodeGenCXX/RelativeVTablesABI/dynamic-cast.cpp b/clang/test/CodeGenCXX/RelativeVTablesABI/dynamic-cast.cpp index 56b56a1b93984..62d674669661d 100644 --- a/clang/test/CodeGenCXX/RelativeVTablesABI/dynamic-cast.cpp +++ b/clang/test/CodeGenCXX/RelativeVTablesABI/dynamic-cast.cpp @@ -35,13 +35,13 @@ // CHECK-NEXT: [[isnull:%[0-9]+]] = icmp eq %class.B* %b, null // CHECK-NEXT: br i1 [[isnull]], label %[[dynamic_cast_end:[a-z0-9._]+]], label %[[dynamic_cast_notnull:[a-z0-9._]+]] // CHECK: [[dynamic_cast_notnull]]: -// CHECK-NEXT: [[b2:%[0-9]+]] = bitcast %class.B* %b to i32** -// CHECK-NEXT: [[vtable:%[a-z0-9]+]] = load i32*, i32** [[b2]], align 8 -// CHECK-NEXT: [[offset_ptr:%.+]] = getelementptr inbounds i32, i32* [[vtable]], i64 -2 -// CHECK-NEXT: [[offset_to_top:%.+]] = load i32, i32* [[offset_ptr]], align 4 -// CHECK-NEXT: [[b:%[0-9]+]] = bitcast %class.B* %b to i8* -// CHECK-NEXT: [[offset_to_top2:%.+]] = sext i32 [[offset_to_top]] to i64 -// CHECK-NEXT: [[casted:%.+]] = getelementptr inbounds i8, i8* [[b]], i64 [[offset_to_top2]] +// CHECK-DAG: [[b2:%[0-9]+]] = bitcast %class.B* %b to i32** +// CHECK-DAG: [[vtable:%[a-z0-9]+]] = load i32*, i32** [[b2]], align 8 +// CHECK-DAG: [[offset_ptr:%.+]] = getelementptr inbounds i32, i32* [[vtable]], i64 -2 +// CHECK-DAG: [[offset_to_top:%.+]] = load i32, i32* [[offset_ptr]], align 4 +// CHECK-DAG: [[b:%[0-9]+]] = bitcast %class.B* %b to i8* +// CHECK-DAG: [[offset_to_top2:%.+]] = sext i32 [[offset_to_top]] to i64 +// CHECK-DAG: [[casted:%.+]] = getelementptr inbounds i8, i8* [[b]], i64 [[offset_to_top2]] // CHECK-NEXT: br label %[[dynamic_cast_end]] // CHECK: [[dynamic_cast_end]]: // CHECK-NEXT: [[res:%[0-9]+]] = phi i8* [ [[casted]], %[[dynamic_cast_notnull]] ], [ null, %entry ] diff --git a/clang/test/CodeGenCXX/aarch64-mangle-sve-vectors.cpp b/clang/test/CodeGenCXX/aarch64-mangle-sve-vectors.cpp index 66e3c1306dd25..d75efbd25c484 100644 --- a/clang/test/CodeGenCXX/aarch64-mangle-sve-vectors.cpp +++ b/clang/test/CodeGenCXX/aarch64-mangle-sve-vectors.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -triple aarch64-none-linux-gnu %s -emit-llvm -o - \ // RUN: | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu %s -emit-llvm -o - \ -// RUN: -target-feature +sve | FileCheck %s +// RUN: -target-feature +sve,+bf16 | FileCheck %s template struct S {}; @@ -27,8 +27,10 @@ void f9(S<__SVFloat16_t>) {} void f10(S<__SVFloat32_t>) {} // CHECK: _Z3f111SIu13__SVFloat64_tE void f11(S<__SVFloat64_t>) {} -// CHECK: _Z3f121SIu10__SVBool_tE -void f12(S<__SVBool_t>) {} +// CHECK: _Z3f121SIu14__SVBFloat16_tE +void f12(S<__SVBFloat16_t>) {} +// CHECK: _Z3f131SIu10__SVBool_tE +void f13(S<__SVBool_t>) {} // The tuple types don't use the internal name for mangling. @@ -98,3 +100,9 @@ void f43(S<__clang_svfloat64x2_t>) {} void f44(S<__clang_svfloat64x3_t>) {} // CHECK: _Z3f451SI13svfloat64x4_tE void f45(S<__clang_svfloat64x4_t>) {} +// CHECK: _Z3f461SI14svbfloat16x2_tE +void f46(S<__clang_svbfloat16x2_t>) {} +// CHECK: _Z3f471SI14svbfloat16x3_tE +void f47(S<__clang_svbfloat16x3_t>) {} +// CHECK: _Z3f481SI14svbfloat16x4_tE +void f48(S<__clang_svbfloat16x4_t>) {} diff --git a/clang/test/CodeGenCXX/aarch64-sve-typeinfo.cpp b/clang/test/CodeGenCXX/aarch64-sve-typeinfo.cpp index 5627efaf6a6a4..6081ab69a2344 100644 --- a/clang/test/CodeGenCXX/aarch64-sve-typeinfo.cpp +++ b/clang/test/CodeGenCXX/aarch64-sve-typeinfo.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -triple aarch64-none-linux-gnu %s -emit-llvm -o - \ // RUN: | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu %s -emit-llvm -o - \ -// RUN: -target-feature +sve | FileCheck %s +// RUN: -target-feature +sve,+bf16 | FileCheck %s namespace std { class type_info; }; @@ -19,6 +19,8 @@ auto &f16 = typeid(__SVFloat16_t); auto &f32 = typeid(__SVFloat32_t); auto &f64 = typeid(__SVFloat64_t); +auto &bf16 = typeid(__SVBFloat16_t); + auto &b8 = typeid(__SVBool_t); // CHECK-DAG: @_ZTSu10__SVInt8_t = {{.*}} c"u10__SVInt8_t\00" @@ -53,6 +55,9 @@ auto &b8 = typeid(__SVBool_t); // CHECK-DAG: @_ZTSu13__SVFloat64_t = {{.*}} c"u13__SVFloat64_t\00" // CHECK-DAG: @_ZTIu13__SVFloat64_t = {{.*}} @_ZTVN10__cxxabiv123__fundamental_type_infoE, {{.*}} @_ZTSu13__SVFloat64_t +// +// CHECK-DAG: @_ZTSu14__SVBFloat16_t = {{.*}} c"u14__SVBFloat16_t\00" +// CHECK-DAG: @_ZTIu14__SVBFloat16_t = {{.*}} @_ZTVN10__cxxabiv123__fundamental_type_infoE, {{.*}} @_ZTSu14__SVBFloat16_t // CHECK-DAG: @_ZTSu10__SVBool_t = {{.*}} c"u10__SVBool_t\00" // CHECK-DAG: @_ZTIu10__SVBool_t = {{.*}} @_ZTVN10__cxxabiv123__fundamental_type_infoE, {{.*}} @_ZTSu10__SVBool_t diff --git a/clang/test/CodeGenCXX/alignment.cpp b/clang/test/CodeGenCXX/alignment.cpp index 37509fcb4dd55..c9378bf20a47c 100644 --- a/clang/test/CodeGenCXX/alignment.cpp +++ b/clang/test/CodeGenCXX/alignment.cpp @@ -308,4 +308,20 @@ namespace test1 { D d; AlignedArray result = d.bArray; } + + // CHECK-LABEL: @_ZN5test11hEPA_NS_1BE + void h(B (*b)[]) { + // CHECK: [[RESULT:%.*]] = alloca [[ARRAY]], align 64 + // CHECK: [[B_P:%.*]] = load [0 x [[B]]]*, [0 x [[B]]]** + // CHECK: [[ELEMENT_P:%.*]] = getelementptr inbounds [0 x [[B]]], [0 x [[B]]]* [[B_P]], i64 0 + // CHECK: [[ARRAY_P:%.*]] = getelementptr inbounds [[B]], [[B]]* [[ELEMENT_P]], i32 0, i32 2 + // CHECK: [[T0:%.*]] = bitcast [[ARRAY]]* [[RESULT]] to i8* + // CHECK: [[T1:%.*]] = bitcast [[ARRAY]]* [[ARRAY_P]] to i8* + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 64 [[T0]], i8* align 16 [[T1]], i64 16, i1 false) + AlignedArray result = (*b)->bArray; + } } + +// CHECK-LABEL: @_Z22incomplete_array_derefPA_i +// CHECK: load i32, i32* {{%.*}}, align 4 +int incomplete_array_deref(int (*p)[]) { return (*p)[2]; } diff --git a/clang/test/CodeGenCXX/builtin-amdgcn-atomic-inc-dec.cpp b/clang/test/CodeGenCXX/builtin-amdgcn-atomic-inc-dec.cpp index 535c3d754954b..77ea3d485c8aa 100644 --- a/clang/test/CodeGenCXX/builtin-amdgcn-atomic-inc-dec.cpp +++ b/clang/test/CodeGenCXX/builtin-amdgcn-atomic-inc-dec.cpp @@ -2,9 +2,9 @@ // RUN: %clang_cc1 %s -x hip -fcuda-is-device -emit-llvm -O0 -o - \ // RUN: -triple=amdgcn-amd-amdhsa | opt -S | FileCheck %s -__attribute__((device)) void test_non_volatile_parameter32(int *ptr) { +__attribute__((device)) void test_non_volatile_parameter32(__UINT32_TYPE__ *ptr) { // CHECK-LABEL: test_non_volatile_parameter32 - int res; + __UINT32_TYPE__ res; // CHECK: %ptr.addr = alloca i32*, align 8, addrspace(5) // CHECK-NEXT: %ptr.addr.ascast = addrspacecast i32* addrspace(5)* %ptr.addr to i32** // CHECK-NEXT: %res = alloca i32, align 4, addrspace(5) @@ -25,9 +25,9 @@ __attribute__((device)) void test_non_volatile_parameter32(int *ptr) { res = __builtin_amdgcn_atomic_dec32(ptr, *ptr, __ATOMIC_SEQ_CST, "workgroup"); } -__attribute__((device)) void test_non_volatile_parameter64(__INT64_TYPE__ *ptr) { +__attribute__((device)) void test_non_volatile_parameter64(__UINT64_TYPE__ *ptr) { // CHECK-LABEL: test_non_volatile_parameter64 - __INT64_TYPE__ res; + __UINT64_TYPE__ res; // CHECK: %ptr.addr = alloca i64*, align 8, addrspace(5) // CHECK-NEXT: %ptr.addr.ascast = addrspacecast i64* addrspace(5)* %ptr.addr to i64** // CHECK-NEXT: %res = alloca i64, align 8, addrspace(5) @@ -48,9 +48,9 @@ __attribute__((device)) void test_non_volatile_parameter64(__INT64_TYPE__ *ptr) res = __builtin_amdgcn_atomic_dec64(ptr, *ptr, __ATOMIC_SEQ_CST, "workgroup"); } -__attribute__((device)) void test_volatile_parameter32(volatile int *ptr) { +__attribute__((device)) void test_volatile_parameter32(volatile __UINT32_TYPE__ *ptr) { // CHECK-LABEL: test_volatile_parameter32 - int res; + __UINT32_TYPE__ res; // CHECK: %ptr.addr = alloca i32*, align 8, addrspace(5) // CHECK-NEXT: %ptr.addr.ascast = addrspacecast i32* addrspace(5)* %ptr.addr to i32** // CHECK-NEXT: %res = alloca i32, align 4, addrspace(5) @@ -71,9 +71,9 @@ __attribute__((device)) void test_volatile_parameter32(volatile int *ptr) { res = __builtin_amdgcn_atomic_dec32(ptr, *ptr, __ATOMIC_SEQ_CST, "workgroup"); } -__attribute__((device)) void test_volatile_parameter64(volatile __INT64_TYPE__ *ptr) { +__attribute__((device)) void test_volatile_parameter64(volatile __UINT64_TYPE__ *ptr) { // CHECK-LABEL: test_volatile_parameter64 - __INT64_TYPE__ res; + __UINT64_TYPE__ res; // CHECK: %ptr.addr = alloca i64*, align 8, addrspace(5) // CHECK-NEXT: %ptr.addr.ascast = addrspacecast i64* addrspace(5)* %ptr.addr to i64** // CHECK-NEXT: %res = alloca i64, align 8, addrspace(5) @@ -96,7 +96,7 @@ __attribute__((device)) void test_volatile_parameter64(volatile __INT64_TYPE__ * __attribute__((device)) void test_shared32() { // CHECK-LABEL: test_shared32 - __attribute__((shared)) int val; + __attribute__((shared)) __UINT32_TYPE__ val; // CHECK: %0 = load i32, i32* addrspacecast (i32 addrspace(3)* @_ZZ13test_shared32vE3val to i32*), align 4 // CHECK-NEXT: %1 = call i32 @llvm.amdgcn.atomic.inc.i32.p0i32(i32* addrspacecast (i32 addrspace(3)* @_ZZ13test_shared32vE3val to i32*), i32 %0, i32 7, i32 2, i1 false) @@ -111,7 +111,7 @@ __attribute__((device)) void test_shared32() { __attribute__((device)) void test_shared64() { // CHECK-LABEL: test_shared64 - __attribute__((shared)) __INT64_TYPE__ val; + __attribute__((shared)) __UINT64_TYPE__ val; // CHECK: %0 = load i64, i64* addrspacecast (i64 addrspace(3)* @_ZZ13test_shared64vE3val to i64*), align 8 // CHECK-NEXT: %1 = call i64 @llvm.amdgcn.atomic.inc.i64.p0i64(i64* addrspacecast (i64 addrspace(3)* @_ZZ13test_shared64vE3val to i64*), i64 %0, i32 7, i32 2, i1 false) @@ -124,7 +124,7 @@ __attribute__((device)) void test_shared64() { val = __builtin_amdgcn_atomic_dec64(&val, val, __ATOMIC_SEQ_CST, "workgroup"); } -int global_val32; +__UINT32_TYPE__ global_val32; __attribute__((device)) void test_global32() { // CHECK-LABEL: test_global32 // CHECK: %0 = load i32, i32* addrspacecast (i32 addrspace(1)* @global_val32 to i32*), align 4 @@ -138,7 +138,7 @@ __attribute__((device)) void test_global32() { global_val32 = __builtin_amdgcn_atomic_dec32(&global_val32, global_val32, __ATOMIC_SEQ_CST, "workgroup"); } -__INT64_TYPE__ global_val64; +__UINT64_TYPE__ global_val64; __attribute__((device)) void test_global64() { // CHECK-LABEL: test_global64 // CHECK: %0 = load i64, i64* addrspacecast (i64 addrspace(1)* @global_val64 to i64*), align 8 @@ -152,10 +152,10 @@ __attribute__((device)) void test_global64() { global_val64 = __builtin_amdgcn_atomic_dec64(&global_val64, global_val64, __ATOMIC_SEQ_CST, "workgroup"); } -__attribute__((constant)) int cval32; +__attribute__((constant)) __UINT32_TYPE__ cval32; __attribute__((device)) void test_constant32() { // CHECK-LABEL: test_constant32 - int local_val; + __UINT32_TYPE__ local_val; // CHECK: %0 = load i32, i32* addrspacecast (i32 addrspace(4)* @cval32 to i32*), align 4 // CHECK-NEXT: %1 = call i32 @llvm.amdgcn.atomic.inc.i32.p0i32(i32* addrspacecast (i32 addrspace(4)* @cval32 to i32*), i32 %0, i32 7, i32 2, i1 false) @@ -168,10 +168,10 @@ __attribute__((device)) void test_constant32() { local_val = __builtin_amdgcn_atomic_dec32(&cval32, cval32, __ATOMIC_SEQ_CST, "workgroup"); } -__attribute__((constant)) __INT64_TYPE__ cval64; +__attribute__((constant)) __UINT64_TYPE__ cval64; __attribute__((device)) void test_constant64() { // CHECK-LABEL: test_constant64 - __INT64_TYPE__ local_val; + __UINT64_TYPE__ local_val; // CHECK: %0 = load i64, i64* addrspacecast (i64 addrspace(4)* @cval64 to i64*), align 8 // CHECK-NEXT: %1 = call i64 @llvm.amdgcn.atomic.inc.i64.p0i64(i64* addrspacecast (i64 addrspace(4)* @cval64 to i64*), i64 %0, i32 7, i32 2, i1 false) @@ -186,7 +186,7 @@ __attribute__((device)) void test_constant64() { __attribute__((device)) void test_order32() { // CHECK-LABEL: test_order32 - __attribute__((shared)) int val; + __attribute__((shared)) __UINT32_TYPE__ val; // CHECK: %1 = call i32 @llvm.amdgcn.atomic.inc.i32.p0i32(i32* addrspacecast (i32 addrspace(3)* @_ZZ12test_order32vE3val to i32*), i32 %0, i32 4, i32 2, i1 false) val = __builtin_amdgcn_atomic_inc32(&val, val, __ATOMIC_ACQUIRE, "workgroup"); @@ -203,7 +203,7 @@ __attribute__((device)) void test_order32() { __attribute__((device)) void test_order64() { // CHECK-LABEL: test_order64 - __attribute__((shared)) __INT64_TYPE__ val; + __attribute__((shared)) __UINT64_TYPE__ val; // CHECK: %1 = call i64 @llvm.amdgcn.atomic.inc.i64.p0i64(i64* addrspacecast (i64 addrspace(3)* @_ZZ12test_order64vE3val to i64*), i64 %0, i32 4, i32 2, i1 false) val = __builtin_amdgcn_atomic_inc64(&val, val, __ATOMIC_ACQUIRE, "workgroup"); @@ -220,7 +220,7 @@ __attribute__((device)) void test_order64() { __attribute__((device)) void test_scope32() { // CHECK-LABEL: test_scope32 - __attribute__((shared)) int val; + __attribute__((shared)) __UINT32_TYPE__ val; // CHECK: %1 = call i32 @llvm.amdgcn.atomic.inc.i32.p0i32(i32* addrspacecast (i32 addrspace(3)* @_ZZ12test_scope32vE3val to i32*), i32 %0, i32 7, i32 1, i1 false) val = __builtin_amdgcn_atomic_inc32(&val, val, __ATOMIC_SEQ_CST, ""); @@ -237,7 +237,7 @@ __attribute__((device)) void test_scope32() { __attribute__((device)) void test_scope64() { // CHECK-LABEL: test_scope64 - __attribute__((shared)) __INT64_TYPE__ val; + __attribute__((shared)) __UINT64_TYPE__ val; // CHECK: %1 = call i64 @llvm.amdgcn.atomic.inc.i64.p0i64(i64* addrspacecast (i64 addrspace(3)* @_ZZ12test_scope64vE3val to i64*), i64 %0, i32 7, i32 1, i1 false) val = __builtin_amdgcn_atomic_inc64(&val, val, __ATOMIC_SEQ_CST, ""); diff --git a/clang/test/CodeGenCXX/debug-info-inheriting-constructor.cpp b/clang/test/CodeGenCXX/debug-info-inheriting-constructor.cpp index 3a2605078220c..d523649ed5ab9 100644 --- a/clang/test/CodeGenCXX/debug-info-inheriting-constructor.cpp +++ b/clang/test/CodeGenCXX/debug-info-inheriting-constructor.cpp @@ -19,7 +19,7 @@ A::A(int i, ...) {} // CHECK-DAG: ![[A:.*]] = distinct !DISubprogram(name: "A", linkageName: "_ZN1BCI11AEiz" void foo() { // CHECK-DAG: ![[LOC]] = !DILocation(line: 0, scope: ![[A]], inlinedAt: ![[INL:[0-9]+]]) -// CHECK-DAG: ![[INL]] = !DILocation(line: [[@LINE+1]], scope: ![[FOO]]) +// CHECK-DAG: ![[INL]] = !DILocation(line: [[@LINE+1]], column: 5, scope: ![[FOO]]) B b(0); -// CHECK: ![[NOINL]] = !DILocation(line: [[@LINE+1]], scope: !{{[0-9]+}}) +// CHECK: ![[NOINL]] = !DILocation(line: [[@LINE+1]], column: 1, scope: !{{[0-9]+}}) } diff --git a/clang/test/CodeGenCXX/debug-info-inlined.cpp b/clang/test/CodeGenCXX/debug-info-inlined.cpp index d36715bcfcb6f..22b60504000ff 100644 --- a/clang/test/CodeGenCXX/debug-info-inlined.cpp +++ b/clang/test/CodeGenCXX/debug-info-inlined.cpp @@ -25,5 +25,5 @@ B::B() : Forward(WithDtor()) {} // CHECK-SAME: %class.Forward** % // CHECK-SAME: !dbg ![[INL:[0-9]+]] -// CHECK: ![[INL]] = !DILocation(line: 10, scope: ![[SP:[0-9]+]], inlinedAt: +// CHECK: ![[INL]] = !DILocation(line: 10, column: 15, scope: ![[SP:[0-9]+]], inlinedAt: // CHECK: ![[SP]] = distinct !DISubprogram(name: "Base", {{.*}} DISPFlagDefinition diff --git a/clang/test/CodeGenCXX/debug-info-lambda.cpp b/clang/test/CodeGenCXX/debug-info-lambda.cpp index a10765de37778..7f79648aa6730 100644 --- a/clang/test/CodeGenCXX/debug-info-lambda.cpp +++ b/clang/test/CodeGenCXX/debug-info-lambda.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm \ -// RUN: -debug-info-kind=line-tables-only -dwarf-column-info -std=c++11 %s -o - | FileCheck %s +// RUN: -debug-info-kind=line-tables-only -std=c++11 %s -o - | FileCheck %s // CHECK-LABEL: define{{.*}}lambda_in_func void lambda_in_func(int &ref) { diff --git a/clang/test/CodeGenCXX/debug-info-line-if.cpp b/clang/test/CodeGenCXX/debug-info-line-if.cpp index 7e6cdb2eb9d81..3b54b5c7c65d0 100644 --- a/clang/test/CodeGenCXX/debug-info-line-if.cpp +++ b/clang/test/CodeGenCXX/debug-info-line-if.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -debug-info-kind=limited -std=c++11 -S -emit-llvm %s -o - | FileCheck -allow-deprecated-dag-overlap %s +// RUN: %clang_cc1 -debug-info-kind=limited -gno-column-info -std=c++11 -S -emit-llvm %s -o - | FileCheck -allow-deprecated-dag-overlap %s // PR19864 extern int v[2]; int a = 0, b = 0; diff --git a/clang/test/CodeGenCXX/debug-info-member-call.cpp b/clang/test/CodeGenCXX/debug-info-member-call.cpp index 3b5adb8e4b826..2b60de8aee491 100644 --- a/clang/test/CodeGenCXX/debug-info-member-call.cpp +++ b/clang/test/CodeGenCXX/debug-info-member-call.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=standalone -dwarf-column-info %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s void ext(); struct Bar { diff --git a/clang/test/CodeGenCXX/debug-info-nested-exprs.cpp b/clang/test/CodeGenCXX/debug-info-nested-exprs.cpp index bd70373e22858..fa934bf2aa008 100644 --- a/clang/test/CodeGenCXX/debug-info-nested-exprs.cpp +++ b/clang/test/CodeGenCXX/debug-info-nested-exprs.cpp @@ -1,13 +1,13 @@ // RUN: %clang_cc1 -triple=x86_64-pc-windows-msvc -debug-info-kind=limited \ -// RUN: -std=c++11 -gcodeview -emit-llvm -o - %s \ +// RUN: -std=c++11 -gcodeview -gno-column-info -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefix=NONEST %s // RUN: %clang_cc1 -triple=x86_64-pc-windows-msvc -debug-info-kind=limited \ -// RUN: -std=c++11 -gcodeview -dwarf-column-info -emit-llvm -o - %s \ +// RUN: -std=c++11 -gcodeview -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefix=COLUMNS %s // RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -debug-info-kind=limited \ -// RUN: -std=c++11 -emit-llvm -o - %s | FileCheck -check-prefix=NESTED %s +// RUN: -std=c++11 -gno-column-info -emit-llvm -o - %s | FileCheck -check-prefix=NESTED %s // RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -debug-info-kind=limited \ -// RUN: -std=c++11 -dwarf-column-info -emit-llvm -o - %s \ +// RUN: -std=c++11 -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefix=COLUMNS %s class Foo { diff --git a/clang/test/CodeGenCXX/debug-info-scope.cpp b/clang/test/CodeGenCXX/debug-info-scope.cpp index 1124282697492..b55ae9e858787 100644 --- a/clang/test/CodeGenCXX/debug-info-scope.cpp +++ b/clang/test/CodeGenCXX/debug-info-scope.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -debug-info-kind=limited -std=c++11 -emit-llvm %s -o -| FileCheck %s +// RUN: %clang_cc1 -debug-info-kind=limited -gno-column-info -std=c++11 -emit-llvm %s -o -| FileCheck %s // // Two variables with the same name in subsequent if staments need to be in separate scopes. // diff --git a/clang/test/CodeGenCXX/linetable-cleanup.cpp b/clang/test/CodeGenCXX/linetable-cleanup.cpp index 748f056918b9b..c8daf40757045 100644 --- a/clang/test/CodeGenCXX/linetable-cleanup.cpp +++ b/clang/test/CodeGenCXX/linetable-cleanup.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin10 %s -o - | FileCheck %s -// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin10 -std=c++98 %s -o - | FileCheck %s -// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-darwin10 -std=c++11 %s -o - | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -gno-column-info -triple x86_64-apple-darwin10 %s -o - | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -gno-column-info -triple x86_64-apple-darwin10 -std=c++98 %s -o - | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -gno-column-info -triple x86_64-apple-darwin10 -std=c++11 %s -o - | FileCheck %s // Check the line numbers for cleanup code with EH in combination with // simple return expressions. diff --git a/clang/test/CodeGenCXX/linetable-eh.cpp b/clang/test/CodeGenCXX/linetable-eh.cpp index b31df54f7c456..6821655a0bb14 100644 --- a/clang/test/CodeGenCXX/linetable-eh.cpp +++ b/clang/test/CodeGenCXX/linetable-eh.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple x86_64-apple-macosx10.9.0 -munwind-tables -std=c++11 -fcxx-exceptions -fexceptions %s -o - | FileCheck -allow-deprecated-dag-overlap %s +// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -gno-column-info -triple x86_64-apple-macosx10.9.0 -munwind-tables -std=c++11 -fcxx-exceptions -fexceptions %s -o - | FileCheck -allow-deprecated-dag-overlap %s // Test that emitting a landing pad does not affect the line table // entries for the code that triggered it. diff --git a/clang/test/CodeGenCXX/linetable-fnbegin.cpp b/clang/test/CodeGenCXX/linetable-fnbegin.cpp index 3b93d70bd7054..d64b5a64b174a 100644 --- a/clang/test/CodeGenCXX/linetable-fnbegin.cpp +++ b/clang/test/CodeGenCXX/linetable-fnbegin.cpp @@ -9,7 +9,7 @@ // CHECK-SAME: file: [[HPP]], line: 22 // CHECK-SAME: DISPFlagDefinition // We shouldn't need a lexical block for this function. -// CHECK: [[DBG]] = !DILocation(line: 23, scope: [[SP]]) +// CHECK: [[DBG]] = !DILocation(line: 23, column: 3, scope: [[SP]]) # 1 "./template.h" 1 diff --git a/clang/test/CodeGenCXX/lpad-linetable.cpp b/clang/test/CodeGenCXX/lpad-linetable.cpp index 9b429bc2a223d..b20106f5f98fe 100644 --- a/clang/test/CodeGenCXX/lpad-linetable.cpp +++ b/clang/test/CodeGenCXX/lpad-linetable.cpp @@ -4,7 +4,7 @@ // CHECK: ret i32 // CHECK: landingpad {{.*}} // CHECK-NEXT: !dbg ![[LPAD:[0-9]+]] -// CHECK: ![[LPAD]] = !DILocation(line: 24, scope: !{{.*}}) +// CHECK: ![[LPAD]] = !DILocation(line: 24, column: 1, scope: !{{.*}}) # 1 "/usr/include/c++/4.2.1/vector" 1 3 typedef long unsigned int __darwin_size_t; diff --git a/clang/test/CodeGenCXX/trivial_abi.cpp b/clang/test/CodeGenCXX/trivial_abi.cpp index e7e7f840944d9..cb9b9dfeb4bd9 100644 --- a/clang/test/CodeGenCXX/trivial_abi.cpp +++ b/clang/test/CodeGenCXX/trivial_abi.cpp @@ -43,6 +43,31 @@ struct HasNonTrivial { NonTrivial m; }; +struct B0 { + virtual Small m0(); +}; + +struct B1 { + virtual Small m0(); +}; + +struct D0 : B0, B1 { + Small m0() override; +}; + +// CHECK-LABEL: define i64 @_ZThn8_N2D02m0Ev( +// CHECK: %[[RETVAL:.*]] = alloca %[[STRUCT_SMALL]], align 8 +// CHECK: %[[CALL:.*]] = tail call i64 @_ZN2D02m0Ev( +// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_SMALL]], %[[STRUCT_SMALL]]* %[[RETVAL]], i32 0, i32 0 +// CHECK: %[[COERCE_VAL_IP:.*]] = inttoptr i64 %[[CALL]] to i32* +// CHECK: store i32* %[[COERCE_VAL_IP]], i32** %[[COERCE_DIVE]], align 8 +// CHECK: %[[COERCE_DIVE2:.*]] = getelementptr inbounds %[[STRUCT_SMALL]], %[[STRUCT_SMALL]]* %[[RETVAL]], i32 0, i32 0 +// CHECK: %[[V3:.*]] = load i32*, i32** %[[COERCE_DIVE2]], align 8 +// CHECK: %[[COERCE_VAL_PI:.*]] = ptrtoint i32* %[[V3]] to i64 +// CHECK: ret i64 %[[COERCE_VAL_PI]] + +Small D0::m0() { return {}; } + // CHECK: define void @_Z14testParamSmall5Small(i64 %[[A_COERCE:.*]]) // CHECK: %[[A:.*]] = alloca %[[STRUCT_SMALL]], align 8 // CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_SMALL]], %[[STRUCT_SMALL]]* %[[A]], i32 0, i32 0 diff --git a/clang/test/CodeGenCXX/ubsan-coroutines.cpp b/clang/test/CodeGenCXX/ubsan-coroutines.cpp index 8728c1511122b..dacc229ce519e 100644 --- a/clang/test/CodeGenCXX/ubsan-coroutines.cpp +++ b/clang/test/CodeGenCXX/ubsan-coroutines.cpp @@ -32,7 +32,7 @@ struct task { struct promise_type { task get_return_object() { return task(); } suspend_always initial_suspend() { return {}; } - suspend_always final_suspend() { return {}; } + suspend_always final_suspend() noexcept { return {}; } void return_void() {} void unhandled_exception() {} }; diff --git a/clang/test/CodeGenCXX/vtable-consteval.cpp b/clang/test/CodeGenCXX/vtable-consteval.cpp new file mode 100644 index 0000000000000..ed4a25290d359 --- /dev/null +++ b/clang/test/CodeGenCXX/vtable-consteval.cpp @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -std=c++20 %s -emit-llvm -o - -triple x86_64-linux | FileCheck %s --check-prefix=ITANIUM --implicit-check-not=DoNotEmit +// RUN: %clang_cc1 -std=c++20 %s -emit-llvm -o - -triple x86_64-windows | FileCheck %s --check-prefix=MSABI --implicit-check-not=DoNotEmit + +// FIXME: The MSVC ABI rule in use here was discussed with MS folks prior to +// them implementing virtual consteval functions, but we do not know for sure +// if this is the ABI rule they will use. + +// ITANIUM-DAG: @_ZTV1A = {{.*}} constant { [2 x i8*] } {{.*}} null, {{.*}} @_ZTI1A +// MSABI-DAG: @[[A_VFTABLE:.*]] = {{.*}} constant { [1 x i8*] } {{.*}} @"??_R4A@@6B@" +struct A { + virtual consteval void DoNotEmit_f() {} +}; +// ITANIUM-DAG: @a = {{.*}}global { i8** } { {{.*}} @_ZTV1A, +// MSABI-DAG: @"?a@@3UA@@A" = {{.*}}global { i8** } { i8** @"??_7A@@6B@" } +A a; + +// ITANIUM-DAG: @_ZTV1B = {{.*}} constant { [4 x i8*] } {{.*}} null, {{.*}} @_ZTI1B {{.*}} @_ZN1B1fEv {{.*}} @_ZN1B1hEv +// MSABI-DAG: @[[B_VFTABLE:.*]] = {{.*}} constant { [3 x i8*] } {{.*}} @"??_R4B@@6B@" {{.*}} @"?f@B@@UEAAXXZ" {{.*}} @"?h@B@@UEAAXXZ" +struct B { + virtual void f() {} + virtual consteval void DoNotEmit_g() {} + virtual void h() {} +}; +// ITANIUM-DAG: @b = {{.*}}global { i8** } { {{.*}} @_ZTV1B, +// MSABI-DAG: @"?b@@3UB@@A" = {{.*}}global { i8** } { i8** @"??_7B@@6B@" } +B b; + +// ITANIUM-DAG: @_ZTV1C = {{.*}} constant { [4 x i8*] } {{.*}} null, {{.*}} @_ZTI1C {{.*}} @_ZN1CD1Ev {{.*}} @_ZN1CD0Ev +// MSABI-DAG: @[[C_VFTABLE:.*]] = {{.*}} constant { [2 x i8*] } {{.*}} @"??_R4C@@6B@" {{.*}} @"??_GC@@UEAAPEAXI@Z" +struct C { + virtual ~C() = default; + virtual consteval C &operator=(const C&) = default; +}; +// ITANIUM-DAG: @c = {{.*}}global { i8** } { {{.*}} @_ZTV1C, +// MSABI-DAG: @"?c@@3UC@@A" = {{.*}}global { i8** } { i8** @"??_7C@@6B@" } +C c; + +// ITANIUM-DAG: @_ZTV1D = {{.*}} constant { [4 x i8*] } {{.*}} null, {{.*}} @_ZTI1D {{.*}} @_ZN1DD1Ev {{.*}} @_ZN1DD0Ev +// MSABI-DAG: @[[D_VFTABLE:.*]] = {{.*}} constant { [2 x i8*] } {{.*}} @"??_R4D@@6B@" {{.*}} @"??_GD@@UEAAPEAXI@Z" +struct D : C {}; +// ITANIUM-DAG: @d = {{.*}}global { i8** } { {{.*}} @_ZTV1D, +// MSABI-DAG: @"?d@@3UD@@A" = {{.*}}global { i8** } { i8** @"??_7D@@6B@" } +D d; + +// ITANIUM-DAG: @_ZTV1E = {{.*}} constant { [3 x i8*] } {{.*}} null, {{.*}} @_ZTI1E {{.*}} @_ZN1E1fEv +// MSABI-DAG: @[[E_VFTABLE:.*]] = {{.*}} constant { [2 x i8*] } {{.*}} @"??_R4E@@6B@" {{.*}} @"?f@E@@UEAAXXZ" +struct E { virtual void f() {} }; +// ITANIUM-DAG: @e = {{.*}}global { i8** } { {{.*}} @_ZTV1E, +// MSABI-DAG: @"?e@@3UE@@A" = {{.*}}global { i8** } { i8** @"??_7E@@6B@" } +E e; + +// ITANIUM-DAG: @_ZTV1F = {{.*}} constant { [3 x i8*] } {{.*}} null, {{.*}} @_ZTI1F {{.*}} @_ZN1E1fEv +// MSABI-DAG: @[[F_VFTABLE:.*]] = {{.*}} constant { [2 x i8*] } {{.*}} @"??_R4F@@6B@" {{.*}} @"?f@E@@UEAAXXZ" +struct F : E { virtual consteval void DoNotEmit_g(); }; +// ITANIUM-DAG: @f = {{.*}}global { i8** } { {{.*}} @_ZTV1F, +// MSABI-DAG: @"?f@@3UF@@A" = {{.*}}global { i8** } { i8** @"??_7F@@6B@" } +F f; + +// MSABI-DAG: @"??_7A@@6B@" = {{.*}} alias {{.*}} @[[A_VFTABLE]], +// MSABI-DAG: @"??_7B@@6B@" = {{.*}} alias {{.*}} @[[B_VFTABLE]], +// MSABI-DAG: @"??_7C@@6B@" = {{.*}} alias {{.*}} @[[C_VFTABLE]], +// MSABI-DAG: @"??_7D@@6B@" = {{.*}} alias {{.*}} @[[D_VFTABLE]], +// MSABI-DAG: @"??_7E@@6B@" = {{.*}} alias {{.*}} @[[E_VFTABLE]], +// MSABI-DAG: @"??_7F@@6B@" = {{.*}} alias {{.*}} @[[F_VFTABLE]], diff --git a/clang/test/CodeGenCXX/vtable-constexpr.cpp b/clang/test/CodeGenCXX/vtable-constexpr.cpp new file mode 100644 index 0000000000000..e398a9e5835d1 --- /dev/null +++ b/clang/test/CodeGenCXX/vtable-constexpr.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -std=c++20 %s -emit-llvm -o - -triple %itanium_abi_triple | FileCheck %s --implicit-check-not=DoNotEmit + +// constexpr virtual functions can be called at runtime and go in the vtable as +// normal. But they are implicitly inline so are never the key function. + +struct DoNotEmit { + virtual constexpr void f(); +}; +constexpr void DoNotEmit::f() {} + +// CHECK-DAG: @_ZTV1B = {{.*}} constant { [3 x i8*] } { {{.*}} null, {{.*}} @_ZTI1B {{.*}} @_ZN1B1fEv +struct B { + // CHECK-DAG: define {{.*}} @_ZN1B1fEv + virtual constexpr void f() {} +}; +B b; + +struct CBase { + virtual constexpr void f(); // not key function +}; + +// CHECK-DAG: @_ZTV1C = {{.*}} constant {{.*}} null, {{.*}} @_ZTI1C {{.*}} @_ZN1C1fEv +struct C : CBase { + void f(); // key function +}; +// CHECK-DAG: define {{.*}} @_ZN1C1fEv +void C::f() {} diff --git a/clang/test/CodeGenCoroutines/Inputs/coroutine.h b/clang/test/CodeGenCoroutines/Inputs/coroutine.h index d58212b1d5280..5cc78a4904aad 100644 --- a/clang/test/CodeGenCoroutines/Inputs/coroutine.h +++ b/clang/test/CodeGenCoroutines/Inputs/coroutine.h @@ -72,9 +72,9 @@ struct suspend_always { void await_resume() {} }; struct suspend_never { - bool await_ready() { return true; } - void await_suspend(coroutine_handle<>) {} - void await_resume() {} + bool await_ready() noexcept { return true; } + void await_suspend(coroutine_handle<>) noexcept {} + void await_resume() noexcept {} }; }}} diff --git a/clang/test/CodeGenCoroutines/coro-alloc.cpp b/clang/test/CodeGenCoroutines/coro-alloc.cpp index a73b7d85a4be6..bf8edf012a33f 100644 --- a/clang/test/CodeGenCoroutines/coro-alloc.cpp +++ b/clang/test/CodeGenCoroutines/coro-alloc.cpp @@ -10,7 +10,7 @@ struct coroutine_traits; // expected-note {{declared here}} template struct coroutine_handle { coroutine_handle() = default; - static coroutine_handle from_address(void *) { return {}; } + static coroutine_handle from_address(void *) noexcept { return {}; } }; template <> @@ -18,7 +18,7 @@ struct coroutine_handle { static coroutine_handle from_address(void *) { return {}; } coroutine_handle() = default; template - coroutine_handle(coroutine_handle) {} + coroutine_handle(coroutine_handle) noexcept {} }; } // end namespace experimental @@ -36,9 +36,9 @@ void operator delete(void* __p, const std::nothrow_t&) noexcept; struct suspend_always { - bool await_ready() { return false; } - void await_suspend(std::experimental::coroutine_handle<>) {} - void await_resume() {} + bool await_ready() noexcept { return false; } + void await_suspend(std::experimental::coroutine_handle<>) noexcept {} + void await_resume() noexcept {} }; struct global_new_delete_tag {}; @@ -48,7 +48,7 @@ struct std::experimental::coroutine_traits { struct promise_type { void get_return_object() {} suspend_always initial_suspend() { return {}; } - suspend_always final_suspend() { return {}; } + suspend_always final_suspend() noexcept { return {}; } void return_void() {} }; }; @@ -89,7 +89,7 @@ struct std::experimental::coroutine_traits { void *operator new(unsigned long); void get_return_object() {} suspend_always initial_suspend() { return {}; } - suspend_always final_suspend() { return {}; } + suspend_always final_suspend() noexcept { return {}; } void return_void() {} }; }; @@ -115,7 +115,7 @@ struct std::experimental::coroutine_traits { void operator delete(void*); void get_return_object() {} suspend_always initial_suspend() { return {}; } - suspend_always final_suspend() { return {}; } + suspend_always final_suspend() noexcept { return {}; } void return_void() {} }; }; @@ -193,7 +193,7 @@ struct std::experimental::coroutine_traits { void operator delete(void*, unsigned long); void get_return_object() {} suspend_always initial_suspend() { return {}; } - suspend_always final_suspend() { return {}; } + suspend_always final_suspend() noexcept { return {}; } void return_void() {} }; }; @@ -218,7 +218,7 @@ struct std::experimental::coroutine_traits { struct promise_type { int get_return_object() { return 0; } suspend_always initial_suspend() { return {}; } - suspend_always final_suspend() { return {}; } + suspend_always final_suspend() noexcept { return {}; } void return_void() {} static int get_return_object_on_allocation_failure() { return -1; } }; diff --git a/clang/test/CodeGenCoroutines/coro-always-inline.cpp b/clang/test/CodeGenCoroutines/coro-always-inline.cpp index a2e4bba45c0c9..e4aa14a6ac397 100644 --- a/clang/test/CodeGenCoroutines/coro-always-inline.cpp +++ b/clang/test/CodeGenCoroutines/coro-always-inline.cpp @@ -14,22 +14,22 @@ namespace experimental { struct handle {}; struct awaitable { - bool await_ready() { return true; } + bool await_ready() noexcept { return true; } // CHECK-NOT: await_suspend - inline void __attribute__((__always_inline__)) await_suspend(handle) {} - bool await_resume() { return true; } + inline void __attribute__((__always_inline__)) await_suspend(handle) noexcept {} + bool await_resume() noexcept { return true; } }; template struct coroutine_handle { - static handle from_address(void *address) { return {}; } + static handle from_address(void *address) noexcept { return {}; } }; template struct coroutine_traits { struct promise_type { awaitable initial_suspend() { return {}; } - awaitable final_suspend() { return {}; } + awaitable final_suspend() noexcept { return {}; } void return_void() {} T get_return_object() { return T(); } void unhandled_exception() {} diff --git a/clang/test/CodeGenCoroutines/coro-await-domination.cpp b/clang/test/CodeGenCoroutines/coro-await-domination.cpp index 5df22374a6e7f..3ce8cd7a6227f 100644 --- a/clang/test/CodeGenCoroutines/coro-await-domination.cpp +++ b/clang/test/CodeGenCoroutines/coro-await-domination.cpp @@ -7,7 +7,7 @@ struct coro { struct promise_type { coro get_return_object(); suspend_never initial_suspend(); - suspend_never final_suspend(); + suspend_never final_suspend() noexcept; void return_void(); static void unhandled_exception(); }; @@ -35,4 +35,3 @@ extern "C" coro f(int) { x = co_await A{}; consume(x); } - diff --git a/clang/test/CodeGenCoroutines/coro-await-resume-eh.cpp b/clang/test/CodeGenCoroutines/coro-await-resume-eh.cpp index f0f8855fbd4d3..b5dcc3f9da78d 100644 --- a/clang/test/CodeGenCoroutines/coro-await-resume-eh.cpp +++ b/clang/test/CodeGenCoroutines/coro-await-resume-eh.cpp @@ -22,7 +22,7 @@ struct throwing_task { struct promise_type { auto get_return_object() { return throwing_task{}; } auto initial_suspend() { return throwing_awaitable{}; } - auto final_suspend() { return coro::suspend_never{}; } + auto final_suspend() noexcept { return coro::suspend_never{}; } void return_void() {} void unhandled_exception() {} }; @@ -76,7 +76,7 @@ throwing_task f() { // CHECK-NEXT: br label %[[COROFINAL]] // CHECK: [[COROFINAL]]: - // CHECK-NEXT: invoke void @_ZN13throwing_task12promise_type13final_suspendEv + // CHECK-NEXT: call void @_ZN13throwing_task12promise_type13final_suspendEv co_return; } @@ -90,7 +90,7 @@ struct noexcept_task { struct promise_type { auto get_return_object() { return noexcept_task{}; } auto initial_suspend() { return noexcept_awaitable{}; } - auto final_suspend() { return coro::suspend_never{}; } + auto final_suspend() noexcept { return coro::suspend_never{}; } void return_void() {} void unhandled_exception() {} }; diff --git a/clang/test/CodeGenCoroutines/coro-await.cpp b/clang/test/CodeGenCoroutines/coro-await.cpp index acd3c4aa97162..90da9be5976d4 100644 --- a/clang/test/CodeGenCoroutines/coro-await.cpp +++ b/clang/test/CodeGenCoroutines/coro-await.cpp @@ -17,7 +17,7 @@ struct coroutine_handle { template struct coroutine_handle : coroutine_handle<> { - static coroutine_handle from_address(void *); + static coroutine_handle from_address(void *) noexcept; }; } @@ -29,9 +29,9 @@ struct init_susp { void await_resume(); }; struct final_susp { - bool await_ready(); - void await_suspend(std::experimental::coroutine_handle<>); - void await_resume(); + bool await_ready() noexcept; + void await_suspend(std::experimental::coroutine_handle<>) noexcept; + void await_resume() noexcept; }; struct suspend_always { @@ -46,7 +46,7 @@ struct std::experimental::coroutine_traits { struct promise_type { void get_return_object(); init_susp initial_suspend(); - final_susp final_suspend(); + final_susp final_suspend() noexcept; void return_void(); }; }; @@ -119,7 +119,7 @@ struct std::experimental::coroutine_traits { struct promise_type { void get_return_object(); init_susp initial_suspend(); - final_susp final_suspend(); + final_susp final_suspend() noexcept; void return_void(); suspend_maybe yield_value(int); }; @@ -295,7 +295,7 @@ struct std::experimental::coroutine_traits { struct promise_type { void get_return_object(); init_susp initial_suspend(); - final_susp final_suspend(); + final_susp final_suspend() noexcept; void return_void(); AwaitResumeReturnsLValue yield_value(int); }; diff --git a/clang/test/CodeGenCoroutines/coro-dest-slot.cpp b/clang/test/CodeGenCoroutines/coro-dest-slot.cpp index 4c7395ba608c3..0c8ef6b045821 100644 --- a/clang/test/CodeGenCoroutines/coro-dest-slot.cpp +++ b/clang/test/CodeGenCoroutines/coro-dest-slot.cpp @@ -8,7 +8,7 @@ struct coro { struct promise_type { coro get_return_object(); suspend_always initial_suspend(); - suspend_never final_suspend(); + suspend_never final_suspend() noexcept; void return_void(); static void unhandled_exception(); }; diff --git a/clang/test/CodeGenCoroutines/coro-gro-nrvo.cpp b/clang/test/CodeGenCoroutines/coro-gro-nrvo.cpp index 42856f4479ec3..787cb01a53e6e 100644 --- a/clang/test/CodeGenCoroutines/coro-gro-nrvo.cpp +++ b/clang/test/CodeGenCoroutines/coro-gro-nrvo.cpp @@ -21,7 +21,7 @@ template struct promise_type { RetObject get_return_object(); suspend_always initial_suspend(); - suspend_never final_suspend(); + suspend_never final_suspend() noexcept; void return_void(); static void unhandled_exception(); }; @@ -52,7 +52,7 @@ struct promise_type_with_on_alloc_failure { static RetObject get_return_object_on_allocation_failure(); RetObject get_return_object(); suspend_always initial_suspend(); - suspend_never final_suspend(); + suspend_never final_suspend() noexcept; void return_void(); static void unhandled_exception(); }; diff --git a/clang/test/CodeGenCoroutines/coro-newpm-pipeline.cpp b/clang/test/CodeGenCoroutines/coro-newpm-pipeline.cpp index cea71a1acc6bc..2a1b0d34658fb 100644 --- a/clang/test/CodeGenCoroutines/coro-newpm-pipeline.cpp +++ b/clang/test/CodeGenCoroutines/coro-newpm-pipeline.cpp @@ -33,19 +33,19 @@ namespace experimental { struct handle {}; struct awaitable { - bool await_ready() { return true; } - void await_suspend(handle) {} - bool await_resume() { return true; } + bool await_ready() noexcept { return true; } + void await_suspend(handle) noexcept {} + bool await_resume() noexcept { return true; } }; template struct coroutine_handle { - static handle from_address(void *address) { return {}; } + static handle from_address(void *address) noexcept { return {}; } }; template struct coroutine_traits { struct promise_type { awaitable initial_suspend() { return {}; } - awaitable final_suspend() { return {}; } + awaitable final_suspend() noexcept { return {}; } void return_void() {} T get_return_object() { return T(); } void unhandled_exception() {} diff --git a/clang/test/CodeGenCoroutines/coro-params.cpp b/clang/test/CodeGenCoroutines/coro-params.cpp index 1302d734d4442..5f8b28b40b2b1 100644 --- a/clang/test/CodeGenCoroutines/coro-params.cpp +++ b/clang/test/CodeGenCoroutines/coro-params.cpp @@ -142,7 +142,7 @@ struct std::experimental::coroutine_traits struct std::experimental::coroutine_traits struct coroutine_handle<> {}; template struct coroutine_handle : coroutine_handle<> { - static coroutine_handle from_address(void *); + static coroutine_handle from_address(void *) noexcept; }; struct e { int await_ready(); @@ -29,13 +29,13 @@ template struct f; struct g { struct h { - int await_ready(); + int await_ready() noexcept; template - void await_suspend(std::experimental::coroutine_handle); - void await_resume(); + void await_suspend(std::experimental::coroutine_handle) noexcept; + void await_resume() noexcept; }; std::experimental::e initial_suspend(); - h final_suspend(); + h final_suspend() noexcept; template auto await_transform(ag) { return ah(ag()); } }; diff --git a/clang/test/CodeGenCoroutines/coro-return.cpp b/clang/test/CodeGenCoroutines/coro-return.cpp index 17356f944ce1f..65c0655b86797 100644 --- a/clang/test/CodeGenCoroutines/coro-return.cpp +++ b/clang/test/CodeGenCoroutines/coro-return.cpp @@ -5,27 +5,27 @@ template struct coroutine_traits; template struct coroutine_handle { coroutine_handle() = default; - static coroutine_handle from_address(void *) { return {}; } + static coroutine_handle from_address(void *) noexcept { return {}; } }; template <> struct coroutine_handle { static coroutine_handle from_address(void *) { return {}; } coroutine_handle() = default; template - coroutine_handle(coroutine_handle) {} + coroutine_handle(coroutine_handle) noexcept {} }; } struct suspend_always { - bool await_ready(); - void await_suspend(std::experimental::coroutine_handle<>); - void await_resume(); + bool await_ready() noexcept; + void await_suspend(std::experimental::coroutine_handle<>) noexcept; + void await_resume() noexcept; }; template <> struct std::experimental::coroutine_traits { struct promise_type { void get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void return_void(); }; }; @@ -44,7 +44,7 @@ struct std::experimental::coroutine_traits { struct promise_type { int get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void return_value(int); }; }; diff --git a/clang/test/CodeGenCoroutines/coro-unhandled-exception.cpp b/clang/test/CodeGenCoroutines/coro-unhandled-exception.cpp index 039f02352cfca..870e67477ed14 100644 --- a/clang/test/CodeGenCoroutines/coro-unhandled-exception.cpp +++ b/clang/test/CodeGenCoroutines/coro-unhandled-exception.cpp @@ -17,7 +17,7 @@ struct coro_t { return {}; } coro::suspend_never initial_suspend() { return {}; } - coro::suspend_never final_suspend() { return {}; } + coro::suspend_never final_suspend() noexcept { return {}; } void return_void(){} void unhandled_exception() noexcept; }; @@ -48,11 +48,9 @@ coro_t f() { // CHECK: [[CATCHRETDEST]]: // CHECK-NEXT: br label %[[TRYCONT:.+]] // CHECK: [[TRYCONT]]: -// CHECK-NEXT: br label %[[RESUMECONT:.+]] -// CHECK: [[RESUMECONT]]: // CHECK-NEXT: br label %[[COROFIN:.+]] // CHECK: [[COROFIN]]: -// CHECK-NEXT: invoke void @"?final_suspend@promise_type@coro_t@@QEAA?AUsuspend_never@coroutines_v1@experimental@std@@XZ"( +// CHECK-NEXT: call void @"?final_suspend@promise_type@coro_t@@QEAA?AUsuspend_never@coroutines_v1@experimental@std@@XZ"( // CHECK-LPAD: @_Z1fv( // CHECK-LPAD: invoke void @_Z9may_throwv() @@ -69,8 +67,6 @@ coro_t f() { // CHECK-LPAD: [[CATCHRETDEST]]: // CHECK-LPAD-NEXT: br label %[[TRYCONT:.+]] // CHECK-LPAD: [[TRYCONT]]: -// CHECK-LPAD: br label %[[RESUMECONT:.+]] -// CHECK-LPAD: [[RESUMECONT]]: -// CHECK-LPAD-NEXT: br label %[[COROFIN:.+]] +// CHECK-LPAD: br label %[[COROFIN:.+]] // CHECK-LPAD: [[COROFIN]]: -// CHECK-LPAD-NEXT: invoke void @_ZN6coro_t12promise_type13final_suspendEv( +// CHECK-LPAD-NEXT: call void @_ZN6coro_t12promise_type13final_suspendEv( diff --git a/clang/test/CodeGenHIP/lit.local.cfg b/clang/test/CodeGenHIP/lit.local.cfg new file mode 100644 index 0000000000000..ded4330455aeb --- /dev/null +++ b/clang/test/CodeGenHIP/lit.local.cfg @@ -0,0 +1 @@ +config.suffixes = ['.cpp', '.hip'] diff --git a/clang/test/CodeGenObjC/aarch64-sve-types.m b/clang/test/CodeGenObjC/aarch64-sve-types.m index 625c752965923..cc0a95a044068 100644 --- a/clang/test/CodeGenObjC/aarch64-sve-types.m +++ b/clang/test/CodeGenObjC/aarch64-sve-types.m @@ -1,7 +1,7 @@ // RUN: not %clang_cc1 -triple aarch64-none-linux-gnu %s -emit-llvm -o - \ // RUN: 2>&1 | FileCheck %s // RUN: not %clang_cc1 -triple aarch64-none-linux-gnu %s -emit-llvm -o - \ -// RUN: -target-feature +sve 2>&1 | FileCheck %s +// RUN: -target-feature +sve,+bf16 2>&1 | FileCheck %s // CHECK: error: cannot yet @encode type __SVInt8_t const char s8[] = @encode(__SVInt8_t); @@ -28,5 +28,8 @@ // CHECK: error: cannot yet @encode type __SVFloat64_t const char f64[] = @encode(__SVFloat64_t); +// CHECK: error: cannot yet @encode type __SVBFloat16_t +const char bf16[] = @encode(__SVBFloat16_t); + // CHECK: error: cannot yet @encode type __SVBool_t const char b8[] = @encode(__SVBool_t); diff --git a/clang/test/CodeGenObjC/arc-blocks.m b/clang/test/CodeGenObjC/arc-blocks.m index 3851773c68b76..0694155b5f4aa 100644 --- a/clang/test/CodeGenObjC/arc-blocks.m +++ b/clang/test/CodeGenObjC/arc-blocks.m @@ -747,5 +747,18 @@ id test22(int c, id x) { return c ? test22_0() : ({ id (^b)(void) = ^{ return x; }; test22_1(); b(); }); } +@interface Test23 +-(void)m:(int)i, ...; +@end + +// CHECK-COMMON-LABEL: define void @test23( +// CHECK-COMMON: %[[V9:.*]] = call i8* @llvm.objc.retainBlock( +// CHECK-COMMON: %[[V10:.*]] = bitcast i8* %[[V9]] to void ()* +// CHECK-COMMON: call void (i8*, i8*, i32, ...) bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32, ...)*)(i8* %{{.*}}, i8* %{{.*}}, i32 123, void ()* %[[V10]]) + +void test23(id x, Test23 *t) { + [t m:123, ^{ (void)x; }]; +} + // CHECK: attributes [[NUW]] = { nounwind } // CHECK-UNOPT: attributes [[NUW]] = { nounwind } diff --git a/clang/test/CodeGenObjC/arc-linetable-autorelease.m b/clang/test/CodeGenObjC/arc-linetable-autorelease.m index 0804b0700a085..93eeacab902f6 100644 --- a/clang/test/CodeGenObjC/arc-linetable-autorelease.m +++ b/clang/test/CodeGenObjC/arc-linetable-autorelease.m @@ -32,8 +32,8 @@ - (NSBezierPath *)_createBezierPathWithWidth:(CGFloat)width height:(CGFloat)heig // CHECK: call void @llvm.objc.storeStrong{{.*}} !dbg ![[ARC:[0-9]+]] // CHECK: call {{.*}} @llvm.objc.autoreleaseReturnValue{{.*}} !dbg ![[ARC]] // CHECK: ret {{.*}} !dbg ![[ARC]] - // CHECK: ![[RET]] = !DILocation(line: [[@LINE+1]], scope: !{{.*}}) + // CHECK: ![[RET]] = !DILocation(line: [[@LINE+1]], column: 10, scope: !{{.*}}) return path; - // CHECK: ![[ARC]] = !DILocation(line: [[@LINE+1]], scope: !{{.*}}) + // CHECK: ![[ARC]] = !DILocation(line: [[@LINE+1]], column: 1, scope: !{{.*}}) } @end diff --git a/clang/test/CodeGenObjC/arc-linetable.m b/clang/test/CodeGenObjC/arc-linetable.m index 3883e0a3a93f2..646136a1cd035 100644 --- a/clang/test/CodeGenObjC/arc-linetable.m +++ b/clang/test/CodeGenObjC/arc-linetable.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -fblocks -fobjc-arc -debug-info-kind=standalone -dwarf-version=4 -disable-llvm-passes -triple x86_64-apple-darwin10 %s -o - | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -fblocks -fobjc-arc -debug-info-kind=standalone -dwarf-version=4 -gno-column-info -disable-llvm-passes -triple x86_64-apple-darwin10 %s -o - | FileCheck %s // Legend: EXP = Return expression, RET = ret instruction diff --git a/clang/test/CodeGenObjCXX/objc-struct-cxx-abi.mm b/clang/test/CodeGenObjCXX/objc-struct-cxx-abi.mm index 7a7781f68891b..d19534f6922dc 100644 --- a/clang/test/CodeGenObjCXX/objc-struct-cxx-abi.mm +++ b/clang/test/CodeGenObjCXX/objc-struct-cxx-abi.mm @@ -178,3 +178,32 @@ void testParamContainsNonTrivial(ContainsNonTrivial a) { void testCallContainsNonTrivial(ContainsNonTrivial *a) { testParamContainsNonTrivial(*a); } + +namespace testThunk { + +// CHECK-LABEL: define i64 @_ZThn8_N9testThunk2D02m0Ev( +// CHECK: %[[RETVAL:.*]] = alloca %[[STRUCT_STRONG]], align 8 +// CHECK: %[[CALL:.*]] = tail call i64 @_ZN9testThunk2D02m0Ev( +// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], %[[STRUCT_STRONG]]* %[[RETVAL]], i32 0, i32 0 +// CHECK: %[[COERCE_VAL_IP:.*]] = inttoptr i64 %[[CALL]] to i8* +// CHECK: store i8* %[[COERCE_VAL_IP]], i8** %[[COERCE_DIVE]], align 8 +// CHECK: %[[COERCE_DIVE2:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], %[[STRUCT_STRONG]]* %[[RETVAL]], i32 0, i32 0 +// CHECK: %[[V3:.*]] = load i8*, i8** %[[COERCE_DIVE2]], align 8 +// CHECK: %[[COERCE_VAL_PI:.*]] = ptrtoint i8* %[[V3]] to i64 +// CHECK: ret i64 %[[COERCE_VAL_PI]] + +struct B0 { + virtual Strong m0(); +}; + +struct B1 { + virtual Strong m0(); +}; + +struct D0 : B0, B1 { + Strong m0() override; +}; + +Strong D0::m0() { return {}; } + +} diff --git a/clang/test/CodeGenOpenCL/blocks.cl b/clang/test/CodeGenOpenCL/blocks.cl index c3e26855dfe01..f8315515f1d9d 100644 --- a/clang/test/CodeGenOpenCL/blocks.cl +++ b/clang/test/CodeGenOpenCL/blocks.cl @@ -70,26 +70,6 @@ void foo(){ // COMMON-NOT: define{{.*}}@__foo_block_invoke_kernel -// Test that we support block arguments. -// COMMON-LABEL: define {{.*}} @blockArgFunc -int blockArgFunc(int (^ bl)(void)) { - return bl(); -} - -// COMMON-LABEL: define {{.*}} @get21 -// COMMON: define {{.*}} @__get21_block_invoke -// COMMON: ret i32 21 -int get21() { - return blockArgFunc(^{return 21;}); -} - -// COMMON-LABEL: define {{.*}} @get42 -// COMMON: define {{.*}} @__get42_block_invoke -// COMMON: ret i32 42 -int get42() { - return blockArgFunc(^{return 42;}); -} - // COMMON-LABEL: define {{.*}}@call_block // call {{.*}}@__call_block_block_invoke int call_block() { diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn-vi.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn-vi.cl index e3e6b81271d1f..5884f84ab081b 100644 --- a/clang/test/CodeGenOpenCL/builtins-amdgcn-vi.cl +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn-vi.cl @@ -22,6 +22,13 @@ void test_rcp_f16(global half* out, half a) *out = __builtin_amdgcn_rcph(a); } +// CHECK-LABEL: @test_sqrt_f16 +// CHECK: call half @llvm.amdgcn.sqrt.f16 +void test_sqrt_f16(global half* out, half a) +{ + *out = __builtin_amdgcn_sqrth(a); +} + // CHECK-LABEL: @test_rsq_f16 // CHECK: call half @llvm.amdgcn.rsq.f16 void test_rsq_f16(global half* out, half a) diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn.cl index 3563ad464c66a..56c83df6b6b41 100644 --- a/clang/test/CodeGenOpenCL/builtins-amdgcn.cl +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn.cl @@ -116,6 +116,20 @@ void test_rcp_f64(global double* out, double a) *out = __builtin_amdgcn_rcp(a); } +// CHECK-LABEL: @test_sqrt_f32 +// CHECK: call float @llvm.amdgcn.sqrt.f32 +void test_sqrt_f32(global float* out, float a) +{ + *out = __builtin_amdgcn_sqrtf(a); +} + +// CHECK-LABEL: @test_sqrt_f64 +// CHECK: call double @llvm.amdgcn.sqrt.f64 +void test_sqrt_f64(global double* out, double a) +{ + *out = __builtin_amdgcn_sqrt(a); +} + // CHECK-LABEL: @test_rsq_f32 // CHECK: call float @llvm.amdgcn.rsq.f32 void test_rsq_f32(global float* out, float a) diff --git a/clang/test/CodeGenOpenCL/convergent.cl b/clang/test/CodeGenOpenCL/convergent.cl index 193d391ced207..49d182579e4c8 100644 --- a/clang/test/CodeGenOpenCL/convergent.cl +++ b/clang/test/CodeGenOpenCL/convergent.cl @@ -70,9 +70,9 @@ void test_merge_if(int a) { // CHECK-NOT: call spir_func void @g() // CHECK: br label %[[if_end]] // CHECK: [[if_end]]: -// CHECK: %[[tobool_pr:.+]] = phi i1 [ true, %[[if_then]] ], [ false, %{{.+}} ] +// CHECK: %[[tobool_not_pr:.+]] = phi i1 [ true, %{{.+}} ], [ false, %[[if_then]] ] // CHECK: tail call spir_func void @convfun() #[[attr4:.+]] -// CHECK: br i1 %[[tobool_pr]], label %[[if_then2:.+]], label %[[if_end3:.+]] +// CHECK: br i1 %[[tobool_not_pr]], label %[[if_end3:.+]], label %[[if_then2:.+]] // CHECK: [[if_then2]]: // CHECK: tail call spir_func void @g() // CHECK: br label %[[if_end3:.+]] diff --git a/clang/test/CodeGenOpenCL/enqueue-kernel-non-entry-block.cl b/clang/test/CodeGenOpenCL/enqueue-kernel-non-entry-block.cl index 8b5c5df2e4bae..1e8917b5324bc 100644 --- a/clang/test/CodeGenOpenCL/enqueue-kernel-non-entry-block.cl +++ b/clang/test/CodeGenOpenCL/enqueue-kernel-non-entry-block.cl @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -cl-std=CL2.0 -O0 -emit-llvm -o - -triple amdgcn < %s | FileCheck %s --check-prefixes=COMMON,AMDGPU // RUN: %clang_cc1 -cl-std=CL2.0 -O0 -emit-llvm -o - -triple "spir-unknown-unknown" < %s | FileCheck %s --check-prefixes=COMMON,SPIR32 // RUN: %clang_cc1 -cl-std=CL2.0 -O0 -emit-llvm -o - -triple "spir64-unknown-unknown" < %s | FileCheck %s --check-prefixes=COMMON,SPIR64 -// RUN: %clang_cc1 -cl-std=CL2.0 -O0 -debug-info-kind=limited -emit-llvm -o - -triple amdgcn < %s | FileCheck %s --check-prefixes=CHECK-DEBUG +// RUN: %clang_cc1 -cl-std=CL2.0 -O0 -debug-info-kind=limited -gno-column-info -emit-llvm -o - -triple amdgcn < %s | FileCheck %s --check-prefixes=CHECK-DEBUG // Check that the enqueue_kernel array temporary is in the entry block to avoid // a dynamic alloca diff --git a/clang/test/CodeGenOpenCL/func-call-dbg-loc.cl b/clang/test/CodeGenOpenCL/func-call-dbg-loc.cl index 4ed082fa9f1ce..117e69ae92dd2 100644 --- a/clang/test/CodeGenOpenCL/func-call-dbg-loc.cl +++ b/clang/test/CodeGenOpenCL/func-call-dbg-loc.cl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple amdgcn---amdgizcl -debug-info-kind=limited -O0 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple amdgcn---amdgizcl -debug-info-kind=limited -gno-column-info -O0 -emit-llvm -o - %s | FileCheck %s typedef struct { diff --git a/clang/test/CodeGenOpenCL/inline-asm-amdgcn.cl b/clang/test/CodeGenOpenCL/inline-asm-amdgcn.cl index 37090772f6646..259c12384f2c8 100644 --- a/clang/test/CodeGenOpenCL/inline-asm-amdgcn.cl +++ b/clang/test/CodeGenOpenCL/inline-asm-amdgcn.cl @@ -33,3 +33,17 @@ kernel void test_agpr() { : "={a1}"(reg_a) : "{a1}"(reg_b)); } + +kernel void test_constraint_DA() { + const long x = 0x200000001; + int res; + // CHECK: call i32 asm sideeffect "v_mov_b32 $0, $1 & 0xFFFFFFFF", "=v,^DA"(i64 8589934593) + __asm volatile("v_mov_b32 %0, %1 & 0xFFFFFFFF" : "=v"(res) : "DA"(x)); +} + +kernel void test_constraint_DB() { + const long x = 0x200000001; + int res; + // CHECK: call i32 asm sideeffect "v_mov_b32 $0, $1 & 0xFFFFFFFF", "=v,^DB"(i64 8589934593) + __asm volatile("v_mov_b32 %0, %1 & 0xFFFFFFFF" : "=v"(res) : "DB"(x)); +} diff --git a/clang/test/CodeGenOpenCL/relaxed-fpmath.cl b/clang/test/CodeGenOpenCL/relaxed-fpmath.cl index ced15f6a8f3dc..1f12392d861ba 100644 --- a/clang/test/CodeGenOpenCL/relaxed-fpmath.cl +++ b/clang/test/CodeGenOpenCL/relaxed-fpmath.cl @@ -5,6 +5,17 @@ // RUN: %clang_cc1 %s -emit-llvm -cl-mad-enable -o - | FileCheck %s -check-prefix=MAD // RUN: %clang_cc1 %s -emit-llvm -cl-no-signed-zeros -o - | FileCheck %s -check-prefix=NOSIGNED +// Check the fp options are correct with PCH. +// RUN: %clang_cc1 %s -DGEN_PCH=1 -finclude-default-header -triple spir-unknown-unknown -emit-pch -o %t.pch +// RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -o - | FileCheck %s -check-prefix=NORMAL +// RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -cl-fast-relaxed-math -o - | FileCheck %s -check-prefix=FAST +// RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -cl-finite-math-only -o - | FileCheck %s -check-prefix=FINITE +// RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -cl-unsafe-math-optimizations -o - | FileCheck %s -check-prefix=UNSAFE +// RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -cl-mad-enable -o - | FileCheck %s -check-prefix=MAD +// RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -cl-no-signed-zeros -o - | FileCheck %s -check-prefix=NOSIGNED + +#if !GEN_PCH + float spscalardiv(float a, float b) { // CHECK: @spscalardiv( @@ -53,3 +64,8 @@ float spscalardiv(float a, float b) { // NOSIGNED: "no-nans-fp-math"="false" // NOSIGNED: "no-signed-zeros-fp-math"="true" // NOSIGNED: "unsafe-fp-math"="false" + +#else +// Undefine this to avoid putting it in the PCH. +#undef GEN_PCH +#endif diff --git a/clang/test/CoverageMapping/coroutine.cpp b/clang/test/CoverageMapping/coroutine.cpp new file mode 100644 index 0000000000000..dc9473348fc90 --- /dev/null +++ b/clang/test/CoverageMapping/coroutine.cpp @@ -0,0 +1,47 @@ +// fixme: the following line is added to cleanup bots, will be removed in weeks. +// RUN: rm -f %S/coroutine.ll +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcoroutines-ts -std=c++14 -emit-llvm -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping %s -o - | FileCheck %s + +namespace std::experimental { +template +struct coroutine_traits; + +template +struct coroutine_handle { + coroutine_handle() = default; + static coroutine_handle from_address(void *) noexcept { return {}; } +}; +template <> +struct coroutine_handle { + static coroutine_handle from_address(void *) { return {}; } + coroutine_handle() = default; + template + coroutine_handle(coroutine_handle) noexcept {} +}; +} // namespace std::experimental + +struct suspend_always { + bool await_ready() noexcept; + void await_suspend(std::experimental::coroutine_handle<>) noexcept; + void await_resume() noexcept; +}; + +template <> +struct std::experimental::coroutine_traits { + struct promise_type { + int get_return_object(); + suspend_always initial_suspend(); + suspend_always final_suspend() noexcept; + void return_value(int); + }; +}; + +// CHECK-LABEL: _Z2f1i: +int f1(int x) { // CHECK-NEXT: File 0, [[@LINE]]:15 -> [[@LINE+7]]:2 = #0 + if (x > 42) { // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:13 = #0 + ++x; // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:14 -> [[@LINE-1]]:15 = #1 + } else { // CHECK-NEXT: File 0, [[@LINE-2]]:15 -> [[@LINE]]:4 = #1 + co_return x + 42; // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:4 -> [[@LINE-1]]:10 = (#0 - #1) + } // CHECK-NEXT: File 0, [[@LINE-2]]:10 -> [[@LINE]]:4 = (#0 - #1) + co_return x; // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:4 -> [[@LINE]]:3 = #1 +} // CHECK-NEXT: File 0, [[@LINE-1]]:3 -> [[@LINE]]:2 = #1 diff --git a/clang/test/CoverageMapping/preprocessor.c b/clang/test/CoverageMapping/preprocessor.c index b3ebc7bd4ec06..9225c9f162a20 100644 --- a/clang/test/CoverageMapping/preprocessor.c +++ b/clang/test/CoverageMapping/preprocessor.c @@ -3,7 +3,7 @@ // CHECK: func void func() { // CHECK: File 0, [[@LINE]]:13 -> [[@LINE+5]]:2 = #0 int i = 0; -#ifdef MACRO // CHECK-NEXT: Skipped,File 0, [[@LINE]]:1 -> [[@LINE+3]]:1 = 0 +#ifdef MACRO // CHECK-NEXT: Skipped,File 0, [[@LINE]]:1 -> [[@LINE+2]]:7 = 0 int x = i; #endif } @@ -11,7 +11,7 @@ void func() { // CHECK: File 0, [[@LINE]]:13 -> [[@LINE+5]]:2 = #0 // CHECK: main int main() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> {{[0-9]+}}:2 = #0 int i = 0; -# if 0 // CHECK-NEXT: Skipped,File 0, [[@LINE]]:1 -> [[@LINE+5]]:1 = 0 +# if 0 // CHECK-NEXT: Skipped,File 0, [[@LINE]]:1 -> [[@LINE+4]]:29 = 0 if(i == 0) { i = 1; } @@ -22,44 +22,44 @@ int main() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> {{[0-9]+}}:2 = #0 if(i == 0) { // CHECK: File 0, [[@LINE]]:14 -> [[@LINE+2]]:4 = #1 i = 1; } -#else // CHECK-NEXT: Skipped,File 0, [[@LINE]]:1 -> [[@LINE+6]]:1 = 0 +#else // CHECK-NEXT: Skipped,File 0, [[@LINE]]:1 -> [[@LINE+5]]:7 = 0 if(i == 1) { i = 0; } } #endif - // CHECK-NEXT: Skipped,File 0, [[@LINE+1]]:1 -> [[@LINE+5]]:1 + // CHECK-NEXT: Skipped,File 0, [[@LINE+1]]:1 -> [[@LINE+4]]:24 #\ if 0 #\ endif // also skipped #if 1 - // CHECK-NEXT: Skipped,File 0, [[@LINE+1]]:1 -> [[@LINE+4]]:1 + // CHECK-NEXT: Skipped,File 0, [[@LINE+1]]:1 -> [[@LINE+3]]:7 #\ elif 0 #endif #if 1 - // CHECK-NEXT: Skipped,File 0, [[@LINE+1]]:1 -> [[@LINE+4]]:1 + // CHECK-NEXT: Skipped,File 0, [[@LINE+1]]:1 -> [[@LINE+3]]:7 #\ else #endif - // CHECK-NEXT: Skipped,File 0, [[@LINE+1]]:1 -> [[@LINE+5]]:1 + // CHECK-NEXT: Skipped,File 0, [[@LINE+1]]:1 -> [[@LINE+4]]:8 #\ ifdef NOT_DEFINED #\ endif - // CHECK-NEXT: Skipped,File 0, [[@LINE+1]]:1 -> [[@LINE+5]]:1 + // CHECK-NEXT: Skipped,File 0, [[@LINE+1]]:1 -> [[@LINE+4]]:8 #\ ifndef __FILE__ #\ endif - // CHECK-NEXT: Skipped,File 0, [[@LINE+1]]:1 -> [[@LINE+7]]:1 + // CHECK-NEXT: Skipped,File 0, [[@LINE+1]]:1 -> [[@LINE+6]]:26 #\ ifdef NOT_DEFINED #\ diff --git a/clang/test/Driver/Inputs/rocm/bin/.hipVersion b/clang/test/Driver/Inputs/rocm/bin/.hipVersion new file mode 100644 index 0000000000000..48ee6f10c3e4e --- /dev/null +++ b/clang/test/Driver/Inputs/rocm/bin/.hipVersion @@ -0,0 +1,4 @@ +# Auto-generated by cmake +HIP_VERSION_MAJOR=3 +HIP_VERSION_MINOR=6 +HIP_VERSION_PATCH=20214-a2917cd diff --git a/clang/test/Driver/aarch64-cpus.c b/clang/test/Driver/aarch64-cpus.c index f774e5c4d8db2..f39241bee8a6d 100644 --- a/clang/test/Driver/aarch64-cpus.c +++ b/clang/test/Driver/aarch64-cpus.c @@ -171,6 +171,13 @@ // ARM64-CORTEX-A76: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "cortex-a76" // ARM64-CORTEX-A76-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic" +// RUN: %clang -target aarch64 -mcpu=cortex-a77 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A77 %s +// CORTEX-A77: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a77" +// RUN: %clang -target aarch64 -mcpu=cortex-x1 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEXX1 %s +// CORTEXX1: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-x1" +// RUN: %clang -target aarch64 -mcpu=cortex-a78 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEXA78 %s +// CORTEXA78: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a78" + // RUN: %clang -target aarch64_be -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3 %s // RUN: %clang -target aarch64 -mbig-endian -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3 %s // RUN: %clang -target aarch64_be -mbig-endian -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3 %s diff --git a/clang/test/Driver/aix-object-mode.c b/clang/test/Driver/aix-object-mode.c new file mode 100644 index 0000000000000..a4bc79a4b41d5 --- /dev/null +++ b/clang/test/Driver/aix-object-mode.c @@ -0,0 +1,22 @@ +// Check that setting an OBJECT_MODE converts the AIX triple to the right variant. +// RUN: env OBJECT_MODE=64 \ +// RUN: %clang -target powerpc-ibm-aix -print-target-triple | FileCheck -check-prefix=CHECK64 %s + +// RUN: env OBJECT_MODE=32 \ +// RUN: %clang -target powerpc64-ibm-aix -print-target-triple | FileCheck -check-prefix=CHECK32 %s + +// Command-line options win. +// RUN: env OBJECT_MODE=64 \ +// RUN: %clang -target powerpc64-ibm-aix -print-target-triple -m32 | FileCheck -check-prefix=CHECK32 %s + +// RUN: env OBJECT_MODE=32 \ +// RUN: %clang -target powerpc-ibm-aix -print-target-triple -m64 | FileCheck -check-prefix=CHECK64 %s + +// CHECK32: powerpc-ibm-aix +// CHECK64: powerpc64-ibm-aix + +// Emit a diagnostic if there is an invalid mode. +// RUN: env OBJECT_MODE=31 \ +// RUN: not %clang -target powerpc-ibm-aix 2>&1 | FileCheck -check-prefix=DIAG %s + +// DIAG: error: OBJECT_MODE setting 31 is not recognized and is not a valid setting. diff --git a/clang/test/Driver/aix-toolchain-include.cpp b/clang/test/Driver/aix-toolchain-include.cpp new file mode 100644 index 0000000000000..dc8b272936a48 --- /dev/null +++ b/clang/test/Driver/aix-toolchain-include.cpp @@ -0,0 +1,136 @@ +// Tests that the AIX toolchain adds system includes to its search path. + +// Check powerpc-ibm-aix, 32-bit/64-bit. +// RUN: %clangxx -### -no-canonical-prefixes %s 2>&1 \ +// RUN: -target powerpc-ibm-aix \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_aix_tree \ +// RUN: | FileCheck -check-prefix=CHECK-INTERNAL-INCLUDE %s + +// RUN: %clangxx -### -no-canonical-prefixes %s 2>&1 \ +// RUN: -target powerpc64-ibm-aix \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_aix_tree \ +// RUN: | FileCheck -check-prefix=CHECK-INTERNAL-INCLUDE %s + +// RUN: %clang -### -xc -no-canonical-prefixes %s 2>&1 \ +// RUN: -target powerpc-ibm-aix \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_aix_tree \ +// RUN: | FileCheck -check-prefix=CHECK-INTERNAL-INCLUDE %s + +// RUN: %clang -### -xc -no-canonical-prefixes %s 2>&1 \ +// RUN: -target powerpc64-ibm-aix \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_aix_tree \ +// RUN: | FileCheck -check-prefix=CHECK-INTERNAL-INCLUDE %s + +// CHECK-INTERNAL-INCLUDE: {{.*}}clang{{.*}}" "-cc1" +// CHECK-INTERNAL-INCLUDE: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-INTERNAL-INCLUDE: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-INTERNAL-INCLUDE: "-internal-isystem" "[[RESOURCE_DIR]]{{(/|\\\\)}}include" +// CHECK-INTERNAL-INCLUDE: "-internal-isystem" "[[SYSROOT]]/usr/include" + +// Check powerpc-ibm-aix, 32-bit/64-bit. -nostdinc option. +// RUN: %clangxx -### -no-canonical-prefixes %s 2>&1 \ +// RUN: -target powerpc-ibm-aix \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_aix_tree \ +// RUN: -nostdinc \ +// RUN: | FileCheck -check-prefix=CHECK-NOSTDINC-INCLUDE %s + +// RUN: %clangxx -### -no-canonical-prefixes %s 2>&1 \ +// RUN: -target powerpc64-ibm-aix \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_aix_tree \ +// RUN: -nostdinc \ +// RUN: | FileCheck -check-prefix=CHECK-NOSTDINC-INCLUDE %s + +// RUN: %clang -### -xc -no-canonical-prefixes %s 2>&1 \ +// RUN: -target powerpc-ibm-aix \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_aix_tree \ +// RUN: -nostdinc \ +// RUN: | FileCheck -check-prefix=CHECK-NOSTDINC-INCLUDE %s + +// RUN: %clang -### -xc -no-canonical-prefixes %s 2>&1 \ +// RUN: -target powerpc64-ibm-aix \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_aix_tree \ +// RUN: -nostdinc \ +// RUN: | FileCheck -check-prefix=CHECK-NOSTDINC-INCLUDE %s + +// CHECK-NOSTDINC-INCLUDE: {{.*}}clang{{.*}}" "-cc1" +// CHECK-NOSTDINC-INCLUDE: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-NOSTDINC-INCLUDE: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-NOSTDINC-INCLUDE-NOT: "-internal-isystem" + +// Check powerpc-ibm-aix, 32-bit/64-bit. -nostdlibinc option. +// RUN: %clangxx -### -no-canonical-prefixes %s 2>&1 \ +// RUN: -target powerpc-ibm-aix \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_aix_tree \ +// RUN: -nostdlibinc \ +// RUN: | FileCheck -check-prefix=CHECK-NOSTDLIBINC-INCLUDE %s + +// RUN: %clangxx -### -no-canonical-prefixes %s 2>&1 \ +// RUN: -target powerpc64-ibm-aix \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_aix_tree \ +// RUN: -nostdlibinc \ +// RUN: | FileCheck -check-prefix=CHECK-NOSTDLIBINC-INCLUDE %s + +// RUN: %clang -### -xc -no-canonical-prefixes %s 2>&1 \ +// RUN: -target powerpc-ibm-aix \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_aix_tree \ +// RUN: -nostdlibinc \ +// RUN: | FileCheck -check-prefix=CHECK-NOSTDLIBINC-INCLUDE %s + +// RUN: %clang -### -xc -no-canonical-prefixes %s 2>&1 \ +// RUN: -target powerpc64-ibm-aix \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_aix_tree \ +// RUN: -nostdlibinc \ +// RUN: | FileCheck -check-prefix=CHECK-NOSTDLIBINC-INCLUDE %s + +// CHECK-NOSTDLIBINC-INCLUDE: {{.*}}clang{{.*}}" "-cc1" +// CHECK-NOSTDLIBINC-INCLUDE: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-NOSTDLIBINC-INCLUDE: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-NOSTDLIBINC-INCLUDE: "-internal-isystem" "[[RESOURCE_DIR]]{{(/|\\\\)}}include" +// CHECK-NOSTDLIBINC-INCLUDE-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include" + +// Check powerpc-ibm-aix, 32-bit/64-bit. -nobuiltininc option. +// RUN: %clangxx -### -no-canonical-prefixes %s 2>&1 \ +// RUN: -target powerpc-ibm-aix \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_aix_tree \ +// RUN: -nobuiltininc \ +// RUN: | FileCheck -check-prefix=CHECK-NOBUILTININC-INCLUDE %s + +// RUN: %clangxx -### -no-canonical-prefixes %s 2>&1 \ +// RUN: -target powerpc64-ibm-aix \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_aix_tree \ +// RUN: -nobuiltininc \ +// RUN: | FileCheck -check-prefix=CHECK-NOBUILTININC-INCLUDE %s + +// RUN: %clang -### -xc -no-canonical-prefixes %s 2>&1 \ +// RUN: -target powerpc-ibm-aix \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_aix_tree \ +// RUN: -nobuiltininc \ +// RUN: | FileCheck -check-prefix=CHECK-NOBUILTININC-INCLUDE %s + +// RUN: %clang -### -xc -no-canonical-prefixes %s 2>&1 \ +// RUN: -target powerpc64-ibm-aix \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_aix_tree \ +// RUN: -nobuiltininc \ +// RUN: | FileCheck -check-prefix=CHECK-NOBUILTININC-INCLUDE %s + +// CHECK-NOBUILTININC-INCLUDE: {{.*}}clang{{.*}}" "-cc1" +// CHECK-NOBUILTININC-INCLUDE: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-NOBUILTININC-INCLUDE: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-NOBUILTININC-INCLUDE-NOT: "-internal-isystem" "[[RESOURCE_DIR]]{{(/|\\\\)}}include" +// CHECK-NOBUILTININC-INCLUDE: "-internal-isystem" "[[SYSROOT]]/usr/include" diff --git a/clang/test/Driver/apple-arm64-arch.c b/clang/test/Driver/apple-arm64-arch.c new file mode 100644 index 0000000000000..a37346b1a9bb0 --- /dev/null +++ b/clang/test/Driver/apple-arm64-arch.c @@ -0,0 +1,7 @@ +// RUN: env SDKROOT="/" %clang -arch arm64 -c -### %s 2>&1 | \ +// RUN: FileCheck %s +// +// REQUIRES: system-darwin +// XFAIL: apple-silicon-mac +// +// CHECK: "-triple" "arm64-apple-ios{{[0-9.]+}}" diff --git a/clang/test/Driver/apple-silicon-arch.c b/clang/test/Driver/apple-silicon-arch.c new file mode 100644 index 0000000000000..b1201fa2d7ddb --- /dev/null +++ b/clang/test/Driver/apple-silicon-arch.c @@ -0,0 +1,6 @@ +// RUN: env SDKROOT="/" %clang -arch arm64 -c -### %s 2>&1 | \ +// RUN: FileCheck %s +// +// REQUIRES: apple-silicon-mac +// +// CHECK: "-triple" "arm64-apple-macosx{{[0-9.]+}}" diff --git a/clang/test/Driver/arclite-link.c b/clang/test/Driver/arclite-link.c index 2cc0271fc0222..a53b12daa47bd 100644 --- a/clang/test/Driver/arclite-link.c +++ b/clang/test/Driver/arclite-link.c @@ -15,3 +15,6 @@ // RUN: %clang -### -target x86_64-apple-darwin10 -fobjc-link-runtime -fobjc-arc -mmacosx-version-min=10.10 %s 2>&1 | FileCheck -check-prefix=CHECK-UNUSED %s // CHECK-UNUSED-NOT: warning: argument unused during compilation: '-fobjc-link-runtime' + +// RUN: %clang -### -target arm64-apple-macos10.8 -fobjc-link-runtime %t.o 2>&1 | FileCheck -check-prefix=CHECK-ARCLITE-ARM-MAC %s +// CHECK-ARCLITE-ARM-MAC-NOT: libarclite diff --git a/clang/test/Driver/arm-cortex-cpus.c b/clang/test/Driver/arm-cortex-cpus.c index c1ce9c08ca874..6de1040e94204 100644 --- a/clang/test/Driver/arm-cortex-cpus.c +++ b/clang/test/Driver/arm-cortex-cpus.c @@ -686,10 +686,12 @@ // RUN: %clang -target arm -mcpu=cortex-a75 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s // RUN: %clang -target arm -mcpu=cortex-a76 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s // RUN: %clang -target arm -mcpu=cortex-a76ae -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s +// RUN: %clang -target arm -mcpu=cortex-a77 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s // RUN: %clang -target arm -mcpu=cortex-a55 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s // RUN: %clang -target arm -mcpu=cortex-a75 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s // RUN: %clang -target arm -mcpu=cortex-a76 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s // RUN: %clang -target arm -mcpu=cortex-a76ae -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s +// RUN: %clang -target arm -mcpu=cortex-a77 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s // // RUN: %clang -target arm -mcpu=exynos-m4 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s // RUN: %clang -target arm -mcpu=exynos-m4 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s @@ -718,10 +720,12 @@ // RUN: %clang -target armeb -mcpu=cortex-a75 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s // RUN: %clang -target armeb -mcpu=cortex-a76 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s // RUN: %clang -target armeb -mcpu=cortex-a76ae -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s +// RUN: %clang -target armeb -mcpu=cortex-a77 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s // RUN: %clang -target arm -mcpu=cortex-a55 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s // RUN: %clang -target arm -mcpu=cortex-a75 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s // RUN: %clang -target arm -mcpu=cortex-a76 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s // RUN: %clang -target arm -mcpu=cortex-a76ae -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s +// RUN: %clang -target arm -mcpu=cortex-a77 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s // // RUN: %clang -target armeb -mcpu=exynos-m4 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s // RUN: %clang -target arm -mcpu=exynos-m4 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s @@ -753,10 +757,12 @@ // RUN: %clang -target arm -mcpu=cortex-a75 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s // RUN: %clang -target arm -mcpu=cortex-a76 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s // RUN: %clang -target arm -mcpu=cortex-a76ae -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s +// RUN: %clang -target arm -mcpu=cortex-a77 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s // RUN: %clang -target arm -mcpu=cortex-a55 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s // RUN: %clang -target arm -mcpu=cortex-a75 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s // RUN: %clang -target arm -mcpu=cortex-a76 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s // RUN: %clang -target arm -mcpu=cortex-a76ae -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s +// RUN: %clang -target arm -mcpu=cortex-a77 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s // // RUN: %clang -target arm -mcpu=exynos-m4 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s // RUN: %clang -target arm -mcpu=exynos-m4 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s @@ -785,10 +791,12 @@ // RUN: %clang -target armeb -mcpu=cortex-a75 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s // RUN: %clang -target armeb -mcpu=cortex-a76 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s // RUN: %clang -target armeb -mcpu=cortex-a76ae -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s +// RUN: %clang -target armeb -mcpu=cortex-a77 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s // RUN: %clang -target arm -mcpu=cortex-a55 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s // RUN: %clang -target arm -mcpu=cortex-a75 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s // RUN: %clang -target arm -mcpu=cortex-a76 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s // RUN: %clang -target arm -mcpu=cortex-a76ae -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s +// RUN: %clang -target arm -mcpu=cortex-a77 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s // // RUN: %clang -target armeb -mcpu=exynos-m4 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s // RUN: %clang -target arm -mcpu=exynos-m4 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s @@ -832,6 +840,18 @@ // CHECK-CORTEX-A76AE-SOFT: "-target-feature" "+soft-float" // CHECK-CORTEX-A76AE-SOFT: "-target-feature" "+soft-float-abi" +// RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-x1 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-X1 %s +// RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-x1 -mfpu=crypto-neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-X1-MFPU %s +// CHECK-CORTEX-X1: "-cc1"{{.*}} "-triple" "armv8.2a-{{.*}} "-target-cpu" "cortex-x1" +// CHECK-CORTEX-X1-MFPU: "-cc1"{{.*}} "-target-feature" "+fp-armv8" +// CHECK-CORTEX-X1-MFPU: "-target-feature" "+crypto" + +// RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a78 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A78 %s +// RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a78 -mfpu=crypto-neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A78-MFPU %s +// CHECK-CORTEX-A78: "-cc1"{{.*}} "-triple" "armv8.2a-{{.*}} "-target-cpu" "cortex-a78" +// CHECK-CORTEX-A78-MFPU: "-cc1"{{.*}} "-target-feature" "+fp-armv8" +// CHECK-CORTEX-A78-MFPU: "-target-feature" "+crypto" + // RUN: %clang -target arm -mcpu=cortex-m23 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8MBASE %s // CHECK-CPUV8MBASE: "-cc1"{{.*}} "-triple" "thumbv8m.base- diff --git a/clang/test/Driver/bindings.c b/clang/test/Driver/bindings.c index 880667b739348..d7f323419d39e 100644 --- a/clang/test/Driver/bindings.c +++ b/clang/test/Driver/bindings.c @@ -23,3 +23,7 @@ // CHECK14: "clang", inputs: ["{{.*}}bindings.c"], output: "{{.*}}.s" // CHECK14: "darwin::Assembler", inputs: ["{{.*}}.s"], output: "{{.*}}.o" // CHECK14: "darwin::Linker", inputs: ["{{.*}}.o"], output: "a.out" + +// GNU StaticLibTool binding +// RUN: %clang -target x86_64-linux-gnu -ccc-print-bindings --emit-static-lib %s 2>&1 | FileCheck %s --check-prefix=CHECK15 +// CHECK15: "x86_64-unknown-linux-gnu" - "GNU::StaticLibTool", inputs: ["{{.*}}.o"], output: "a.out" diff --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c index 848a532b24f93..0dcaf61088069 100644 --- a/clang/test/Driver/cl-options.c +++ b/clang/test/Driver/cl-options.c @@ -56,15 +56,6 @@ // fpstrict-NOT: -menable-unsafe-fp-math // fpstrict-NOT: -ffast-math -// RUN: %clang_cl /Z7 -gcolumn-info -### -- %s 2>&1 | FileCheck -check-prefix=gcolumn %s -// gcolumn: -dwarf-column-info - -// RUN: %clang_cl /Z7 -gno-column-info -### -- %s 2>&1 | FileCheck -check-prefix=gnocolumn %s -// gnocolumn-NOT: -dwarf-column-info - -// RUN: %clang_cl /Z7 -### -- %s 2>&1 | FileCheck -check-prefix=gdefcolumn %s -// gdefcolumn-NOT: -dwarf-column-info - // RUN: %clang_cl -### /FA -fprofile-instr-generate -- %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-INSTR-GENERATE %s // RUN: %clang_cl -### /FA -fprofile-instr-generate=/tmp/somefile.profraw -- %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-INSTR-GENERATE-FILE %s // CHECK-PROFILE-INSTR-GENERATE: "-fprofile-instrument=clang" "--dependent-lib=clang_rt.profile-{{[^"]*}}.lib" @@ -533,11 +524,11 @@ // RUN: %clang_cl /Zi /c -### -- %s 2>&1 | FileCheck -check-prefix=Zi %s // Zi: "-gcodeview" -// Zi: "-debug-info-kind=limited" +// Zi: "-debug-info-kind=constructor" // RUN: %clang_cl /Z7 /c -### -- %s 2>&1 | FileCheck -check-prefix=Z7 %s // Z7: "-gcodeview" -// Z7: "-debug-info-kind=limited" +// Z7: "-debug-info-kind=constructor" // RUN: %clang_cl /Zd /c -### -- %s 2>&1 | FileCheck -check-prefix=Z7GMLT %s // Z7GMLT: "-gcodeview" @@ -566,7 +557,7 @@ // which made it "win". This test could not detect that bug. // RUN: %clang_cl /Z7 -gdwarf /c -### -- %s 2>&1 | FileCheck -check-prefix=Z7_gdwarf %s // Z7_gdwarf: "-gcodeview" -// Z7_gdwarf: "-debug-info-kind=limited" +// Z7_gdwarf: "-debug-info-kind=constructor" // Z7_gdwarf: "-dwarf-version=4" // RUN: %clang_cl -fmsc-version=1800 -TP -### -- %s 2>&1 | FileCheck -check-prefix=CXX11 %s diff --git a/clang/test/Driver/clang-g-opts.c b/clang/test/Driver/clang-g-opts.c index bc714b6c93791..60c97790b7dae 100644 --- a/clang/test/Driver/clang-g-opts.c +++ b/clang/test/Driver/clang-g-opts.c @@ -31,7 +31,7 @@ // RUN: | FileCheck --check-prefix=CHECK-WITH-G-DWARF2 %s // CHECK-WITHOUT-G-NOT: -debug-info-kind -// CHECK-WITH-G: "-debug-info-kind=limited" +// CHECK-WITH-G: "-debug-info-kind=constructor" // CHECK-WITH-G: "-dwarf-version=4" // CHECK-WITH-G-DWARF2: "-dwarf-version=2" diff --git a/clang/test/Driver/codeview-column-info.c b/clang/test/Driver/codeview-column-info.c index 6b524accd7b70..4cabefac06e64 100644 --- a/clang/test/Driver/codeview-column-info.c +++ b/clang/test/Driver/codeview-column-info.c @@ -1,4 +1,4 @@ -// Check that -dwarf-column-info does not get added to the cc1 line: +// Check that -gno-column-info gets added to the cc1 line: // 1) When -gcodeview is present via the clang or clang++ driver // 2) When /Z7 is present via the cl driver. @@ -11,5 +11,8 @@ // RUN: %clang_cl -### --target=x86_64-windows-msvc /c /Z7 -- %s 2> %t2 // RUN: FileCheck < %t2 %s -// CHECK: "-cc1" -// CHECK-NOT: "-dwarf-column-info" +// CHECK: "-gno-column-info" + +// RUN: %clang_cl -### /Z7 -gcolumn-info -- %s 2>&1 | FileCheck --check-prefix=COLUMN %s + +// COLUMN-NOT: "-gno-column-info" diff --git a/clang/test/Driver/crash-report-crashfile.m b/clang/test/Driver/crash-report-crashfile.m index 980b1acd9fed7..fd26246073faa 100644 --- a/clang/test/Driver/crash-report-crashfile.m +++ b/clang/test/Driver/crash-report-crashfile.m @@ -18,6 +18,7 @@ const int x = MODULE_MACRO; // CRASH_ENV: failing because environment variable 'FORCE_CLANG_DIAGNOSTICS_CRASH' is set +// CRASH_ENV: PLEASE submit a bug report to {{.*}} and include the crash backtrace, preprocessed source, and associated run script. // CRASH_ENV: Preprocessed source(s) and associated run script(s) are located at: // CRASH_ENV-NEXT: note: diagnostic msg: {{.*}}.m // CRASH_ENV-NEXT: note: diagnostic msg: {{.*}}.cache diff --git a/clang/test/Driver/crash-report-modules.m b/clang/test/Driver/crash-report-modules.m index ded31b4ed4fed..e6d0335337910 100644 --- a/clang/test/Driver/crash-report-modules.m +++ b/clang/test/Driver/crash-report-modules.m @@ -19,6 +19,7 @@ @import simple; const int x = MODULE_MACRO; +// CHECK: PLEASE submit a bug report to {{.*}} and include the crash backtrace, preprocessed source, and associated run script. // CHECK: Preprocessed source(s) and associated run script(s) are located at: // CHECK-NEXT: note: diagnostic msg: {{.*}}.m // CHECK-NEXT: note: diagnostic msg: {{.*}}.cache diff --git a/clang/test/Driver/crash-report-null.test b/clang/test/Driver/crash-report-null.test index 7281f5309eb33..05309bf63f275 100644 --- a/clang/test/Driver/crash-report-null.test +++ b/clang/test/Driver/crash-report-null.test @@ -3,5 +3,6 @@ // FIXME: Investigating. "fatal error: file 'nul' modified since it was first processed" // XFAIL: windows-gnu +// CHECK: PLEASE submit a bug report to {{.*}} and include the crash backtrace, preprocessed source, and associated run script. // CHECK: Preprocessed source(s) and associated run script(s) are located at: // CHECK-NEXT: note: diagnostic msg: {{.*}}null-{{.*}}.c diff --git a/clang/test/Driver/cuda-dwarf-2.cu b/clang/test/Driver/cuda-dwarf-2.cu index bcfb2444bc516..92b8919729fc4 100644 --- a/clang/test/Driver/cuda-dwarf-2.cu +++ b/clang/test/Driver/cuda-dwarf-2.cu @@ -49,7 +49,7 @@ // HAS_DEBUG-NOT: warning: debug // HAS_DEBUG: "-fcuda-is-device" -// HAS_DEBUG-SAME: "-debug-info-kind={{limited|line-tables-only}}" +// HAS_DEBUG-SAME: "-debug-info-kind={{constructor|line-tables-only}}" // HAS_DEBUG-SAME: "-dwarf-version=2" // HAS_DEBUG: ptxas // HAS_DEBUG-SAME: "-g" diff --git a/clang/test/Driver/darwin-ld-platform-version-macos.c b/clang/test/Driver/darwin-ld-platform-version-macos.c index c1b940a3f35f3..d3f49093ef868 100644 --- a/clang/test/Driver/darwin-ld-platform-version-macos.c +++ b/clang/test/Driver/darwin-ld-platform-version-macos.c @@ -7,9 +7,22 @@ // RUN: env SDKROOT=%S/Inputs/MacOSX10.14.sdk %clang -target x86_64-apple-macos10.13.0.1 -mlinker-version=520 -### %t.o 2>&1 \ // RUN: | FileCheck --check-prefix=LINKER-NEW %s +// RUN: %clang -target arm64-apple-macos10.13 -isysroot %S/Inputs/MacOSX10.14.sdk -mlinker-version=520 -### %t.o 2>&1 \ +// RUN: | FileCheck --check-prefix=ARM64_NEW %s +// RUN: %clang -target arm64-apple-darwin19 -isysroot %S/Inputs/MacOSX10.14.sdk -mlinker-version=520 -### %t.o 2>&1 \ +// RUN: | FileCheck --check-prefix=ARM64_NEW %s +// RUN: %clang -target arm64-apple-macos11.1 -isysroot %S/Inputs/MacOSX10.14.sdk -mlinker-version=520 -### %t.o 2>&1 \ +// RUN: | FileCheck --check-prefix=ARM64_NEW_1 %s +// RUN: %clang -target arm64-apple-macos10.13 -isysroot %S/Inputs/MacOSX10.14.sdk -mlinker-version=400 -### %t.o 2>&1 \ +// RUN: | FileCheck --check-prefix=ARM64_OLD %s + // LINKER-OLD: "-macosx_version_min" "10.13.0" // LINKER-NEW: "-platform_version" "macos" "10.13.0" "10.14" +// ARM64_NEW: "-platform_version" "macos" "11.0.0" "10.14" +// ARM64_NEW_1: "-platform_version" "macos" "11.1.0" "10.14" +// ARM64_OLD: "-macosx_version_min" "11.0.0" + // RUN: %clang -target x86_64-apple-macos10.13 -mlinker-version=520 -### %t.o 2>&1 \ // RUN: | FileCheck --check-prefix=NOSDK %s // NOSDK: "-platform_version" "macos" "10.13.0" "0.0.0" diff --git a/clang/test/Driver/darwin-sdk-vs-os-version.c b/clang/test/Driver/darwin-sdk-vs-os-version.c index 391f4d5a73052..94e52a9036ede 100644 --- a/clang/test/Driver/darwin-sdk-vs-os-version.c +++ b/clang/test/Driver/darwin-sdk-vs-os-version.c @@ -2,9 +2,9 @@ // Ensure that we never pick a version that's based on the SDK that's newer than // the system version: -// RUN: rm -rf %t/SDKs/MacOSX10.99.99.sdk -// RUN: mkdir -p %t/SDKs/MacOSX10.99.99.sdk -// RUN: %clang -target x86_64-apple-darwin -isysroot %t/SDKs/MacOSX10.99.99.sdk %s -### 2>&1 \ +// RUN: rm -rf %t/SDKs/MacOSX99.99.99.sdk +// RUN: mkdir -p %t/SDKs/MacOSX99.99.99.sdk +// RUN: %clang -target x86_64-apple-darwin -isysroot %t/SDKs/MacOSX99.99.99.sdk %s -### 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-MACOSX-SYSTEM-VERSION %s -// CHECK-MACOSX-SYSTEM-VERSION-NOT: 10.99.99" +// CHECK-MACOSX-SYSTEM-VERSION-NOT: 99.99.99" diff --git a/clang/test/Driver/darwin-version.c b/clang/test/Driver/darwin-version.c index 7885b59646266..3471552c937f2 100644 --- a/clang/test/Driver/darwin-version.c +++ b/clang/test/Driver/darwin-version.c @@ -305,3 +305,13 @@ // RUN: %clang -target armv7k-apple-ios10.1-simulator -c %s -### 2>&1 | \ // RUN: FileCheck --check-prefix=CHECK-VERSION-TENV-SIM2 %s // CHECK-VERSION-TENV-SIM2: "thumbv7k-apple-ios10.1.0-simulator" + + +// RUN: %clang -target x86_64-apple-macos11 -c %s -### 2>&1 | \ +// RUN: FileCheck --check-prefix=CHECK-MACOS11 %s +// RUN: %clang -target x86_64-apple-darwin20 -c %s -### 2>&1 | \ +// RUN: FileCheck --check-prefix=CHECK-MACOS11 %s +// RUN: %clang -target x86_64-apple-darwin -mmacos-version-min=11 -c %s -### 2>&1 | \ +// RUN: FileCheck --check-prefix=CHECK-MACOS11 %s + +// CHECK-MACOS11: "x86_64-apple-macosx11.0.0" diff --git a/clang/test/Driver/darwin-warning-options.c b/clang/test/Driver/darwin-warning-options.c new file mode 100644 index 0000000000000..b0a591eac8204 --- /dev/null +++ b/clang/test/Driver/darwin-warning-options.c @@ -0,0 +1,7 @@ +// REQUIRES: system-darwin + +// Always error about undefined 'TARGET_OS_*' macros on Darwin. +// RUN: %clang -### %s 2>&1 | FileCheck %s + +// CHECK-DAG: "-Wundef-prefix=TARGET_OS_" +// CHECK-DAG: "-Werror=undef-prefix" diff --git a/clang/test/Driver/debug-options-as.c b/clang/test/Driver/debug-options-as.c index 51475680e9b18..4808219702e76 100644 --- a/clang/test/Driver/debug-options-as.c +++ b/clang/test/Driver/debug-options-as.c @@ -23,7 +23,7 @@ // RUN: | FileCheck %s // // CHECK: "-cc1as" -// CHECK: "-debug-info-kind=limited" +// CHECK: "-debug-info-kind=constructor" // Check to make sure clang with -g on a .s file gets passed -dwarf-debug-producer. // rdar://12955296 diff --git a/clang/test/Driver/debug-options.c b/clang/test/Driver/debug-options.c index 1dd95db4b92ab..2d1a0b2d5cd8f 100644 --- a/clang/test/Driver/debug-options.c +++ b/clang/test/Driver/debug-options.c @@ -274,18 +274,18 @@ // GLIO_ONLY_DWARF2: "-dwarf-version=2" // // G_ONLY: "-cc1" -// G_ONLY: "-debug-info-kind=limited" +// G_ONLY: "-debug-info-kind=constructor" // // These tests assert that "-gline-tables-only" "-g" uses the latter, // but otherwise not caring about the DebugInfoKind. // G_ONLY_DWARF2: "-cc1" -// G_ONLY_DWARF2: "-debug-info-kind={{standalone|limited}}" +// G_ONLY_DWARF2: "-debug-info-kind={{standalone|constructor}}" // G_ONLY_DWARF2: "-dwarf-version=2" // // G_STANDALONE: "-cc1" // G_STANDALONE: "-debug-info-kind=standalone" // G_LIMITED: "-cc1" -// G_LIMITED: "-debug-info-kind=limited" +// G_LIMITED: "-debug-info-kind=constructor" // G_DWARF2: "-dwarf-version=2" // G_DWARF4: "-dwarf-version=4" // @@ -334,12 +334,12 @@ // NOFDTS-NOT: "-mllvm" "-generate-type-units" // NOFDTSE-NOT: error: unsupported option '-fdebug-types-section' for target 'x86_64-apple-darwin' // -// CI: "-dwarf-column-info" +// CI-NOT: "-gno-column-info" // -// NOCI-NOT: "-dwarf-column-info" +// NOCI: "-gno-column-info" // // GEXTREFS: "-dwarf-ext-refs" "-fmodule-format=obj" -// GEXTREFS: "-debug-info-kind={{standalone|limited}}" +// GEXTREFS: "-debug-info-kind={{standalone|constructor}}" // RUN: not %clang -cc1 -debug-info-kind=watkind 2>&1 | FileCheck -check-prefix=BADSTRING1 %s // BADSTRING1: error: invalid value 'watkind' in '-debug-info-kind=watkind' diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c index 9ff2bdf58d6cd..7340bfb35e40c 100644 --- a/clang/test/Driver/fsanitize.c +++ b/clang/test/Driver/fsanitize.c @@ -868,9 +868,7 @@ // RUN: %clang -target x86_64-linux-gnu -fsanitize=hwaddress -fsanitize-hwaddress-abi=platform %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HWASAN-PLATFORM-ABI // RUN: %clang -target x86_64-linux-gnu -fsanitize=hwaddress -fsanitize-hwaddress-abi=foo %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HWASAN-FOO-ABI // CHECK-HWASAN-INTERCEPTOR-ABI: "-default-function-attr" "hwasan-abi=interceptor" -// CHECK-HWASAN-INTERCEPTOR-ABI: "-target-feature" "+tagged-globals" // CHECK-HWASAN-PLATFORM-ABI: "-default-function-attr" "hwasan-abi=platform" -// CHECK-HWASAN-PLATFORM-ABI: "-target-feature" "+tagged-globals" // CHECK-HWASAN-FOO-ABI: error: invalid value 'foo' in '-fsanitize-hwaddress-abi=foo' // RUN: %clang -target x86_64-linux-gnu -fsanitize=address,pointer-compare,pointer-subtract %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-POINTER-ALL diff --git a/clang/test/Driver/fzero-initialized-in-bss.c b/clang/test/Driver/fzero-initialized-in-bss.c new file mode 100644 index 0000000000000..34a1dc9788cda --- /dev/null +++ b/clang/test/Driver/fzero-initialized-in-bss.c @@ -0,0 +1,8 @@ +// RUN: %clang -### %s -c -fzero-initialized-in-bss 2>&1 | FileCheck %s --check-prefix=NO +// RUN: %clang -### %s -c 2>&1 | FileCheck %s --check-prefix=NO + +// NO-NOT: -fno-zero-initialized-in-bss + +// RUN: %clang -### %s -c -fzero-initialized-in-bss -fno-zero-initialized-in-bss 2>&1 | FileCheck %s + +// CHECK: -fno-zero-initialized-in-bss diff --git a/clang/test/Driver/hip-binding.hip b/clang/test/Driver/hip-binding.hip index 53fe9af0e653c..3d83930223462 100644 --- a/clang/test/Driver/hip-binding.hip +++ b/clang/test/Driver/hip-binding.hip @@ -25,12 +25,15 @@ // RUN: --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 -fgpu-rdc %t.o\ // RUN: 2>&1 | FileCheck %s -// CHECK: # "amdgcn-amd-amdhsa" - "offload bundler", inputs: ["[[IN:.*o]]"], outputs: ["[[OBJ1:.*o]]", "[[OBJ2:.*o]]", "[[OBJ3:.*o]]"] -// CHECK: # "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[OBJ2]]"], output: "[[IMG2:.*out]]" +// CHECK: # "x86_64-unknown-linux-gnu" - "offload bundler", inputs: ["[[IN:.*o]]"], outputs: ["[[HOSTOBJ:.*o]]", "{{.*o}}", "{{.*o}}"] +// CHECK: # "amdgcn-amd-amdhsa" - "offload bundler", inputs: ["[[IN]]"], outputs: ["{{.*o}}", "[[DOBJ1:.*o]]", "[[DOBJ2:.*o]]"] +// CHECK: # "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[DOBJ1]]"], output: "[[IMG1:.*out]]" // CHECK-NOT: offload bundler -// CHECK: # "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[OBJ3]]"], output: "[[IMG3:.*out]]" +// CHECK: # "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[DOBJ2]]"], output: "[[IMG2:.*out]]" // CHECK-NOT: offload bundler -// CHECK: # "x86_64-unknown-linux-gnu" - "GNU::Linker", inputs: ["[[OBJ1]]", "[[IMG2]]", "[[IMG3]]"], output: "a.out" +// CHECK: # "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[IMG1]]", "[[IMG2]]"], output: "[[FATBINOBJ:.*o]]" +// CHECK-NOT: offload bundler +// CHECK: # "x86_64-unknown-linux-gnu" - "GNU::Linker", inputs: ["[[HOSTOBJ]]", "[[FATBINOBJ]]"], output: "a.out" // RUN: %clang --hip-link -ccc-print-bindings -target x86_64-linux-gnu \ // RUN: --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %t.o\ diff --git a/clang/test/Driver/hip-include-path.hip b/clang/test/Driver/hip-include-path.hip index 996c53bc3f286..7af06fabe5aec 100644 --- a/clang/test/Driver/hip-include-path.hip +++ b/clang/test/Driver/hip-include-path.hip @@ -19,9 +19,10 @@ // COMMON-LABEL: "{{[^"]*}}clang{{[^"]*}}" "-cc1" // CLANG-SAME: "-internal-isystem" "{{.*}}clang/{{.*}}/include/cuda_wrappers" // NOCLANG-NOT: "{{.*}}clang/{{.*}}/include/cuda_wrappers" -// CLANG-SAME: "-include" "__clang_hip_runtime_wrapper.h" // HIP-SAME: "-internal-isystem" "{{.*}}Inputs/rocm/include" // NOHIP-NOT: "{{.*}}Inputs/rocm/include" +// HIP-SAME: "-include" "__clang_hip_runtime_wrapper.h" +// NOHIP-NOT: "-include" "__clang_hip_runtime_wrapper.h" // skip check of standard C++ include path // CLANG-SAME: "-internal-isystem" "{{.*}}clang/{{.*}}/include" // NOCLANG-NOT: "{{.*}}clang/{{.*}}/include" @@ -29,9 +30,22 @@ // COMMON-LABEL: "{{[^"]*}}clang{{[^"]*}}" "-cc1" // CLANG-SAME: "-internal-isystem" "{{.*}}clang/{{.*}}/include/cuda_wrappers" // NOCLANG-NOT: "{{.*}}clang/{{.*}}/include/cuda_wrappers" -// CLANG-SAME: "-include" "__clang_hip_runtime_wrapper.h" // HIP-SAME: "-internal-isystem" "{{.*}}Inputs/rocm/include" // NOHIP-NOT: "{{.*}}Inputs/rocm/include" +// HIP-SAME: "-include" "__clang_hip_runtime_wrapper.h" +// NOHIP-NOT: "-include" "__clang_hip_runtime_wrapper.h" // skip check of standard C++ include path // CLANG-SAME: "-internal-isystem" "{{.*}}clang/{{.*}}/include" // NOCLANG-NOT: "{{.*}}clang/{{.*}}/include" + +// RUN: %clang -c -### -target x86_64-unknown-linux-gnu --cuda-gpu-arch=gfx900 \ +// RUN: -std=c++11 --rocm-path=%S/Inputs/rocm -nogpulib %s 2>&1 \ +// RUN: --hip-version=3.5 | FileCheck -check-prefixes=ROCM35 %s + +// ROCM35-LABEL: "{{[^"]*}}clang{{[^"]*}}" "-cc1" +// ROCM35-NOT: "{{.*}}clang/{{.*}}/include/cuda_wrappers" +// ROCM35-SAME: "-internal-isystem" "{{[^"]*}}clang/{{[^"]*}}" +// ROCM35-SAME: "-internal-isystem" "{{[^"]*}}Inputs/rocm/include" +// ROCM35-NOT: "-include" "__clang_hip_runtime_wrapper.h" +// skip check of standard C++ include path +// ROCM35-SAME: "-internal-isystem" "{{[^"]*}}clang/{{[^"]*}}/include" diff --git a/clang/test/Driver/hip-launch-api.hip b/clang/test/Driver/hip-launch-api.hip new file mode 100644 index 0000000000000..a7d7d15c9b5ae --- /dev/null +++ b/clang/test/Driver/hip-launch-api.hip @@ -0,0 +1,17 @@ +// REQUIRES: clang-driver +// REQUIRES: x86-registered-target +// REQUIRES: amdgpu-registered-target + +// By default FE assumes -fhip-new-launch-api. + +// RUN: %clang -### -target x86_64-unknown-linux-gnu -offload-arch=gfx906 %s \ +// RUN: 2>&1 | FileCheck -check-prefixes=NEW %s +// NEW: "-fhip-new-launch-api" + +// RUN: %clang -### -target x86_64-unknown-linux-gnu -offload-arch=gfx906 %s \ +// RUN: -fhip-new-launch-api 2>&1 | FileCheck -check-prefixes=NEW %s +// NEW: "-fhip-new-launch-api" + +// RUN: %clang -### -target x86_64-unknown-linux-gnu -offload-arch=gfx906 %s \ +// RUN: -fno-hip-new-launch-api 2>&1 | FileCheck -check-prefixes=OLD %s +// OLD-NOT: "-fhip-new-launch-api" diff --git a/clang/test/Driver/hip-link-save-temps.hip b/clang/test/Driver/hip-link-save-temps.hip index 304be921ebc62..f2d3630dd119f 100644 --- a/clang/test/Driver/hip-link-save-temps.hip +++ b/clang/test/Driver/hip-link-save-temps.hip @@ -18,16 +18,35 @@ // RUN: --offload-arch=gfx906 %T/obj1.o %T/obj2.o 2>&1 | \ // RUN: FileCheck -check-prefixes=CHECK,NOUT %s +// -fgpu-rdc link with output and --emit-static-lib +// RUN: touch %T/obj1.o +// RUN: touch %T/obj2.o +// RUN: %clang -### -target x86_64-linux-gnu -nogpulib -save-temps \ +// RUN: --hip-link -o libTest.a -fgpu-rdc --cuda-gpu-arch=gfx900 \ +// RUN: --emit-static-lib \ +// RUN: --offload-arch=gfx906 %T/obj1.o %T/obj2.o 2>&1 | \ +// RUN: FileCheck -check-prefixes=CHECK,SLO %s + +// -fgpu-rdc link without output and --emit-static-lib +// RUN: touch %T/obj1.o +// RUN: touch %T/obj2.o +// RUN: %clang -### -target x86_64-linux-gnu -nogpulib -save-temps \ +// RUN: --hip-link -fgpu-rdc --cuda-gpu-arch=gfx900 \ +// RUN: --emit-static-lib \ +// RUN: --offload-arch=gfx906 %T/obj1.o %T/obj2.o 2>&1 | \ +// RUN: FileCheck -check-prefixes=CHECK,SLNO %s + // CHECK: "{{.*clang-offload-bundler.*}}" {{.*}} "-outputs=obj1-host-x86_64-unknown-linux-gnu.o,obj1-hip-amdgcn-amd-amdhsa-gfx900.o,obj1-hip-amdgcn-amd-amdhsa-gfx906.o" "-unbundle" // CHECK: "{{.*clang-offload-bundler.*}}" {{.*}} "-outputs=obj2-host-x86_64-unknown-linux-gnu.o,obj2-hip-amdgcn-amd-amdhsa-gfx900.o,obj2-hip-amdgcn-amd-amdhsa-gfx906.o" "-unbundle" -// CHECK-NOT: llvm-link -// CHECK-NOT: opt -// CHECK-NOT: llc -// CHECK: "{{.*lld.*}}" {{.*}} "-mllvm" "-amdgpu-internalize-symbols" +// CHECK-NOT: {{".*/llvm-link"}} +// CHECK-NOT: {{".*/opt"}} +// CHECK-NOT: {{".*/llc"}} +// CHECK: "{{.*lld.*}}" {{.*}} "-plugin-opt=-amdgpu-internalize-symbols" // CHECK-SAME: "-o" "a.out-hip-amdgcn-amd-amdhsa-gfx900" "obj1-hip-amdgcn-amd-amdhsa-gfx900.o" "obj2-hip-amdgcn-amd-amdhsa-gfx900.o" -// CHECK: "{{.*lld.*}}" {{.*}} "-mllvm" "-amdgpu-internalize-symbols" +// CHECK: "{{.*lld.*}}" {{.*}} "-plugin-opt=-amdgpu-internalize-symbols" // CHECK-SAME: "-o" "a.out-hip-amdgcn-amd-amdhsa-gfx906" "obj1-hip-amdgcn-amd-amdhsa-gfx906.o" "obj2-hip-amdgcn-amd-amdhsa-gfx906.o" -// OUT: "{{.*clang-offload-bundler.*}}" {{.*}} "-outputs=executable.hipfb" -// OUT: "{{.*ld.*}}" {{.*}} "-o" "executable" {{.*}} "-T" "executable.lk" -// NOUT: "{{.*clang-offload-bundler.*}}" {{.*}} "-outputs=a.out.hipfb" -// NOUT: "{{.*ld.*}}" {{.*}} "-o" "a.out" {{.*}} "-T" "a.out.lk" +// CHECK: {{".*llvm-mc.*"}} "-o" "[[OBJBUNDLE:.*.o]]" "{{.*}}.mcin" "--filetype=obj" +// OUT: "{{.*ld.*}}" {{.*}} "-o" "executable" {{.*}} "[[OBJBUNDLE]]" +// NOUT: "{{.*ld.*}}" {{.*}} "-o" "a.out" {{.*}} "[[OBJBUNDLE]]" +// SLO: "{{.*llvm-ar.*}}" "rcsD" "libTest.a" {{.*}} "[[OBJBUNDLE]]" +// SLNO: "{{.*llvm-ar.*}}" "rcsD" "a.out" {{.*}} "[[OBJBUNDLE]]" diff --git a/clang/test/Driver/hip-link-shared-library.hip b/clang/test/Driver/hip-link-shared-library.hip index cb409d1a874d8..895bd53225e12 100644 --- a/clang/test/Driver/hip-link-shared-library.hip +++ b/clang/test/Driver/hip-link-shared-library.hip @@ -3,10 +3,13 @@ // RUN: --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %t.o %S/Inputs/in.so \ // RUN: -fgpu-rdc 2>&1 | FileCheck %s -// CHECK: # "amdgcn-amd-amdhsa" - "offload bundler", inputs: ["[[IN:.*o]]"], outputs: ["[[OBJ1:.*o]]", "[[OBJ2:.*o]]", "[[OBJ3:.*o]]"] -// CHECK: # "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[OBJ2]]"], output: "[[IMG2:.*out]]" +// CHECK: # "x86_64-unknown-linux-gnu" - "offload bundler", inputs: ["[[IN:.*o]]"], outputs: ["[[HOSTOBJ:.*o]]", "{{.*o}}", "{{.*o}}"] +// CHECK: # "amdgcn-amd-amdhsa" - "offload bundler", inputs: ["[[IN]]"], outputs: ["{{.*o}}", "[[DOBJ1:.*o]]", "[[DOBJ2:.*o]]"] +// CHECK: # "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[DOBJ1]]"], output: "[[IMG1:.*out]]" // CHECK-NOT: offload bundler -// CHECK: # "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[OBJ3]]"], output: "[[IMG3:.*out]]" +// CHECK: # "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[DOBJ2]]"], output: "[[IMG2:.*out]]" // CHECK-NOT: offload bundler -// CHECK: # "x86_64-unknown-linux-gnu" - "GNU::Linker", inputs: ["[[OBJ1]]", "{{.*}}/Inputs/in.so", "[[IMG2]]", "[[IMG3]]"], output: "a.out" +// CHECK: # "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[IMG1]]", "[[IMG2]]"], output: "[[FATBINOBJ:.*o]]" +// CHECK-NOT: offload bundler +// CHECK: # "x86_64-unknown-linux-gnu" - "GNU::Linker", inputs: ["[[HOSTOBJ]]", "{{.*}}/Inputs/in.so", "[[FATBINOBJ]]"], output: "a.out" diff --git a/clang/test/Driver/hip-link-static-library.hip b/clang/test/Driver/hip-link-static-library.hip new file mode 100644 index 0000000000000..55c5a5acc5ca6 --- /dev/null +++ b/clang/test/Driver/hip-link-static-library.hip @@ -0,0 +1,27 @@ +// REQUIRES: clang-driver +// REQUIRES: x86-registered-target +// REQUIRES: amdgpu-registered-target + +// RUN: touch %t.o +// RUN: %clang --hip-link -ccc-print-bindings -target x86_64-linux-gnu \ +// RUN: --emit-static-lib \ +// RUN: --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 -fgpu-rdc %t.o\ +// RUN: 2>&1 | FileCheck %s + +// CHECK: # "x86_64-unknown-linux-gnu" - "offload bundler", inputs: ["[[IN:.*o]]"], outputs: ["[[HOSTOBJ:.*o]]", "{{.*o}}", "{{.*o}}"] +// CHECK: # "amdgcn-amd-amdhsa" - "offload bundler", inputs: ["[[IN]]"], outputs: ["{{.*o}}", "[[DOBJ1:.*o]]", "[[DOBJ2:.*o]]"] +// CHECK: # "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[DOBJ1]]"], output: "[[IMG1:.*out]]" +// CHECK-NOT: offload bundler +// CHECK: # "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[DOBJ2]]"], output: "[[IMG2:.*out]]" +// CHECK-NOT: offload bundler +// CHECK: # "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[IMG1]]", "[[IMG2]]"], output: "[[FATBINOBJ:.*o]]" +// CHECK-NOT: offload bundler +// CHECK: # "x86_64-unknown-linux-gnu" - "GNU::StaticLibTool", inputs: ["[[HOSTOBJ]]", "[[FATBINOBJ]]"], output: "a.out" + +// RUN: %clang --hip-link -ccc-print-bindings -target x86_64-linux-gnu \ +// RUN: --emit-static-lib \ +// RUN: --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %t.o\ +// RUN: 2>&1 | FileCheck -check-prefix=NORDC %s + +// NORDC-NOT: offload bundler +// NORDC: # "x86_64-unknown-linux-gnu" - "GNU::StaticLibTool", inputs: ["{{.*o}}"], output: "a.out" diff --git a/clang/test/Driver/hip-phases.hip b/clang/test/Driver/hip-phases.hip index b27ae44167a21..7c2dc1384ccd4 100644 --- a/clang/test/Driver/hip-phases.hip +++ b/clang/test/Driver/hip-phases.hip @@ -21,25 +21,27 @@ // BIN-DAG: [[P0:[0-9]+]]: input, "{{.*}}hip-phases.hip", [[T:hip]], (host-[[T]]) // BIN-DAG: [[P1:[0-9]+]]: preprocessor, {[[P0]]}, [[T]]-cpp-output, (host-[[T]]) // BIN-DAG: [[P2:[0-9]+]]: compiler, {[[P1]]}, ir, (host-[[T]]) +// RDC-DAG: [[P12:[0-9]+]]: backend, {[[P2]]}, assembler, (host-[[T]]) +// RDC-DAG: [[P13:[0-9]+]]: assembler, {[[P12]]}, object, (host-[[T]]) // BIN-DAG: [[P3:[0-9]+]]: input, "{{.*}}hip-phases.hip", [[T]], (device-[[T]], [[ARCH:gfx803]]) // BIN-DAG: [[P4:[0-9]+]]: preprocessor, {[[P3]]}, [[T]]-cpp-output, (device-[[T]], [[ARCH]]) // BIN-DAG: [[P5:[0-9]+]]: compiler, {[[P4]]}, ir, (device-[[T]], [[ARCH]]) // NRD-DAG: [[P6:[0-9]+]]: backend, {[[P5]]}, assembler, (device-[[T]], [[ARCH]]) // NRD-DAG: [[P7:[0-9]+]]: assembler, {[[P6]]}, object, (device-[[T]], [[ARCH]]) -// NRD-DAG: [[P8:[0-9]+]]: linker, {[[P7]]}, image, (device-[[T]], [[ARCH]]) -// NRD-DAG: [[P9:[0-9]+]]: offload, "device-[[T]] (amdgcn-amd-amdhsa:[[ARCH]])" {[[P8]]}, image +// RDC-DAG: [[P7:[0-9]+]]: backend, {[[P5]]}, ir, (device-[[T]], [[ARCH]]) +// BIN-DAG: [[P8:[0-9]+]]: linker, {[[P7]]}, image, (device-[[T]], [[ARCH]]) +// BIN-DAG: [[P9:[0-9]+]]: offload, "device-[[T]] (amdgcn-amd-amdhsa:[[ARCH]])" {[[P8]]}, image // NRD-DAG: [[P10:[0-9]+]]: linker, {[[P9]]}, hip-fatbin, (device-[[T]]) -// RDC-DAG: [[P6:[0-9]+]]: backend, {[[P5]]}, ir, (device-[[T]], [[ARCH]]) -// RDC-DAG: [[P10:[0-9]+]]: linker, {[[P6]]}, image, (device-[[T]], [[ARCH]]) +// RDC-DAG: [[P10:[0-9]+]]: linker, {[[P9]]}, object, (device-[[T]]) -// NRD-DAG: [[P12:[0-9]+]]: offload, "host-[[T]] (x86_64-unknown-linux-gnu)" {[[P2]]}, "device-[[T]] (amdgcn-amd-amdhsa)" {[[P10]]}, ir +// NRD-DAG: [[P11:[0-9]+]]: offload, "host-[[T]] (x86_64-unknown-linux-gnu)" {[[P2]]}, "device-[[T]] (amdgcn-amd-amdhsa)" {[[P10]]}, ir +// RDC-DAG: [[P11:[0-9]+]]: offload, "device-[[T]] (amdgcn-amd-amdhsa)" {[[P10]]}, object +// NRD-DAG: [[P12:[0-9]+]]: backend, {[[P11]]}, assembler, (host-[[T]]) +// NRD-DAG: [[P13:[0-9]+]]: assembler, {[[P12]]}, object, (host-[[T]]) +// NRD-DAG: [[P14:[0-9]+]]: linker, {[[P13]]}, image, (host-[[T]]) +// RDC-DAG: [[P14:[0-9]+]]: linker, {[[P13]], [[P11]]}, image, (host-[[T]]) -// NRD-DAG: [[P13:[0-9]+]]: backend, {[[P12]]}, assembler, (host-[[T]]) -// RDC-DAG: [[P13:[0-9]+]]: backend, {[[P2]]}, assembler, (host-[[T]]) -// BIN-DAG: [[P14:[0-9]+]]: assembler, {[[P13]]}, object, (host-[[T]]) -// BIN-DAG: [[P15:[0-9]+]]: linker, {[[P14]]}, image, (host-[[T]]) -// RDC-DAG: [[P16:[0-9]+]]: offload, "host-[[T]] (x86_64-unknown-linux-gnu)" {[[P15]]}, "device-[[T]] (amdgcn-amd-amdhsa:gfx803)" {[[P10]]}, image // // Test single gpu architecture up to the assemble phase. // @@ -56,59 +58,84 @@ // ASM-DAG: [[P8:[0-9]+]]: backend, {[[P7]]}, assembler, (host-[[T]]) // -// Test two gpu architectures with complete compilation. +// Test two gpu architectures with complete compilation with -fno-gpu-rdc. // // RUN: %clang -x hip -target x86_64-unknown-linux-gnu -ccc-print-phases \ // RUN: --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %s 2>&1 \ -// RUN: | FileCheck -check-prefixes=BIN2,NRD2,CL2 %s +// RUN: | FileCheck -check-prefixes=NRD2,NCL2 %s // RUN: %clang -x hip -target x86_64-unknown-linux-gnu -ccc-print-phases \ // RUN: --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %s -c 2>&1 \ -// RUN: | FileCheck -check-prefixes=BIN2,NRD2 %s +// RUN: | FileCheck -check-prefixes=NRD2 %s +// NRD2-DAG: [[P0:[0-9]+]]: input, "{{.*}}hip-phases.hip", [[T:hip]], (host-[[T]]) +// NRD2-DAG: [[P1:[0-9]+]]: preprocessor, {[[P0]]}, [[T]]-cpp-output, (host-[[T]]) +// NRD2-DAG: [[P2:[0-9]+]]: compiler, {[[P1]]}, ir, (host-[[T]]) + +// NRD2-DAG: [[P3:[0-9]+]]: input, "{{.*}}hip-phases.hip", [[T]], (device-[[T]], [[ARCH1:gfx803]]) +// NRD2-DAG: [[P4:[0-9]+]]: preprocessor, {[[P3]]}, [[T]]-cpp-output, (device-[[T]], [[ARCH1]]) +// NRD2-DAG: [[P5:[0-9]+]]: compiler, {[[P4]]}, ir, (device-[[T]], [[ARCH1]]) +// NRD2-DAG: [[P6:[0-9]+]]: backend, {[[P5]]}, assembler, (device-[[T]], [[ARCH1]]) +// NRD2-DAG: [[P7:[0-9]+]]: assembler, {[[P6]]}, object, (device-[[T]], [[ARCH1]]) +// NRD2-DAG: [[P8:[0-9]+]]: linker, {[[P7]]}, image, (device-[[T]], [[ARCH1]]) +// NRD2-DAG: [[P9:[0-9]+]]: offload, "device-[[T]] (amdgcn-amd-amdhsa:[[ARCH1]])" {[[P8]]}, image + +// NRD2-DAG: [[P10:[0-9]+]]: input, "{{.*}}hip-phases.hip", [[T]], (device-[[T]], [[ARCH2:gfx900]]) +// NRD2-DAG: [[P11:[0-9]+]]: preprocessor, {[[P10]]}, [[T]]-cpp-output, (device-[[T]], [[ARCH2]]) +// NRD2-DAG: [[P12:[0-9]+]]: compiler, {[[P11]]}, ir, (device-[[T]], [[ARCH2]]) +// NRD2-DAG: [[P13:[0-9]+]]: backend, {[[P12]]}, assembler, (device-[[T]], [[ARCH2]]) +// NRD2-DAG: [[P14:[0-9]+]]: assembler, {[[P13]]}, object, (device-[[T]], [[ARCH2]]) +// NRD2-DAG: [[P15:[0-9]+]]: linker, {[[P14]]}, image, (device-[[T]], [[ARCH2]]) +// NRD2-DAG: [[P16:[0-9]+]]: offload, "device-[[T]] (amdgcn-amd-amdhsa:[[ARCH2]])" {[[P15]]}, image +// NRD2-DAG: [[P17:[0-9]+]]: linker, {[[P9]], [[P16]]}, hip-fatbin, (device-[[T]]) +// NRD2-DAG: [[P18:[0-9]+]]: offload, "host-[[T]] (x86_64-unknown-linux-gnu)" {[[P2]]}, "device-[[T]] (amdgcn-amd-amdhsa)" {[[P17]]}, ir +// NRD2-DAG: [[P19:[0-9]+]]: backend, {[[P18]]}, assembler, (host-[[T]]) +// NRD2-DAG: [[P20:[0-9]+]]: assembler, {[[P19]]}, object, (host-[[T]]) +// NCL2-DAG: [[P21:[0-9]+]]: linker, {[[P20]]}, image, (host-[[T]]) + +// +// Test two gpu architectures with complete compilation with -fgpu-rdc. +// // RUN: %clang -x hip -target x86_64-unknown-linux-gnu -ccc-print-phases \ // RUN: --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %s -fgpu-rdc 2>&1 \ -// RUN: | FileCheck -check-prefixes=BIN2,RDC2,CL2,RCL2 %s +// RUN: | FileCheck -check-prefixes=RDC2,CL2,RCL2 %s // RUN: %clang -x hip -target x86_64-unknown-linux-gnu -ccc-print-phases \ // RUN: --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %s -fgpu-rdc -c 2>&1 \ -// RUN: | FileCheck -check-prefixes=BIN2,RDC2,RC2 %s +// RUN: | FileCheck -check-prefixes=RDC2,RC2 %s -// BIN2-DAG: [[P0:[0-9]+]]: input, "{{.*}}hip-phases.hip", [[T:hip]], (host-[[T]]) -// BIN2-DAG: [[P1:[0-9]+]]: preprocessor, {[[P0]]}, [[T]]-cpp-output, (host-[[T]]) -// BIN2-DAG: [[P2:[0-9]+]]: compiler, {[[P1]]}, ir, (host-[[T]]) +// RCL2-DAG: [[P0:[0-9]+]]: input, "{{.*}}hip-phases.hip", [[T:hip]], (host-[[T]]) +// RCL2-DAG: [[P1:[0-9]+]]: preprocessor, {[[P0]]}, [[T]]-cpp-output, (host-[[T]]) +// RCL2-DAG: [[P2:[0-9]+]]: compiler, {[[P1]]}, ir, (host-[[T]]) +// RCL2-DAG: [[P19:[0-9]+]]: backend, {[[P2]]}, assembler, (host-[[T]]) +// RCL2-DAG: [[P20:[0-9]+]]: assembler, {[[P19]]}, object, (host-[[T]]) -// BIN2-DAG: [[P3:[0-9]+]]: input, "{{.*}}hip-phases.hip", [[T]], (device-[[T]], [[ARCH1:gfx803]]) -// BIN2-DAG: [[P4:[0-9]+]]: preprocessor, {[[P3]]}, [[T]]-cpp-output, (device-[[T]], [[ARCH1]]) -// BIN2-DAG: [[P5:[0-9]+]]: compiler, {[[P4]]}, ir, (device-[[T]], [[ARCH1]]) -// NRD2-DAG: [[P6:[0-9]+]]: backend, {[[P5]]}, assembler, (device-[[T]], [[ARCH1]]) +// RDC2-DAG: [[P3:[0-9]+]]: input, "{{.*}}hip-phases.hip", [[T:hip]], (device-[[T]], [[ARCH1:gfx803]]) +// RDC2-DAG: [[P4:[0-9]+]]: preprocessor, {[[P3]]}, [[T]]-cpp-output, (device-[[T]], [[ARCH1]]) +// RDC2-DAG: [[P5:[0-9]+]]: compiler, {[[P4]]}, ir, (device-[[T]], [[ARCH1]]) // RDC2-DAG: [[P6:[0-9]+]]: backend, {[[P5]]}, ir, (device-[[T]], [[ARCH1]]) -// NRD2-DAG: [[P7:[0-9]+]]: assembler, {[[P6]]}, object, (device-[[T]], [[ARCH1]]) -// NRD2-DAG: [[P8:[0-9]+]]: linker, {[[P7]]}, image, (device-[[T]], [[ARCH1]]) // RCL2-DAG: [[P8:[0-9]+]]: linker, {[[P6]]}, image, (device-[[T]], [[ARCH1]]) -// NRD2-DAG: [[P9:[0-9]+]]: offload, "device-[[T]] (amdgcn-amd-amdhsa:[[ARCH1]])" {[[P8]]}, image +// RCL2-DAG: [[P9:[0-9]+]]: offload, "device-[[T]] (amdgcn-amd-amdhsa:[[ARCH1]])" {[[P8]]}, image // RC2-DAG: [[P9:[0-9]+]]: offload, "device-[[T]] (amdgcn-amd-amdhsa:[[ARCH1]])" {[[P6]]}, ir -// BIN2-DAG: [[P10:[0-9]+]]: input, "{{.*}}hip-phases.hip", [[T]], (device-[[T]], [[ARCH2:gfx900]]) -// BIN2-DAG: [[P11:[0-9]+]]: preprocessor, {[[P10]]}, [[T]]-cpp-output, (device-[[T]], [[ARCH2]]) -// BIN2-DAG: [[P12:[0-9]+]]: compiler, {[[P11]]}, ir, (device-[[T]], [[ARCH2]]) -// NRD2-DAG: [[P13:[0-9]+]]: backend, {[[P12]]}, assembler, (device-[[T]], [[ARCH2]]) +// RDC2-DAG: [[P10:[0-9]+]]: input, "{{.*}}hip-phases.hip", [[T]], (device-[[T]], [[ARCH2:gfx900]]) +// RDC2-DAG: [[P11:[0-9]+]]: preprocessor, {[[P10]]}, [[T]]-cpp-output, (device-[[T]], [[ARCH2]]) +// RDC2-DAG: [[P12:[0-9]+]]: compiler, {[[P11]]}, ir, (device-[[T]], [[ARCH2]]) // RDC2-DAG: [[P13:[0-9]+]]: backend, {[[P12]]}, ir, (device-[[T]], [[ARCH2]]) -// NRD2-DAG: [[P14:[0-9]+]]: assembler, {[[P13]]}, object, (device-[[T]], [[ARCH2]]) -// NRD2-DAG: [[P15:[0-9]+]]: linker, {[[P14]]}, image, (device-[[T]], [[ARCH2]]) // RCL2-DAG: [[P15:[0-9]+]]: linker, {[[P13]]}, image, (device-[[T]], [[ARCH2]]) -// NRD2-DAG: [[P16:[0-9]+]]: offload, "device-[[T]] (amdgcn-amd-amdhsa:[[ARCH2]])" {[[P15]]}, image +// RCL2-DAG: [[P16:[0-9]+]]: offload, "device-[[T]] (amdgcn-amd-amdhsa:[[ARCH2]])" {[[P15]]}, image // RC2-DAG: [[P16:[0-9]+]]: offload, "device-[[T]] (amdgcn-amd-amdhsa:[[ARCH2]])" {[[P13]]}, ir -// NRD2-DAG: [[P17:[0-9]+]]: linker, {[[P9]], [[P16]]}, hip-fatbin, (device-[[T]]) +// RC2-DAG: [[P0:[0-9]+]]: input, "{{.*}}hip-phases.hip", [[T:hip]], (host-[[T]]) +// RC2-DAG: [[P1:[0-9]+]]: preprocessor, {[[P0]]}, [[T]]-cpp-output, (host-[[T]]) +// RC2-DAG: [[P2:[0-9]+]]: compiler, {[[P1]]}, ir, (host-[[T]]) +// RC2-DAG: [[P19:[0-9]+]]: backend, {[[P2]]}, assembler, (host-[[T]]) +// RC2-DAG: [[P20:[0-9]+]]: assembler, {[[P19]]}, object, (host-[[T]]) -// NRD2-DAG: [[P18:[0-9]+]]: offload, "host-[[T]] (x86_64-unknown-linux-gnu)" {[[P2]]}, "device-[[T]] (amdgcn-amd-amdhsa)" {[[P17]]}, ir -// NRD2-DAG: [[P19:[0-9]+]]: backend, {[[P18]]}, assembler, (host-[[T]]) -// RDC2-DAG: [[P19:[0-9]+]]: backend, {[[P2]]}, assembler, (host-[[T]]) -// BIN2-DAG: [[P20:[0-9]+]]: assembler, {[[P19]]}, object, (host-[[T]]) -// CL2-DAG: [[P21:[0-9]+]]: linker, {[[P20]]}, image, (host-[[T]]) -// RCL2-DAG: [[P22:[0-9]+]]: offload, "host-[[T]] (x86_64-unknown-linux-gnu)" {[[P21]]}, "device-[[T]] (amdgcn-amd-amdhsa:[[ARCH1]])" {[[P8]]}, "device-[[T]] (amdgcn-amd-amdhsa:[[ARCH2]])" {[[P15]]}, image -// RC2-DAG: [[P22:[0-9]+]]: clang-offload-bundler, {[[P9]], [[P16]], [[P20]]}, object, (host-[[T]]) +// RCL2-DAG: [[P17:[0-9]+]]: linker, {[[P9]], [[P16]]}, object, (device-[[T]]) +// RCL2-DAG: [[P22:[0-9]+]]: offload, "device-[[T]] (amdgcn-amd-amdhsa)" {[[P17]]}, object +// RCL2-DAG: [[P23:[0-9]+]]: linker, {[[P20]], [[P22]]}, image, (host-[[T]]) +// RC2-DAG: [[P23:[0-9]+]]: clang-offload-bundler, {[[P9]], [[P16]], [[P20]]}, object, (host-[[T]]) // // Test two gpu architecturess up to the assemble phase. @@ -253,8 +280,13 @@ // RL2-DAG: [[P1:[0-9]+]]: clang-offload-unbundler, {[[P0]]}, object, (host-[[T]]) // L2-DAG: [[P2:[0-9]+]]: input, "{{.*}}obj2.o", object, (host-[[T]]) // RL2-DAG: [[P3:[0-9]+]]: clang-offload-unbundler, {[[P2]]}, object, (host-[[T]]) -// NL2-DAG: [[P4:[0-9]+]]: linker, {[[P0]], [[P2]]}, image, (host-[[T]]) -// RL2-DAG: [[P4:[0-9]+]]: linker, {[[P1]], [[P3]]}, image, (host-[[T]]) -// RL2-DAG: [[P5:[0-9]+]]: linker, {[[P1]], [[P3]]}, image, (device-[[T]], [[ARCH1:gfx803]]) + +// RL2-DAG: [[P4:[0-9]+]]: linker, {[[P1]], [[P3]]}, image, (device-[[T]], [[ARCH1:gfx803]]) +// RL2-DAG: [[P5:[0-9]+]]: offload, "device-[[T]] (amdgcn-amd-amdhsa:[[ARCH1]])" {[[P4]]}, image // RL2-DAG: [[P6:[0-9]+]]: linker, {[[P1]], [[P3]]}, image, (device-[[T]], [[ARCH2:gfx900]]) -// RL2-DAG: [[P7:[0-9]+]]: offload, "host-[[T]] (x86_64-unknown-linux-gnu)" {[[P4]]}, "device-[[T]] (amdgcn-amd-amdhsa:[[ARCH1]])" {[[P5]]}, "device-[[T]] (amdgcn-amd-amdhsa:[[ARCH2]])" {[[P6]]}, image +// RL2-DAG: [[P7:[0-9]+]]: offload, "device-[[T]] (amdgcn-amd-amdhsa:[[ARCH2]])" {[[P6]]}, image +// RL2-DAG: [[P8:[0-9]+]]: linker, {[[P5]], [[P7]]}, object, (device-[[T]]) +// RL2-DAG: [[P9:[0-9]+]]: offload, "device-[[T]] (amdgcn-amd-amdhsa)" {[[P8]]}, object + +// NL2-DAG: [[P4:[0-9]+]]: linker, {[[P0]], [[P2]]}, image, (host-[[T]]) +// RL2-DAG: [[P4:[0-9]+]]: linker, {[[P1]], [[P3]], [[P9]]}, image, (host-[[T]]) diff --git a/clang/test/Driver/hip-save-temps.hip b/clang/test/Driver/hip-save-temps.hip index 1ac506aa6fba1..b5d54a8092a92 100644 --- a/clang/test/Driver/hip-save-temps.hip +++ b/clang/test/Driver/hip-save-temps.hip @@ -25,13 +25,20 @@ // -fgpu-rdc without -o // RUN: %clang -### -target x86_64-linux-gnu -nogpulib -save-temps \ // RUN: -fgpu-rdc --cuda-gpu-arch=gfx900 %s 2>&1 | \ -// RUN: FileCheck -check-prefixes=CHECK,RDC,RDCL,RDC-NOUT,NOUT %s +// RUN: FileCheck -check-prefixes=CHECK,RDC,RDCL,NOUT %s // -fgpu-rdc with -o -// RUN: %clang -### -target x86_64-linux-gnu -nogpulib -save-temps \ -// RUN: -o executable -fgpu-rdc --cuda-gpu-arch=gfx900 %s 2>&1 | \ -// RUN: FileCheck -check-prefixes=CHECK,RDC,RDCL,RDC-WOUT,WOUT %s +// UN: %clang -### -target x86_64-linux-gnu -nogpulib -save-temps \ +// UN: -o executable -fgpu-rdc --cuda-gpu-arch=gfx900 %s 2>&1 | \ +// UN: FileCheck -check-prefixes=CHECK,RDC,RDCL,WOUT %s + +// -fgpu-rdc host object path +// RDCL: "{{.*clang.*}}" "-cc1" {{.*}} "-E" {{.*}} "-o" "hip-save-temps-host-x86_64-unknown-linux-gnu.cui" +// RDCL: "{{.*clang.*}}" "-cc1" {{.*}} "-emit-llvm-bc" {{.*}} "-o" "hip-save-temps-host-x86_64-unknown-linux-gnu.bc" +// RDCL: "{{.*clang.*}}" "-cc1" {{.*}} "-S" {{.*}} "-o" "hip-save-temps-host-x86_64-unknown-linux-gnu.s" +// RDCL: "{{.*clang.*}}" "-cc1as" {{.*}} "-o" "hip-save-temps-host-x86_64-unknown-linux-gnu.o" +// device object paths // CHECK: {{".*clang.*"}} "-cc1" {{.*}} "-E" {{.*}} [[CPU:"-target-cpu" "gfx900"]] {{.*}} "-o" "hip-save-temps-hip-amdgcn-amd-amdhsa-gfx900.cui" // NORDC: {{".*clang.*"}} "-cc1" {{.*}} "-emit-llvm-bc" {{.*}} [[CPU]] {{.*}} "-disable-llvm-passes" {{.*}} "-o" "hip-save-temps-hip-amdgcn-amd-amdhsa-gfx900.bc" // RDC: {{".*clang.*"}} "-cc1" {{.*}} "-emit-llvm-bc" {{.*}} [[CPU]] {{.*}} "-disable-llvm-passes" {{.*}} "-o" "hip-save-temps-hip-amdgcn-amd-amdhsa-gfx900.tmp.bc" @@ -43,22 +50,26 @@ // RDC: {{".*clang.*"}} "-cc1" {{.*}} "-emit-llvm-bc" {{.*}} [[CPU]] {{.*}} "-o" "hip-save-temps-hip-amdgcn-amd-amdhsa-gfx900.bc" // NORDC: {{".*clang.*"}} "-cc1as" {{.*}} "-filetype" "obj" {{.*}} [[CPU]] {{.*}} "-o" "hip-save-temps-hip-amdgcn-amd-amdhsa-gfx900.o" -// CHECK-NOT: llvm-link -// CHECK-NOT: opt -// CHECK-NOT: llc +// CHECK-NOT: "{{.*}}llvm-link" +// CHECK-NOT: "{{.*}}opt" +// CHECK-NOT: "{{.*}}llc" // NORDC: {{.*lld.*}}"-o" "hip-save-temps-hip-amdgcn-amd-amdhsa-gfx900.out" - -// RDCL: "{{.*lld.*}}" {{.*}} "-mllvm" "-amdgpu-internalize-symbols" +// RDCL: "{{.*lld.*}}" {{.*}} "-plugin-opt=-amdgpu-internalize-symbols" {{.*}}"-save-temps" // RDCL-SAME: "-o" "a.out-hip-amdgcn-amd-amdhsa-gfx900" +// RDCC: "{{.*clang.*}}" "-cc1" {{.*}} "-E" {{.*}} "-o" "hip-save-temps-host-x86_64-unknown-linux-gnu.cui" +// RDCC: "{{.*clang.*}}" "-cc1" {{.*}} "-emit-llvm-bc" {{.*}} "-o" "hip-save-temps-host-x86_64-unknown-linux-gnu.bc" +// RDCC: "{{.*clang.*}}" "-cc1" {{.*}} "-S" {{.*}} "-o" "hip-save-temps-host-x86_64-unknown-linux-gnu.s" +// RDCC: "{{.*clang.*}}" "-cc1as" {{.*}} "-o" "hip-save-temps-host-x86_64-unknown-linux-gnu.o" +// RDCC: "{{.*clang-offload-bundler.*}}" {{.*}} "-outputs=hip-save-temps.o" +// RDCL: "{{.*clang-offload-bundler.*}}" {{.*}} "-outputs=hip-save-temps-hip-amdgcn-amd-amdhsa.hipfb" +// RDCL: {{.*}}llvm-mc{{.*}}"-o" "hip-save-temps-hip-amdgcn-amd-amdhsa.o" "hip-save-temps-hip-amdgcn-amd-amdhsa.mcin" "--filetype=obj" -// NORDC: "{{.*clang-offload-bundler.*}}" {{.*}} "-outputs=hip-save-temps.hip-hip-amdgcn-amd-amdhsa.hipfb" -// CHECK: "{{.*clang.*}}" "-cc1" {{.*}} "-E" {{.*}} "-o" "hip-save-temps-host-x86_64-unknown-linux-gnu.cui" +// -fno-gpu-rdc host object path +// NORDC: "{{.*clang.*}}" "-cc1" {{.*}} "-E" {{.*}} "-o" "hip-save-temps-host-x86_64-unknown-linux-gnu.cui" // NORDC: "{{.*clang.*}}" "-cc1" {{.*}} "-emit-llvm-bc" {{.*}} "-fcuda-include-gpubinary" {{.*}} "-o" "hip-save-temps-host-x86_64-unknown-linux-gnu.bc" -// RDC: "{{.*clang.*}}" "-cc1" {{.*}} "-emit-llvm-bc" {{.*}} "-o" "hip-save-temps-host-x86_64-unknown-linux-gnu.bc" -// CHECK: "{{.*clang.*}}" "-cc1" {{.*}} "-S" {{.*}} "-o" "hip-save-temps-host-x86_64-unknown-linux-gnu.s" -// CHECK: "{{.*clang.*}}" "-cc1as" {{.*}} "-o" "hip-save-temps{{.*}}.o" -// RDCC: "{{.*clang-offload-bundler.*}}" {{.*}} "-outputs=hip-save-temps.o" -// RDC-NOUT: "{{.*clang-offload-bundler.*}}" {{.*}} "-outputs=a.out.hipfb" -// RDC-WOUT: "{{.*clang-offload-bundler.*}}" {{.*}} "-outputs=executable.hipfb" -// NOUT: "{{.*ld.*}}" {{.*}} "-o" "a.out" -// WOUT: "{{.*ld.*}}" {{.*}} "-o" "executable" \ No newline at end of file +// NORDC: "{{.*clang.*}}" "-cc1" {{.*}} "-S" {{.*}} "-o" "hip-save-temps-host-x86_64-unknown-linux-gnu.s" +// NORDC: "{{.*clang.*}}" "-cc1as" {{.*}} "-o" "hip-save-temps{{.*}}.o" + +// output to default a.out or -o specified file name +// NOUT: {{.*}}ld{{.*}}"-o" "a.out" +// WOUT: {{.*}}ld{{.*}}"-o" "executable" diff --git a/clang/test/Driver/hip-std.hip b/clang/test/Driver/hip-std.hip new file mode 100644 index 0000000000000..4bdf05ab495d5 --- /dev/null +++ b/clang/test/Driver/hip-std.hip @@ -0,0 +1,23 @@ +// REQUIRES: clang-driver +// REQUIRES: x86-registered-target +// REQUIRES: amdgpu-registered-target + +// RUN: %clang -### -target x86_64-unknown-linux-gnu -offload-arch=gfx906 %s \ +// RUN: 2>&1 | FileCheck -check-prefixes=DEFAULT %s +// DEFAULT: "{{.*}}clang{{.*}}" "-cc1"{{.*}}"-fcuda-is-device"{{.*}}"-std=c++11" +// DEFAULT: "{{.*}}clang{{.*}}" "-cc1"{{.*}}"-std=c++11" + +// RUN: %clang -### -target x86_64-unknown-linux-gnu -offload-arch=gfx906 %s \ +// RUN: -std=c++17 %s 2>&1 | FileCheck -check-prefixes=SPECIFIED %s +// SPECIFIED: "{{.*}}clang{{.*}}" "-cc1"{{.*}}"-fcuda-is-device"{{.*}}"-std=c++17" +// SPECIFIED: "{{.*}}clang{{.*}}" "-cc1"{{.*}}"-std=c++17" + +// RUN: %clang -### -target x86_64-pc-windows-msvc -offload-arch=gfx906 %s \ +// RUN: 2>&1 | FileCheck -check-prefixes=MSVC-DEF %s +// MSVC-DEF: "{{.*}}clang{{.*}}" "-cc1"{{.*}}"-fcuda-is-device"{{.*}}"-std=c++14" +// MSVC-DEF: "{{.*}}clang{{.*}}" "-cc1"{{.*}}"-std=c++14" + +// RUN: %clang -### -target x86_64-pc-windows-msvc -offload-arch=gfx906 %s \ +// RUN: -std=c++17 %s 2>&1 | FileCheck -check-prefixes=MSVC-SPEC %s +// MSVC-SPEC: "{{.*}}clang{{.*}}" "-cc1"{{.*}}"-fcuda-is-device"{{.*}}"-std=c++17" +// MSVC-SPEC: "{{.*}}clang{{.*}}" "-cc1"{{.*}}"-std=c++17" diff --git a/clang/test/Driver/hip-toolchain-features.hip b/clang/test/Driver/hip-toolchain-features.hip index 3b90d4101ee3d..c236d2c7102fb 100644 --- a/clang/test/Driver/hip-toolchain-features.hip +++ b/clang/test/Driver/hip-toolchain-features.hip @@ -2,36 +2,53 @@ // REQUIRES: x86-registered-target // REQUIRES: amdgpu-registered-target -// RUN: %clang -### -c -target x86_64-linux-gnu -fgpu-rdc \ +// RUN: %clang -### -target x86_64-linux-gnu -fgpu-rdc -nogpulib \ // RUN: --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %s \ // RUN: -mxnack 2>&1 | FileCheck %s -check-prefix=XNACK -// RUN: %clang -### -c -target x86_64-linux-gnu -fgpu-rdc \ +// RUN: %clang -### -target x86_64-linux-gnu -fgpu-rdc -nogpulib \ // RUN: --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %s \ // RUN: -mno-xnack 2>&1 | FileCheck %s -check-prefix=NOXNACK // XNACK: {{.*}}clang{{.*}}"-target-feature" "+xnack" +// XNACK: {{.*}}lld{{.*}}"-plugin-opt=-mattr=+xnack" // NOXNACK: {{.*}}clang{{.*}}"-target-feature" "-xnack" +// NOXNACK: {{.*}}lld{{.*}}"-plugin-opt=-mattr=-xnack" -// RUN: %clang -### -c -target x86_64-linux-gnu -fgpu-rdc \ +// RUN: %clang -### -target x86_64-linux-gnu -fgpu-rdc -nogpulib \ // RUN: --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %s \ // RUN: -msram-ecc 2>&1 | FileCheck %s -check-prefix=SRAM -// RUN: %clang -### -c -target x86_64-linux-gnu -fgpu-rdc \ +// RUN: %clang -### -target x86_64-linux-gnu -fgpu-rdc -nogpulib \ // RUN: --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %s \ // RUN: -mno-sram-ecc 2>&1 | FileCheck %s -check-prefix=NOSRAM // SRAM: {{.*}}clang{{.*}}"-target-feature" "+sram-ecc" +// SRAM: {{.*}}lld{{.*}}"-plugin-opt=-mattr=+sram-ecc" // NOSRAM: {{.*}}clang{{.*}}"-target-feature" "-sram-ecc" +// NOSRAM: {{.*}}lld{{.*}}"-plugin-opt=-mattr=-sram-ecc" -// RUN: %clang -### -c -target x86_64-linux-gnu -fgpu-rdc \ +// RUN: %clang -### -target x86_64-linux-gnu -fgpu-rdc -nogpulib \ // RUN: --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %s \ // RUN: -mxnack -msram-ecc \ // RUN: 2>&1 | FileCheck %s -check-prefix=ALL3 -// RUN: %clang -### -c -target x86_64-linux-gnu -fgpu-rdc \ +// RUN: %clang -### -target x86_64-linux-gnu -fgpu-rdc -nogpulib \ // RUN: --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %s \ // RUN: -mno-xnack -mno-sram-ecc \ // RUN: 2>&1 | FileCheck %s -check-prefix=NOALL3 // ALL3: {{.*}}clang{{.*}}"-target-feature" "+xnack" "-target-feature" "+sram-ecc" +// ALL3: {{.*}}lld{{.*}}"-plugin-opt=-mattr=+xnack,+sram-ecc" // NOALL3: {{.*}}clang{{.*}}"-target-feature" "-xnack" "-target-feature" "-sram-ecc" +// NOALL3: {{.*}}lld{{.*}}"-plugin-opt=-mattr=-xnack,-sram-ecc" + +// RUN: %clang -### -target x86_64-linux-gnu -fgpu-rdc -nogpulib \ +// RUN: --cuda-gpu-arch=gfx1010 %s \ +// RUN: -mcumode -mcumode -mno-cumode -mwavefrontsize64 -mcumode \ +// RUN: -mwavefrontsize64 -mno-wavefrontsize64 2>&1 \ +// RUN: | FileCheck %s -check-prefix=DUP +// DUP: {{.*}}clang{{.*}} "-target-feature" "-wavefrontsize16" +// DUP-SAME: "-target-feature" "+wavefrontsize32" +// DUP-SAME: "-target-feature" "-wavefrontsize64" +// DUP-SAME: "-target-feature" "+cumode" +// DUP: {{.*}}lld{{.*}} "-plugin-opt=-mattr=-wavefrontsize16,+wavefrontsize32,-wavefrontsize64,+cumode" diff --git a/clang/test/Driver/hip-toolchain-mllvm.hip b/clang/test/Driver/hip-toolchain-mllvm.hip index 66556d0b726b8..5b47e1e0b5d86 100644 --- a/clang/test/Driver/hip-toolchain-mllvm.hip +++ b/clang/test/Driver/hip-toolchain-mllvm.hip @@ -7,20 +7,25 @@ // RUN: -mllvm -amdgpu-function-calls=0 \ // RUN: %s 2>&1 | FileCheck %s +// RUN: %clang -### -target x86_64-linux-gnu \ +// RUN: --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 \ +// RUN: -fgpu-rdc -mllvm -amdgpu-function-calls=0 \ +// RUN: %s 2>&1 | FileCheck -check-prefixes=CHECK,RDC %s + // CHECK: [[CLANG:".*clang.*"]] "-cc1" "-triple" "amdgcn-amd-amdhsa" // CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" -// CHECK-SAME: "-emit-obj" // CHECK-SAME: {{.*}} "-target-cpu" "gfx803" // CHECK-SAME: {{.*}} "-mllvm" "-amdgpu-function-calls=0" {{.*}} // CHECK-NOT: {{".*opt"}} // CHECK-NOT: {{".*llc"}} +// RDC: [[LLD:".*lld.*"]] {{.*}} "-plugin-opt=-amdgpu-function-calls=0" // CHECK: [[CLANG]] "-cc1" "-triple" "amdgcn-amd-amdhsa" // CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" -// CHECK-SAME: "-emit-obj" // CHECK-SAME: {{.*}} "-target-cpu" "gfx900" // CHECK-SAME: {{.*}} "-mllvm" "-amdgpu-function-calls=0" {{.*}} // CHECK-NOT: {{".*opt"}} // CHECK-NOT: {{".*llc"}} +// RDC: [[LLD:".*lld.*"]] {{.*}} "-plugin-opt=-amdgpu-function-calls=0" diff --git a/clang/test/Driver/hip-toolchain-opt.hip b/clang/test/Driver/hip-toolchain-opt.hip index 4a470dba38557..d58471aec5f51 100644 --- a/clang/test/Driver/hip-toolchain-opt.hip +++ b/clang/test/Driver/hip-toolchain-opt.hip @@ -72,6 +72,16 @@ // ALL-NOT: "{{.*}}llc" +// ALL: "{{.*}}lld{{.*}}" {{.*}} "-plugin-opt=mcpu=gfx900" +// DEFAULT-NOT: "-plugin-opt=O{{.*}}" +// O0-SAME: "-plugin-opt=O0" +// O1-SAME: "-plugin-opt=O1" +// O2-SAME: "-plugin-opt=O2" +// O3-SAME: "-plugin-opt=O3" +// Os-SAME: "-plugin-opt=O2" +// Oz-SAME: "-plugin-opt=O2" +// Og-SAME: "-plugin-opt=O1" + // ALL: "{{.*}}clang{{.*}}" "-cc1" "-triple" "x86_64-unknown-linux-gnu" // DEFAULT-NOT: "-O{{.}}" // O0-SAME: "-O0" diff --git a/clang/test/Driver/hip-toolchain-rdc-separate.hip b/clang/test/Driver/hip-toolchain-rdc-separate.hip index 25661f399a82f..ab89e19256be9 100644 --- a/clang/test/Driver/hip-toolchain-rdc-separate.hip +++ b/clang/test/Driver/hip-toolchain-rdc-separate.hip @@ -86,29 +86,43 @@ // LINK: [[BUNDLER:".*clang-offload-bundler"]] "-type=o" // LINK-SAME: "-targets=host-x86_64-unknown-linux-gnu,hip-amdgcn-amd-amdhsa-gfx803,hip-amdgcn-amd-amdhsa-gfx900" -// LINK-SAME: "-inputs=[[A_O:.*a.o]]" "-outputs=[[A_OBJ_HOST:.*o]],[[A_BC1:.*o]],[[A_BC2:.*o]]" +// LINK-SAME: "-inputs=[[A_O:.*a.o]]" "-outputs=[[A_OBJ_HOST:.*o]],{{.*o}},{{.*o}}" // LINK: "-unbundle" // LINK: [[BUNDLER:".*clang-offload-bundler"]] "-type=o" // LINK-SAME: "-targets=host-x86_64-unknown-linux-gnu,hip-amdgcn-amd-amdhsa-gfx803,hip-amdgcn-amd-amdhsa-gfx900" -// LINK-SAME: "-inputs=[[B_O:.*b.o]]" "-outputs=[[B_OBJ_HOST:.*o]],[[B_BC1:.*o]],[[B_BC2:.*o]]" +// LINK-SAME: "-inputs=[[B_O:.*b.o]]" "-outputs=[[B_OBJ_HOST:.*o]],{{.*o}},{{.*o}}" +// LINK: "-unbundle" + +// LINK: [[BUNDLER:".*clang-offload-bundler"]] "-type=o" +// LINK-SAME: "-targets=host-x86_64-unknown-linux-gnu,hip-amdgcn-amd-amdhsa-gfx803,hip-amdgcn-amd-amdhsa-gfx900" +// LINK-SAME: "-inputs=[[A_O]]" "-outputs={{.*o}},[[A_BC1:.*o]],[[A_BC2:.*o]]" +// LINK: "-unbundle" + +// LINK: [[BUNDLER:".*clang-offload-bundler"]] "-type=o" +// LINK-SAME: "-targets=host-x86_64-unknown-linux-gnu,hip-amdgcn-amd-amdhsa-gfx803,hip-amdgcn-amd-amdhsa-gfx900" +// LINK-SAME: "-inputs=[[B_O]]" "-outputs={{.*o}},[[B_BC1:.*o]],[[B_BC2:.*o]]" // LINK: "-unbundle" // LINK-NOT: "*.llvm-link" // LINK-NOT: ".*opt" // LINK-NOT: ".*llc" -// LINK: {{".*lld.*"}} {{.*}} "-mllvm" "-amdgpu-internalize-symbols" +// LINK: {{".*lld.*"}} {{.*}} "-plugin-opt=-amdgpu-internalize-symbols" +// LINK: "-plugin-opt=mcpu=gfx803" // LINK-SAME: "-o" "[[IMG_DEV1:.*.out]]" "[[A_BC1]]" "[[B_BC1]]" // LINK-NOT: "*.llvm-link" // LINK-NOT: ".*opt" // LINK-NOT: ".*llc" -// LINK: {{".*lld.*"}} {{.*}} "-mllvm" "-amdgpu-internalize-symbols" +// LINK: {{".*lld.*"}} {{.*}} "-plugin-opt=-amdgpu-internalize-symbols" +// LINK: "-plugin-opt=mcpu=gfx900" // LINK-SAME: "-o" "[[IMG_DEV2:.*.out]]" "[[A_BC2]]" "[[B_BC2]]" // LINK: [[BUNDLER:".*clang-offload-bundler"]] "-type=o" // LINK-SAME: "-targets={{.*}},hip-amdgcn-amd-amdhsa-gfx803,hip-amdgcn-amd-amdhsa-gfx900" // LINK-SAME: "-inputs={{.*}},[[IMG_DEV1]],[[IMG_DEV2]]" "-outputs=[[BUNDLE:.*hipfb]]" -// LINK: [[LD:".*ld.*"]] {{.*}} "[[A_OBJ_HOST]]" "[[B_OBJ_HOST]]" -// LINK-SAME: {{.*}} "-T" "{{.*}}.lk" +// LINK: {{".*llvm-mc.*"}} "-o" "[[OBJBUNDLE:.*o]]" "{{.*}}.mcin" "--filetype=obj" + +// LINK: [[LD:".*ld.*"]] {{.*}} "-o" "a.out" {{.*}} "[[A_OBJ_HOST]]" +// LINK-SAME: "[[B_OBJ_HOST]]" "[[OBJBUNDLE]]" diff --git a/clang/test/Driver/hip-toolchain-rdc-static-lib.hip b/clang/test/Driver/hip-toolchain-rdc-static-lib.hip new file mode 100644 index 0000000000000..dc29b0f87e366 --- /dev/null +++ b/clang/test/Driver/hip-toolchain-rdc-static-lib.hip @@ -0,0 +1,83 @@ +// REQUIRES: clang-driver +// REQUIRES: x86-registered-target +// REQUIRES: amdgpu-registered-target + +// RUN: %clang -### -target x86_64-linux-gnu \ +// RUN: -x hip --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 \ +// RUN: --emit-static-lib -nogpulib \ +// RUN: -fuse-ld=lld -fgpu-rdc -nogpuinc \ +// RUN: %S/Inputs/hip_multiple_inputs/a.cu \ +// RUN: %S/Inputs/hip_multiple_inputs/b.hip \ +// RUN: 2>&1 | FileCheck %s + +// emit objects for host side path +// CHECK: [[CLANG:".*clang.*"]] "-cc1" "-triple" "x86_64-unknown-linux-gnu" +// CHECK-SAME: "-aux-triple" "amdgcn-amd-amdhsa" +// CHECK-SAME: "-emit-obj" +// CHECK-SAME: {{.*}} "-main-file-name" "a.cu" +// CHECK-SAME: {{.*}} "-o" [[A_OBJ_HOST:".*o"]] "-x" "hip" +// CHECK-SAME: {{.*}} [[A_SRC:".*a.cu"]] + +// CHECK: [[CLANG]] "-cc1" "-triple" "x86_64-unknown-linux-gnu" +// CHECK-SAME: "-aux-triple" "amdgcn-amd-amdhsa" +// CHECK-SAME: "-emit-obj" +// CHECK-SAME: {{.*}} "-main-file-name" "b.hip" +// CHECK-SAME: {{.*}} "-o" [[B_OBJ_HOST:".*o"]] "-x" "hip" +// CHECK-SAME: {{.*}} [[B_SRC:".*b.hip"]] + +// generate image for device side path on gfx803 +// CHECK: [[CLANG]] "-cc1" "-triple" "amdgcn-amd-amdhsa" +// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" +// CHECK-SAME: "-emit-llvm-bc" +// CHECK-SAME: {{.*}} "-main-file-name" "a.cu" +// CHECK-SAME: "-fcuda-is-device" "-fgpu-rdc" +// CHECK-SAME: "-target-cpu" "gfx803" +// CHECK-SAME: {{.*}} "-o" [[A_BC1:".*bc"]] "-x" "hip" +// CHECK-SAME: {{.*}} [[A_SRC]] + +// CHECK: [[CLANG]] "-cc1" "-triple" "amdgcn-amd-amdhsa" +// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" +// CHECK-SAME: "-emit-llvm-bc" +// CHECK-SAME: {{.*}} "-main-file-name" "b.hip" +// CHECK-SAME: "-fcuda-is-device" "-fgpu-rdc" +// CHECK-SAME: "-target-cpu" "gfx803" +// CHECK-SAME: {{.*}} "-o" [[B_BC1:".*bc"]] "-x" "hip" +// CHECK-SAME: {{.*}} [[B_SRC]] + +// CHECK-NOT: "*.llvm-link" +// CHECK-NOT: ".*opt" +// CHECK-NOT: ".*llc" +// CHECK: [[LLD: ".*lld"]] {{.*}} "-o" "[[IMG_DEV1:.*out]]" [[A_BC1]] [[B_BC1]] + +// generate image for device side path on gfx900 +// CHECK: [[CLANG]] "-cc1" "-triple" "amdgcn-amd-amdhsa" +// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" +// CHECK-SAME: "-emit-llvm-bc" +// CHECK-SAME: {{.*}} "-main-file-name" "a.cu" +// CHECK-SAME: "-fcuda-is-device" "-fgpu-rdc" +// CHECK-SAME: "-target-cpu" "gfx900" +// CHECK-SAME: {{.*}} "-o" [[A_BC2:".*bc"]] "-x" "hip" +// CHECK-SAME: {{.*}} [[A_SRC]] + +// CHECK: [[CLANG]] "-cc1" "-triple" "amdgcn-amd-amdhsa" +// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" +// CHECK-SAME: "-emit-llvm-bc" +// CHECK-SAME: {{.*}} "-main-file-name" "b.hip" +// CHECK-SAME: "-fcuda-is-device" "-fgpu-rdc" +// CHECK-SAME: "-target-cpu" "gfx900" +// CHECK-SAME: {{.*}} "-o" [[B_BC2:".*bc"]] "-x" "hip" +// CHECK-SAME: {{.*}} [[B_SRC]] + +// CHECK-NOT: "*.llvm-link" +// CHECK-NOT: ".*opt" +// CHECK-NOT: ".*llc" +// CHECK: [[LLD]] {{.*}} "-o" "[[IMG_DEV2:.*out]]" [[A_BC2]] [[B_BC2]] + +// combine images generated into hip fat binary object +// CHECK: [[BUNDLER:".*clang-offload-bundler"]] "-type=o" +// CHECK-SAME: "-targets={{.*}},hip-amdgcn-amd-amdhsa-gfx803,hip-amdgcn-amd-amdhsa-gfx900" +// CHECK-SAME: "-inputs={{.*}},[[IMG_DEV1]],[[IMG_DEV2]]" "-outputs=[[BUNDLE:.*hipfb]]" + +// CHECK: [[MC:".*llvm-mc"]] "-o" [[OBJBUNDLE:".*o"]] "{{.*}}.mcin" "--filetype=obj" + +// CHECK: [[AR:".*llvm-ar.*"]] "rcsD" "{{.*}}.out" [[A_OBJ_HOST]] [[B_OBJ_HOST]] [[OBJBUNDLE]] diff --git a/clang/test/Driver/hip-toolchain-rdc.hip b/clang/test/Driver/hip-toolchain-rdc.hip index f520236abcb9f..97d5e59c0c4b1 100644 --- a/clang/test/Driver/hip-toolchain-rdc.hip +++ b/clang/test/Driver/hip-toolchain-rdc.hip @@ -12,7 +12,23 @@ // RUN: %S/Inputs/hip_multiple_inputs/b.hip \ // RUN: 2>&1 | FileCheck %s -// CHECK: [[CLANG:".*clang.*"]] "-cc1" "-triple" "amdgcn-amd-amdhsa" +// emit objects for host side path +// CHECK: [[CLANG:".*clang.*"]] "-cc1" "-triple" "x86_64-unknown-linux-gnu" +// CHECK-SAME: "-aux-triple" "amdgcn-amd-amdhsa" +// CHECK-SAME: "-emit-obj" +// CHECK-SAME: {{.*}} "-main-file-name" "a.cu" +// CHECK-SAME: {{.*}} "-o" [[A_OBJ_HOST:".*o"]] "-x" "hip" +// CHECK-SAME: {{.*}} [[A_SRC:".*a.cu"]] + +// CHECK: [[CLANG]] "-cc1" "-triple" "x86_64-unknown-linux-gnu" +// CHECK-SAME: "-aux-triple" "amdgcn-amd-amdhsa" +// CHECK-SAME: "-emit-obj" +// CHECK-SAME: {{.*}} "-main-file-name" "b.hip" +// CHECK-SAME: {{.*}} "-o" [[B_OBJ_HOST:".*o"]] "-x" "hip" +// CHECK-SAME: {{.*}} [[B_SRC:".*b.hip"]] + +// generate image for device side path on gfx803 +// CHECK: [[CLANG]] "-cc1" "-triple" "amdgcn-amd-amdhsa" // CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" // CHECK-SAME: "-emit-llvm-bc" // CHECK-SAME: {{.*}} "-main-file-name" "a.cu" @@ -21,7 +37,7 @@ // CHECK-SAME: "{{.*}}lib1.bc" "{{.*}}lib2.bc" // CHECK-SAME: "-target-cpu" "gfx803" // CHECK-SAME: {{.*}} "-o" [[A_BC1:".*bc"]] "-x" "hip" -// CHECK-SAME: {{.*}} [[A_SRC:".*a.cu"]] +// CHECK-SAME: {{.*}} [[A_SRC]] // CHECK: [[CLANG]] "-cc1" "-triple" "amdgcn-amd-amdhsa" // CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" @@ -32,14 +48,16 @@ // CHECK-SAME: "{{.*}}lib1.bc" "{{.*}}lib2.bc" // CHECK-SAME: "-target-cpu" "gfx803" // CHECK-SAME: {{.*}} "-o" [[B_BC1:".*bc"]] "-x" "hip" -// CHECK-SAME: {{.*}} [[B_SRC:".*b.hip"]] +// CHECK-SAME: {{.*}} [[B_SRC]] // CHECK-NOT: "*.llvm-link" // CHECK-NOT: ".*opt" // CHECK-NOT: ".*llc" -// CHECK: {{".*lld.*"}} {{.*}} "-mllvm" "-amdgpu-internalize-symbols" +// CHECK: {{".*lld.*"}} {{.*}} "-plugin-opt=-amdgpu-internalize-symbols" +// CHECK-SAME: "-plugin-opt=mcpu=gfx803" // CHECK-SAME: "-o" "[[IMG_DEV1:.*.out]]" [[A_BC1]] [[B_BC1]] +// generate image for device side path on gfx900 // CHECK: [[CLANG]] "-cc1" "-triple" "amdgcn-amd-amdhsa" // CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" // CHECK-SAME: "-emit-llvm-bc" @@ -63,26 +81,16 @@ // CHECK-NOT: "*.llvm-link" // CHECK-NOT: ".*opt" // CHECK-NOT: ".*llc" -// CHECK: {{".*lld.*"}} {{.*}} "-mllvm" "-amdgpu-internalize-symbols" +// CHECK: {{".*lld.*"}} {{.*}} "-plugin-opt=-amdgpu-internalize-symbols" +// CHECK-SAME: "-plugin-opt=mcpu=gfx900" // CHECK-SAME: "-o" "[[IMG_DEV2:.*.out]]" [[A_BC2]] [[B_BC2]] -// CHECK: [[CLANG]] "-cc1" "-triple" "x86_64-unknown-linux-gnu" -// CHECK-SAME: "-aux-triple" "amdgcn-amd-amdhsa" -// CHECK-SAME: "-emit-obj" -// CHECK-SAME: {{.*}} "-main-file-name" "a.cu" -// CHECK-SAME: {{.*}} "-o" [[A_OBJ_HOST:".*o"]] "-x" "hip" -// CHECK-SAME: {{.*}} [[A_SRC]] - -// CHECK: [[CLANG]] "-cc1" "-triple" "x86_64-unknown-linux-gnu" -// CHECK-SAME: "-aux-triple" "amdgcn-amd-amdhsa" -// CHECK-SAME: "-emit-obj" -// CHECK-SAME: {{.*}} "-main-file-name" "b.hip" -// CHECK-SAME: {{.*}} "-o" [[B_OBJ_HOST:".*o"]] "-x" "hip" -// CHECK-SAME: {{.*}} [[B_SRC]] - +// combine images generated into hip fat binary object // CHECK: [[BUNDLER:".*clang-offload-bundler"]] "-type=o" // CHECK-SAME: "-targets={{.*}},hip-amdgcn-amd-amdhsa-gfx803,hip-amdgcn-amd-amdhsa-gfx900" // CHECK-SAME: "-inputs={{.*}},[[IMG_DEV1]],[[IMG_DEV2]]" "-outputs=[[BUNDLE:.*hipfb]]" -// CHECK: [[LD:".*ld.*"]] {{.*}} [[A_OBJ_HOST]] [[B_OBJ_HOST]] -// CHECK-SAME: {{.*}} "-T" "{{.*}}.lk" +// CHECK: [[MC:".*llvm-mc"]] "-o" [[OBJBUNDLE:".*o"]] "{{.*}}.mcin" "--filetype=obj" + +// output the executable +// CHECK: [[LD:".*ld.*"]] {{.*}}"-o" "a.out" {{.*}} [[A_OBJ_HOST]] [[B_OBJ_HOST]] [[OBJBUNDLE]] diff --git a/clang/test/Driver/hip-version.hip b/clang/test/Driver/hip-version.hip new file mode 100644 index 0000000000000..eb1295210cfc1 --- /dev/null +++ b/clang/test/Driver/hip-version.hip @@ -0,0 +1,42 @@ +// REQUIRES: clang-driver +// REQUIRES: x86-registered-target +// REQUIRES: amdgpu-registered-target + +// RUN: %clang -v --rocm-path=%S/Inputs/rocm 2>&1 \ +// RUN: | FileCheck -check-prefixes=FOUND %s + +// RUN: %clang -v --rocm-path=%S/Inputs/rocm 2>&1 \ +// RUN: -target amdgcn-amd-amdhsa \ +// RUN: | FileCheck -check-prefixes=FOUND %s + +// FOUND: Found HIP installation: {{.*Inputs.*rocm}}, version 3.6.20214-a2917cd + +// When --rocm-path is set and .hipVersion is not found, use default version + +// RUN: %clang -v --rocm-path=%S 2>&1 \ +// RUN: | FileCheck -check-prefixes=DEFAULT %s + +// RUN: %clang -v --rocm-path=%S 2>&1 \ +// RUN: -target amdgcn-amd-amdhsa \ +// RUN: | FileCheck -check-prefixes=DEFAULT %s + +// DEFAULT: Found HIP installation: {{.*Driver}}, version 3.5. + +// RUN: %clang -v --rocm-path=%S --hip-version=3.7.0 2>&1 \ +// RUN: | FileCheck -check-prefixes=SPECIFIED %s + +// RUN: %clang -v --rocm-path=%S --hip-version=3.7.0 2>&1 \ +// RUN: -target amdgcn-amd-amdhsa \ +// RUN: | FileCheck -check-prefixes=SPECIFIED %s + +// SPECIFIED: Found HIP installation: {{.*Driver}}, version 3.7.0 + +// RUN: %clang -v --rocm-path=%S --hip-version=3.7 2>&1 \ +// RUN: | FileCheck -check-prefixes=SPECIFIED2 %s + +// SPECIFIED2: Found HIP installation: {{.*Driver}}, version 3.7.0 + +// RUN: not %clang -v --rocm-path=%S --hip-version=x.y 2>&1 \ +// RUN: | FileCheck -check-prefixes=INVALID %s + +// INVALID: error: invalid value 'x.y' in '--hip-version=x.y' diff --git a/clang/test/Driver/integrated-as.s b/clang/test/Driver/integrated-as.s index 0194a3d5a4382..05999cfe002b5 100644 --- a/clang/test/Driver/integrated-as.s +++ b/clang/test/Driver/integrated-as.s @@ -27,19 +27,19 @@ // XA_INCLUDE2: "-Ifoo_dir" // RUN: %clang -### -target x86_64--- -c -integrated-as %s -gdwarf-4 -gdwarf-2 2>&1 | FileCheck --check-prefix=DWARF2 %s -// DWARF2: "-debug-info-kind=limited" "-dwarf-version=2" +// DWARF2: "-debug-info-kind=constructor" "-dwarf-version=2" // RUN: %clang -### -target x86_64--- -c -integrated-as %s -gdwarf-3 2>&1 | FileCheck --check-prefix=DWARF3 %s -// DWARF3: "-debug-info-kind=limited" "-dwarf-version=3" +// DWARF3: "-debug-info-kind=constructor" "-dwarf-version=3" // RUN: %clang -### -target x86_64--- -c -integrated-as %s -gdwarf-4 2>&1 | FileCheck --check-prefix=DWARF4 %s -// DWARF4: "-debug-info-kind=limited" "-dwarf-version=4" +// DWARF4: "-debug-info-kind=constructor" "-dwarf-version=4" // RUN: %clang -### -target x86_64--- -c -integrated-as %s -Xassembler -gdwarf-2 2>&1 | FileCheck --check-prefix=DWARF2XASSEMBLER %s -// DWARF2XASSEMBLER: "-debug-info-kind=limited" "-dwarf-version=2" +// DWARF2XASSEMBLER: "-debug-info-kind=constructor" "-dwarf-version=2" // RUN: %clang -### -target x86_64--- -c -integrated-as %s -Wa,-gdwarf-2 2>&1 | FileCheck --check-prefix=DWARF2WA %s -// DWARF2WA: "-debug-info-kind=limited" "-dwarf-version=2" +// DWARF2WA: "-debug-info-kind=constructor" "-dwarf-version=2" // A dwarf version number that driver can't parse is just stuffed in. // RUN: %clang -### -target x86_64--- -c -integrated-as %s -Wa,-gdwarf-huh 2>&1 | FileCheck --check-prefix=BOGODWARF %s diff --git a/clang/test/Driver/macos-apple-silicon-slice-link-libs.cpp b/clang/test/Driver/macos-apple-silicon-slice-link-libs.cpp new file mode 100644 index 0000000000000..522fda34987e9 --- /dev/null +++ b/clang/test/Driver/macos-apple-silicon-slice-link-libs.cpp @@ -0,0 +1,42 @@ +// RUN: %clang -### -target arm64-apple-macos10.7 %s 2>&1 | FileCheck -check-prefix=ARM64-10_7 %s +// RUN: %clang -### -target x86_64-apple-macos10.7 %s 2>&1 | FileCheck -check-prefix=x86_64-10_7 %s + +// RUN: %clang -### -target arm64-apple-macos10.5 %s 2>&1 | FileCheck -check-prefix=ARM64-10_5 %s +// RUN: %clang -### -target x86_64-apple-macos10.5 %s 2>&1 | FileCheck -check-prefix=x86_64-10_5 %s + +// RUN: %clang -### -target arm64-apple-macos10.4 %s 2>&1 | FileCheck -check-prefix=ARM64-10_4 %s +// RUN: %clang -### -target x86_64-apple-macos10.4 %s 2>&1 | FileCheck -check-prefix=x86_64-10_4 %s + +// RUN: %clang -### -target arm64-apple-macos10.5 -bundle %s 2>&1 | FileCheck -check-prefix=ARM64-BUNDLE %s +// RUN: %clang -### -target x86_64-apple-macos10.5 -bundle %s 2>&1 | FileCheck -check-prefix=x86_64-BUNDLE %s + +// RUN: %clang -### -target arm64-apple-macos10.5 -dynamiclib %s 2>&1 | FileCheck -check-prefix=ARM64-10_5-DYNAMICLIB %s +// RUN: %clang -### -target x86_64-apple-macos10.5 -dynamiclib %s 2>&1 | FileCheck -check-prefix=x86_64-10_5-DYNAMICLIB %s + +// RUN: %clang -### -target arm64-apple-macos10.4 -dynamiclib %s 2>&1 | FileCheck -check-prefix=ARM64-10_4-DYNAMICLIB %s +// RUN: %clang -### -target arm64-apple-darwin8 -dynamiclib %s 2>&1 | FileCheck -check-prefix=ARM64-10_4-DYNAMICLIB %s +// RUN: %clang -### -target x86_64-apple-macos10.4 -dynamiclib %s 2>&1 | FileCheck -check-prefix=x86_64-10_4-DYNAMICLIB %s +// RUN: %clang -### -target x86_64-apple-darwin8 -dynamiclib %s 2>&1 | FileCheck -check-prefix=x86_64-10_4-DYNAMICLIB %s + +// RUN: %clang -### -target arm64-apple-macos10.7 -static %s 2>&1 | FileCheck -check-prefix=STATIC %s +// RUN: %clang -### -target x86_64-apple-macos10.7 -static %s 2>&1 | FileCheck -check-prefix=STATIC %s + +// ARM64-10_7-NOT: -lcrt1.10.6.o +// x86_64-10_7: -lcrt1.10.6.o + +// ARM64-10_5-NOT: -lcrt1.10.5.o +// x86_64-10_5: -lcrt1.10.5.o + +// ARM64-10_4-NOT: -lcrt1.o +// x86_64-10_4: -lcrt1.o + +// ARM64-BUNDLE-NOT: -lbundle1.o +// x86_64-BUNDLE: -lbundle1.o + +// ARM64-10_5-DYNAMICLIB-NOT: -ldylib1.10.5.o +// x86_64-10_5-DYNAMICLIB: -ldylib1.10.5.o + +// ARM64-10_4-DYNAMICLIB-NOT: -ldylib1.o +// x86_64-10_4-DYNAMICLIB: -ldylib1.o + +// STATIC: -lcrt0.o diff --git a/clang/test/Driver/modules-cache-path.m b/clang/test/Driver/modules-cache-path.m index 419d6d479f6b2..51df6739a5055 100644 --- a/clang/test/Driver/modules-cache-path.m +++ b/clang/test/Driver/modules-cache-path.m @@ -1,5 +1,2 @@ -// RUN: env USERNAME=asdf LOGNAME=asdf %clang -fmodules -### %s 2>&1 | FileCheck %s -check-prefix=CHECK-SET -// CHECK-SET: -fmodules-cache-path={{.*}}org.llvm.clang.asdf{{[/\\]+}}ModuleCache - // RUN: %clang -fmodules -### %s 2>&1 | FileCheck %s -check-prefix=CHECK-DEFAULT -// CHECK-DEFAULT: -fmodules-cache-path={{.*}}org.llvm.clang.{{[A-Za-z0-9_]*[/\\]+}}ModuleCache +// CHECK-DEFAULT: -fmodules-cache-path={{.*}}clang{{[/\\]+}}ModuleCache diff --git a/clang/test/Driver/myriad-toolchain.c b/clang/test/Driver/myriad-toolchain.c index 215a02fd0dec1..a4bd260a14986 100644 --- a/clang/test/Driver/myriad-toolchain.c +++ b/clang/test/Driver/myriad-toolchain.c @@ -83,7 +83,7 @@ // NOSTDLIB-NOT: "-lc" // RUN: %clang -### -c -g %s -target sparc-myriad 2>&1 | FileCheck -check-prefix=G_SPARC %s -// G_SPARC: "-debug-info-kind=limited" "-dwarf-version=2" +// G_SPARC: "-debug-info-kind=constructor" "-dwarf-version=2" // RUN: %clang -### -c %s -target sparc-myriad-rtems -fuse-init-array 2>&1 \ // RUN: | FileCheck -check-prefix=USE-INIT-ARRAY %s diff --git a/clang/test/Driver/openmp-offload-gpu.c b/clang/test/Driver/openmp-offload-gpu.c index 6415f1d61b720..3ddd6446d1176 100644 --- a/clang/test/Driver/openmp-offload-gpu.c +++ b/clang/test/Driver/openmp-offload-gpu.c @@ -241,7 +241,7 @@ // HAS_DEBUG-NOT: warning: debug // HAS_DEBUG: "-triple" "nvptx64-nvidia-cuda" -// HAS_DEBUG-SAME: "-debug-info-kind={{limited|line-tables-only}}" +// HAS_DEBUG-SAME: "-debug-info-kind={{constructor|line-tables-only}}" // HAS_DEBUG-SAME: "-dwarf-version=2" // HAS_DEBUG-SAME: "-fopenmp-is-device" // HAS_DEBUG: ptxas diff --git a/clang/test/Driver/program-path-priority.c b/clang/test/Driver/program-path-priority.c new file mode 100644 index 0000000000000..ba893e7e2e2cd --- /dev/null +++ b/clang/test/Driver/program-path-priority.c @@ -0,0 +1,109 @@ +/// Don't create symlinks on Windows +// UNSUPPORTED: system-windows + +/// Check the priority used when searching for tools +/// Names and locations are usually in this order: +/// -tool, tool, -tool +/// program path, PATH +/// (from highest to lowest priority) +/// A higher priority name found in a lower priority +/// location will win over a lower priority name in a +/// higher priority location. +/// Prefix dirs (added with -B) override the location, +/// so only name priority is accounted for, unless we fail to find +/// anything at all in the prefix. + +/// Symlink clang to a new dir which will be its +/// "program path" for these tests +// RUN: rm -rf %t && mkdir -p %t +// RUN: ln -s %clang %t/clang + +/// No gccs at all, nothing is found +// RUN: env "PATH=" %t/clang -### -target notreal-none-elf %s 2>&1 | \ +// RUN: FileCheck --check-prefix=NO_NOTREAL_GCC %s +// NO_NOTREAL_GCC-NOT: notreal-none-elf-gcc +// NO_NOTREAL_GCC-NOT: /gcc + +/// -gcc in program path is found +// RUN: touch %t/notreal-none-elf-gcc && chmod +x %t/notreal-none-elf-gcc +// RUN: env "PATH=" %t/clang -### -target notreal-none-elf %s 2>&1 | \ +// RUN: FileCheck --check-prefix=PROG_PATH_NOTREAL_GCC %s +// PROG_PATH_NOTREAL_GCC: notreal-none-elf-gcc + +/// -gcc on the PATH is found +// RUN: mkdir -p %t/env +// RUN: rm %t/notreal-none-elf-gcc +// RUN: touch %t/env/notreal-none-elf-gcc && chmod +x %t/env/notreal-none-elf-gcc +// RUN: env "PATH=%t/env/" %t/clang -### -target notreal-none-elf %s 2>&1 | \ +// RUN: FileCheck --check-prefix=ENV_PATH_NOTREAL_GCC %s +// ENV_PATH_NOTREAL_GCC: env/notreal-none-elf-gcc + +/// -gcc in program path is preferred to one on the PATH +// RUN: touch %t/notreal-none-elf-gcc && chmod +x %t/notreal-none-elf-gcc +// RUN: env "PATH=%t/env/" %t/clang -### -target notreal-none-elf %s 2>&1 | \ +// RUN: FileCheck --check-prefix=BOTH_NOTREAL_GCC %s +// BOTH_NOTREAL_GCC: notreal-none-elf-gcc +// BOTH_NOTREAL_GCC-NOT: env/notreal-none-elf-gcc + +/// On program path, -gcc is preferred to plain gcc +// RUN: touch %t/gcc && chmod +x %t/gcc +// RUN: env "PATH=" %t/clang -### -target notreal-none-elf %s 2>&1 | \ +// RUN: FileCheck --check-prefix=NOTREAL_GCC_PREFERRED %s +// NOTREAL_GCC_PREFERRED: notreal-none-elf-gcc +// NOTREAL_GCC_PREFERRED-NOT: /gcc + +/// -gcc on the PATH is preferred to gcc in program path +// RUN: rm %t/notreal-none-elf-gcc +// RUN: env "PATH=%t/env/" %t/clang -### -target notreal-none-elf %s 2>&1 | \ +// RUN: FileCheck --check-prefix=NOTREAL_PATH_OVER_GCC_PROG %s +// NOTREAL_PATH_OVER_GCC_PROG: env/notreal-none-elf-gcc +// NOTREAL_PATH_OVER_GCC_PROG-NOT: /gcc + +/// -gcc on the PATH is preferred to gcc on the PATH +// RUN: rm %t/gcc +// RUN: touch %t/env/gcc && chmod +x %t/env/gcc +// RUN: env "PATH=%t/env/" %t/clang -### -target notreal-none-elf %s 2>&1 | \ +// RUN: FileCheck --check-prefix=NOTREAL_PATH_OVER_GCC_PATH %s +// NOTREAL_PATH_OVER_GCC_PATH: env/notreal-none-elf-gcc +// NOTREAL_PATH_OVER_GCC_PATH-NOT: /gcc + +/// -gcc has lowest priority so -gcc +/// on PATH beats default triple in program path +/// Darwin triples have a version appended to them, even if set via +/// LLVM_DEFAULT_TARGET_TRIPLE. So the only way to know for sure is to ask clang. +// RUN: DEFAULT_TRIPLE=`%t/clang --version | grep "Target:" | cut -d ' ' -f2` +// RUN: touch %t/$DEFAULT_TRIPLE-gcc && chmod +x %t/$DEFAULT_TRIPLE-gcc +// RUN: env "PATH=%t/env/" %t/clang -### -target notreal-none-elf %s 2>&1 | \ +// RUN: FileCheck --check-prefix=DEFAULT_TRIPLE_GCC %s +// DEFAULT_TRIPLE_GCC: env/notreal-none-elf-gcc + +/// plain gcc on PATH beats default triple in program path +// RUN: rm %t/env/notreal-none-elf-gcc +// RUN: env "PATH=%t/env/" %t/clang -### -target notreal-none-elf %s 2>&1 | \ +// RUN: FileCheck --check-prefix=DEFAULT_TRIPLE_NO_NOTREAL %s +// DEFAULT_TRIPLE_NO_NOTREAL: env/gcc +// DEFAULT_TRIPLE_NO_NOTREAL-NOT: -gcc + +/// default triple only chosen when no others are present +// RUN: rm %t/env/gcc +// RUN: env "PATH=%t/env/" %t/clang -### -target notreal-none-elf %s 2>&1 | \ +// RUN: FileCheck --check-prefix=DEFAULT_TRIPLE_NO_OTHERS %s +// DEFAULT_TRIPLE_NO_OTHERS: -gcc +// DEFAULT_TRIPLE_NO_OTHERS-NOT: notreal-none-elf-gcc +// DEFAULT_TRIPLE_NO_OTHERS-NOT: /gcc + +/// -B paths are searched separately so default triple will win +/// if put in one of those even if other paths have higher priority names +// RUN: mkdir -p %t/prefix +// RUN: mv %t/$DEFAULT_TRIPLE-gcc %t/prefix +// RUN: touch %t/notreal-none-elf-gcc && chmod +x %t/notreal-none-elf-gcc +// RUN: env "PATH=" %t/clang -### -target notreal-none-elf %s -B %t/prefix 2>&1 | \ +// RUN: FileCheck --check-prefix=DEFAULT_TRIPLE_IN_PREFIX %s +// DEFAULT_TRIPLE_IN_PREFIX: prefix/{{.*}}-gcc +// DEFAULT_TRIPLE_IN_PREFIX-NOT: notreal-none-elf-gcc + +/// Only if there is nothing in the prefix will we search other paths +// RUN: rm %t/prefix/$DEFAULT_TRIPLE-gcc +// RUN: env "PATH=" %t/clang -### -target notreal-none-elf %s -B %t/prefix 2>&1 | \ +// RUN: FileCheck --check-prefix=EMPTY_PREFIX_DIR %s +// EMPTY_PREFIX_DIR: notreal-none-elf-gcc diff --git a/clang/test/Driver/riscv-arch.c b/clang/test/Driver/riscv-arch.c index ba93be9caa36e..e3062feb7dee0 100644 --- a/clang/test/Driver/riscv-arch.c +++ b/clang/test/Driver/riscv-arch.c @@ -360,3 +360,22 @@ // RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBB-ZBP %s // RV32-EXPERIMENTAL-ZBB-ZBP: "-target-feature" "+experimental-zbb" // RV32-EXPERIMENTAL-ZBB-ZBP: "-target-feature" "+experimental-zbp" + +// RUN: %clang -target riscv32-unknown-elf -march=rv32iv -### %s -c 2>&1 | \ +// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-V-NOFLAG %s +// RV32-EXPERIMENTAL-V-NOFLAG: error: invalid arch name 'rv32iv' +// RV32-EXPERIMENTAL-V-NOFLAG: requires '-menable-experimental-extensions' + +// RUN: %clang -target riscv32-unknown-elf -march=rv32iv -menable-experimental-extensions -### %s -c 2>&1 | \ +// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-V-NOVERS %s +// RV32-EXPERIMENTAL-V-NOVERS: error: invalid arch name 'rv32iv' +// RV32-EXPERIMENTAL-V-NOVERS: experimental extension requires explicit version number + +// RUN: %clang -target riscv32-unknown-elf -march=rv32iv0p1 -menable-experimental-extensions -### %s -c 2>&1 | \ +// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-V-BADVERS %s +// RV32-EXPERIMENTAL-V-BADVERS: error: invalid arch name 'rv32iv0p1' +// RV32-EXPERIMENTAL-V-BADVERS: unsupported version number 0.1 for experimental extension + +// RUN: %clang -target riscv32-unknown-elf -march=rv32iv0p8 -menable-experimental-extensions -### %s -c 2>&1 | \ +// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-V-GOODVERS %s +// RV32-EXPERIMENTAL-V-GOODVERS: "-target-feature" "+experimental-v" diff --git a/clang/test/Driver/rocm-detect.cl b/clang/test/Driver/rocm-detect.cl index 75378bf003bee..2fac3aa7cc8d2 100644 --- a/clang/test/Driver/rocm-detect.cl +++ b/clang/test/Driver/rocm-detect.cl @@ -16,6 +16,6 @@ // RUN: | FileCheck -check-prefixes=COMMON,GFX902,NODEFAULTLIBS %s -// GFX902-DEFAULTLIBS: error: cannot find device library for gfx902. Provide path to different ROCm installation via --rocm-path, or pass -nogpulib to build without linking default libraries. +// GFX902-DEFAULTLIBS: error: cannot find ROCm device library for gfx902. Provide its path via --rocm-path or --rocm-device-lib-path, or pass -nogpulib to build without ROCm device library // NODEFAULTLIBS-NOT: error: cannot find diff --git a/clang/test/Driver/rocm-detect.hip b/clang/test/Driver/rocm-detect.hip index 9490ec9ba3762..3a3a028facb48 100644 --- a/clang/test/Driver/rocm-detect.hip +++ b/clang/test/Driver/rocm-detect.hip @@ -22,6 +22,6 @@ // RUN: | FileCheck -check-prefixes=COMMON,GFX902,NODEFAULTLIBS %s -// GFX902-DEFAULTLIBS: error: cannot find device library for gfx902. Provide path to different ROCm installation via --rocm-path, or pass -nogpulib to build without linking default libraries. +// GFX902-DEFAULTLIBS: error: cannot find ROCm device library for gfx902. Provide its path via --rocm-path or --rocm-device-lib-path, or pass -nogpulib to build without ROCm device library // NODEFAULTLIBS-NOT: error: cannot find diff --git a/clang/test/Driver/rocm-not-found.cl b/clang/test/Driver/rocm-not-found.cl index ee931971d9e6a..122f826714b51 100644 --- a/clang/test/Driver/rocm-not-found.cl +++ b/clang/test/Driver/rocm-not-found.cl @@ -5,7 +5,7 @@ // RUN: %clang -### --sysroot=%s/no-rocm-there -target amdgcn--amdhsa %s 2>&1 | FileCheck %s --check-prefix ERR // RUN: %clang -### --rocm-path=%s/no-rocm-there -target amdgcn--amdhsa %s 2>&1 | FileCheck %s --check-prefix ERR -// ERR: cannot find ROCm installation. Provide its path via --rocm-path, or pass -nogpulib and -nogpuinc to build without ROCm device library and HIP includes. +// ERR: cannot find ROCm device library. Provide its path via --rocm-path or --rocm-device-lib-path, or pass -nogpulib to build without ROCm device library // Accept nogpulib or nostdlib for OpenCL. // RUN: %clang -### -nogpulib --rocm-path=%s/no-rocm-there %s 2>&1 | FileCheck %s --check-prefix OK diff --git a/clang/test/Driver/split-debug.c b/clang/test/Driver/split-debug.c index d40207d5ae3b6..70f8d91d48e01 100644 --- a/clang/test/Driver/split-debug.c +++ b/clang/test/Driver/split-debug.c @@ -68,18 +68,18 @@ // RUN: FileCheck -check-prefix=CHECK-NOINLINE-WITHOUT-SPLIT < %t %s // // CHECK-NOINLINE-WITHOUT-SPLIT: "-fno-split-dwarf-inlining" -// CHECK-NOINLINE-WITHOUT-SPLIT: "-debug-info-kind=limited" +// CHECK-NOINLINE-WITHOUT-SPLIT: "-debug-info-kind=constructor" // RUN: %clang -target x86_64-unknown-linux-gnu -gmlt -gsplit-dwarf -fno-split-dwarf-inlining -S -### %s 2> %t // RUN: FileCheck -check-prefix=CHECK-SPLIT-WITH-GMLT < %t %s // -// CHECK-SPLIT-WITH-GMLT: "-debug-info-kind=limited" +// CHECK-SPLIT-WITH-GMLT: "-debug-info-kind=constructor" // CHECK-SPLIT-WITH-GMLT: "-split-dwarf-output" // RUN: %clang -target x86_64-unknown-linux-gnu -gsplit-dwarf -fno-split-dwarf-inlining -S -### %s 2> %t // RUN: FileCheck -check-prefix=CHECK-SPLIT-WITH-NOINL < %t %s // -// CHECK-SPLIT-WITH-NOINL: "-debug-info-kind=limited" +// CHECK-SPLIT-WITH-NOINL: "-debug-info-kind=constructor" // CHECK-SPLIT-WITH-NOINL: "-split-dwarf-output" // RUN: %clang -target x86_64-unknown-linux-gnu -gsplit-dwarf -gmlt -fsplit-dwarf-inlining -S -### %s 2> %t @@ -92,7 +92,7 @@ // RUN: %clang -target x86_64-unknown-linux-gnu -gmlt -gsplit-dwarf -S -### %s 2> %t // RUN: FileCheck -check-prefix=CHECK-SPLIT-OVER-GMLT < %t %s // -// CHECK-SPLIT-OVER-GMLT: "-debug-info-kind=limited" +// CHECK-SPLIT-OVER-GMLT: "-debug-info-kind=constructor" // CHECK-SPLIT-OVER-GMLT: "-split-dwarf-file" // CHECK-SPLIT-OVER-GMLT: "-split-dwarf-output" @@ -117,6 +117,6 @@ // RUN: %clang -target x86_64-unknown-linux-gnu -g0 -gsplit-dwarf=split -S -### %s 2> %t // RUN: FileCheck -check-prefix=CHECK-SPLIT-OVER-G0 < %t %s // -// CHECK-SPLIT-OVER-G0: "-debug-info-kind=limited" +// CHECK-SPLIT-OVER-G0: "-debug-info-kind=constructor" // CHECK-SPLIT-OVER-G0: "-split-dwarf-file" // CHECK-SPLIT-OVER-G0: "-split-dwarf-output" diff --git a/clang/test/Driver/ve-toolchain.c b/clang/test/Driver/ve-toolchain.c new file mode 100644 index 0000000000000..7b93797ee5970 --- /dev/null +++ b/clang/test/Driver/ve-toolchain.c @@ -0,0 +1,82 @@ +/// Check the behavior of toolchain for NEC Aurora VE +/// REQUIRES: ve-registered-target + +///----------------------------------------------------------------------------- +/// Checking dwarf-version + +// RUN: %clang -### -g -target ve %s 2>&1 | FileCheck -check-prefix=DWARF_VER %s +// DWARF_VER: "-dwarf-version=4" + +///----------------------------------------------------------------------------- +/// Checking dynamic-linker + +// RUN: %clang -### -target ve %s 2>&1 | FileCheck -check-prefix=DYNLINKER %s +// DYNLINKER: nld{{.*}} "-dynamic-linker" "/opt/nec/ve/lib/ld-linux-ve.so.1" + +///----------------------------------------------------------------------------- +/// Checking VE specific option + +// RUN: %clang -### -target ve %s 2>&1 | FileCheck -check-prefix=VENLDOPT %s +// VENLDOPT: nld{{.*}} "-z" "max-page-size=0x4000000" + +///----------------------------------------------------------------------------- +/// Checking include-path + +// RUN: %clang -### -target ve %s 2>&1 | FileCheck -check-prefix=DEFINC %s +// DEFINC: clang{{.*}} "-cc1" +// DEFINC: "-nostdsysteminc" +// DEFINC: "-internal-isystem" "{{.*}}/lib/clang/{{[0-9.]*}}/include" +// DEFINC: "-internal-isystem" "/opt/nec/ve/include" + +// RUN: %clang -### -target ve %s -nostdlibinc 2>&1 | \ +// RUN: FileCheck -check-prefix=NOSTDLIBINC %s +// NOSTDLIBINC: clang{{.*}} "-cc1" +// NOSTDLIBINC: "-internal-isystem" "{{.*}}/lib/clang/{{[0-9.]*}}/include" +// NOSTDLIBINC-NOT: "-internal-isystem" "/opt/nec/ve/include" + +// RUN: %clang -### -target ve %s -nobuiltininc 2>&1 | \ +// RUN: FileCheck -check-prefix=NOBUILTININC %s +// NOBUILTININC: clang{{.*}} "-cc1" +// NOBUILTININC: "-nobuiltininc" +// NOBUILTININC-NOT: "-internal-isystem" "{{.*}}/lib/clang/{{[0-9.]*}}/include" +// NOBUILTININC: "-internal-isystem" "/opt/nec/ve/include" + +// RUN: %clang -### -target ve %s -nostdinc 2>&1 | \ +// RUN: FileCheck -check-prefix=NOSTDINC %s +// NOSTDINC: clang{{.*}} "-cc1" +// NOSTDINC: "-nobuiltininc" +// NOSTDINC-NOT: "-internal-isystem" "{{.*}}/lib/clang/{{[0-9.]*}}/include" +// NOSTDINC-NOT: "-internal-isystem" "/opt/nec/ve/include" + +///----------------------------------------------------------------------------- +/// Checking -fuse-init-array + +// RUN: %clang -### -target ve %s 2>&1 | FileCheck -check-prefix=DEFINITARRAY %s +// DEFINITARRAY: clang{{.*}} "-cc1" +// DEFINITARRAY-NOT: "-fuse-init-array" + +// RUN: %clang -### -target ve %s -fno-use-init-array 2>&1 | \ +// RUN: FileCheck -check-prefix=NOTINITARRAY %s +// NOTINITARRAY: clang{{.*}} "-cc1" +// NOTINITARRAY: "-fno-use-init-array" + +///----------------------------------------------------------------------------- +/// Checking exceptions + +// RUN: %clang -### -target ve %s 2>&1 | FileCheck -check-prefix=DEFEXCEPTION %s +// DEFEXCEPTION: clang{{.*}} "-cc1" +// DEFEXCEPTION: "-fsjlj-exceptions" + +///----------------------------------------------------------------------------- +/// Passing -fintegrated-as + +// RUN: %clang -### -target ve -x assembler %s 2>&1 | \ +// RUN: FileCheck -check-prefix=NAS_LINK %s +// RUN: %clang -### -target ve -fintegrated-as -x assembler %s 2>&1 | \ +// RUN: FileCheck -check-prefix=AS_LINK %s + +// NAS_LINK: nas{{.*}} +// NAS_LINK: nld{{.*}} + +// AS_LINK: clang{{.*}} "-cc1as" +// AS_LINK: nld{{.*}} diff --git a/clang/test/Driver/windows-thumbv7em.cpp b/clang/test/Driver/windows-thumbv7em.cpp new file mode 100644 index 0000000000000..5d7c00b31fd16 --- /dev/null +++ b/clang/test/Driver/windows-thumbv7em.cpp @@ -0,0 +1,8 @@ +// RUN: %clang -target thumb-none-windows-eabi-coff -mcpu=cortex-m7 -### -c %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix CHECK-V7 +// CHECK-V7-NOT: error: the target architecture 'thumbv7em' is not supported by the target 'thumbv7em-none-windows-eabi' + +// RUN: %clang -target thumb-none-windows-eabi-coff -mcpu=cortex-m1 -### -c %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix CHECK-V6 +// CHECK-V6: error: the target architecture 'thumbv6m' is not supported by the target 'thumbv6m-none-windows-eabi' + diff --git a/clang/test/Driver/x86-target-features.c b/clang/test/Driver/x86-target-features.c index b96eed287bd9f..85a9374ab9057 100644 --- a/clang/test/Driver/x86-target-features.c +++ b/clang/test/Driver/x86-target-features.c @@ -178,6 +178,27 @@ // RUN: %clang -target i386-linux-gnu -mlvi-hardening -mretpoline-external-thunk %s -### -o %t.o 2>&1 | FileCheck -check-prefix=LVIHARDENING-RETPOLINE-EXTERNAL-THUNK %s // LVIHARDENING-RETPOLINE-EXTERNAL-THUNK: error: invalid argument 'mretpoline-external-thunk' not allowed with 'mlvi-hardening' +// RUN: %clang -target i386-linux-gnu -mseses %s -### -o %t.o 2>&1 | FileCheck -check-prefix=SESES %s +// RUN: %clang -target i386-linux-gnu -mno-seses %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-SESES %s +// SESES: "-target-feature" "+seses" +// SESES: "-target-feature" "+lvi-cfi" +// NO-SESES-NOT: seses +// NO-SESES-NOT: lvi-cfi + +// RUN: %clang -target i386-linux-gnu -mseses -mno-lvi-cfi %s -### -o %t.o 2>&1 | FileCheck -check-prefix=SESES-NOLVICFI %s +// SESES-NOLVICFI: "-target-feature" "+seses" +// SESES-NOLVICFI-NOT: lvi-cfi + +// RUN: %clang -target i386-linux-gnu -mseses -mspeculative-load-hardening %s -### -o %t.o 2>&1 | FileCheck -check-prefix=SESES-SLH %s +// SESES-SLH: error: invalid argument 'mspeculative-load-hardening' not allowed with 'mseses' +// RUN: %clang -target i386-linux-gnu -mseses -mretpoline %s -### -o %t.o 2>&1 | FileCheck -check-prefix=SESES-RETPOLINE %s +// SESES-RETPOLINE: error: invalid argument 'mretpoline' not allowed with 'mseses' +// RUN: %clang -target i386-linux-gnu -mseses -mretpoline-external-thunk %s -### -o %t.o 2>&1 | FileCheck -check-prefix=SESES-RETPOLINE-EXTERNAL-THUNK %s +// SESES-RETPOLINE-EXTERNAL-THUNK: error: invalid argument 'mretpoline-external-thunk' not allowed with 'mseses' + +// RUN: %clang -target i386-linux-gnu -mseses -mlvi-hardening %s -### -o %t.o 2>&1 | FileCheck -check-prefix=SESES-LVIHARDENING %s +// SESES-LVIHARDENING: error: invalid argument 'mlvi-hardening' not allowed with 'mseses' + // RUN: %clang -target i386-linux-gnu -mwaitpkg %s -### -o %t.o 2>&1 | FileCheck -check-prefix=WAITPKG %s // RUN: %clang -target i386-linux-gnu -mno-waitpkg %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-WAITPKG %s // WAITPKG: "-target-feature" "+waitpkg" @@ -232,3 +253,18 @@ // RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-tsxldtrk %s -### -o %t.o 2>&1 | FileCheck --check-prefix=NO-TSXLDTRK %s // TSXLDTRK: "-target-feature" "+tsxldtrk" // NO-TSXLDTRK: "-target-feature" "-tsxldtrk" + +// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mamx-tile %s -### -o %t.o 2>&1 | FileCheck --check-prefix=AMX-TILE %s +// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-amx-tile %s -### -o %t.o 2>&1 | FileCheck --check-prefix=NO-AMX-TILE %s +// AMX-TILE: "-target-feature" "+amx-tile" +// NO-AMX-TILE: "-target-feature" "-amx-tile" + +// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mamx-bf16 %s -### -o %t.o 2>&1 | FileCheck --check-prefix=AMX-BF16 %s +// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-amx-bf16 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-AMX-BF16 %s +// AMX-BF16: "-target-feature" "+amx-bf16" +// NO-AMX-BF16: "-target-feature" "-amx-bf16" + +// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mamx-int8 %s -### -o %t.o 2>&1 | FileCheck --check-prefix=AMX-INT8 %s +// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-amx-int8 %s -### -o %t.o 2>&1 | FileCheck --check-prefix=NO-AMX-INT8 %s +// AMX-INT8: "-target-feature" "+amx-int8" +// NO-AMX-INT8: "-target-feature" "-amx-int8" diff --git a/clang/test/Frontend/fixed_point_add.c b/clang/test/Frontend/fixed_point_add.c index be3d5a8f5e9e0..078976503ecd0 100644 --- a/clang/test/Frontend/fixed_point_add.c +++ b/clang/test/Frontend/fixed_point_add.c @@ -413,7 +413,7 @@ void SaturatedAddition() { // SIGNED-NEXT: [[USA_SAT_RESIZE:%[a-z0-9]+]] = zext i16 [[USA_SAT]] to i40 // SIGNED-NEXT: [[I_RESIZE:%[a-z0-9]+]] = sext i32 [[I]] to i40 // SIGNED-NEXT: [[I_UPSCALE:%[a-z0-9]+]] = shl i40 [[I_RESIZE]], 8 - // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i40 @llvm.uadd.sat.i40(i40 [[USA_SAT_RESIZE]], i40 [[I_UPSCALE]]) + // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i40 @llvm.sadd.sat.i40(i40 [[USA_SAT_RESIZE]], i40 [[I_UPSCALE]]) // SIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i40 [[SUM]], 65535 // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = select i1 [[USE_MAX]], i40 65535, i40 [[SUM]] // SIGNED-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i40 [[RESULT]], 0 @@ -422,7 +422,7 @@ void SaturatedAddition() { // UNSIGNED-NEXT: [[USA_SAT_RESIZE:%[a-z0-9]+]] = zext i16 [[USA_SAT]] to i39 // UNSIGNED-NEXT: [[I_RESIZE:%[a-z0-9]+]] = sext i32 [[I]] to i39 // UNSIGNED-NEXT: [[I_UPSCALE:%[a-z0-9]+]] = shl i39 [[I_RESIZE]], 7 - // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i39 @llvm.uadd.sat.i39(i39 [[USA_SAT_RESIZE]], i39 [[I_UPSCALE]]) + // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i39 @llvm.sadd.sat.i39(i39 [[USA_SAT_RESIZE]], i39 [[I_UPSCALE]]) // UNSIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i39 [[SUM]], 32767 // UNSIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = select i1 [[USE_MAX]], i39 32767, i39 [[SUM]] // UNSIGNED-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i39 [[RESULT]], 0 diff --git a/clang/test/Frontend/fixed_point_crash.c b/clang/test/Frontend/fixed_point_crash.c new file mode 100644 index 0000000000000..12dc1944f018e --- /dev/null +++ b/clang/test/Frontend/fixed_point_crash.c @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -verify -ffixed-point %s + +union a { + _Accum x; + int i; +}; + +int fn1() { + union a m; + m.x = 5.6k; + return m.i; +} + +int fn2() { + union a m; + m.x = 7, 5.6k; // expected-warning {{expression result unused}} + return m.x, m.i; // expected-warning {{expression result unused}} +} + +_Accum acc = (0.5r, 6.9k); // expected-warning {{expression result unused}} diff --git a/clang/test/Frontend/fixed_point_div.c b/clang/test/Frontend/fixed_point_div.c index ec17e082558cb..b18ba59ae735c 100644 --- a/clang/test/Frontend/fixed_point_div.c +++ b/clang/test/Frontend/fixed_point_div.c @@ -1,6 +1,72 @@ // RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED // RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -fpadding-on-unsigned-fixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNSIGNED +// Division between different fixed point types +short _Accum sa_const = 1.0hk / 2.0hk; // CHECK-DAG: @sa_const = {{.*}}global i16 64, align 2 +_Accum a_const = 1.0hk / 2.0k; // CHECK-DAG: @a_const = {{.*}}global i32 16384, align 4 +long _Accum la_const = 1.0hk / 2.0lk; // CHECK-DAG: @la_const = {{.*}}global i64 1073741824, align 8 +short _Accum sa_const2 = 0.5hr / 2.0hk; // CHECK-DAG: @sa_const2 = {{.*}}global i16 32, align 2 +short _Accum sa_const3 = 0.5r / 2.0hk; // CHECK-DAG: @sa_const3 = {{.*}}global i16 32, align 2 +short _Accum sa_const4 = 0.5lr / 2.0hk; // CHECK-DAG: @sa_const4 = {{.*}}global i16 32, align 2 +short _Accum sa_const5 = 2.0hk / 0.5lr; // CHECK-DAG: @sa_const5 = {{.*}}global i16 512, align 2 + +// Unsigned division +unsigned short _Accum usa_const = 3.0uhk / 2.0uhk; +// CHECK-SIGNED-DAG: @usa_const = {{.*}}global i16 192, align 2 +// CHECK-UNSIGNED-DAG: @usa_const = {{.*}}global i16 384, align 2 + +// Unsigned / signed +short _Accum sa_const6 = 1.0uhk / 2.0hk; +// CHECK-DAG: @sa_const6 = {{.*}}global i16 64, align 2 + +// Division with negative number +short _Accum sa_const7 = 0.5hr / (-2.0hk); +// CHECK-DAG: @sa_const7 = {{.*}}global i16 -32, align 2 + +// Int division +unsigned short _Accum usa_const2 = 2 / 0.5uhk; +// CHECK-SIGNED-DAG: @usa_const2 = {{.*}}global i16 512, align 2 +// CHECK-UNSIGNED-DAG: @usa_const2 = {{.*}}global i16 1024, align 2 +short _Accum sa_const8 = 2 / (-0.5hk); // CHECK-DAG: @sa_const8 = {{.*}}global i16 -512, align 2 +short _Accum sa_const9 = 256 / 2.0hk; // CHECK-DAG: @sa_const9 = {{.*}}global i16 16384, align 2 +long _Fract lf_const = 0.5lr / -1; // CHECK-DAG: @lf_const = {{.*}}global i32 -1073741824, align 4 + +// Saturated division +_Sat short _Accum sat_sa_const = (_Sat short _Accum)128.0hk / (-0.25hk); +// CHECK-DAG: @sat_sa_const = {{.*}}global i16 -32768, align 2 +_Sat unsigned short _Accum sat_usa_const = (_Sat unsigned short _Accum)128.0uhk / (0.25uhk); +// CHECK-SIGNED-DAG: @sat_usa_const = {{.*}}global i16 65535, align 2 +// CHECK-UNSIGNED-DAG: @sat_usa_const = {{.*}}global i16 32767, align 2 +_Sat short _Accum sat_sa_const2 = (_Sat short _Accum)-128.0hk / (-0.0125hr); +// CHECK-DAG: @sat_sa_const2 = {{.*}}global i16 32767, align 2 +_Sat unsigned short _Accum sat_usa_const2 = (_Sat unsigned short _Accum)128.0uhk / (-128); +// CHECK-SIGNED-DAG: @sat_usa_const2 = {{.*}}global i16 65535, align 2 +// CHECK-UNSIGNED-DAG: @sat_usa_const2 = {{.*}}global i16 32767, align 2 +_Sat unsigned short _Accum sat_usa_const3 = (_Sat unsigned short _Accum)0.5uhk / -1; +// CHECK-DAG: @sat_usa_const3 = {{.*}}global i16 0, align 2 +_Sat short _Accum sat_sa_const3 = (_Sat short _Accum)-128.0hk / 128; +// CHECK-DAG: @sat_sa_const3 = {{.*}}global i16 -128, align 2 +_Sat short _Accum sat_sa_const4 = (_Sat short _Accum)-25.7hk / 0.1lk; +// CHECK-DAG: @sat_sa_const4 = {{.*}}global i16 -32768, align 2 + +// Some more cases +short _Accum sa_const10 = 255.9921875hk / 255.9921875hk; +// CHECK-DAG: @sa_const10 = {{.*}}global i16 128, align 2 +short _Accum sat_sa_const5 = (_Sat short _Accum)(-255.0hk - 1.0hk) / 0.0078125hk; +// CHECK-DAG: @sat_sa_const5 = {{.*}}global i16 -32768, align 2 +_Sat short _Accum sat_sa_const6 = (_Sat short _Accum)(-255.0hk - 1.0hk) / -0.0078125hk; +// CHECK-DAG: @sat_sa_const6 = {{.*}}global i16 32767, align 2 +short _Accum sa_const12 = 255.9921875hk / -1.0hk; +// CHECK-DAG: @sa_const12 = {{.*}}global i16 -32767, align 2 +_Sat short _Accum sat_sa_const7 = (_Sat short _Accum)(-255.0hk - 1.0hk) / -1.0hk; +// CHECK-DAG: @sat_sa_const7 = {{.*}}global i16 32767, align 2 +short _Accum sa_const13 = 0.0234375hk / 2.0hk; +// CHECK-DAG: @sa_const13 = {{.*}}global i16 1, align 2 +short _Accum sa_const14 = -0.0234375hk / 2.0hk; +// CHECK-DAG: @sa_const14 = {{.*}}global i16 -2, align 2 +short _Accum sa_const15 = -0.0078125hk / 255.28125hk; +// CHECK-DAG: @sa_const15 = {{.*}}global i16 -1, align 2 + void SignedDivision() { // CHECK-LABEL: SignedDivision short _Accum sa; @@ -233,12 +299,12 @@ void IntDivision() { // SIGNED-NEXT: [[RESIZE7:%.*]] = zext i16 [[TMP6]] to i40 // SIGNED-NEXT: [[RESIZE8:%.*]] = sext i32 [[TMP7]] to i40 // SIGNED-NEXT: [[UPSCALE9:%.*]] = shl i40 [[RESIZE8]], 8 - // SIGNED-NEXT: [[TMP8:%.*]] = call i40 @llvm.udiv.fix.i40(i40 [[RESIZE7]], i40 [[UPSCALE9]], i32 8) + // SIGNED-NEXT: [[TMP8:%.*]] = call i40 @llvm.sdiv.fix.i40(i40 [[RESIZE7]], i40 [[UPSCALE9]], i32 8) // SIGNED-NEXT: [[RESIZE10:%.*]] = trunc i40 [[TMP8]] to i16 // UNSIGNED-NEXT: [[RESIZE7:%.*]] = zext i16 [[TMP6]] to i39 // UNSIGNED-NEXT: [[RESIZE8:%.*]] = sext i32 [[TMP7]] to i39 // UNSIGNED-NEXT: [[UPSCALE9:%.*]] = shl i39 [[RESIZE8]], 7 - // UNSIGNED-NEXT: [[TMP8:%.*]] = call i39 @llvm.udiv.fix.i39(i39 [[RESIZE7]], i39 [[UPSCALE9]], i32 7) + // UNSIGNED-NEXT: [[TMP8:%.*]] = call i39 @llvm.sdiv.fix.i39(i39 [[RESIZE7]], i39 [[UPSCALE9]], i32 7) // UNSIGNED-NEXT: [[RESIZE10:%.*]] = trunc i39 [[TMP8]] to i16 // CHECK-NEXT: store i16 [[RESIZE10]], i16* %usa, align 2 usa = usa / i; @@ -411,7 +477,7 @@ void SaturatedDivision() { // SIGNED-NEXT: [[USA_SAT_RESIZE:%[a-z0-9]+]] = zext i16 [[USA_SAT]] to i40 // SIGNED-NEXT: [[I_RESIZE:%[a-z0-9]+]] = sext i32 [[I]] to i40 // SIGNED-NEXT: [[I_UPSCALE:%[a-z0-9]+]] = shl i40 [[I_RESIZE]], 8 - // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i40 @llvm.udiv.fix.sat.i40(i40 [[USA_SAT_RESIZE]], i40 [[I_UPSCALE]], i32 8) + // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i40 @llvm.sdiv.fix.sat.i40(i40 [[USA_SAT_RESIZE]], i40 [[I_UPSCALE]], i32 8) // SIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i40 [[SUM]], 65535 // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = select i1 [[USE_MAX]], i40 65535, i40 [[SUM]] // SIGNED-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i40 [[RESULT]], 0 @@ -420,7 +486,7 @@ void SaturatedDivision() { // UNSIGNED-NEXT: [[USA_SAT_RESIZE:%[a-z0-9]+]] = zext i16 [[USA_SAT]] to i39 // UNSIGNED-NEXT: [[I_RESIZE:%[a-z0-9]+]] = sext i32 [[I]] to i39 // UNSIGNED-NEXT: [[I_UPSCALE:%[a-z0-9]+]] = shl i39 [[I_RESIZE]], 7 - // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i39 @llvm.udiv.fix.sat.i39(i39 [[USA_SAT_RESIZE]], i39 [[I_UPSCALE]], i32 7) + // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i39 @llvm.sdiv.fix.sat.i39(i39 [[USA_SAT_RESIZE]], i39 [[I_UPSCALE]], i32 7) // UNSIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i39 [[SUM]], 32767 // UNSIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = select i1 [[USE_MAX]], i39 32767, i39 [[SUM]] // UNSIGNED-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i39 [[RESULT]], 0 diff --git a/clang/test/Frontend/fixed_point_errors.c b/clang/test/Frontend/fixed_point_errors.c index 9b600fbc2642b..2fd8cfd1fdf70 100644 --- a/clang/test/Frontend/fixed_point_errors.c +++ b/clang/test/Frontend/fixed_point_errors.c @@ -250,3 +250,20 @@ unsigned u_const = -2.5hk; // expected-warning{{implicit conversi char c_const = 256.0uk; // expected-warning{{implicit conversion from 256.0 cannot fit within the range of values for 'char'}} short _Accum sa_const5 = 256; // expected-warning{{implicit conversion from 256 cannot fit within the range of values for 'short _Accum'}} unsigned short _Accum usa_const2 = -2; // expected-warning{{implicit conversion from -2 cannot fit within the range of values for 'unsigned short _Accum'}} + +short _Accum add_ovf1 = 255.0hk + 20.0hk; // expected-warning {{overflow in expression; result is -237.0 with type 'short _Accum'}} +short _Accum add_ovf2 = 10 + 0.5hr; // expected-warning {{overflow in expression; result is 0.5 with type 'short _Fract'}} +short _Accum sub_ovf1 = 16.0uhk - 32.0uhk; // expected-warning {{overflow in expression; result is 240.0 with type 'unsigned short _Accum'}} +short _Accum sub_ovf2 = -255.0hk - 20; // expected-warning {{overflow in expression; result is 237.0 with type 'short _Accum'}} +short _Accum mul_ovf1 = 200.0uhk * 10.0uhk; // expected-warning {{overflow in expression; result is 208.0 with type 'unsigned short _Accum'}} +short _Accum mul_ovf2 = (-0.5hr - 0.5hr) * (-0.5hr - 0.5hr); // expected-warning {{overflow in expression; result is -1.0 with type 'short _Fract'}} +short _Accum div_ovf1 = 255.0hk / 0.5hk; // expected-warning {{overflow in expression; result is -2.0 with type 'short _Accum'}} + +// No warnings for saturation +short _Fract add_sat = (_Sat short _Fract)0.5hr + 0.5hr; +short _Accum sub_sat = (_Sat short _Accum)-200.0hk - 80.0hk; +short _Accum mul_sat = (_Sat short _Accum)80.0hk * 10.0hk; +short _Fract div_sat = (_Sat short _Fract)0.9hr / 0.1hr; + +// Division by zero +short _Accum div_zero = 4.5k / 0.0lr; // expected-error {{initializer element is not a compile-time constant}} diff --git a/clang/test/Frontend/fixed_point_mul.c b/clang/test/Frontend/fixed_point_mul.c index 274528fe9d9a6..5e4741de1fe75 100644 --- a/clang/test/Frontend/fixed_point_mul.c +++ b/clang/test/Frontend/fixed_point_mul.c @@ -1,6 +1,49 @@ // RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED // RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -fpadding-on-unsigned-fixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNSIGNED +// Multiplication between different fixed point types +short _Accum sa_const = 2.0hk * 2.0hk; // CHECK-DAG: @sa_const = {{.*}}global i16 512, align 2 +_Accum a_const = 3.0hk * 2.0k; // CHECK-DAG: @a_const = {{.*}}global i32 196608, align 4 +long _Accum la_const = 4.0hk * 2.0lk; // CHECK-DAG: @la_const = {{.*}}global i64 17179869184, align 8 +short _Accum sa_const2 = 0.5hr * 2.0hk; // CHECK-DAG: @sa_const2 = {{.*}}global i16 128, align 2 +short _Accum sa_const3 = 0.5r * 3.0hk; // CHECK-DAG: @sa_const3 = {{.*}}global i16 192, align 2 +short _Accum sa_const4 = 0.5lr * 4.0hk; // CHECK-DAG: @sa_const4 = {{.*}}global i16 256, align 2 + +// Unsigned multiplication +unsigned short _Accum usa_const = 1.0uhk * 2.0uhk; +// CHECK-SIGNED-DAG: @usa_const = {{.*}}global i16 768, align 2 +// CHECK-UNSIGNED-DAG: @usa_const = {{.*}}global i16 384, align 2 + +// Unsigned * signed +short _Accum sa_const5 = 20.0uhk * 3.0hk; +// CHECK-DAG: @sa_const5 = {{.*}}global i16 7680, align 2 + +// Multiplication with negative number +short _Accum sa_const6 = 0.5hr * (-2.0hk); +// CHECK-DAG: @sa_const6 = {{.*}}global i16 -128, align 2 + +// Int multiplication +unsigned short _Accum usa_const2 = 5 * 10.5uhk; +// CHECK-SIGNED-DAG: @usa_const2 = {{.*}}global i16 640, align 2 +// CHECK-UNSIGNED-DAG: @usa_const2 = {{.*}}global i16 320, align 2 +short _Accum sa_const7 = 3 * (-0.5hk); // CHECK-DAG: @sa_const7 = {{.*}}global i16 -192, align 2 +short _Accum sa_const8 = 100 * (-2.0hk); // CHECK-DAG: @sa_const8 = {{.*}}global i16 -25600, align 2 +long _Fract lf_const = -0.25lr * 3; // CHECK-DAG: @lf_const = {{.*}}global i32 -1610612736, align 4 + +// Saturated multiplication +_Sat short _Accum sat_sa_const = (_Sat short _Accum)128.0hk * 3.0hk; +// CHECK-DAG: @sat_sa_const = {{.*}}global i16 32767, align 2 +_Sat unsigned short _Accum sat_usa_const = (_Sat unsigned short _Accum)128.0uhk * 128.0uhk; +// CHECK-SIGNED-DAG: @sat_usa_const = {{.*}}global i16 65535, align 2 +// CHECK-UNSIGNED-DAG: @sat_usa_const = {{.*}}global i16 32767, align 2 +_Sat short _Accum sat_sa_const2 = (_Sat short _Accum)128.0hk * -128; +// CHECK-DAG: @sat_sa_const2 = {{.*}}global i16 -32768, align 2 +_Sat unsigned short _Accum sat_usa_const2 = (_Sat unsigned short _Accum)128.0uhk * 30; +// CHECK-SIGNED-DAG: @sat_usa_const2 = {{.*}}global i16 65535, align 2 +// CHECK-UNSIGNED-DAG: @sat_usa_const2 = {{.*}}global i16 32767, align 2 +_Sat unsigned short _Accum sat_usa_const3 = (_Sat unsigned short _Accum)0.5uhk * (-2); +// CHECK-DAG: @sat_usa_const3 = {{.*}}global i16 0, align 2 + void SignedMultiplication() { // CHECK-LABEL: SignedMultiplication short _Accum sa; @@ -233,12 +276,12 @@ void IntMultiplication() { // SIGNED-NEXT: [[RESIZE7:%.*]] = zext i16 [[TMP6]] to i40 // SIGNED-NEXT: [[RESIZE8:%.*]] = sext i32 [[TMP7]] to i40 // SIGNED-NEXT: [[UPSCALE9:%.*]] = shl i40 [[RESIZE8]], 8 - // SIGNED-NEXT: [[TMP8:%.*]] = call i40 @llvm.umul.fix.i40(i40 [[RESIZE7]], i40 [[UPSCALE9]], i32 8) + // SIGNED-NEXT: [[TMP8:%.*]] = call i40 @llvm.smul.fix.i40(i40 [[RESIZE7]], i40 [[UPSCALE9]], i32 8) // SIGNED-NEXT: [[RESIZE10:%.*]] = trunc i40 [[TMP8]] to i16 // UNSIGNED-NEXT: [[RESIZE7:%.*]] = zext i16 [[TMP6]] to i39 // UNSIGNED-NEXT: [[RESIZE8:%.*]] = sext i32 [[TMP7]] to i39 // UNSIGNED-NEXT: [[UPSCALE9:%.*]] = shl i39 [[RESIZE8]], 7 - // UNSIGNED-NEXT: [[TMP8:%.*]] = call i39 @llvm.umul.fix.i39(i39 [[RESIZE7]], i39 [[UPSCALE9]], i32 7) + // UNSIGNED-NEXT: [[TMP8:%.*]] = call i39 @llvm.smul.fix.i39(i39 [[RESIZE7]], i39 [[UPSCALE9]], i32 7) // UNSIGNED-NEXT: [[RESIZE10:%.*]] = trunc i39 [[TMP8]] to i16 // CHECK-NEXT: store i16 [[RESIZE10]], i16* %usa, align 2 usa = usa * i; @@ -411,7 +454,7 @@ void SaturatedMultiplication() { // SIGNED-NEXT: [[USA_SAT_RESIZE:%[a-z0-9]+]] = zext i16 [[USA_SAT]] to i40 // SIGNED-NEXT: [[I_RESIZE:%[a-z0-9]+]] = sext i32 [[I]] to i40 // SIGNED-NEXT: [[I_UPSCALE:%[a-z0-9]+]] = shl i40 [[I_RESIZE]], 8 - // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i40 @llvm.umul.fix.sat.i40(i40 [[USA_SAT_RESIZE]], i40 [[I_UPSCALE]], i32 8) + // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i40 @llvm.smul.fix.sat.i40(i40 [[USA_SAT_RESIZE]], i40 [[I_UPSCALE]], i32 8) // SIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i40 [[SUM]], 65535 // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = select i1 [[USE_MAX]], i40 65535, i40 [[SUM]] // SIGNED-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i40 [[RESULT]], 0 @@ -420,7 +463,7 @@ void SaturatedMultiplication() { // UNSIGNED-NEXT: [[USA_SAT_RESIZE:%[a-z0-9]+]] = zext i16 [[USA_SAT]] to i39 // UNSIGNED-NEXT: [[I_RESIZE:%[a-z0-9]+]] = sext i32 [[I]] to i39 // UNSIGNED-NEXT: [[I_UPSCALE:%[a-z0-9]+]] = shl i39 [[I_RESIZE]], 7 - // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i39 @llvm.umul.fix.sat.i39(i39 [[USA_SAT_RESIZE]], i39 [[I_UPSCALE]], i32 7) + // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i39 @llvm.smul.fix.sat.i39(i39 [[USA_SAT_RESIZE]], i39 [[I_UPSCALE]], i32 7) // UNSIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i39 [[SUM]], 32767 // UNSIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = select i1 [[USE_MAX]], i39 32767, i39 [[SUM]] // UNSIGNED-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i39 [[RESULT]], 0 diff --git a/clang/test/Frontend/fixed_point_sub.c b/clang/test/Frontend/fixed_point_sub.c index 59b2e0a43aed6..b30825e555be0 100644 --- a/clang/test/Frontend/fixed_point_sub.c +++ b/clang/test/Frontend/fixed_point_sub.c @@ -1,6 +1,55 @@ // RUN: %clang_cc1 -ffixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED // RUN: %clang_cc1 -ffixed-point -fpadding-on-unsigned-fixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNSIGNED +// Subtraction between different fixed point types +short _Accum sa_const = 1.0hk - 2.0hk; // CHECK-DAG: @sa_const = {{.*}}global i16 -128, align 2 +_Accum a_const = 1.0hk - 2.0k; // CHECK-DAG: @a_const = {{.*}}global i32 -32768, align 4 +long _Accum la_const = 1.0hk - 2.0lk; // CHECK-DAG: @la_const = {{.*}}global i64 -2147483648, align 8 +short _Accum sa_const2 = 0.5hr - 2.0hk; // CHECK-DAG: @sa_const2 = {{.*}}global i16 -192, align 2 +short _Accum sa_const3 = 0.5r - 2.0hk; // CHECK-DAG: @sa_const3 = {{.*}}global i16 -192, align 2 +short _Accum sa_const4 = 0.5lr - 2.0hk; // CHECK-DAG: @sa_const4 = {{.*}}global i16 -192, align 2 +short _Accum sa_const5 = 2.0hk - 0.5lr; // CHECK-DAG: @sa_const5 = {{.*}}global i16 192, align 2 + +// Unsigned subtraction +unsigned short _Accum usa_const = 3.0uhk - 2.0uhk; +// CHECK-SIGNED-DAG: @usa_const = {{.*}}global i16 768, align 2 +// CHECK-UNSIGNED-DAG: @usa_const = {{.*}}global i16 384, align 2 + +// Unsigned - signed +short _Accum sa_const6 = 1.0uhk - 2.0hk; +// CHECK-DAG: @sa_const6 = {{.*}}global i16 -128, align 2 + +// Subtraction with negative number +short _Accum sa_const7 = 0.5hr - (-2.0hk); +// CHECK-DAG: @sa_const7 = {{.*}}global i16 320, align 2 + +// Int subtraction +unsigned short _Accum usa_const2 = 2 - 0.5uhk; +// CHECK-SIGNED-DAG: @usa_const2 = {{.*}}global i16 640, align 2 +// CHECK-UNSIGNED-DAG: @usa_const2 = {{.*}}global i16 320, align 2 +short _Accum sa_const8 = 2 - (-0.5hk); // CHECK-DAG: @sa_const8 = {{.*}}global i16 320, align 2 +short _Accum sa_const9 = 257 - 2.0hk; // CHECK-DAG: @sa_const9 = {{.*}}global i16 32640, align 2 +long _Fract lf_const = 0.5lr - 1; // CHECK-DAG: @lf_const = {{.*}}global i32 -1073741824, align 4 + +// Saturated subtraction +_Sat short _Accum sat_sa_const = (_Sat short _Accum)128.0hk - (-128.0hk); +// CHECK-DAG: @sat_sa_const = {{.*}}global i16 32767, align 2 +_Sat unsigned short _Accum sat_usa_const = (_Sat unsigned short _Accum)128.0uhk - (-128.0uhk); +// CHECK-SIGNED-DAG: @sat_usa_const = {{.*}}global i16 65535, align 2 +// CHECK-UNSIGNED-DAG: @sat_usa_const = {{.*}}global i16 32767, align 2 +_Sat short _Accum sat_sa_const2 = (_Sat short _Accum)128.0hk - (-128); +// CHECK-DAG: @sat_sa_const2 = {{.*}}global i16 32767, align 2 +_Sat unsigned short _Accum sat_usa_const2 = (_Sat unsigned short _Accum)128.0uhk - (-128); +// CHECK-SIGNED-DAG: @sat_usa_const2 = {{.*}}global i16 65535, align 2 +// CHECK-UNSIGNED-DAG: @sat_usa_const2 = {{.*}}global i16 32767, align 2 +_Sat unsigned short _Accum sat_usa_const3 = (_Sat unsigned short _Accum)0.5uhk - 2; +// CHECK-DAG: @sat_usa_const3 = {{.*}}global i16 0, align 2 +_Sat short _Accum sat_sa_const3 = (_Sat short _Accum)-128.0hk - 128; +// CHECK-DAG: @sat_sa_const3 = {{.*}}global i16 -32768, align 2 +_Sat short _Accum sat_sa_const4 = (_Sat short _Accum)-150.0hk - 130.0lk; +// CHECK-DAG: @sat_sa_const4 = {{.*}}global i16 -32768, align 2 + + void SignedSubtraction() { // CHECK-LABEL: SignedSubtraction short _Accum sa; @@ -370,7 +419,7 @@ void SaturatedSubtraction() { // SIGNED-NEXT: [[USA_SAT_RESIZE:%[a-z0-9]+]] = zext i16 [[USA_SAT]] to i40 // SIGNED-NEXT: [[I_RESIZE:%[a-z0-9]+]] = sext i32 [[I]] to i40 // SIGNED-NEXT: [[I_UPSCALE:%[a-z0-9]+]] = shl i40 [[I_RESIZE]], 8 - // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i40 @llvm.usub.sat.i40(i40 [[USA_SAT_RESIZE]], i40 [[I_UPSCALE]]) + // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i40 @llvm.ssub.sat.i40(i40 [[USA_SAT_RESIZE]], i40 [[I_UPSCALE]]) // SIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i40 [[SUM]], 65535 // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = select i1 [[USE_MAX]], i40 65535, i40 [[SUM]] // SIGNED-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i40 [[RESULT]], 0 @@ -379,7 +428,7 @@ void SaturatedSubtraction() { // UNSIGNED-NEXT: [[USA_SAT_RESIZE:%[a-z0-9]+]] = zext i16 [[USA_SAT]] to i39 // UNSIGNED-NEXT: [[I_RESIZE:%[a-z0-9]+]] = sext i32 [[I]] to i39 // UNSIGNED-NEXT: [[I_UPSCALE:%[a-z0-9]+]] = shl i39 [[I_RESIZE]], 7 - // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i39 @llvm.usub.sat.i39(i39 [[USA_SAT_RESIZE]], i39 [[I_UPSCALE]]) + // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i39 @llvm.ssub.sat.i39(i39 [[USA_SAT_RESIZE]], i39 [[I_UPSCALE]]) // UNSIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i39 [[SUM]], 32767 // UNSIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = select i1 [[USE_MAX]], i39 32767, i39 [[SUM]] // UNSIGNED-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i39 [[RESULT]], 0 diff --git a/clang/test/Frontend/opencl.cl b/clang/test/Frontend/opencl.cl index ea7d3d4c87317..e25a4b8fac6a6 100644 --- a/clang/test/Frontend/opencl.cl +++ b/clang/test/Frontend/opencl.cl @@ -21,7 +21,7 @@ int member; #endif #endif -void f(void (^g)(void)) { +typedef int (^bl_t)(void); #if defined(__OPENCL_C_VERSION__) || defined(__OPENCL_CPP_VERSION__) #if !defined(BLOCKS) && (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ != CL_VERSION_2_0) // expected-error@-3{{blocks support disabled - compile with -fblocks or for OpenCL 2.0}} @@ -29,7 +29,6 @@ void f(void (^g)(void)) { #else // expected-error@-6{{blocks support disabled - compile with -fblocks or pick a deployment target that supports them}} #endif -} // CHECK-INVALID-OPENCL-VERSION11: warning: OpenCL version 1.1 does not support the option '-cl-strict-aliasing' // CHECK-INVALID-OPENCL-VERSION12: warning: OpenCL version 1.2 does not support the option '-cl-strict-aliasing' diff --git a/clang/test/Frontend/optimization-remark-line-directive.c b/clang/test/Frontend/optimization-remark-line-directive.c index 516555ff45503..095791e505f8b 100644 --- a/clang/test/Frontend/optimization-remark-line-directive.c +++ b/clang/test/Frontend/optimization-remark-line-directive.c @@ -2,11 +2,11 @@ // directives. We cannot map #line directives back to // a SourceLocation. -// RUN: %clang_cc1 %s -Rpass=inline -debug-info-kind=line-tables-only -dwarf-column-info -emit-llvm-only -verify -fno-experimental-new-pass-manager +// RUN: %clang_cc1 %s -Rpass=inline -debug-info-kind=line-tables-only -emit-llvm-only -verify -fno-experimental-new-pass-manager // The new PM inliner is not added to the default pipeline at O0, so we add // some optimizations to trigger it. -// RUN: %clang_cc1 %s -Rpass=inline -fexperimental-new-pass-manager -O1 -debug-info-kind=line-tables-only -dwarf-column-info -emit-llvm-only -verify +// RUN: %clang_cc1 %s -Rpass=inline -fexperimental-new-pass-manager -O1 -debug-info-kind=line-tables-only -emit-llvm-only -verify int foo(int x, int y) __attribute__((always_inline)); int foo(int x, int y) { return x + y; } diff --git a/clang/test/Headers/Inputs/include/cmath b/clang/test/Headers/Inputs/include/cmath index 0cadc131d2111..5e4e8b67514f0 100644 --- a/clang/test/Headers/Inputs/include/cmath +++ b/clang/test/Headers/Inputs/include/cmath @@ -49,8 +49,12 @@ double fma(double, double, double); float fma(float, float, float); double fmax(double, double); float fmax(float, float); +float max(float, float); +double max(double, double); double fmin(double, double); float fmin(float, float); +float min(float, float); +double min(double, double); double fmod(double, double); float fmod(float, float); int fpclassify(double); diff --git a/clang/test/Headers/Inputs/include/complex b/clang/test/Headers/Inputs/include/complex new file mode 100644 index 0000000000000..f3aefab7954be --- /dev/null +++ b/clang/test/Headers/Inputs/include/complex @@ -0,0 +1,301 @@ +#pragma once + +#include + +#define INFINITY (__builtin_inff()) + +namespace std { + +// Taken from libc++ +template +class complex { +public: + typedef _Tp value_type; + +private: + value_type __re_; + value_type __im_; + +public: + complex(const value_type &__re = value_type(), const value_type &__im = value_type()) + : __re_(__re), __im_(__im) {} + template + complex(const complex<_Xp> &__c) + : __re_(__c.real()), __im_(__c.imag()) {} + + value_type real() const { return __re_; } + value_type imag() const { return __im_; } + + void real(value_type __re) { __re_ = __re; } + void imag(value_type __im) { __im_ = __im; } + + complex &operator=(const value_type &__re) { + __re_ = __re; + __im_ = value_type(); + return *this; + } + complex &operator+=(const value_type &__re) { + __re_ += __re; + return *this; + } + complex &operator-=(const value_type &__re) { + __re_ -= __re; + return *this; + } + complex &operator*=(const value_type &__re) { + __re_ *= __re; + __im_ *= __re; + return *this; + } + complex &operator/=(const value_type &__re) { + __re_ /= __re; + __im_ /= __re; + return *this; + } + + template + complex &operator=(const complex<_Xp> &__c) { + __re_ = __c.real(); + __im_ = __c.imag(); + return *this; + } + template + complex &operator+=(const complex<_Xp> &__c) { + __re_ += __c.real(); + __im_ += __c.imag(); + return *this; + } + template + complex &operator-=(const complex<_Xp> &__c) { + __re_ -= __c.real(); + __im_ -= __c.imag(); + return *this; + } + template + complex &operator*=(const complex<_Xp> &__c) { + *this = *this * complex(__c.real(), __c.imag()); + return *this; + } + template + complex &operator/=(const complex<_Xp> &__c) { + *this = *this / complex(__c.real(), __c.imag()); + return *this; + } +}; + +template +inline complex<_Tp> +operator+(const complex<_Tp> &__x, const complex<_Tp> &__y) { + complex<_Tp> __t(__x); + __t += __y; + return __t; +} + +template +inline complex<_Tp> +operator+(const complex<_Tp> &__x, const _Tp &__y) { + complex<_Tp> __t(__x); + __t += __y; + return __t; +} + +template +inline complex<_Tp> +operator+(const _Tp &__x, const complex<_Tp> &__y) { + complex<_Tp> __t(__y); + __t += __x; + return __t; +} + +template +inline complex<_Tp> +operator-(const complex<_Tp> &__x, const complex<_Tp> &__y) { + complex<_Tp> __t(__x); + __t -= __y; + return __t; +} + +template +inline complex<_Tp> +operator-(const complex<_Tp> &__x, const _Tp &__y) { + complex<_Tp> __t(__x); + __t -= __y; + return __t; +} + +template +inline complex<_Tp> +operator-(const _Tp &__x, const complex<_Tp> &__y) { + complex<_Tp> __t(-__y); + __t += __x; + return __t; +} + +template +complex<_Tp> +operator*(const complex<_Tp> &__z, const complex<_Tp> &__w) { + _Tp __a = __z.real(); + _Tp __b = __z.imag(); + _Tp __c = __w.real(); + _Tp __d = __w.imag(); + _Tp __ac = __a * __c; + _Tp __bd = __b * __d; + _Tp __ad = __a * __d; + _Tp __bc = __b * __c; + _Tp __x = __ac - __bd; + _Tp __y = __ad + __bc; + if (std::isnan(__x) && std::isnan(__y)) { + bool __recalc = false; + if (std::isinf(__a) || std::isinf(__b)) { + __a = copysign(std::isinf(__a) ? _Tp(1) : _Tp(0), __a); + __b = copysign(std::isinf(__b) ? _Tp(1) : _Tp(0), __b); + if (std::isnan(__c)) + __c = copysign(_Tp(0), __c); + if (std::isnan(__d)) + __d = copysign(_Tp(0), __d); + __recalc = true; + } + if (std::isinf(__c) || std::isinf(__d)) { + __c = copysign(std::isinf(__c) ? _Tp(1) : _Tp(0), __c); + __d = copysign(std::isinf(__d) ? _Tp(1) : _Tp(0), __d); + if (std::isnan(__a)) + __a = copysign(_Tp(0), __a); + if (std::isnan(__b)) + __b = copysign(_Tp(0), __b); + __recalc = true; + } + if (!__recalc && (std::isinf(__ac) || std::isinf(__bd) || + std::isinf(__ad) || std::isinf(__bc))) { + if (std::isnan(__a)) + __a = copysign(_Tp(0), __a); + if (std::isnan(__b)) + __b = copysign(_Tp(0), __b); + if (std::isnan(__c)) + __c = copysign(_Tp(0), __c); + if (std::isnan(__d)) + __d = copysign(_Tp(0), __d); + __recalc = true; + } + if (__recalc) { + __x = _Tp(INFINITY) * (__a * __c - __b * __d); + __y = _Tp(INFINITY) * (__a * __d + __b * __c); + } + } + return complex<_Tp>(__x, __y); +} + +template +inline complex<_Tp> +operator*(const complex<_Tp> &__x, const _Tp &__y) { + complex<_Tp> __t(__x); + __t *= __y; + return __t; +} + +template +inline complex<_Tp> +operator*(const _Tp &__x, const complex<_Tp> &__y) { + complex<_Tp> __t(__y); + __t *= __x; + return __t; +} + +template +complex<_Tp> +operator/(const complex<_Tp> &__z, const complex<_Tp> &__w) { + int __ilogbw = 0; + _Tp __a = __z.real(); + _Tp __b = __z.imag(); + _Tp __c = __w.real(); + _Tp __d = __w.imag(); + _Tp __logbw = logb(fmax(fabs(__c), fabs(__d))); + if (std::isfinite(__logbw)) { + __ilogbw = static_cast(__logbw); + __c = scalbn(__c, -__ilogbw); + __d = scalbn(__d, -__ilogbw); + } + _Tp __denom = __c * __c + __d * __d; + _Tp __x = scalbn((__a * __c + __b * __d) / __denom, -__ilogbw); + _Tp __y = scalbn((__b * __c - __a * __d) / __denom, -__ilogbw); + if (std::isnan(__x) && std::isnan(__y)) { + if ((__denom == _Tp(0)) && (!std::isnan(__a) || !std::isnan(__b))) { + __x = copysign(_Tp(INFINITY), __c) * __a; + __y = copysign(_Tp(INFINITY), __c) * __b; + } else if ((std::isinf(__a) || std::isinf(__b)) && std::isfinite(__c) && std::isfinite(__d)) { + __a = copysign(std::isinf(__a) ? _Tp(1) : _Tp(0), __a); + __b = copysign(std::isinf(__b) ? _Tp(1) : _Tp(0), __b); + __x = _Tp(INFINITY) * (__a * __c + __b * __d); + __y = _Tp(INFINITY) * (__b * __c - __a * __d); + } else if (std::isinf(__logbw) && __logbw > _Tp(0) && std::isfinite(__a) && std::isfinite(__b)) { + __c = copysign(std::isinf(__c) ? _Tp(1) : _Tp(0), __c); + __d = copysign(std::isinf(__d) ? _Tp(1) : _Tp(0), __d); + __x = _Tp(0) * (__a * __c + __b * __d); + __y = _Tp(0) * (__b * __c - __a * __d); + } + } + return complex<_Tp>(__x, __y); +} + +template +inline complex<_Tp> +operator/(const complex<_Tp> &__x, const _Tp &__y) { + return complex<_Tp>(__x.real() / __y, __x.imag() / __y); +} + +template +inline complex<_Tp> +operator/(const _Tp &__x, const complex<_Tp> &__y) { + complex<_Tp> __t(__x); + __t /= __y; + return __t; +} + +template +inline complex<_Tp> +operator+(const complex<_Tp> &__x) { + return __x; +} + +template +inline complex<_Tp> +operator-(const complex<_Tp> &__x) { + return complex<_Tp>(-__x.real(), -__x.imag()); +} + +template +inline bool +operator==(const complex<_Tp> &__x, const complex<_Tp> &__y) { + return __x.real() == __y.real() && __x.imag() == __y.imag(); +} + +template +inline bool +operator==(const complex<_Tp> &__x, const _Tp &__y) { + return __x.real() == __y && __x.imag() == 0; +} + +template +inline bool +operator==(const _Tp &__x, const complex<_Tp> &__y) { + return __x == __y.real() && 0 == __y.imag(); +} + +template +inline bool +operator!=(const complex<_Tp> &__x, const complex<_Tp> &__y) { + return !(__x == __y); +} + +template +inline bool +operator!=(const complex<_Tp> &__x, const _Tp &__y) { + return !(__x == __y); +} + +template +inline bool +operator!=(const _Tp &__x, const complex<_Tp> &__y) { + return !(__x == __y); +} + +} // namespace std diff --git a/clang/test/Headers/Inputs/include/cstdlib b/clang/test/Headers/Inputs/include/cstdlib index 00e81e8c4a150..1d1864a98976b 100644 --- a/clang/test/Headers/Inputs/include/cstdlib +++ b/clang/test/Headers/Inputs/include/cstdlib @@ -24,4 +24,8 @@ inline long long abs(long long __x) { return __builtin_llabs (__x); } float fabs(float __x) { return __builtin_fabs(__x); } + +float abs(float __x) { return fabs(__x); } +double abs(double __x) { return fabs(__x); } + } diff --git a/clang/test/Headers/nvptx_device_math_complex.c b/clang/test/Headers/nvptx_device_math_complex.c index 43f4ec6a6b590..6e3e8bffbd24e 100644 --- a/clang/test/Headers/nvptx_device_math_complex.c +++ b/clang/test/Headers/nvptx_device_math_complex.c @@ -1,10 +1,44 @@ // REQUIRES: nvptx-registered-target -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s +// RUN: %clang_cc1 -verify -internal-isystem %S/Inputs/include -fopenmp -x c -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -verify -internal-isystem %S/../../lib/Headers/openmp_wrappers -include __clang_openmp_device_functions.h -internal-isystem %S/Inputs/include -fopenmp -x c -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -aux-triple powerpc64le-unknown-unknown -o - | FileCheck %s +// RUN: %clang_cc1 -verify -internal-isystem %S/Inputs/include -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -verify -internal-isystem %S/../../lib/Headers/openmp_wrappers -include __clang_openmp_device_functions.h -internal-isystem %S/Inputs/include -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -aux-triple powerpc64le-unknown-unknown -o - | FileCheck %s // expected-no-diagnostics -// CHECK-DAG: call { float, float } @__divsc3( -// CHECK-DAG: call { float, float } @__mulsc3( +#ifdef __cplusplus +#include +#else +#include +#endif + +// CHECK: define weak {{.*}} @__muldc3 +// CHECK-DAG: call i32 @__nv_isnand( +// CHECK-DAG: call i32 @__nv_isinfd( +// CHECK-DAG: call double @__nv_copysign( + +// CHECK: define weak {{.*}} @__mulsc3 +// CHECK-DAG: call i32 @__nv_isnanf( +// CHECK-DAG: call i32 @__nv_isinff( +// CHECK-DAG: call float @__nv_copysignf( + +// CHECK: define weak {{.*}} @__divdc3 +// CHECK-DAG: call i32 @__nv_isnand( +// CHECK-DAG: call i32 @__nv_isinfd( +// CHECK-DAG: call i32 @__nv_isfinited( +// CHECK-DAG: call double @__nv_copysign( +// CHECK-DAG: call double @__nv_scalbn( +// CHECK-DAG: call double @__nv_fabs( +// CHECK-DAG: call double @__nv_logb( + +// CHECK: define weak {{.*}} @__divsc3 +// CHECK-DAG: call i32 @__nv_isnanf( +// CHECK-DAG: call i32 @__nv_isinff( +// CHECK-DAG: call i32 @__nv_finitef( +// CHECK-DAG: call float @__nv_copysignf( +// CHECK-DAG: call float @__nv_scalbnf( +// CHECK-DAG: call float @__nv_fabsf( +// CHECK-DAG: call float @__nv_logbf( + void test_scmplx(float _Complex a) { #pragma omp target { @@ -12,9 +46,6 @@ void test_scmplx(float _Complex a) { } } - -// CHECK-DAG: call { double, double } @__divdc3( -// CHECK-DAG: call { double, double } @__muldc3( void test_dcmplx(double _Complex a) { #pragma omp target { diff --git a/clang/test/Headers/nvptx_device_math_complex.cpp b/clang/test/Headers/nvptx_device_math_complex.cpp new file mode 100644 index 0000000000000..e4b78deb05d7b --- /dev/null +++ b/clang/test/Headers/nvptx_device_math_complex.cpp @@ -0,0 +1,48 @@ +// REQUIRES: nvptx-registered-target +// RUN: %clang_cc1 -verify -internal-isystem %S/Inputs/include -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -verify -internal-isystem %S/../../lib/Headers/openmp_wrappers -include __clang_openmp_device_functions.h -internal-isystem %S/Inputs/include -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -aux-triple powerpc64le-unknown-unknown -o - | FileCheck %s +// expected-no-diagnostics + +#include + +// CHECK: define weak {{.*}} @__muldc3 +// CHECK-DAG: call i32 @__nv_isnand( +// CHECK-DAG: call i32 @__nv_isinfd( +// CHECK-DAG: call double @__nv_copysign( + +// CHECK: define weak {{.*}} @__mulsc3 +// CHECK-DAG: call i32 @__nv_isnanf( +// CHECK-DAG: call i32 @__nv_isinff( +// CHECK-DAG: call float @__nv_copysignf( + +// CHECK: define weak {{.*}} @__divdc3 +// CHECK-DAG: call i32 @__nv_isnand( +// CHECK-DAG: call i32 @__nv_isinfd( +// CHECK-DAG: call i32 @__nv_isfinited( +// CHECK-DAG: call double @__nv_copysign( +// CHECK-DAG: call double @__nv_scalbn( +// CHECK-DAG: call double @__nv_fabs( +// CHECK-DAG: call double @__nv_logb( + +// CHECK: define weak {{.*}} @__divsc3 +// CHECK-DAG: call i32 @__nv_isnanf( +// CHECK-DAG: call i32 @__nv_isinff( +// CHECK-DAG: call i32 @__nv_finitef( +// CHECK-DAG: call float @__nv_copysignf( +// CHECK-DAG: call float @__nv_scalbnf( +// CHECK-DAG: call float @__nv_fabsf( +// CHECK-DAG: call float @__nv_logbf( + +void test_scmplx(std::complex a) { +#pragma omp target + { + (void)(a * (a / a)); + } +} + +void test_dcmplx(std::complex a) { +#pragma omp target + { + (void)(a * (a / a)); + } +} diff --git a/clang/test/Import/switch-stmt/test.cpp b/clang/test/Import/switch-stmt/test.cpp index e274e895c444e..fcd8263727eaa 100644 --- a/clang/test/Import/switch-stmt/test.cpp +++ b/clang/test/Import/switch-stmt/test.cpp @@ -5,20 +5,26 @@ // CHECK-NEXT: CompoundStmt // CHECK-NEXT: CaseStmt // CHECK-NEXT: ConstantExpr +// CHECK-NEXT: value: Int 1 // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: CaseStmt // CHECK-NEXT: ConstantExpr +// CHECK-NEXT: value: Int 2 // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: BreakStmt // CHECK-NEXT: CaseStmt // CHECK-NEXT: ConstantExpr +// CHECK-NEXT: value: Int 3 // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: ConstantExpr +// CHECK-NEXT: value: Int 4 // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: CaseStmt // CHECK-NEXT: ConstantExpr +// CHECK-NEXT: value: Int 5 // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: ConstantExpr +// CHECK-NEXT: value: Int 5 // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: BreakStmt @@ -30,16 +36,20 @@ // CHECK-NEXT: CompoundStmt // CHECK-NEXT: CaseStmt // CHECK-NEXT: ConstantExpr +// CHECK-NEXT: value: Int 1 // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: BreakStmt // CHECK-NEXT: CaseStmt // CHECK-NEXT: ConstantExpr +// CHECK-NEXT: value: Int 2 // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: BreakStmt // CHECK-NEXT: CaseStmt // CHECK-NEXT: ConstantExpr +// CHECK-NEXT: value: Int 3 // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: ConstantExpr +// CHECK-NEXT: value: Int 5 // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: BreakStmt diff --git a/clang/test/Index/complete-method-decls.m b/clang/test/Index/complete-method-decls.m index f561f81496a90..66c1bc56e8c95 100644 --- a/clang/test/Index/complete-method-decls.m +++ b/clang/test/Index/complete-method-decls.m @@ -111,40 +111,40 @@ -(void)foo {} // CHECK-CC1: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText abc} (40) // CHECK-CC1: ObjCInstanceMethodDecl:{LeftParen (}{Text int}{RightParen )}{TypedText getInt} (40) // CHECK-CC1: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText getSelf} (40) -// CHECK-CC1: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText initWithInt}{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text x} (40) -// CHECK-CC1: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText initWithTwoInts}{TypedText :}{LeftParen (}{Text inout }{Text int}{RightParen )}{Text x}{HorizontalSpace }{TypedText second:}{LeftParen (}{Text int}{RightParen )}{Text y} (40) +// CHECK-CC1: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText initWithInt:}{LeftParen (}{Text int}{RightParen )}{Text x} (40) +// CHECK-CC1: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText initWithTwoInts:}{LeftParen (}{Text inout }{Text int}{RightParen )}{Text x}{HorizontalSpace }{TypedText second:}{LeftParen (}{Text int}{RightParen )}{Text y} (40) // RUN: c-index-test -code-completion-at=%s:17:7 %s | FileCheck -check-prefix=CHECK-CC2 %s // CHECK-CC2: ObjCInstanceMethodDecl:{TypedText abc} // CHECK-CC2-NEXT: ObjCInstanceMethodDecl:{TypedText getSelf} -// CHECK-CC2: ObjCInstanceMethodDecl:{TypedText initWithInt}{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text x} -// CHECK-CC2: ObjCInstanceMethodDecl:{TypedText initWithTwoInts}{TypedText :}{LeftParen (}{Text inout }{Text int}{RightParen )}{Text x}{HorizontalSpace }{TypedText second:}{LeftParen (}{Text int}{RightParen )}{Text y} +// CHECK-CC2: ObjCInstanceMethodDecl:{TypedText initWithInt:}{LeftParen (}{Text int}{RightParen )}{Text x} +// CHECK-CC2: ObjCInstanceMethodDecl:{TypedText initWithTwoInts:}{LeftParen (}{Text inout }{Text int}{RightParen )}{Text x}{HorizontalSpace }{TypedText second:}{LeftParen (}{Text int}{RightParen )}{Text y} // RUN: c-index-test -code-completion-at=%s:24:7 %s | FileCheck -check-prefix=CHECK-CC3 %s // CHECK-CC3: ObjCInstanceMethodDecl:{TypedText abc} // CHECK-CC3-NEXT: ObjCInstanceMethodDecl:{TypedText getSelf} // CHECK-CC3: ObjCInstanceMethodDecl:{TypedText init} -// CHECK-CC3: ObjCInstanceMethodDecl:{TypedText initWithInt}{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text x} -// CHECK-CC3: ObjCInstanceMethodDecl:{TypedText initWithTwoInts}{TypedText :}{LeftParen (}{Text inout }{Text int}{RightParen )}{Text x}{HorizontalSpace }{TypedText second:}{LeftParen (}{Text int}{RightParen )}{Text y} +// CHECK-CC3: ObjCInstanceMethodDecl:{TypedText initWithInt:}{LeftParen (}{Text int}{RightParen )}{Text x} +// CHECK-CC3: ObjCInstanceMethodDecl:{TypedText initWithTwoInts:}{LeftParen (}{Text inout }{Text int}{RightParen )}{Text x}{HorizontalSpace }{TypedText second:}{LeftParen (}{Text int}{RightParen )}{Text y} // RUN: env CINDEXTEST_CODE_COMPLETE_PATTERNS=1 c-index-test -code-completion-at=%s:33:3 %s | FileCheck -check-prefix=CHECK-CC4 %s // CHECK-CC4: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText abc}{HorizontalSpace }{LeftBrace {}{VerticalSpace }{Text return}{HorizontalSpace }{Placeholder expression}{SemiColon ;}{VerticalSpace }{RightBrace }} (42) // CHECK-CC4: ObjCInstanceMethodDecl:{LeftParen (}{Text int}{RightParen )}{TypedText getInt}{HorizontalSpace }{LeftBrace {}{VerticalSpace // CHECK-CC4: ObjCInstanceMethodDecl:{LeftParen (}{Text int}{RightParen )}{TypedText getSecondValue}{HorizontalSpace }{LeftBrace {}{VerticalSpace // CHECK-CC4: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText getSelf}{HorizontalSpace }{LeftBrace {}{VerticalSpace }{Text return}{HorizontalSpace }{Placeholder expression}{SemiColon ;}{VerticalSpace }{RightBrace }} (40) -// CHECK-CC4: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText initWithInt}{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace }{LeftBrace {}{VerticalSpace -// CHECK-CC4: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText initWithTwoInts}{TypedText :}{LeftParen (}{Text inout }{Text int}{RightParen )}{Text x}{HorizontalSpace }{TypedText second:}{LeftParen (}{Text int}{RightParen )}{Text y}{HorizontalSpace }{LeftBrace {}{VerticalSpace -// CHECK-CC4: ObjCInstanceMethodDecl:{LeftParen (}{Text int}{RightParen )}{TypedText setValue}{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace }{LeftBrace {}{VerticalSpace +// CHECK-CC4: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText initWithInt:}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace }{LeftBrace {}{VerticalSpace +// CHECK-CC4: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText initWithTwoInts:}{LeftParen (}{Text inout }{Text int}{RightParen )}{Text x}{HorizontalSpace }{TypedText second:}{LeftParen (}{Text int}{RightParen )}{Text y}{HorizontalSpace }{LeftBrace {}{VerticalSpace +// CHECK-CC4: ObjCInstanceMethodDecl:{LeftParen (}{Text int}{RightParen )}{TypedText setValue:}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace }{LeftBrace {}{VerticalSpace // RUN: env CINDEXTEST_CODE_COMPLETE_PATTERNS=1 c-index-test -code-completion-at=%s:33:8 %s | FileCheck -check-prefix=CHECK-CC5 %s // CHECK-CC5: ObjCInstanceMethodDecl:{TypedText getInt}{HorizontalSpace }{LeftBrace {}{VerticalSpace }{Text return}{HorizontalSpace }{Placeholder expression}{SemiColon ;}{VerticalSpace }{RightBrace }} (42) // CHECK-CC5: ObjCInstanceMethodDecl:{TypedText getSecondValue}{HorizontalSpace }{LeftBrace {}{VerticalSpace }{Text return}{HorizontalSpace }{Placeholder expression}{SemiColon ;}{VerticalSpace }{RightBrace }} (40) // CHECK-CC5-NOT: {TypedText getSelf}{HorizontalSpace }{LeftBrace {}{VerticalSpace -// CHECK-CC5: ObjCInstanceMethodDecl:{TypedText setValue}{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace }{LeftBrace {}{VerticalSpace +// CHECK-CC5: ObjCInstanceMethodDecl:{TypedText setValue:}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace }{LeftBrace {}{VerticalSpace // RUN: env CINDEXTEST_CODE_COMPLETE_PATTERNS=1 c-index-test -code-completion-at=%s:37:7 %s | FileCheck -check-prefix=CHECK-CC6 %s -// CHECK-CC6: ObjCInstanceMethodDecl:{TypedText abc}{HorizontalSpace }{LeftBrace {}{VerticalSpace +// CHECK-CC6: ObjCInstanceMethodDecl:{TypedText abc}{HorizontalSpace }{LeftBrace {}{VerticalSpace // CHECK-CC6: ObjCInstanceMethodDecl:{TypedText getSelf}{HorizontalSpace }{LeftBrace {}{VerticalSpace }{Text return}{HorizontalSpace }{Placeholder expression}{SemiColon ;}{VerticalSpace }{RightBrace }} (40) -// CHECK-CC6: ObjCInstanceMethodDecl:{TypedText initWithInt}{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace }{LeftBrace {}{VerticalSpace -// CHECK-CC6: ObjCInstanceMethodDecl:{TypedText initWithTwoInts}{TypedText :}{LeftParen (}{Text inout }{Text int}{RightParen )}{Text x}{HorizontalSpace }{TypedText second:}{LeftParen (}{Text int}{RightParen )}{Text y}{HorizontalSpace }{LeftBrace {}{VerticalSpace +// CHECK-CC6: ObjCInstanceMethodDecl:{TypedText initWithInt:}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace }{LeftBrace {}{VerticalSpace +// CHECK-CC6: ObjCInstanceMethodDecl:{TypedText initWithTwoInts:}{LeftParen (}{Text inout }{Text int}{RightParen )}{Text x}{HorizontalSpace }{TypedText second:}{LeftParen (}{Text int}{RightParen )}{Text y}{HorizontalSpace }{LeftBrace {}{VerticalSpace // RUN: env CINDEXTEST_CODE_COMPLETE_PATTERNS=1 c-index-test -code-completion-at=%s:42:3 %s | FileCheck -check-prefix=CHECK-CC7 %s // CHECK-CC7: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText abc}{HorizontalSpace }{LeftBrace {}{VerticalSpace }{Text return}{HorizontalSpace }{Placeholder expression}{SemiColon ;}{VerticalSpace }{RightBrace }} (42) -// CHECK-CC7: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText categoryFunction}{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace }{LeftBrace {}{VerticalSpace +// CHECK-CC7: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText categoryFunction:}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace }{LeftBrace {}{VerticalSpace // CHECK-CC7: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText getSelf}{HorizontalSpace }{LeftBrace {}{VerticalSpace }{Text return}{HorizontalSpace }{Placeholder expression}{SemiColon ;}{VerticalSpace }{RightBrace }} (42) // RUN: env CINDEXTEST_CODE_COMPLETE_PATTERNS=1 c-index-test -code-completion-at=%s:52:21 %s | FileCheck -check-prefix=CHECK-CC8 %s // CHECK-CC8: ObjCInstanceMethodDecl:{ResultType id}{Informative first:}{TypedText second2:}{Text (float)y2}{HorizontalSpace }{TypedText third:}{Text (double)z} (35) @@ -157,9 +157,9 @@ -(void)foo {} // RUN: env CINDEXTEST_CODE_COMPLETE_PATTERNS=1 c-index-test -code-completion-at=%s:52:36 %s | FileCheck -check-prefix=CHECK-CCA %s // CHECK-CCA: NotImplemented:{TypedText y2} (40) // RUN: c-index-test -code-completion-at=%s:56:3 %s | FileCheck -check-prefix=CHECK-CCB %s -// CHECK-CCB: ObjCInstanceMethodDecl:{LeftParen (}{Text int}{RightParen )}{TypedText first}{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace }{TypedText second2:}{LeftParen (}{Text float}{RightParen )}{Text y}{HorizontalSpace }{TypedText third:}{LeftParen (}{Text double}{RightParen )}{Text z} (40) +// CHECK-CCB: ObjCInstanceMethodDecl:{LeftParen (}{Text int}{RightParen )}{TypedText first:}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace }{TypedText second2:}{LeftParen (}{Text float}{RightParen )}{Text y}{HorizontalSpace }{TypedText third:}{LeftParen (}{Text double}{RightParen )}{Text z} (40) // RUN: c-index-test -code-completion-at=%s:56:8 %s | FileCheck -check-prefix=CHECK-CCC %s -// CHECK-CCC: ObjCInstanceMethodDecl:{TypedText first}{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace }{TypedText second2:}{LeftParen (}{Text float}{RightParen )}{Text y}{HorizontalSpace }{TypedText third:}{LeftParen (}{Text double}{RightParen )}{Text z} (40) +// CHECK-CCC: ObjCInstanceMethodDecl:{TypedText first:}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace }{TypedText second2:}{LeftParen (}{Text float}{RightParen )}{Text y}{HorizontalSpace }{TypedText third:}{LeftParen (}{Text double}{RightParen )}{Text z} (40) // RUN: c-index-test -code-completion-at=%s:56:21 %s | FileCheck -check-prefix=CHECK-CCD %s // CHECK-CCD: ObjCInstanceMethodDecl:{ResultType id}{Informative first:}{TypedText second2:}{Text (float)y2}{HorizontalSpace }{TypedText third:}{Text (double)z} (35) // CHECK-CCD: ObjCInstanceMethodDecl:{ResultType int}{Informative first:}{TypedText second2:}{Text (float)y}{HorizontalSpace }{TypedText third:}{Text (double)z} (8) @@ -214,11 +214,11 @@ -(void)foo {} // // RUN: c-index-test -code-completion-at=%s:68:9 %s | FileCheck -check-prefix=CHECK-8939352 %s -// CHECK-8939352: ObjCInstanceMethodDecl:{TypedText method}{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace }{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text y} (40) +// CHECK-8939352: ObjCInstanceMethodDecl:{TypedText method:}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace }{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text y} (40) // RUN: c-index-test -code-completion-at=%s:72:2 %s | FileCheck -check-prefix=CHECK-ONEWAY %s -// CHECK-ONEWAY: ObjCInstanceMethodDecl:{LeftParen (}{Text oneway }{Text void}{RightParen )}{TypedText method}{TypedText :}{LeftParen (}{Text in }{Text id}{RightParen )}{Text x} (40) +// CHECK-ONEWAY: ObjCInstanceMethodDecl:{LeftParen (}{Text oneway }{Text void}{RightParen )}{TypedText method:}{LeftParen (}{Text in }{Text id}{RightParen )}{Text x} (40) // RUN: c-index-test -code-completion-at=%s:85:2 %s | FileCheck -check-prefix=CHECK-CLASSTY %s // CHECK-CLASSTY: ObjCInstanceMethodDecl:{LeftParen (}{Text Class}{RightParen )}{TypedText meth} @@ -226,16 +226,16 @@ -(void)foo {} // CHECK-CLASSTY: ObjCInstanceMethodDecl:{LeftParen (}{Text MyObjectRef}{RightParen )}{TypedText meth3} // RUN: c-index-test -code-completion-at=%s:96:2 %s -target x86_64-apple-macosx10.7 | FileCheck -check-prefix=CHECK-NULLABILITY %s -// CHECK-NULLABILITY: ObjCInstanceMethodDecl:{LeftParen (}{Text I2 *}{RightParen )}{TypedText produceI2}{TypedText :}{LeftParen (}{Text I2 *}{RightParen )}{Text i2} (40) +// CHECK-NULLABILITY: ObjCInstanceMethodDecl:{LeftParen (}{Text I2 *}{RightParen )}{TypedText produceI2:}{LeftParen (}{Text I2 *}{RightParen )}{Text i2} (40) // CHECK-NULLABILITY: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText prop} // CHECK-NULLABILITY: ObjCInstanceMethodDecl:{LeftParen (}{Text void (^)(int * _Nullable)}{RightParen )}{TypedText propWB} -// CHECK-NULLABILITY: ObjCInstanceMethodDecl:{LeftParen (}{Text void}{RightParen )}{TypedText setProp}{TypedText :}{LeftParen (}{Text id}{RightParen )}{Text prop} -// CHECK-NULLABILITY: ObjCInstanceMethodDecl:{LeftParen (}{Text void}{RightParen )}{TypedText setPropWB}{TypedText :}{LeftParen (}{Text void (^)(int * _Nullable)}{RightParen )}{Text propWB} -// CHECK-NULLABILITY: ObjCInstanceMethodDecl:{LeftParen (}{Text int * _Nullable *}{RightParen )}{TypedText something}{TypedText :}{LeftParen (}{Text void (^)(int * _Nullable)}{RightParen )}{Text b} +// CHECK-NULLABILITY: ObjCInstanceMethodDecl:{LeftParen (}{Text void}{RightParen )}{TypedText setProp:}{LeftParen (}{Text id}{RightParen )}{Text prop} +// CHECK-NULLABILITY: ObjCInstanceMethodDecl:{LeftParen (}{Text void}{RightParen )}{TypedText setPropWB:}{LeftParen (}{Text void (^)(int * _Nullable)}{RightParen )}{Text propWB} +// CHECK-NULLABILITY: ObjCInstanceMethodDecl:{LeftParen (}{Text int * _Nullable *}{RightParen )}{TypedText something:}{LeftParen (}{Text void (^)(int * _Nullable)}{RightParen )}{Text b} // RUN: c-index-test -code-completion-at=%s:107:2 %s -target x86_64-apple-macosx10.7 | FileCheck -check-prefix=CHECK-NULLABILITY2 %s // CHECK-NULLABILITY2: ObjCInstanceMethodDecl:{LeftParen (}{Text instancetype}{RightParen )}{TypedText getI3} (40) -// CHECK-NULLABILITY2: ObjCInstanceMethodDecl:{LeftParen (}{Text I3 *}{RightParen )}{TypedText produceI3}{TypedText :}{LeftParen (}{Text I3 *}{RightParen )}{Text i3} (40) +// CHECK-NULLABILITY2: ObjCInstanceMethodDecl:{LeftParen (}{Text I3 *}{RightParen )}{TypedText produceI3:}{LeftParen (}{Text I3 *}{RightParen )}{Text i3} (40) @interface CompleteWithoutLeadingPrefix @@ -253,8 +253,21 @@ @implementation CompleteWithoutLeadingPrefix // RUN: c-index-test -code-completion-at=%s:250:1 %s | FileCheck -check-prefix=CHECK-COMP-NO-PREFIX %s // CHECK-COMP-NO-PREFIX: NotImplemented:{TypedText @end} (40) -// CHECK-COMP-NO-PREFIX: ObjCClassMethodDecl:{Text +}{HorizontalSpace }{LeftParen (}{Text int}{RightParen )}{TypedText aClassMethod}{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text x} (40) +// CHECK-COMP-NO-PREFIX: ObjCClassMethodDecl:{Text +}{HorizontalSpace }{LeftParen (}{Text int}{RightParen )}{TypedText aClassMethod:}{LeftParen (}{Text int}{RightParen )}{Text x} (40) // CHECK-COMP-NO-PREFIX: ObjCInstanceMethodDecl:{Text -}{HorizontalSpace }{LeftParen (}{Text void}{RightParen )}{TypedText aMethod} (40) // CHECK-COMP-NO-PREFIX: ObjCInterfaceDecl:{TypedText I1} // CHECK-COMP-NO-PREFIX: ObjCInstanceMethodDecl:{Text -}{HorizontalSpace }{LeftParen (}{Text int}{RightParen )}{TypedText p} (40) -// CHECK-COMP-NO-PREFIX: ObjCInstanceMethodDecl:{Text -}{HorizontalSpace }{LeftParen (}{Text void}{RightParen )}{TypedText setP}{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text p} (40) +// CHECK-COMP-NO-PREFIX: ObjCInstanceMethodDecl:{Text -}{HorizontalSpace }{LeftParen (}{Text void}{RightParen )}{TypedText setP:}{LeftParen (}{Text int}{RightParen )}{Text p} (40) + +@interface NoNameSelectors +- (void):(int)a; +- (void):(int)a :(int)b; +@end + +@implementation NoNameSelectors + +@end + +// RUN: c-index-test -code-completion-at=%s:268:1 %s | FileCheck -check-prefix=CHECK-NNS %s +// CHECK-NNS: ObjCInstanceMethodDecl:{Text -}{HorizontalSpace }{LeftParen (}{Text void}{RightParen )}{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text a} +// CHECK-NNS: ObjCInstanceMethodDecl:{Text -}{HorizontalSpace }{LeftParen (}{Text void}{RightParen )}{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text a}{HorizontalSpace }{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text b} diff --git a/clang/test/Index/complete-parameterized-classes.m b/clang/test/Index/complete-parameterized-classes.m index ffef991acbeec..701cf5d410b35 100644 --- a/clang/test/Index/complete-parameterized-classes.m +++ b/clang/test/Index/complete-parameterized-classes.m @@ -65,9 +65,9 @@ void test3() { // CHECK-CC5: ObjCIvarDecl:{ResultType __kindof NSObject *}{TypedText myVar} (35) // RUN: c-index-test -code-completion-at=%s:37:2 %s | FileCheck -check-prefix=CHECK-CC6 %s -// CHECK-CC6: ObjCInstanceMethodDecl:{LeftParen (}{Text void}{RightParen )}{TypedText apply2}{TypedText :}{LeftParen (}{Text void (^)(id, NSObject *)}{RightParen )}{Text block} (40) -// CHECK-CC6: ObjCInstanceMethodDecl:{LeftParen (}{Text void}{RightParen )}{TypedText apply}{TypedText :}{LeftParen (}{Text void (^)(id, NSObject *)}{RightParen )}{Text block} (40) -// CHECK-CC6: ObjCInstanceMethodDecl:{LeftParen (}{Text NSObject *}{RightParen )}{TypedText getit}{TypedText :}{LeftParen (}{Text id}{RightParen )}{Text val} (40) +// CHECK-CC6: ObjCInstanceMethodDecl:{LeftParen (}{Text void}{RightParen )}{TypedText apply2:}{LeftParen (}{Text void (^)(id, NSObject *)}{RightParen )}{Text block} (40) +// CHECK-CC6: ObjCInstanceMethodDecl:{LeftParen (}{Text void}{RightParen )}{TypedText apply:}{LeftParen (}{Text void (^)(id, NSObject *)}{RightParen )}{Text block} (40) +// CHECK-CC6: ObjCInstanceMethodDecl:{LeftParen (}{Text NSObject *}{RightParen )}{TypedText getit:}{LeftParen (}{Text id}{RightParen )}{Text val} (40) // CHECK-CC6: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText prop} (40) // RUN: c-index-test -code-completion-at=%s:41:8 %s | FileCheck -check-prefix=CHECK-CC7 %s diff --git a/clang/test/Index/coroutines.cpp b/clang/test/Index/coroutines.cpp index 5853437926c68..000327ffaec49 100644 --- a/clang/test/Index/coroutines.cpp +++ b/clang/test/Index/coroutines.cpp @@ -7,7 +7,7 @@ using std::experimental::suspend_never; struct promise_void { void get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void return_void(); void unhandled_exception(); }; diff --git a/clang/test/Index/evaluate-cursor.cpp b/clang/test/Index/evaluate-cursor.cpp index af396318aab7e..901e988bc99e5 100644 --- a/clang/test/Index/evaluate-cursor.cpp +++ b/clang/test/Index/evaluate-cursor.cpp @@ -26,6 +26,15 @@ template class e { static const auto g = alignof(f); }; +constexpr static int calc_val() { return 1 + 2; } +const auto the_value = calc_val() + sizeof(char); + +void vlaTest() { + int msize = 4; + float arr[msize]; + [&arr] {}; +} + // RUN: c-index-test -evaluate-cursor-at=%s:4:7 \ // RUN: -evaluate-cursor-at=%s:8:7 \ // RUN: -evaluate-cursor-at=%s:8:11 -std=c++11 %s | FileCheck %s @@ -53,3 +62,16 @@ template class e { // RUN: -evaluate-cursor-at=%s:26:21 \ // RUN: -std=c++11 %s | FileCheck -check-prefix=CHECK-DOES-NOT-CRASH %s // CHECK-DOES-NOT-CRASH: Not Evaluatable + +// RUN: c-index-test -evaluate-cursor-at=%s:30:1 \ +// RUN: -evaluate-cursor-at=%s:30:32 \ +// RUN: -evaluate-cursor-at=%s:30:35 \ +// RUN: -evaluate-cursor-at=%s:30:37 -std=c++11 %s | FileCheck %s -check-prefix=CHECK-EXPR +// CHECK-EXPR: unsigned, Value: 4 +// CHECK-EXPR: Value: 3 +// CHECK-EXPR: unsigned, Value: 4 +// CHECK-EXPR: unsigned, Value: 1 + +// RUN: c-index-test -evaluate-cursor-at=%s:35:5 \ +// RUN: -std=c++11 %s | FileCheck -check-prefix=VLA %s +// VLA: Not Evaluatable diff --git a/clang/test/Misc/warning-flags.c b/clang/test/Misc/warning-flags.c index 841c748b8025d..e4f9069b88c86 100644 --- a/clang/test/Misc/warning-flags.c +++ b/clang/test/Misc/warning-flags.c @@ -18,7 +18,7 @@ This test serves two purposes: The list of warnings below should NEVER grow. It should gradually shrink to 0. -CHECK: Warnings without flags (69): +CHECK: Warnings without flags (68): CHECK-NEXT: ext_expected_semi_decl_list CHECK-NEXT: ext_explicit_specialization_storage_class @@ -58,7 +58,6 @@ CHECK-NEXT: warn_fe_macro_contains_embedded_newline CHECK-NEXT: warn_ignoring_ftabstop_value CHECK-NEXT: warn_implements_nscopying CHECK-NEXT: warn_incompatible_qualified_id -CHECK-NEXT: warn_inline_namespace_reopened_noninline CHECK-NEXT: warn_invalid_asm_cast_lvalue CHECK-NEXT: warn_maynot_respond CHECK-NEXT: warn_method_param_redefinition diff --git a/clang/test/Modules/Inputs/codegen-flags/foo.h b/clang/test/Modules/Inputs/codegen-flags/foo.h index 7b9c1cd8e086e..74cfab1771f62 100644 --- a/clang/test/Modules/Inputs/codegen-flags/foo.h +++ b/clang/test/Modules/Inputs/codegen-flags/foo.h @@ -1,4 +1,7 @@ +#ifndef FOO_H +#define FOO_H struct foo { }; inline void f1() { } +#endif diff --git a/clang/test/Modules/context-hash.c b/clang/test/Modules/context-hash.c index 33dfb2f15a2ce..8bb7422f6a54f 100644 --- a/clang/test/Modules/context-hash.c +++ b/clang/test/Modules/context-hash.c @@ -1,3 +1,6 @@ +// This test verifies that only strict hashing includes search paths and +// diagnostics in the module context hash. + // RUN: rm -rf %t // RUN: %clang_cc1 -fsyntax-only -internal-isystem \ // RUN: %S/Inputs/System/usr/include -fmodules -fimplicit-module-maps \ @@ -20,8 +23,25 @@ // RUN: echo %t > %t.path // RUN: cat %t.path %t1 %t2 %t3 %t4 | FileCheck %s -// This test verifies that only strict hashing includes search paths and -// diagnostics in the module context hash. +// This tests things verified by ASTReader::checkLanguageOptions that are not +// part of LangOpts.def. + +// RUN: rm -rf %t +// RUN: %clang_cc1 -fsyntax-only -internal-isystem \ +// RUN: %S/Inputs/System/usr/include -fmodules -fimplicit-module-maps \ +// RUN: -fmodules-cache-path=%t -x objective-c %s -Rmodule-build 2> %t1 +// RUN: rm -rf %t +// RUN: %clang_cc1 -fsyntax-only -internal-isystem \ +// RUN: %S/Inputs/System/usr/include -fmodules -fimplicit-module-maps \ +// RUN: -fobjc-runtime=macosx-1.0.0.0 \ +// RUN: -fmodules-cache-path=%t -x objective-c %s -Rmodule-build 2> %t2 +// RUN: rm -rf %t +// RUN: %clang_cc1 -fsyntax-only -internal-isystem \ +// RUN: %S/Inputs/System/usr/include -fmodules -fimplicit-module-maps \ +// RUN: -fcomment-block-commands=lp,bj \ +// RUN: -fmodules-cache-path=%t -x objective-c %s -Rmodule-build 2> %t3 +// RUN: echo %t > %t.path +// RUN: cat %t.path %t1 %t2 %t3 | FileCheck --check-prefix=LANGOPTS %s #include @@ -32,3 +52,10 @@ // CHECK: cstd-[[AST_HASH]].pcm' // CHECK-NOT: building module 'cstd' as '{{.*[/\\]}}[[CONTEXT_HASH]]{{[/\\]}} // CHECK: cstd-[[AST_HASH]].pcm' + +// LANGOPTS: [[PREFIX:(.*[/\\])+[a-zA-Z0-9.-]+]] +// LANGOPTS: building module 'cstd' as '[[PREFIX]]{{[/\\]}}[[CONTEXT_HASH:[A-Z0-9]+]]{{[/\\]}}cstd-[[AST_HASH:[A-Z0-9]+]].pcm' +// LANGOPTS-NOT: building module 'cstd' as '{{.*[/\\]}}[[CONTEXT_HASH]]{{[/\\]}} +// LANGOPTS: cstd-[[AST_HASH]].pcm' +// LANGOPTS-NOT: building module 'cstd' as '{{.*[/\\]}}[[CONTEXT_HASH]]{{[/\\]}} +// LANGOPTS: cstd-[[AST_HASH]].pcm' diff --git a/clang/test/OpenMP/declare_reduction_codegen.c b/clang/test/OpenMP/declare_reduction_codegen.c index efc2466657f0a..f5695ffaac342 100644 --- a/clang/test/OpenMP/declare_reduction_codegen.c +++ b/clang/test/OpenMP/declare_reduction_codegen.c @@ -2,6 +2,9 @@ // RUN: %clang_cc1 -fopenmp -x c -triple %itanium_abi_triple -emit-pch -o %t %s -femit-all-decls -disable-llvm-passes // RUN: %clang_cc1 -fopenmp -x c -triple %itanium_abi_triple -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefix=CHECK-LOAD %s +// RUN: %clang_cc1 -fopenmp -x c -triple %itanium_abi_triple -emit-pch -o %t %s -femit-all-decls -disable-llvm-passes -fopenmp-version=45 +// RUN: %clang_cc1 -fopenmp -x c -triple %itanium_abi_triple -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-passes -fopenmp-version=45 | FileCheck --check-prefixes=CHECK-LOAD,OMP45-LOAD %s + // RUN: %clang_cc1 -verify -fopenmp-simd -x c -emit-llvm %s -triple %itanium_abi_triple -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefix SIMD-ONLY0 %s // RUN: %clang_cc1 -fopenmp-simd -x c -triple %itanium_abi_triple -emit-pch -o %t %s -femit-all-decls -disable-llvm-passes // RUN: %clang_cc1 -fopenmp-simd -x c -triple %itanium_abi_triple -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefix SIMD-ONLY0 %s @@ -146,18 +149,18 @@ int main() { return 0; } -// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1) -// CHECK-LOAD: [[MUL:%.+]] = mul nsw i32 -// CHECK-LOAD-NEXT: store i32 [[MUL]], i32* -// CHECK-LOAD-NEXT: ret void -// CHECK-LOAD-NEXT: } +// OMP45-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1) +// OMP45-LOAD: [[MUL:%.+]] = mul nsw i32 +// OMP45-LOAD-NEXT: store i32 [[MUL]], i32* +// OMP45-LOAD-NEXT: ret void +// OMP45-LOAD-NEXT: } -// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i8* noalias %0, i8* noalias %1) -// CHECK-LOAD: sext i8 -// CHECK-LOAD: sext i8 -// CHECK-LOAD: [[MUL:%.+]] = mul nsw i32 -// CHECK-LOAD-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i8 -// CHECK-LOAD-NEXT: store i8 [[TRUNC]], i8* -// CHECK-LOAD-NEXT: ret void -// CHECK-LOAD-NEXT: } +// OMP45-LOAD: define internal {{.*}}void @{{[^(]+}}(i8* noalias %0, i8* noalias %1) +// OMP45-LOAD: sext i8 +// OMP45-LOAD: sext i8 +// OMP45-LOAD: [[MUL:%.+]] = mul nsw i32 +// OMP45-LOAD-NEXT: [[TRUNC:%.+]] = trunc i32 [[MUL]] to i8 +// OMP45-LOAD-NEXT: store i8 [[TRUNC]], i8* +// OMP45-LOAD-NEXT: ret void +// OMP45-LOAD-NEXT: } #endif diff --git a/clang/test/OpenMP/declare_reduction_codegen.cpp b/clang/test/OpenMP/declare_reduction_codegen.cpp index 8d49d81cd0e36..6209e00ba0a3e 100644 --- a/clang/test/OpenMP/declare_reduction_codegen.cpp +++ b/clang/test/OpenMP/declare_reduction_codegen.cpp @@ -1,6 +1,10 @@ // RUN: %clang_cc1 -verify -fopenmp -x c++ -emit-llvm %s -triple x86_64-linux -fexceptions -fcxx-exceptions -o - -femit-all-decls -disable-llvm-passes | FileCheck %s // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-linux -fexceptions -fcxx-exceptions -emit-pch -o %t %s -femit-all-decls -disable-llvm-passes -// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-linux -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefix=CHECK-LOAD %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-linux -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefixes=CHECK-LOAD,OMP50-LOAD %s + +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -emit-llvm %s -triple x86_64-linux -fexceptions -fcxx-exceptions -o - -femit-all-decls -disable-llvm-passes | FileCheck %s --check-prefixes=CHECK,OMP45 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple x86_64-linux -fexceptions -fcxx-exceptions -emit-pch -o %t %s -femit-all-decls -disable-llvm-passes +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple x86_64-linux -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefixes=CHECK-LOAD,OMP45-LOAD %s // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -emit-llvm %s -triple x86_64-linux -fexceptions -fcxx-exceptions -o - -femit-all-decls -disable-llvm-passes | FileCheck --check-prefix SIMD-ONLY0 %s // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-linux -fexceptions -fcxx-exceptions -emit-pch -o %t %s -femit-all-decls -disable-llvm-passes @@ -14,25 +18,25 @@ // CHECK: [[SSS_INT:.+]] = type { i32 } // CHECK-LOAD: [[SSS_INT:.+]] = type { i32 } -// CHECK: add +// OMP45: add void add(short &out, short &in) {} #pragma omp declare reduction(my_add : short : add(omp_out, omp_in)) -// CHECK: define internal void @. -// CHECK: call void @{{.+}}add{{.+}}( -// CHECK: ret void +// OMP45: define internal void @. +// OMP45: call void @{{.+}}add{{.+}}( +// OMP45: ret void -// CHECK: foo_reduction_array +// OMP45: foo_reduction_array void foo_reduction_array() { short y[1]; - // CHECK: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call( + // OMP45: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call( #pragma omp parallel for reduction(my_add : y) for (int i = 0; i < 1; i++) { } } -// CHECK: define internal void @ +// OMP45: define internal void @ #pragma omp declare reduction(+ : int, char : omp_out *= omp_in) // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1) @@ -181,17 +185,17 @@ int main() { // CHECK-LABEL: i32 @{{.+}}foo{{[^(].+}}(i32 // CHECK-LOAD-LABEL: i32 @{{.+}}foo{{[^(].+}}(i32 -// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1) -// CHECK-LOAD: [[XOR:%.+]] = xor i32 -// CHECK-LOAD-NEXT: store i32 [[XOR]], i32* -// CHECK-LOAD-NEXT: ret void -// CHECK-LOAD-NEXT: } - -// CHECK-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1) -// CHECK-LOAD: [[ADD:%.+]] = add nsw i32 24, -// CHECK-LOAD-NEXT: store i32 [[ADD]], i32* -// CHECK-LOAD-NEXT: ret void -// CHECK-LOAD-NEXT: } +// OMP45-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1) +// OMP45-LOAD: [[XOR:%.+]] = xor i32 +// OMP45-LOAD-NEXT: store i32 [[XOR]], i32* +// OMP45-LOAD-NEXT: ret void +// OMP45-LOAD-NEXT: } + +// OMP45-LOAD: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1) +// OMP45-LOAD: [[ADD:%.+]] = add nsw i32 24, +// OMP45-LOAD-NEXT: store i32 [[ADD]], i32* +// OMP45-LOAD-NEXT: ret void +// OMP45-LOAD-NEXT: } // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1) // CHECK: [[ADD:%.+]] = add nsw i32 diff --git a/clang/test/OpenMP/declare_target_ast_print.cpp b/clang/test/OpenMP/declare_target_ast_print.cpp index 510162f808d2e..14115e6a3ad6a 100644 --- a/clang/test/OpenMP/declare_target_ast_print.cpp +++ b/clang/test/OpenMP/declare_target_ast_print.cpp @@ -33,9 +33,7 @@ void bazz(); #endif // _OPENMP int out_decl_target = 0; -#if _OPENMP == 201811 #pragma omp declare target (out_decl_target) -#endif // _OPENMP // CHECK: #pragma omp declare target{{$}} // CHECK: int out_decl_target = 0; diff --git a/clang/test/OpenMP/declare_target_codegen.cpp b/clang/test/OpenMP/declare_target_codegen.cpp index e55397ca74e75..0cd725ac5665f 100644 --- a/clang/test/OpenMP/declare_target_codegen.cpp +++ b/clang/test/OpenMP/declare_target_codegen.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc -DLOAD -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -DLOAD | FileCheck %s -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -emit-pch -o %t -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -o - -DLOAD | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc -DLOAD +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -DLOAD | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -emit-pch -o %t +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -o - -DLOAD | FileCheck %s // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - -fopenmp-version=50 -DOMP5 | FileCheck %s --check-prefix HOST5 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc -fopenmp-version=50 -DOMP5 @@ -13,10 +13,10 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc -fopenmp-version=50 -DOMP5 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -fopenmp-version=50 -DOMP5 | FileCheck %s --check-prefix SIMD-ONLY -// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc -// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o -| FileCheck %s --check-prefix SIMD-ONLY -// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -emit-pch -o %t -// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify -o - | FileCheck %s --check-prefix SIMD-ONLY +// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc -fopenmp-version=45 +// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -fopenmp-version=45 | FileCheck %s --check-prefix SIMD-ONLY +// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -emit-pch -o %t -fopenmp-version=45 +// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify -o - -fopenmp-version=45 | FileCheck %s --check-prefix SIMD-ONLY // expected-no-diagnostics diff --git a/clang/test/OpenMP/declare_target_messages.cpp b/clang/test/OpenMP/declare_target_messages.cpp index 1a371d699789f..3a78e492af587 100644 --- a/clang/test/OpenMP/declare_target_messages.cpp +++ b/clang/test/OpenMP/declare_target_messages.cpp @@ -1,10 +1,10 @@ -// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify=expected,omp45 -fopenmp -fnoopenmp-use-tls -ferror-limit 100 -o - %s +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify=expected,omp45 -fopenmp -fopenmp-version=45 -fnoopenmp-use-tls -ferror-limit 100 -o - %s // RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify=expected,omp5,host5 -fopenmp -fopenmp-version=50 -fnoopenmp-use-tls -ferror-limit 100 -o - %s // RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify=expected,omp5,dev5 -fopenmp -fopenmp-is-device -fopenmp-targets=x86_64-apple-macos10.7.0 -aux-triple x86_64-apple-macos10.7.0 -fopenmp-version=50 -fnoopenmp-use-tls -ferror-limit 100 -o - %s // RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify=expected,omp5,host5 -fopenmp-simd -fopenmp-version=50 -fnoopenmp-use-tls -ferror-limit 100 -o - %s // RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify=expected,omp5,host5 -fopenmp-simd -fopenmp-is-device -fopenmp-version=50 -fnoopenmp-use-tls -ferror-limit 100 -o - %s -// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify=expected,omp45 -fopenmp-simd -fnoopenmp-use-tls -ferror-limit 100 -o - %s +// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify=expected,omp45 -fopenmp-version=45 -fopenmp-simd -fnoopenmp-use-tls -ferror-limit 100 -o - %s #pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}} diff --git a/clang/test/OpenMP/declare_variant_implementation_vendor_codegen.cpp b/clang/test/OpenMP/declare_variant_implementation_vendor_codegen.cpp index bc34d174c1491..70e24c027eb82 100644 --- a/clang/test/OpenMP/declare_variant_implementation_vendor_codegen.cpp +++ b/clang/test/OpenMP/declare_variant_implementation_vendor_codegen.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple %itanium_abi_triple -emit-llvm %s -fexceptions -fcxx-exceptions -o - -fsanitize-address-use-after-scope | FileCheck %s --implicit-check-not='ret i32 {{6|7|8|9|10|12|13|14|15|19|21|22|23|24}}' +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple %itanium_abi_triple -emit-llvm %s -fexceptions -fcxx-exceptions -o - -fsanitize-address-use-after-scope -fopenmp-version=45 | FileCheck %s --implicit-check-not='ret i32 {{6|7|8|9|10|12|13|14|15|19|21|22|23|24}}' // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -emit-pch -o %t -fopenmp-version=50 %s // RUN: %clang_cc1 -fopenmp -x c++ -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -fopenmp-version=50 | FileCheck %s --implicit-check-not='ret i32 {{6|7|8|9|10|12|13|14|15|19|21|22|23|24}}' // expected-no-diagnostics diff --git a/clang/test/OpenMP/distribute_parallel_for_default_messages.cpp b/clang/test/OpenMP/distribute_parallel_for_default_messages.cpp index 0629ba096d0c2..67e4615ae8c01 100644 --- a/clang/test/OpenMP/distribute_parallel_for_default_messages.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_default_messages.cpp @@ -2,8 +2,17 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp -ferror-limit 100 -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + template T tmain(T argc) { int i; @@ -14,12 +23,12 @@ T tmain(T argc) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp distribute parallel for default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp distribute parallel for default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -34,7 +43,7 @@ T tmain(T argc) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp distribute parallel for default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -62,12 +71,12 @@ int main(int argc, char **argv) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp distribute parallel for default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp distribute parallel for default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -82,7 +91,7 @@ int main(int argc, char **argv) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp distribute parallel for default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -98,5 +107,15 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} foo(); +#ifdef OMP51 +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + for (i = 0; i < argc; ++i) { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif + return (tmain(argc) + tmain(argv[0][0])); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} expected-note {{in instantiation of function template specialization 'tmain' requested here}} } diff --git a/clang/test/OpenMP/distribute_parallel_for_simd_default_messages.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_default_messages.cpp index b9c5546ec5d95..9aab00f16c48f 100644 --- a/clang/test/OpenMP/distribute_parallel_for_simd_default_messages.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_simd_default_messages.cpp @@ -2,8 +2,17 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s -Wuninitialized -DOMP51 -fopenmp-version=51 + +// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized -DOMP51 -fopenmp-version=51 + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + template T tmain(T argc) { int i; @@ -14,12 +23,12 @@ T tmain(T argc) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp distribute parallel for simd default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp distribute parallel for simd default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -34,7 +43,7 @@ T tmain(T argc) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp distribute parallel for simd default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -62,12 +71,12 @@ int main(int argc, char **argv) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp distribute parallel for simd default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp distribute parallel for simd default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -82,7 +91,7 @@ int main(int argc, char **argv) { foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp distribute parallel for simd default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -90,6 +99,15 @@ int main(int argc, char **argv) { #pragma omp distribute parallel for simd default(none) // expected-note {{explicit data sharing attribute requested here}} for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} foo(); +#ifdef OpenMP51 +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + for (i = 0; i < argc; ++i) { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif #pragma omp parallel default(none) // expected-note 2 {{explicit data sharing attribute requested here}} #pragma omp target diff --git a/clang/test/OpenMP/distribute_parallel_for_simd_loop_messages.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_loop_messages.cpp index c58c56b6ca7af..8f7f3c44f7a77 100644 --- a/clang/test/OpenMP/distribute_parallel_for_simd_loop_messages.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_simd_loop_messages.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wno-openmp-mapping -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wno-openmp-mapping -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wno-openmp-mapping -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wno-openmp-mapping -Wuninitialized class S { diff --git a/clang/test/OpenMP/distribute_simd_loop_messages.cpp b/clang/test/OpenMP/distribute_simd_loop_messages.cpp index ff50109a1c405..5838ac7592a2a 100644 --- a/clang/test/OpenMP/distribute_simd_loop_messages.cpp +++ b/clang/test/OpenMP/distribute_simd_loop_messages.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized class S5 { diff --git a/clang/test/OpenMP/driver.c b/clang/test/OpenMP/driver.c index dad4479833e12..047478256f9f5 100644 --- a/clang/test/OpenMP/driver.c +++ b/clang/test/OpenMP/driver.c @@ -15,9 +15,9 @@ // RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=1 | FileCheck --check-prefix=CHECK-DEFAULT-VERSION %s // RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=0 | FileCheck --check-prefix=CHECK-DEFAULT-VERSION %s // RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=100 | FileCheck --check-prefix=CHECK-DEFAULT-VERSION %s -// RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=45 | FileCheck --check-prefix=CHECK-DEFAULT-VERSION %s +// RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=50 | FileCheck --check-prefix=CHECK-DEFAULT-VERSION %s -// CHECK-DEFAULT-VERSION: #define _OPENMP 201511 +// CHECK-DEFAULT-VERSION: #define _OPENMP 201811 // RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=31 | FileCheck --check-prefix=CHECK-31-VERSION %s // CHECK-31-VERSION: #define _OPENMP 201107 @@ -26,8 +26,8 @@ // CHECK-40-VERSION: #define _OPENMP 201307 // RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=45 | FileCheck --check-prefix=CHECK-45-VERSION %s -// RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-simd | FileCheck --check-prefix=CHECK-45-VERSION %s -// RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-targets=x86_64-unknown-unknown -o - | FileCheck --check-prefix=CHECK-45-VERSION --check-prefix=CHECK-45-VERSION2 %s +// RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=45 -fopenmp-simd | FileCheck --check-prefix=CHECK-45-VERSION %s +// RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=45 -fopenmp-targets=x86_64-unknown-unknown -o - | FileCheck --check-prefix=CHECK-45-VERSION --check-prefix=CHECK-45-VERSION2 %s // CHECK-45-VERSION: #define _OPENMP 201511 // CHECK-45-VERSION2: #define _OPENMP 201511 @@ -47,6 +47,7 @@ // RUN: %clang %s -c -E -dM -fopenmp-simd -fopenmp-version=31 | FileCheck --check-prefix=CHECK-VERSION %s // RUN: %clang %s -c -E -dM -fopenmp-simd -fopenmp-version=40 | FileCheck --check-prefix=CHECK-VERSION %s // RUN: %clang %s -c -E -dM -fopenmp-simd -fopenmp-version=45 | FileCheck --check-prefix=CHECK-VERSION %s +// RUN: %clang %s -c -E -dM -fopenmp-simd -fopenmp-version=51 | FileCheck --check-prefix=CHECK-VERSION %s // CHECK-VERSION-NOT: #define _OPENMP diff --git a/clang/test/OpenMP/for_codegen.cpp b/clang/test/OpenMP/for_codegen.cpp index f91301c8a897c..26b09c574f3c7 100644 --- a/clang/test/OpenMP/for_codegen.cpp +++ b/clang/test/OpenMP/for_codegen.cpp @@ -1,9 +1,10 @@ -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - -fsanitize-address-use-after-scope | FileCheck %s --check-prefix=CHECK --check-prefix=LIFETIME --check-prefix=OMP45 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - -fsanitize-address-use-after-scope | FileCheck %s --check-prefix=CHECK --check-prefix=LIFETIME --check-prefix=OMP45 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - -fsanitize-address-use-after-scope | FileCheck %s --check-prefix=CHECK --check-prefix=LIFETIME --check-prefix=OMP5 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t -fopenmp-version=50 %s // RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -fopenmp-version=50 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP5 -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK --check-prefix=OMP45 -// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -fopenmp-version=45 -emit-llvm -o - | FileCheck %s --check-prefix=CHECK --check-prefix=OMP45 +// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -gno-column-info -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG // RUN: %clang_cc1 -main-file-name for_codegen.cpp %s -o - -emit-llvm -fprofile-instrument=clang -fprofile-instrument-path=for_codegen-test.profraw | FileCheck %s --check-prefix=PROF-INSTR-PATH // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck --check-prefix SIMD-ONLY0 %s diff --git a/clang/test/OpenMP/for_collapse_messages.cpp b/clang/test/OpenMP/for_collapse_messages.cpp index 2316ca6ba3f0d..6fe6ef79c4c39 100644 --- a/clang/test/OpenMP/for_collapse_messages.cpp +++ b/clang/test/OpenMP/for_collapse_messages.cpp @@ -1,13 +1,13 @@ -// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp %s -Wuninitialized -// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp -std=c++98 %s -Wuninitialized -// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp -fopenmp-version=45 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp -fopenmp-version=45 -std=c++98 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp -fopenmp-version=45 -std=c++11 %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,omp50 -fopenmp -fopenmp-version=50 %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,omp50 -fopenmp -fopenmp-version=50 -std=c++98 %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,omp50 -fopenmp -fopenmp-version=50 -std=c++11 %s -Wuninitialized -// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp-simd %s -Wuninitialized -// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp-simd -std=c++98 %s -Wuninitialized -// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp-simd -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp-simd -fopenmp-version=45 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp-simd -fopenmp-version=45 -std=c++98 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp-simd -fopenmp-version=45 -std=c++11 %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,omp50 -fopenmp-simd -fopenmp-version=50 %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,omp50 -fopenmp-simd -fopenmp-version=50 -std=c++98 %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,omp50 -fopenmp-simd -fopenmp-version=50 -std=c++11 %s -Wuninitialized diff --git a/clang/test/OpenMP/for_loop_messages.cpp b/clang/test/OpenMP/for_loop_messages.cpp index 087db755273a2..b423bfa0f31fa 100644 --- a/clang/test/OpenMP/for_loop_messages.cpp +++ b/clang/test/OpenMP/for_loop_messages.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized class S { diff --git a/clang/test/OpenMP/for_simd_loop_messages.cpp b/clang/test/OpenMP/for_simd_loop_messages.cpp index 99f30a64eb5e3..6c5820ab7c451 100644 --- a/clang/test/OpenMP/for_simd_loop_messages.cpp +++ b/clang/test/OpenMP/for_simd_loop_messages.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized class S { diff --git a/clang/test/OpenMP/master_taskloop_loop_messages.cpp b/clang/test/OpenMP/master_taskloop_loop_messages.cpp index 9b50439705c42..10a60f306a904 100644 --- a/clang/test/OpenMP/master_taskloop_loop_messages.cpp +++ b/clang/test/OpenMP/master_taskloop_loop_messages.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized class S { diff --git a/clang/test/OpenMP/master_taskloop_simd_loop_messages.cpp b/clang/test/OpenMP/master_taskloop_simd_loop_messages.cpp index e39dbceda0fce..a4eb21bf24b69 100644 --- a/clang/test/OpenMP/master_taskloop_simd_loop_messages.cpp +++ b/clang/test/OpenMP/master_taskloop_simd_loop_messages.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized class S { diff --git a/clang/test/OpenMP/nesting_of_regions.cpp b/clang/test/OpenMP/nesting_of_regions.cpp index 9824c1df5310e..f391d21df616d 100644 --- a/clang/test/OpenMP/nesting_of_regions.cpp +++ b/clang/test/OpenMP/nesting_of_regions.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -fopenmp -verify=expected,omp45,omp45warn %s +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -verify=expected,omp45,omp45warn %s // RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=50 -verify=expected,omp50 %s // RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -verify=expected,omp45 -Wno-openmp %s // RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -verify=expected,omp45 -Wno-source-uses-openmp %s diff --git a/clang/test/OpenMP/nvptx_data_sharing.cpp b/clang/test/OpenMP/nvptx_data_sharing.cpp index 1905999977358..1372246c7fc8c 100644 --- a/clang/test/OpenMP/nvptx_data_sharing.cpp +++ b/clang/test/OpenMP/nvptx_data_sharing.cpp @@ -2,7 +2,8 @@ ///==========================================================================/// // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -disable-llvm-optzns | FileCheck %s --check-prefix CK1 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -disable-llvm-optzns | FileCheck %s --check-prefix CK1 --check-prefix SEQ +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -disable-llvm-optzns -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CK1 --check-prefix PAR // expected-no-diagnostics @@ -26,11 +27,11 @@ void test_ds(){ } } } -// CK1: [[MEM_TY:%.+]] = type { [128 x i8] } -// CK1-DAG: [[SHARED_GLOBAL_RD:@.+]] = common addrspace(3) global [[MEM_TY]] zeroinitializer -// CK1-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null -// CK1-DAG: [[KERNEL_SIZE:@.+]] = internal unnamed_addr constant i64 8 -// CK1-DAG: [[KERNEL_SHARED:@.+]] = internal unnamed_addr constant i16 1 +// SEQ: [[MEM_TY:%.+]] = type { [128 x i8] } +// SEQ-DAG: [[SHARED_GLOBAL_RD:@.+]] = common addrspace(3) global [[MEM_TY]] zeroinitializer +// SEQ-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null +// SEQ-DAG: [[KERNEL_SIZE:@.+]] = internal unnamed_addr constant i64 8 +// SEQ-DAG: [[KERNEL_SHARED:@.+]] = internal unnamed_addr constant i16 1 /// ========= In the worker function ========= /// // CK1: {{.*}}define internal void @__omp_offloading{{.*}}test_ds{{.*}}_worker() @@ -44,16 +45,17 @@ void test_ds(){ // CK1: [[SHAREDARGS2:%.+]] = alloca i8** // CK1: call void @__kmpc_kernel_init // CK1: call void @__kmpc_data_sharing_init_stack -// CK1: [[SHARED_MEM_FLAG:%.+]] = load i16, i16* [[KERNEL_SHARED]], -// CK1: [[SIZE:%.+]] = load i64, i64* [[KERNEL_SIZE]], -// CK1: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i64 [[SIZE]], i16 [[SHARED_MEM_FLAG]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**)) -// CK1: [[KERNEL_RD:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]], -// CK1: [[GLOBALSTACK:%.+]] = getelementptr inbounds i8, i8* [[KERNEL_RD]], i64 0 +// SEQ: [[SHARED_MEM_FLAG:%.+]] = load i16, i16* [[KERNEL_SHARED]], +// SEQ: [[SIZE:%.+]] = load i64, i64* [[KERNEL_SIZE]], +// SEQ: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i64 [[SIZE]], i16 [[SHARED_MEM_FLAG]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**)) +// SEQ: [[KERNEL_RD:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]], +// SEQ: [[GLOBALSTACK:%.+]] = getelementptr inbounds i8, i8* [[KERNEL_RD]], i64 0 +// PAR: [[GLOBALSTACK:%.+]] = call i8* @__kmpc_data_sharing_push_stack(i{{32|64}} 8, i16 1) // CK1: [[GLOBALSTACK2:%.+]] = bitcast i8* [[GLOBALSTACK]] to %struct._globalized_locals_ty* // CK1: [[A:%.+]] = getelementptr inbounds %struct._globalized_locals_ty, %struct._globalized_locals_ty* [[GLOBALSTACK2]], i32 0, i32 0 // CK1: [[B:%.+]] = getelementptr inbounds %struct._globalized_locals_ty, %struct._globalized_locals_ty* [[GLOBALSTACK2]], i32 0, i32 1 // CK1: store i32 10, i32* [[A]] -// CK1: call void @__kmpc_kernel_prepare_parallel({{.*}}, i16 1) +// CK1: call void @__kmpc_kernel_prepare_parallel({{.*}}) // CK1: call void @__kmpc_begin_sharing_variables(i8*** [[SHAREDARGS1]], i64 1) // CK1: [[SHARGSTMP1:%.+]] = load i8**, i8*** [[SHAREDARGS1]] // CK1: [[SHARGSTMP2:%.+]] = getelementptr inbounds i8*, i8** [[SHARGSTMP1]], i64 0 @@ -63,7 +65,7 @@ void test_ds(){ // CK1: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0) // CK1: call void @__kmpc_end_sharing_variables() // CK1: store i32 100, i32* [[B]] -// CK1: call void @__kmpc_kernel_prepare_parallel({{.*}}, i16 1) +// CK1: call void @__kmpc_kernel_prepare_parallel({{.*}}) // CK1: call void @__kmpc_begin_sharing_variables(i8*** [[SHAREDARGS2]], i64 2) // CK1: [[SHARGSTMP3:%.+]] = load i8**, i8*** [[SHAREDARGS2]] // CK1: [[SHARGSTMP4:%.+]] = getelementptr inbounds i8*, i8** [[SHARGSTMP3]], i64 0 @@ -75,8 +77,9 @@ void test_ds(){ // CK1: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0) // CK1: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0) // CK1: call void @__kmpc_end_sharing_variables() -// CK1: [[SHARED_MEM_FLAG:%.+]] = load i16, i16* [[KERNEL_SHARED]], -// CK1: call void @__kmpc_restore_team_static_memory(i16 0, i16 [[SHARED_MEM_FLAG]]) +// SEQ: [[SHARED_MEM_FLAG:%.+]] = load i16, i16* [[KERNEL_SHARED]], +// SEQ: call void @__kmpc_restore_team_static_memory(i16 0, i16 [[SHARED_MEM_FLAG]]) +// PAR: call void @__kmpc_data_sharing_pop_stack(i8* [[GLOBALSTACK]]) // CK1: call void @__kmpc_kernel_deinit(i16 1) /// ========= In the data sharing wrapper function ========= /// diff --git a/clang/test/OpenMP/nvptx_distribute_parallel_generic_mode_codegen.cpp b/clang/test/OpenMP/nvptx_distribute_parallel_generic_mode_codegen.cpp index 87d2c622015de..62cbeaa1326a7 100644 --- a/clang/test/OpenMP/nvptx_distribute_parallel_generic_mode_codegen.cpp +++ b/clang/test/OpenMP/nvptx_distribute_parallel_generic_mode_codegen.cpp @@ -1,9 +1,12 @@ // Test target codegen - host bc file has to be created first. // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -disable-llvm-optzns | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -disable-llvm-optzns | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix SEQ +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -disable-llvm-optzns -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix PAR // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc -// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -disable-llvm-optzns | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 -// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -disable-llvm-optzns | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -disable-llvm-optzns | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix SEQ +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -disable-llvm-optzns | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix SEQ +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -disable-llvm-optzns -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix PAR +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -disable-llvm-optzns -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix PAR // expected-no-diagnostics #ifndef HEADER #define HEADER @@ -21,19 +24,20 @@ int main(int argc, char **argv) { return 0; } -// CHECK: [[MEM_TY:%.+]] = type { [128 x i8] } -// CHECK-DAG: [[SHARED_GLOBAL_RD:@.+]] = common addrspace(3) global [[MEM_TY]] zeroinitializer -// CHECK-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null -// CHECK-DAG: [[KERNEL_SIZE:@.+]] = internal unnamed_addr constant i{{64|32}} 40 -// CHECK-DAG: [[KERNEL_SHARED:@.+]] = internal unnamed_addr constant i16 1 -// CHECK-DAG: @__omp_offloading_{{.*}}_main_l17_exec_mode = weak constant i8 0 - -// CHECK: define weak void @__omp_offloading_{{.*}}_main_l17([10 x i32]* nonnull align 4 dereferenceable(40) %{{.+}}, [10 x i32]* nonnull align 4 dereferenceable(40) %{{.+}}, i32* nonnull align 4 dereferenceable(4) %{{.+}}, i{{64|32}} %{{.+}}, [10 x i32]* nonnull align 4 dereferenceable(40) %{{.+}}) -// CHECK: [[SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]], -// CHECK: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE]], -// CHECK: call void @__kmpc_get_team_static_memory(i16 1, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**)) -// CHECK: [[PTR:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]], -// CHECK: [[GEP:%.+]] = getelementptr inbounds i8, i8* [[PTR]], i{{64|32}} 0 +// SEQ: [[MEM_TY:%.+]] = type { [128 x i8] } +// SEQ-DAG: [[SHARED_GLOBAL_RD:@.+]] = common addrspace(3) global [[MEM_TY]] zeroinitializer +// SEQ-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null +// SEQ-DAG: [[KERNEL_SIZE:@.+]] = internal unnamed_addr constant i{{64|32}} 40 +// SEQ-DAG: [[KERNEL_SHARED:@.+]] = internal unnamed_addr constant i16 1 +// CHECK-DAG: @__omp_offloading_{{.*}}_main_l20_exec_mode = weak constant i8 0 + +// CHECK: define weak void @__omp_offloading_{{.*}}_main_l20([10 x i32]* nonnull align 4 dereferenceable(40) %{{.+}}, [10 x i32]* nonnull align 4 dereferenceable(40) %{{.+}}, i32* nonnull align 4 dereferenceable(4) %{{.+}}, i{{64|32}} %{{.+}}, [10 x i32]* nonnull align 4 dereferenceable(40) %{{.+}}) +// SEQ: [[SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]], +// SEQ: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE]], +// SEQ: call void @__kmpc_get_team_static_memory(i16 1, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**)) +// SEQ: [[PTR:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]], +// SEQ: [[GEP:%.+]] = getelementptr inbounds i8, i8* [[PTR]], i{{64|32}} 0 +// PAR: [[GEP:%.+]] = call i8* @__kmpc_data_sharing_push_stack(i{{32|64}} 40, i16 1) // CHECK: [[STACK:%.+]] = bitcast i8* [[GEP]] to %struct._globalized_locals_ty* // CHECK: getelementptr inbounds %struct._globalized_locals_ty, %struct._globalized_locals_ty* [[STACK]], i{{32|64}} 0, i{{32|64}} 0 // CHECK-NOT: getelementptr inbounds %struct._globalized_locals_ty, %struct._globalized_locals_ty* [[STACK]], @@ -43,8 +47,9 @@ int main(int argc, char **argv) { // CHECK: call void @__kmpc_for_static_fini(%struct.ident_t* @ -// CHECK: [[SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]], -// CHECK: call void @__kmpc_restore_team_static_memory(i16 1, i16 [[SHARED]]) +// SEQ: [[SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]], +// SEQ: call void @__kmpc_restore_team_static_memory(i16 1, i16 [[SHARED]]) +// PAR: call void @__kmpc_data_sharing_pop_stack(i8* [[GEP]]) // CHECK: define internal void [[PARALLEL]]( // CHECK-NOT: call i8* @__kmpc_data_sharing_push_stack( diff --git a/clang/test/OpenMP/nvptx_parallel_codegen.cpp b/clang/test/OpenMP/nvptx_parallel_codegen.cpp index 9acc5aef72d1f..ad25e0d775d12 100644 --- a/clang/test/OpenMP/nvptx_parallel_codegen.cpp +++ b/clang/test/OpenMP/nvptx_parallel_codegen.cpp @@ -1,9 +1,12 @@ // Test target codegen - host bc file has to be created first. // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -disable-llvm-optzns | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -disable-llvm-optzns | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix SEQ +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -disable-llvm-optzns -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix PAR // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -disable-llvm-optzns | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 -// RUN: %clang_cc1 -verify -fopenmp -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -disable-llvm-optzns | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -disable-llvm-optzns | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix SEQ +// RUN: %clang_cc1 -verify -fopenmp -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -disable-llvm-optzns | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix SEQ +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -disable-llvm-optzns -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix PAR +// RUN: %clang_cc1 -verify -fopenmp -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -disable-llvm-optzns -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix PAR // expected-no-diagnostics #ifndef HEADER #define HEADER @@ -72,15 +75,15 @@ int bar(int n){ return a; } -// CHECK: [[MEM_TY:%.+]] = type { [128 x i8] } -// CHECK-DAG: [[SHARED_GLOBAL_RD:@.+]] = common addrspace(3) global [[MEM_TY]] zeroinitializer -// CHECK-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null -// CHECK-DAG: [[KERNEL_SIZE:@.+]] = internal unnamed_addr constant i{{64|32}} 4 -// CHECK-DAG: [[KERNEL_SHARED:@.+]] = internal unnamed_addr constant i16 1 +// SEQ: [[MEM_TY:%.+]] = type { [128 x i8] } +// SEQ-DAG: [[SHARED_GLOBAL_RD:@.+]] = common addrspace(3) global [[MEM_TY]] zeroinitializer +// SEQ-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null +// SEQ-DAG: [[KERNEL_SIZE:@.+]] = internal unnamed_addr constant i{{64|32}} 4 +// SEQ-DAG: [[KERNEL_SHARED:@.+]] = internal unnamed_addr constant i16 1 -// CHECK-NOT: define {{.*}}void {{@__omp_offloading_.+template.+l17}}_worker() +// CHECK-NOT: define {{.*}}void {{@__omp_offloading_.+template.+l20}}_worker() -// CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l26}}_worker() +// CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l29}}_worker() // CHECK-DAG: [[OMP_EXEC_STATUS:%.+]] = alloca i8, // CHECK-DAG: [[OMP_WORK_FN:%.+]] = alloca i8*, // CHECK: store i8* null, i8** [[OMP_WORK_FN]], @@ -89,7 +92,7 @@ int bar(int n){ // // CHECK: [[AWAIT_WORK]] // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0) #[[#CONVERGENT:]] -// CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]] +// CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]]) // CHECK: [[KPRB:%.+]] = zext i1 [[KPR]] to i8 // store i8 [[KPRB]], i8* [[OMP_EXEC_STATUS]], align 1 // CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]], @@ -133,7 +136,7 @@ int bar(int n){ // CHECK: [[EXIT]] // CHECK: ret void -// CHECK: define {{.*}}void [[T6:@__omp_offloading_.+template.+l26]](i[[SZ:32|64]] +// CHECK: define {{.*}}void [[T6:@__omp_offloading_.+template.+l29]](i[[SZ:32|64]] // Create local storage for each capture. // CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]], // CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]] @@ -163,13 +166,13 @@ int bar(int n){ // CHECK-DAG: [[MWS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize() // CHECK: [[MTMP1:%.+]] = sub nuw i32 [[MNTH]], [[MWS]] // CHECK: call void @__kmpc_kernel_init(i32 [[MTMP1]] -// CHECK: call void @__kmpc_kernel_prepare_parallel(i8* bitcast (void (i16, i32)* [[PARALLEL_FN1]]_wrapper to i8*), +// CHECK: call void @__kmpc_kernel_prepare_parallel(i8* bitcast (void (i16, i32)* [[PARALLEL_FN1]]_wrapper to i8*)) // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0) // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0) // CHECK: call void @__kmpc_serialized_parallel( // CHECK: {{call|invoke}} void [[PARALLEL_FN3:@.+]]( // CHECK: call void @__kmpc_end_serialized_parallel( -// CHECK: call void @__kmpc_kernel_prepare_parallel(i8* bitcast (void (i16, i32)* [[PARALLEL_FN2]]_wrapper to i8*), +// CHECK: call void @__kmpc_kernel_prepare_parallel(i8* bitcast (void (i16, i32)* [[PARALLEL_FN2]]_wrapper to i8*)) // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0) // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0) // CHECK-64-DAG: load i32, i32* [[REF_A]] @@ -199,7 +202,7 @@ int bar(int n){ // CHECK: store i[[SZ]] 44, i[[SZ]]* %a, // CHECK: ret void -// CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l43}}_worker() +// CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l46}}_worker() // CHECK-DAG: [[OMP_EXEC_STATUS:%.+]] = alloca i8, // CHECK-DAG: [[OMP_WORK_FN:%.+]] = alloca i8*, // CHECK: store i8* null, i8** [[OMP_WORK_FN]], @@ -208,7 +211,7 @@ int bar(int n){ // // CHECK: [[AWAIT_WORK]] // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0) -// CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]], +// CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]]) // CHECK: [[KPRB:%.+]] = zext i1 [[KPR]] to i8 // store i8 [[KPRB]], i8* [[OMP_EXEC_STATUS]], align 1 // CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]], @@ -243,7 +246,7 @@ int bar(int n){ // CHECK: [[EXIT]] // CHECK: ret void -// CHECK: define {{.*}}void [[T6:@__omp_offloading_.+template.+l43]](i[[SZ:32|64]] +// CHECK: define {{.*}}void [[T6:@__omp_offloading_.+template.+l46]](i[[SZ:32|64]] // Create local storage for each capture. // CHECK: [[LOCAL_N:%.+]] = alloca i[[SZ]], // CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]], @@ -288,7 +291,7 @@ int bar(int n){ // CHECK: br i1 [[CMP]], label {{%?}}[[IF_THEN:.+]], label {{%?}}[[IF_ELSE:.+]] // // CHECK: [[IF_THEN]] -// CHECK: call void @__kmpc_kernel_prepare_parallel(i8* bitcast (void (i16, i32)* [[PARALLEL_FN4]]_wrapper to i8*), +// CHECK: call void @__kmpc_kernel_prepare_parallel(i8* bitcast (void (i16, i32)* [[PARALLEL_FN4]]_wrapper to i8*)) // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0) // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0) // CHECK: br label {{%?}}[[IF_END:.+]] @@ -323,23 +326,25 @@ int bar(int n){ // CHECK: declare void @__kmpc_barrier(%struct.ident_t*, i32) #[[#CONVERGENT]] -// CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l55}}_worker() -// CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l55}}( +// CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l58}}_worker() +// CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l58}}( // CHECK-32: [[A_ADDR:%.+]] = alloca i32, // CHECK-64: [[A_ADDR:%.+]] = alloca i64, // CHECK-64: [[CONV:%.+]] = bitcast i64* [[A_ADDR]] to i32* -// CHECK: [[IS_SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]], -// CHECK: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE]], -// CHECK: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[IS_SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**)) -// CHECK: [[KERNEL_RD:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]], -// CHECK: [[STACK:%.+]] = getelementptr inbounds i8, i8* [[KERNEL_RD]], i{{64|32}} 0 +// SEQ: [[IS_SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]], +// SEQ: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE]], +// SEQ: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[IS_SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**)) +// SEQ: [[KERNEL_RD:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]], +// SEQ: [[STACK:%.+]] = getelementptr inbounds i8, i8* [[KERNEL_RD]], i{{64|32}} 0 +// PAR: [[STACK:%.+]] = call i8* @__kmpc_data_sharing_push_stack(i{{32|64}} 4, i16 1) // CHECK: [[BC:%.+]] = bitcast i8* [[STACK]] to %struct._globalized_locals_ty* // CHECK-32: [[A:%.+]] = load i32, i32* [[A_ADDR]], // CHECK-64: [[A:%.+]] = load i32, i32* [[CONV]], // CHECK: [[GLOBAL_A_ADDR:%.+]] = getelementptr inbounds %struct._globalized_locals_ty, %struct._globalized_locals_ty* [[BC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // CHECK: store i32 [[A]], i32* [[GLOBAL_A_ADDR]], -// CHECK: [[IS_SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]], -// CHECK: call void @__kmpc_restore_team_static_memory(i16 0, i16 [[IS_SHARED]]) +// SEQ: [[IS_SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]], +// SEQ: call void @__kmpc_restore_team_static_memory(i16 0, i16 [[IS_SHARED]]) +// PAR: call void @__kmpc_data_sharing_pop_stack(i8* [[STACK]]) // CHECK-LABEL: define internal void @{{.+}}(i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* nonnull align {{[0-9]+}} dereferenceable{{.*}}) // CHECK: [[CC:%.+]] = alloca i32, diff --git a/clang/test/OpenMP/nvptx_parallel_for_codegen.cpp b/clang/test/OpenMP/nvptx_parallel_for_codegen.cpp index 94b4959853d8e..4ef167de3b8a8 100644 --- a/clang/test/OpenMP/nvptx_parallel_for_codegen.cpp +++ b/clang/test/OpenMP/nvptx_parallel_for_codegen.cpp @@ -1,6 +1,7 @@ // Test target codegen - host bc file has to be created first. // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -disable-llvm-optzns | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -disable-llvm-optzns | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix SEQ +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -disable-llvm-optzns -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix PAR // expected-no-diagnostics #ifndef HEADER #define HEADER @@ -30,33 +31,35 @@ int bar(int n){ return a; } -// CHECK: [[MEM_TY:%.+]] = type { [128 x i8] } -// CHECK-DAG: [[SHARED_GLOBAL_RD:@.+]] = common addrspace(3) global [[MEM_TY]] zeroinitializer -// CHECK-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null -// CHECK-DAG: [[KERNEL_SIZE:@.+]] = internal unnamed_addr constant i{{64|32}} 4 -// CHECK-DAG: [[KERNEL_SHARED:@.+]] = internal unnamed_addr constant i16 1 +// SEQ: [[MEM_TY:%.+]] = type { [128 x i8] } +// SEQ-DAG: [[SHARED_GLOBAL_RD:@.+]] = common addrspace(3) global [[MEM_TY]] zeroinitializer +// SEQ-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null +// SEQ-DAG: [[KERNEL_SIZE:@.+]] = internal unnamed_addr constant i{{64|32}} 4 +// SEQ-DAG: [[KERNEL_SHARED:@.+]] = internal unnamed_addr constant i16 1 -// CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l12}}_worker() +// CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l13}}_worker() // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0) // CHECK: call i1 @__kmpc_kernel_parallel( // CHECK: call void @__omp_outlined___wrapper( -// CHECK: define weak void @__omp_offloading_{{.*}}l12( -// CHECK: call void @__omp_offloading_{{.*}}l12_worker() +// CHECK: define weak void @__omp_offloading_{{.*}}l13( +// CHECK: call void @__omp_offloading_{{.*}}l13_worker() // CHECK: call void @__kmpc_kernel_init( // CHECK: call void @__kmpc_data_sharing_init_stack() -// CHECK: [[IS_SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]], -// CHECK: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE]], -// CHECK: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i64 %7, i16 %6, i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**)) -// CHECK: [[KERNEL_RD:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]], -// CHECK: [[STACK:%.+]] = getelementptr inbounds i8, i8* [[KERNEL_RD]], i{{64|32}} 0 +// SEQ: [[IS_SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]], +// SEQ: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE]], +// SEQ: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i64 %7, i16 %6, i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**)) +// SEQ: [[KERNEL_RD:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]], +// SEQ: [[STACK:%.+]] = getelementptr inbounds i8, i8* [[KERNEL_RD]], i{{64|32}} 0 +// PAR: [[STACK:%.+]] = call i8* @__kmpc_data_sharing_push_stack(i{{32|64}} 4, i16 1) // CHECK: call void @__kmpc_kernel_prepare_parallel( // CHECK: call void @__kmpc_begin_sharing_variables({{.*}}, i64 2) // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0) // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0) // CHECK: call void @__kmpc_end_sharing_variables() -// CHECK: [[IS_SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]], -// CHECK: call void @__kmpc_restore_team_static_memory(i16 0, i16 [[IS_SHARED]]) +// SEQ: [[IS_SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]], +// SEQ: call void @__kmpc_restore_team_static_memory(i16 0, i16 [[IS_SHARED]]) +// PAR: call void @__kmpc_data_sharing_pop_stack(i8* [[STACK]]) // CHECK: call void @__kmpc_kernel_deinit(i16 1) // CHECK: define internal void @__omp_outlined__( diff --git a/clang/test/OpenMP/nvptx_target_codegen.cpp b/clang/test/OpenMP/nvptx_target_codegen.cpp index 91f31185d8c1a..56f04cb01f0aa 100644 --- a/clang/test/OpenMP/nvptx_target_codegen.cpp +++ b/clang/test/OpenMP/nvptx_target_codegen.cpp @@ -612,7 +612,7 @@ int baz(int f, double &a) { // CHECK: call void @__kmpc_end_serialized_parallel(%struct.ident_t* [[UNKNOWN]], i32 [[GTID]]) // CHECK: br label -// CHECK: call void @__kmpc_kernel_prepare_parallel(i8* bitcast (void (i16, i32)* @{{.+}} to i8*), i16 1) +// CHECK: call void @__kmpc_kernel_prepare_parallel(i8* bitcast (void (i16, i32)* @{{.+}} to i8*)) // CHECK: call void @__kmpc_begin_sharing_variables(i8*** [[SHARED_PTR:%.+]], i{{64|32}} 2) // CHECK: [[SHARED:%.+]] = load i8**, i8*** [[SHARED_PTR]], // CHECK: [[REF:%.+]] = getelementptr inbounds i8*, i8** [[SHARED]], i{{64|32}} 0 diff --git a/clang/test/OpenMP/nvptx_target_simd_codegen.cpp b/clang/test/OpenMP/nvptx_target_simd_codegen.cpp index 073d6fa2f14e3..7a1f01c1f1ad4 100644 --- a/clang/test/OpenMP/nvptx_target_simd_codegen.cpp +++ b/clang/test/OpenMP/nvptx_target_simd_codegen.cpp @@ -78,7 +78,6 @@ int bar(int n){ // CHECK: call void @__kmpc_spmd_kernel_init(i32 %{{.+}}, i16 0, i16 0) // CHECK-NOT: call void @__kmpc_for_static_init // CHECK-NOT: call void @__kmpc_for_static_fini -// CHECK-NOT: call i32 @__kmpc_nvptx_simd_reduce_nowait( // CHECK-NOT: call void @__kmpc_nvptx_end_reduce_nowait( // CHECK: call void @__kmpc_spmd_kernel_deinit_v2(i16 0) // CHECK: ret void diff --git a/clang/test/OpenMP/nvptx_target_teams_codegen.cpp b/clang/test/OpenMP/nvptx_target_teams_codegen.cpp index 3ab955fa85080..8ff393f074e4a 100644 --- a/clang/test/OpenMP/nvptx_target_teams_codegen.cpp +++ b/clang/test/OpenMP/nvptx_target_teams_codegen.cpp @@ -68,7 +68,7 @@ int bar(int n){ // // CHECK: [[AWAIT_WORK]] // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0) - // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]], i16 1) + // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]]) // CHECK: [[KPRB:%.+]] = zext i1 [[KPR]] to i8 // store i8 [[KPRB]], i8* [[OMP_EXEC_STATUS]], align 1 // CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]], @@ -154,7 +154,7 @@ int bar(int n){ // // CHECK: [[AWAIT_WORK]] // CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0) - // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]], i16 1) + // CHECK: [[KPR:%.+]] = call i1 @__kmpc_kernel_parallel(i8** [[OMP_WORK_FN]]) // CHECK: [[KPRB:%.+]] = zext i1 [[KPR]] to i8 // store i8 [[KPRB]], i8* [[OMP_EXEC_STATUS]], align 1 // CHECK: [[WORK:%.+]] = load i8*, i8** [[OMP_WORK_FN]], diff --git a/clang/test/OpenMP/nvptx_target_teams_distribute_codegen.cpp b/clang/test/OpenMP/nvptx_target_teams_distribute_codegen.cpp index abd9f4ae715f2..4f23f18730cc2 100644 --- a/clang/test/OpenMP/nvptx_target_teams_distribute_codegen.cpp +++ b/clang/test/OpenMP/nvptx_target_teams_distribute_codegen.cpp @@ -1,17 +1,20 @@ // Test target codegen - host bc file has to be created first. // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix SEQ +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix PAR // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 -// RUN: %clang_cc1 -verify -fopenmp -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix SEQ +// RUN: %clang_cc1 -verify -fopenmp -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix SEQ +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix PAR +// RUN: %clang_cc1 -verify -fopenmp -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix PAR // expected-no-diagnostics #ifndef HEADER #define HEADER -// CHECK: [[MEM_TY:%.+]] = type { [128 x i8] } -// CHECK-DAG: {{@__omp_offloading_.+}}_l20_exec_mode = weak constant i8 1 -// CHECK-DAG: [[KERNEL_SIZE:@.+]] = internal unnamed_addr constant i{{64|32}} 4 -// CHECK-DAG: [[KERNEL_SHARED:@.+]] = internal unnamed_addr constant i16 1 +// SEQ: [[MEM_TY:%.+]] = type { [128 x i8] } +// SEQ-DAG: {{@__omp_offloading_.+}}_l23_exec_mode = weak constant i8 1 +// SEQ-DAG: [[KERNEL_SIZE:@.+]] = internal unnamed_addr constant i{{64|32}} 4 +// SEQ-DAG: [[KERNEL_SHARED:@.+]] = internal unnamed_addr constant i16 1 template tx ftemplate(int n) { @@ -35,10 +38,10 @@ int bar(int n){ return a; } - // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l20}}_worker() + // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l23}}_worker() // CHECK: ret void - // CHECK: define {{.*}}void {{@__omp_offloading_.+template.+l20}}() + // CHECK: define {{.*}}void {{@__omp_offloading_.+template.+l23}}() // CHECK-DAG: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x() // CHECK-DAG: [[NTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x() @@ -48,7 +51,7 @@ int bar(int n){ // CHECK: br i1 [[IS_WORKER]], label {{%?}}[[WORKER:.+]], label {{%?}}[[CHECK_MASTER:.+]] // // CHECK: [[WORKER]] - // CHECK: {{call|invoke}} void {{@__omp_offloading_.+template.+l20}}_worker() + // CHECK: {{call|invoke}} void {{@__omp_offloading_.+template.+l23}}_worker() // CHECK: br label {{%?}}[[EXIT:.+]] // // CHECK: [[CHECK_MASTER]] @@ -75,16 +78,17 @@ int bar(int n){ // CHECK: ret void // CHECK: define internal void [[PARALLEL]](i32* noalias %{{.+}}, i32* noalias %{{.+}}) - // CHECK: [[SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]], - // CHECK: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE]], - // CHECK: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* @{{.+}}, i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[SHARED]], i8** addrspacecast (i8* addrspace(3)* [[BUF:@.+]] to i8**)) - // CHECK: [[PTR:%.+]] = load i8*, i8* addrspace(3)* [[BUF]], - // CHECK: [[ADDR:%.+]] = getelementptr inbounds i8, i8* [[PTR]], i{{64|32}} 0 + // SEQ: [[SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]], + // SEQ: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE]], + // SEQ: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* @{{.+}}, i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[SHARED]], i8** addrspacecast (i8* addrspace(3)* [[BUF:@.+]] to i8**)) + // SEQ: [[PTR:%.+]] = load i8*, i8* addrspace(3)* [[BUF]], + // SEQ: [[ADDR:%.+]] = getelementptr inbounds i8, i8* [[PTR]], i{{64|32}} 0 + // PAR: [[ADDR:%.+]] = call i8* @__kmpc_data_sharing_push_stack(i{{32|64}} 4, i16 1) // CHECK: [[RD:%.+]] = bitcast i8* [[ADDR]] to [[GLOB_TY:%.+]]* // CHECK: [[I_ADDR:%.+]] = getelementptr inbounds [[GLOB_TY]], [[GLOB_TY]]* [[RD]], i32 0, i32 0 // // CHECK: call void @__kmpc_for_static_init_4( - // CHECK: call void @__kmpc_kernel_prepare_parallel(i8* bitcast (void (i16, i32)* @{{.+}} to i8*), i16 1) + // CHECK: call void @__kmpc_kernel_prepare_parallel(i8* bitcast (void (i16, i32)* @{{.+}} to i8*)) // CHECK: call void @__kmpc_begin_sharing_variables(i8*** [[SHARED_VARS_PTR:%.+]], i{{64|32}} 1) // CHECK: [[SHARED_VARS_BUF:%.+]] = load i8**, i8*** [[SHARED_VARS_PTR]], // CHECK: [[VARS_BUF:%.+]] = getelementptr inbounds i8*, i8** [[SHARED_VARS_BUF]], i{{64|32}} 0 diff --git a/clang/test/OpenMP/nvptx_target_teams_distribute_parallel_for_codegen.cpp b/clang/test/OpenMP/nvptx_target_teams_distribute_parallel_for_codegen.cpp index a7e81ba1b7405..c90a3d2248e84 100644 --- a/clang/test/OpenMP/nvptx_target_teams_distribute_parallel_for_codegen.cpp +++ b/clang/test/OpenMP/nvptx_target_teams_distribute_parallel_for_codegen.cpp @@ -1,21 +1,25 @@ // Test target codegen - host bc file has to be created first. // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix CHECK-DIV64 -// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -fopenmp-optimistic-collapse -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-DIV32 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix CHECK-DIV64 --check-prefix SEQ +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix CHECK-DIV64 --check-prefix PAR +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -fopenmp-optimistic-collapse -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-DIV32 --check-prefix SEQ +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -fopenmp-optimistic-collapse -o - -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CHECK --check-prefix CHECK-DIV32 --check-prefix PAR // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc -// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 -// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix SEQ +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix SEQ +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix PAR +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix PAR // expected-no-diagnostics #ifndef HEADER #define HEADER // Check that the execution mode of all 5 target regions on the gpu is set to SPMD Mode. -// CHECK-DAG: {{@__omp_offloading_.+l34}}_exec_mode = weak constant i8 0 -// CHECK-DAG: {{@__omp_offloading_.+l40}}_exec_mode = weak constant i8 0 -// CHECK-DAG: {{@__omp_offloading_.+l45}}_exec_mode = weak constant i8 0 -// CHECK-DAG: {{@__omp_offloading_.+l50}}_exec_mode = weak constant i8 0 -// CHECK-DAG: {{@__omp_offloading_.+l58}}_exec_mode = weak constant i8 0 -// CHECK-DAG: {{@__omp_offloading_.+l65}}_exec_mode = weak constant i8 0 +// CHECK-DAG: {{@__omp_offloading_.+l38}}_exec_mode = weak constant i8 0 +// CHECK-DAG: {{@__omp_offloading_.+l44}}_exec_mode = weak constant i8 0 +// CHECK-DAG: {{@__omp_offloading_.+l49}}_exec_mode = weak constant i8 0 +// CHECK-DAG: {{@__omp_offloading_.+l54}}_exec_mode = weak constant i8 0 +// CHECK-DAG: {{@__omp_offloading_.+l62}}_exec_mode = weak constant i8 0 +// CHECK-DAG: {{@__omp_offloading_.+l69}}_exec_mode = weak constant i8 0 #define N 1000 #define M 10 @@ -76,31 +80,33 @@ int bar(int n){ return a; } -// CHECK-DAG: [[MEM_TY:%.+]] = type { [128 x i8] } -// CHECK-DAG: [[SHARED_GLOBAL_RD:@.+]] = common addrspace(3) global [[MEM_TY]] zeroinitializer -// CHECK-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null -// CHECK-DAG: [[KERNEL_SIZE:@.+]] = internal unnamed_addr constant i{{64|32}} 4 -// CHECK-DAG: [[KERNEL_SHARED:@.+]] = internal unnamed_addr constant i16 1 +// SEQ-DAG: [[MEM_TY:%.+]] = type { [128 x i8] } +// SEQ-DAG: [[SHARED_GLOBAL_RD:@.+]] = common addrspace(3) global [[MEM_TY]] zeroinitializer +// SEQ-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null +// SEQ-DAG: [[KERNEL_SIZE:@.+]] = internal unnamed_addr constant i{{64|32}} 4 +// SEQ-DAG: [[KERNEL_SHARED:@.+]] = internal unnamed_addr constant i16 1 -// CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+}}_l34( +// CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+}}_l38( // CHECK-DAG: [[THREAD_LIMIT:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x() // CHECK: call void @__kmpc_spmd_kernel_init(i32 [[THREAD_LIMIT]], i16 0, i16 0) // CHECK: call void [[PARALLEL:@.+]]( // CHECK: call void @__kmpc_spmd_kernel_deinit_v2(i16 0) // CHECK: define internal void [[PARALLEL]]( -// CHECK: [[SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]], -// CHECK: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE]], -// CHECK: call void @__kmpc_get_team_static_memory(i16 1, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**)) -// CHECK: [[TEAM_ALLOC:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]], -// CHECK: [[ADDR:%.+]] = getelementptr inbounds i8, i8* [[TEAM_ALLOC]], i{{64|32}} 0 +// SEQ: [[SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]], +// SEQ: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE]], +// SEQ: call void @__kmpc_get_team_static_memory(i16 1, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**)) +// SEQ: [[TEAM_ALLOC:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]], +// SEQ: [[ADDR:%.+]] = getelementptr inbounds i8, i8* [[TEAM_ALLOC]], i{{64|32}} 0 +// PAR: [[ADDR:%.+]] = call i8* @__kmpc_data_sharing_push_stack(i{{32|64}} 4, i16 1) // CHECK: [[BC:%.+]] = bitcast i8* [[ADDR]] to [[REC:%.+]]* // CHECK: getelementptr inbounds [[REC]], [[REC]]* [[BC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, {{.+}} 91, // CHECK: {{call|invoke}} void [[OUTL1:@.+]]( // CHECK: call void @__kmpc_for_static_fini( -// CHECK: [[SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]], -// CHECK: call void @__kmpc_restore_team_static_memory(i16 1, i16 [[SHARED]]) +// SEQ: [[SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]], +// SEQ: call void @__kmpc_restore_team_static_memory(i16 1, i16 [[SHARED]]) +// PAR: call void @__kmpc_data_sharing_pop_stack(i8* [[ADDR]]) // CHECK: ret void // CHECK: define internal void [[OUTL1]]( @@ -233,13 +239,13 @@ int bar(int n){ // CHECK: call void @__kmpc_for_static_fini( // CHECK: ret void -// CHECK: define weak void @__omp_offloading_{{.*}}_l58(i[[SZ:64|32]] %{{[^,]+}}, [10 x [10 x i32]]* nonnull align {{[0-9]+}} dereferenceable{{.*}}) +// CHECK: define weak void @__omp_offloading_{{.*}}_l62(i[[SZ:64|32]] %{{[^,]+}}, [10 x [10 x i32]]* nonnull align {{[0-9]+}} dereferenceable{{.*}}) // CHECK: call void [[OUTLINED:@__omp_outlined.*]](i32* %{{.+}}, i32* %{{.+}}, i[[SZ]] %{{.*}}, i[[SZ]] %{{.*}}, i[[SZ]] %{{.*}}, [10 x [10 x i32]]* %{{.*}}) // CHECK: define internal void [[OUTLINED]](i32* noalias %{{.*}}, i32* noalias %{{.*}} i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, [10 x [10 x i32]]* nonnull align {{[0-9]+}} dereferenceable{{.*}}) // CHECK-DIV64: div i64 // CHECK-DIV32-NO: div i64 -// CHECK: define weak void @__omp_offloading_{{.*}}_l65(i[[SZ:64|32]] %{{[^,]+}}, [1000 x i32]* nonnull align {{[0-9]+}} dereferenceable{{.*}}, i32* %{{[^)]+}}) +// CHECK: define weak void @__omp_offloading_{{.*}}_l69(i[[SZ:64|32]] %{{[^,]+}}, [1000 x i32]* nonnull align {{[0-9]+}} dereferenceable{{.*}}, i32* %{{[^)]+}}) // CHECK: call void [[OUTLINED:@__omp_outlined.*]](i32* %{{.+}}, i32* %{{.+}}, i[[SZ]] %{{.*}}, i[[SZ]] %{{.*}}, i[[SZ]] %{{.*}}, [1000 x i32]* %{{.*}}, i32* %{{.*}}) // CHECK: define internal void [[OUTLINED]](i32* noalias %{{.*}}, i32* noalias %{{.*}} i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, [1000 x i32]* nonnull align {{[0-9]+}} dereferenceable{{.*}}, i32* %{{.*}}) diff --git a/clang/test/OpenMP/nvptx_target_teams_distribute_parallel_for_simd_codegen.cpp b/clang/test/OpenMP/nvptx_target_teams_distribute_parallel_for_simd_codegen.cpp index 2d43ffed70163..50ce394461066 100644 --- a/clang/test/OpenMP/nvptx_target_teams_distribute_parallel_for_simd_codegen.cpp +++ b/clang/test/OpenMP/nvptx_target_teams_distribute_parallel_for_simd_codegen.cpp @@ -1,18 +1,21 @@ // Test target codegen - host bc file has to be created first. // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix SEQ +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix PAR // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc -// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 -// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix SEQ +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix SEQ +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix PAR +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix PAR // expected-no-diagnostics #ifndef HEADER #define HEADER // Check that the execution mode of all 4 target regions on the gpu is set to SPMD Mode. -// CHECK-DAG: {{@__omp_offloading_.+l30}}_exec_mode = weak constant i8 0 -// CHECK-DAG: {{@__omp_offloading_.+l36}}_exec_mode = weak constant i8 0 -// CHECK-DAG: {{@__omp_offloading_.+l41}}_exec_mode = weak constant i8 0 -// CHECK-DAG: {{@__omp_offloading_.+l46}}_exec_mode = weak constant i8 0 +// CHECK-DAG: {{@__omp_offloading_.+l33}}_exec_mode = weak constant i8 0 +// CHECK-DAG: {{@__omp_offloading_.+l39}}_exec_mode = weak constant i8 0 +// CHECK-DAG: {{@__omp_offloading_.+l44}}_exec_mode = weak constant i8 0 +// CHECK-DAG: {{@__omp_offloading_.+l49}}_exec_mode = weak constant i8 0 #define N 1000 #define M 10 @@ -62,29 +65,31 @@ int bar(int n){ return a; } -// CHECK-DAG: [[MEM_TY:%.+]] = type { [128 x i8] } -// CHECK-DAG: [[SHARED_GLOBAL_RD:@.+]] = common addrspace(3) global [[MEM_TY]] zeroinitializer -// CHECK-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null -// CHECK-DAG: [[KERNEL_SIZE:@.+]] = internal unnamed_addr constant i{{64|32}} 4 -// CHECK-DAG: [[KERNEL_SHARED:@.+]] = internal unnamed_addr constant i16 1 +// SEQ-DAG: [[MEM_TY:%.+]] = type { [128 x i8] } +// SEQ-DAG: [[SHARED_GLOBAL_RD:@.+]] = common addrspace(3) global [[MEM_TY]] zeroinitializer +// SEQ-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null +// SEQ-DAG: [[KERNEL_SIZE:@.+]] = internal unnamed_addr constant i{{64|32}} 4 +// SEQ-DAG: [[KERNEL_SHARED:@.+]] = internal unnamed_addr constant i16 1 -// CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+}}_l30( +// CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+}}_l33( // CHECK-DAG: [[THREAD_LIMIT:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x() // CHECK: call void @__kmpc_spmd_kernel_init(i32 [[THREAD_LIMIT]], i16 0, i16 0) // CHECK: call void @__kmpc_spmd_kernel_deinit_v2(i16 0) -// CHECK: [[SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]], -// CHECK: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE]], -// CHECK: call void @__kmpc_get_team_static_memory(i16 1, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**)) -// CHECK: [[TEAM_ALLOC:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]], -// CHECK: [[PTR:%.+]] = getelementptr inbounds i8, i8* [[TEAM_ALLOC]], i{{64|32}} 0 +// SEQ: [[SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]], +// SEQ: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE]], +// SEQ: call void @__kmpc_get_team_static_memory(i16 1, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**)) +// SEQ: [[TEAM_ALLOC:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]], +// SEQ: [[PTR:%.+]] = getelementptr inbounds i8, i8* [[TEAM_ALLOC]], i{{64|32}} 0 +// PAR: [[PTR:%.+]] = call i8* @__kmpc_data_sharing_push_stack(i{{32|64}} 4, i16 1) // CHECK: [[BC:%.+]] = bitcast i8* [[PTR]] to [[REC:%.+]]* // CHECK: getelementptr inbounds [[REC]], [[REC]]* [[BC]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, {{.+}} 91, // CHECK: {{call|invoke}} void [[OUTL1:@.+]]( // CHECK: call void @__kmpc_for_static_fini( -// CHECK: [[SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]], -// CHECK: call void @__kmpc_restore_team_static_memory(i16 1, i16 [[SHARED]]) +// SEQ: [[SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED]], +// SEQ: call void @__kmpc_restore_team_static_memory(i16 1, i16 [[SHARED]]) +// PAR: call void @__kmpc_data_sharing_pop_stack(i8* [[PTR]]) // CHECK: ret void // CHECK: define internal void [[OUTL1]]( diff --git a/clang/test/OpenMP/nvptx_teams_codegen.cpp b/clang/test/OpenMP/nvptx_teams_codegen.cpp index a796ccc3e9677..36bb972175a54 100644 --- a/clang/test/OpenMP/nvptx_teams_codegen.cpp +++ b/clang/test/OpenMP/nvptx_teams_codegen.cpp @@ -1,8 +1,10 @@ // Test target codegen - host bc file has to be created first. // RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 --check-prefix SEQ +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 --check-prefix PAR // RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc -// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 --check-prefix SEQ +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 --check-prefix PAR // expected-no-diagnostics #ifndef HEADER #define HEADER @@ -27,13 +29,13 @@ int main (int argc, char **argv) { return tmain(argv); } -// CK1: [[MEM_TY:%.+]] = type { [128 x i8] } -// CK1-DAG: [[SHARED_GLOBAL_RD:@.+]] = common addrspace(3) global [[MEM_TY]] zeroinitializer -// CK1-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null -// CK1-DAG: [[KERNEL_SIZE1:@.+]] = internal unnamed_addr constant i{{64|32}} 4 -// CK1-DAG: [[KERNEL_SIZE2:@.+]] = internal unnamed_addr constant i{{64|32}} {{8|4}} -// CK1-DAG: [[KERNEL_SHARED1:@.+]] = internal unnamed_addr constant i16 1 -// CK1-DAG: [[KERNEL_SHARED2:@.+]] = internal unnamed_addr constant i16 1 +// SEQ: [[MEM_TY:%.+]] = type { [128 x i8] } +// SEQ-DAG: [[SHARED_GLOBAL_RD:@.+]] = common addrspace(3) global [[MEM_TY]] zeroinitializer +// SEQ-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null +// SEQ-DAG: [[KERNEL_SIZE1:@.+]] = internal unnamed_addr constant i{{64|32}} 4 +// SEQ-DAG: [[KERNEL_SIZE2:@.+]] = internal unnamed_addr constant i{{64|32}} {{8|4}} +// SEQ-DAG: [[KERNEL_SHARED1:@.+]] = internal unnamed_addr constant i16 1 +// SEQ-DAG: [[KERNEL_SHARED2:@.+]] = internal unnamed_addr constant i16 1 // only nvptx side: do not outline teams region and do not call fork_teams // CK1: define {{.*}}void @{{[^,]+}}(i{{[0-9]+}} [[ARGC:%.+]]) @@ -41,11 +43,12 @@ int main (int argc, char **argv) { // CK1: store {{.+}} 0, {{.+}}, // CK1: store i{{[0-9]+}} [[ARGC]], i{{[0-9]+}}* [[ARGCADDR]], // CK1-64: [[CONV:%.+]] = bitcast i{{[0-9]+}}* [[ARGCADDR]] to i{{[0-9]+}}* -// CK1: [[IS_SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED1]], -// CK1: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE1]], -// CK1: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[IS_SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**)) -// CK1: [[KERNEL_RD:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]], -// CK1: [[GLOBALSTACK:%.+]] = getelementptr inbounds i8, i8* [[KERNEL_RD]], i{{64|32}} 0 +// SEQ: [[IS_SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED1]], +// SEQ: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE1]], +// SEQ: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[IS_SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**)) +// SEQ: [[KERNEL_RD:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]], +// SEQ: [[GLOBALSTACK:%.+]] = getelementptr inbounds i8, i8* [[KERNEL_RD]], i{{64|32}} 0 +// PAR: [[GLOBALSTACK:%.+]] = call i8* @__kmpc_data_sharing_push_stack(i{{32|64}} 4, i16 1) // CK1-64: [[ARG:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[CONV]] // CK1-32: [[ARG:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[ARGCADDR]] // CK1: [[ARGCADDR:%.+]] = getelementptr inbounds %struct.{{.*}}, %struct.{{.*}}* %{{.*}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 @@ -62,11 +65,12 @@ int main (int argc, char **argv) { // CK1: define {{.*}}void @{{[^,]+}}(i{{.+}}** [[ARGC:%.+]]) // CK1: [[ARGCADDR:%.+]] = alloca i{{.+}}**, // CK1: store i{{.+}}** [[ARGC]], i{{.+}}*** [[ARGCADDR]] -// CK1: [[IS_SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED2]], -// CK1: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE2]], -// CK1: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[IS_SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**)) -// CK1: [[KERNEL_RD:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]], -// CK1: [[GLOBALSTACK:%.+]] = getelementptr inbounds i8, i8* [[KERNEL_RD]], i{{64|32}} 0 +// SEQ: [[IS_SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED2]], +// SEQ: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE2]], +// SEQ: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[IS_SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**)) +// SEQ: [[KERNEL_RD:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]], +// SEQ: [[GLOBALSTACK:%.+]] = getelementptr inbounds i8, i8* [[KERNEL_RD]], i{{64|32}} 0 +// PAR: [[GLOBALSTACK:%.+]] = call i8* @__kmpc_data_sharing_push_stack(i{{32|64}} {{4|8}}, i16 1) // CK1: [[ARG:%.+]] = load i{{[0-9]+}}**, i{{[0-9]+}}*** [[ARGCADDR]] // CK1: [[ARGCADDR:%.+]] = getelementptr inbounds %struct.{{.*}}, %struct.{{.*}}* %{{.*}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 // CK1: store i{{[0-9]+}}** [[ARG]], i{{[0-9]+}}*** [[ARGCADDR]], @@ -83,9 +87,11 @@ int main (int argc, char **argv) { // Test target codegen - host bc file has to be created first. // RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 --check-prefix SEQ2 +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 --check-prefix PAR2 // RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc -// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 --check-prefix SEQ2 +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 --check-prefix PAR2 // expected-no-diagnostics #ifdef CK2 @@ -112,13 +118,13 @@ int main (int argc, char **argv) { return tmain(argv); } -// CK2: [[MEM_TY:%.+]] = type { [128 x i8] } -// CK2-DAG: [[SHARED_GLOBAL_RD:@.+]] = common addrspace(3) global [[MEM_TY]] zeroinitializer -// CK2-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null -// CK2-DAG: [[KERNEL_SIZE1:@.+]] = internal unnamed_addr constant i{{64|32}} 4 -// CK2-DAG: [[KERNEL_SIZE2:@.+]] = internal unnamed_addr constant i{{64|32}} {{8|4}} -// CK2-DAG: [[KERNEL_SHARED1:@.+]] = internal unnamed_addr constant i16 1 -// CK2-DAG: [[KERNEL_SHARED2:@.+]] = internal unnamed_addr constant i16 1 +// SEQ2: [[MEM_TY:%.+]] = type { [128 x i8] } +// SEQ2-DAG: [[SHARED_GLOBAL_RD:@.+]] = common addrspace(3) global [[MEM_TY]] zeroinitializer +// SEQ2-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null +// SEQ2-DAG: [[KERNEL_SIZE1:@.+]] = internal unnamed_addr constant i{{64|32}} 4 +// SEQ2-DAG: [[KERNEL_SIZE2:@.+]] = internal unnamed_addr constant i{{64|32}} {{8|4}} +// SEQ2-DAG: [[KERNEL_SHARED1:@.+]] = internal unnamed_addr constant i16 1 +// SEQ2-DAG: [[KERNEL_SHARED2:@.+]] = internal unnamed_addr constant i16 1 // CK2: define {{.*}}void @{{[^,]+}}(i{{[0-9]+}} [[A_IN:%.+]], i{{[0-9]+}} [[B_IN:%.+]], i{{[0-9]+}} [[ARGC_IN:.+]]) // CK2: [[AADDR:%.+]] = alloca i{{[0-9]+}}, @@ -130,11 +136,12 @@ int main (int argc, char **argv) { // CK2-64: [[ACONV:%.+]] = bitcast i64* [[AADDR]] to i32* // CK2-64: [[BCONV:%.+]] = bitcast i64* [[BADDR]] to i32* // CK2-64: [[CONV:%.+]] = bitcast i64* [[ARGCADDR]] to i32* -// CK2: [[IS_SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED1]], -// CK2: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE1]], -// CK2: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[IS_SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**)) -// CK2: [[KERNEL_RD:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]], -// CK2: [[GLOBALSTACK:%.+]] = getelementptr inbounds i8, i8* [[KERNEL_RD]], i{{64|32}} 0 +// SEQ2: [[IS_SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED1]], +// SEQ2: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE1]], +// SEQ2: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[IS_SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**)) +// SEQ2: [[KERNEL_RD:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]], +// SEQ2: [[GLOBALSTACK:%.+]] = getelementptr inbounds i8, i8* [[KERNEL_RD]], i{{64|32}} 0 +// PAR2: [[GLOBALSTACK:%.+]] = call i8* @__kmpc_data_sharing_push_stack(i{{32|64}} 4, i16 1) // CK2-64: [[ARG:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[CONV]] // CK2-32: [[ARG:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[ARGCADDR]] // CK2: [[ARGCADDR:%.+]] = getelementptr inbounds %struct.{{.*}}, %struct.{{.*}}* %{{.*}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 @@ -155,11 +162,12 @@ int main (int argc, char **argv) { // CK2: store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[AADDR]], // CK2: store i{{[0-9]+}} [[B_IN]], i{{[0-9]+}}* [[BADDR]], // CK2: store i{{[0-9]+}}** [[ARGC]], i{{[0-9]+}}*** [[ARGCADDR]], -// CK2: [[IS_SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED2]], -// CK2: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE2]], -// CK2: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[IS_SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**)) -// CK2: [[KERNEL_RD:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]], -// CK2: [[GLOBALSTACK:%.+]] = getelementptr inbounds i8, i8* [[KERNEL_RD]], i{{64|32}} 0 +// SEQ2: [[IS_SHARED:%.+]] = load i16, i16* [[KERNEL_SHARED2]], +// SEQ2: [[SIZE:%.+]] = load i{{64|32}}, i{{64|32}}* [[KERNEL_SIZE2]], +// SEQ2: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} [[SIZE]], i16 [[IS_SHARED]], i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**)) +// SEQ2: [[KERNEL_RD:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]], +// SEQ2: [[GLOBALSTACK:%.+]] = getelementptr inbounds i8, i8* [[KERNEL_RD]], i{{64|32}} 0 +// PAR2: [[GLOBALSTACK:%.+]] = call i8* @__kmpc_data_sharing_push_stack(i{{32|64}} {{4|8}}, i16 1) // CK2: [[ARG:%.+]] = load i{{[0-9]+}}**, i{{[0-9]+}}*** [[ARGCADDR]] // CK2: [[ARGCADDR:%.+]] = getelementptr inbounds %struct.{{.*}}, %struct.{{.*}}* %{{.*}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 // CK2: store i{{[0-9]+}}** [[ARG]], i{{[0-9]+}}*** [[ARGCADDR]], diff --git a/clang/test/OpenMP/nvptx_teams_reduction_codegen.cpp b/clang/test/OpenMP/nvptx_teams_reduction_codegen.cpp index 465b0e8de6d5e..5aa3e1978b106 100644 --- a/clang/test/OpenMP/nvptx_teams_reduction_codegen.cpp +++ b/clang/test/OpenMP/nvptx_teams_reduction_codegen.cpp @@ -1,9 +1,12 @@ // Test target codegen - host bc file has to be created first. // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix SEQ +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix PAR // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 -// RUN: %clang_cc1 -verify -fopenmp -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -fopenmp-cuda-teams-reduction-recs-num=2048 -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix SEQ +// RUN: %clang_cc1 -verify -fopenmp -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -fopenmp-cuda-teams-reduction-recs-num=2048 -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix SEQ +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix PAR +// RUN: %clang_cc1 -verify -fopenmp -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -fopenmp-cuda-teams-reduction-recs-num=2048 -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - -fopenmp-cuda-parallel-target-regions | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix PAR // expected-no-diagnostics #ifndef HEADER #define HEADER @@ -12,21 +15,21 @@ // CHECK-DAG: [[TEAM2_REDUCE_TY:%.+]] = type { [{{1024|2048}} x i8], [{{1024|2048}} x float] } // CHECK-DAG: [[TEAM3_REDUCE_TY:%.+]] = type { [{{1024|2048}} x i32], [{{1024|2048}} x i16] } // CHECK-DAG: [[TEAMS_REDUCE_UNION_TY:%.+]] = type { [[TEAM1_REDUCE_TY]] } -// CHECK-DAG: [[MAP_TY:%.+]] = type { [128 x i8] } +// SEQ-DAG: [[MAP_TY:%.+]] = type { [128 x i8] } -// CHECK-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null -// CHECK-DAG: [[KERNEL_SHARED1:@.+]] = internal unnamed_addr constant i16 1 -// CHECK-DAG: [[KERNEL_SHARED2:@.+]] = internal unnamed_addr constant i16 1 -// CHECK-DAG: [[KERNEL_SIZE1:@.+]] = internal unnamed_addr constant i{{64|32}} {{16|8}} -// CHECK-DAG: [[KERNEL_SIZE2:@.+]] = internal unnamed_addr constant i{{64|32}} 16 +// SEQ-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null +// SEQ-DAG: [[KERNEL_SHARED1:@.+]] = internal unnamed_addr constant i16 1 +// SEQ-DAG: [[KERNEL_SHARED2:@.+]] = internal unnamed_addr constant i16 1 +// SEQ-DAG: [[KERNEL_SIZE1:@.+]] = internal unnamed_addr constant i{{64|32}} {{16|8}} +// SEQ-DAG: [[KERNEL_SIZE2:@.+]] = internal unnamed_addr constant i{{64|32}} 16 // Check for the data transfer medium in shared memory to transfer the reduction list to the first warp. // CHECK-DAG: [[TRANSFER_STORAGE:@.+]] = common addrspace([[SHARED_ADDRSPACE:[0-9]+]]) global [32 x i32] // Check that the execution mode of 2 target regions is set to Non-SPMD and the 3rd is in SPMD. -// CHECK-DAG: {{@__omp_offloading_.+l41}}_exec_mode = weak constant i8 1 -// CHECK-DAG: {{@__omp_offloading_.+l47}}_exec_mode = weak constant i8 1 -// CHECK-DAG: {{@__omp_offloading_.+l54}}_exec_mode = weak constant i8 0 +// CHECK-DAG: {{@__omp_offloading_.+l44}}_exec_mode = weak constant i8 1 +// CHECK-DAG: {{@__omp_offloading_.+l50}}_exec_mode = weak constant i8 1 +// CHECK-DAG: {{@__omp_offloading_.+l57}}_exec_mode = weak constant i8 0 // CHECK-DAG: [[TEAMS_RED_BUFFER:@.+]] = internal global [[TEAMS_REDUCE_UNION_TY]] zeroinitializer @@ -70,9 +73,9 @@ int bar(int n){ return a; } - // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l41}}_worker() + // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l44}}_worker() - // CHECK: define {{.*}}void [[T1:@__omp_offloading_.+template.+l41]]( + // CHECK: define {{.*}}void [[T1:@__omp_offloading_.+template.+l44]]( // // CHECK: {{call|invoke}} void [[T1]]_worker() // @@ -337,9 +340,9 @@ int bar(int n){ // CHECK: call void [[REDUCTION_FUNC]](i8* [[RL_BC]], i8* [[LOCAL_RL_BC]]) // CHECK: ret void - // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l47}}_worker() + // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l50}}_worker() - // CHECK: define {{.*}}void [[T2:@__omp_offloading_.+template.+l47]]( + // CHECK: define {{.*}}void [[T2:@__omp_offloading_.+template.+l50]]( // // CHECK: {{call|invoke}} void [[T2]]_worker() @@ -704,13 +707,13 @@ int bar(int n){ // CHECK: call void [[REDUCTION_FUNC]](i8* [[RL_BC]], i8* [[LOCAL_RL_BC]]) // CHECK: ret void - // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l54}}( + // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l57}}( // // CHECK: call void @__kmpc_spmd_kernel_init( // CHECK: call void @__kmpc_data_sharing_init_stack_spmd() // CHECK: call void @__kmpc_spmd_kernel_deinit_v2(i16 1) - // CHECK-NOT: call void @__kmpc_get_team_static_memory + // CHECK-NOT: call void @{{__kmpc_get_team_static_memory|__kmpc_data_sharing_push_stack}} // CHECK: store i32 0, // CHECK: store i32 0, // CHECK: store i32 0, i32* [[A_ADDR:%.+]], align diff --git a/clang/test/OpenMP/ordered_codegen.cpp b/clang/test/OpenMP/ordered_codegen.cpp index 7797dad0d4846..07ecee45974c5 100644 --- a/clang/test/OpenMP/ordered_codegen.cpp +++ b/clang/test/OpenMP/ordered_codegen.cpp @@ -1,7 +1,11 @@ -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefixes=CHECK,OMP50 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s // RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -fopenmp-version=45 -o - | FileCheck %s --check-prefixes=CHECK,OMP45 +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -fopenmp-version=45 -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s + // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck --check-prefix SIMD-ONLY0 %s // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s // RUN: %clang_cc1 -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s @@ -65,7 +69,8 @@ void static_not_chunked(float *a, float *b, float *c, float *d) { void dynamic1(float *a, float *b, float *c, float *d) { // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]]) #pragma omp for schedule(dynamic) ordered -// CHECK: call void @__kmpc_dispatch_init_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 67, i64 0, i64 16908287, i64 1, i64 1) +// OMP45: call void @__kmpc_dispatch_init_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 67, i64 0, i64 16908287, i64 1, i64 1) +// OMP50: call void @__kmpc_dispatch_init_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 1073741891, i64 0, i64 16908287, i64 1, i64 1) // // CHECK: [[HASWORK:%.+]] = call i32 @__kmpc_dispatch_next_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32* [[OMP_ISLAST:%[^,]+]], i64* [[OMP_LB:%[^,]+]], i64* [[OMP_UB:%[^,]+]], i64* [[OMP_ST:%[^,]+]]) // CHECK-NEXT: [[O_CMP:%.+]] = icmp ne i32 [[HASWORK]], 0 @@ -119,7 +124,8 @@ void test_auto(float *a, float *b, float *c, float *d) { unsigned int y = 0; // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]]) #pragma omp for schedule(auto) collapse(2) ordered -// CHECK: call void @__kmpc_dispatch_init_8([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 70, i64 0, i64 [[LAST_ITER:%[^,]+]], i64 1, i64 1) +// OMP45: call void @__kmpc_dispatch_init_8([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 70, i64 0, i64 [[LAST_ITER:%[^,]+]], i64 1, i64 1) +// OMP50: call void @__kmpc_dispatch_init_8([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 1073741894, i64 0, i64 [[LAST_ITER:%[^,]+]], i64 1, i64 1) // // CHECK: [[HASWORK:%.+]] = call i32 @__kmpc_dispatch_next_8([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32* [[OMP_ISLAST:%[^,]+]], i64* [[OMP_LB:%[^,]+]], i64* [[OMP_UB:%[^,]+]], i64* [[OMP_ST:%[^,]+]]) // CHECK-NEXT: [[O_CMP:%.+]] = icmp ne i32 [[HASWORK]], 0 @@ -172,7 +178,8 @@ void runtime(float *a, float *b, float *c, float *d) { int x = 0; // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]]) #pragma omp for collapse(2) schedule(runtime) ordered -// CHECK: call void @__kmpc_dispatch_init_4([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 69, i32 0, i32 199, i32 1, i32 1) +// OMP45: call void @__kmpc_dispatch_init_4([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 69, i32 0, i32 199, i32 1, i32 1) +// OMP50: call void @__kmpc_dispatch_init_4([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32 1073741893, i32 0, i32 199, i32 1, i32 1) // // CHECK: [[HASWORK:%.+]] = call i32 @__kmpc_dispatch_next_4([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32* [[OMP_ISLAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]]) // CHECK-NEXT: [[O_CMP:%.+]] = icmp ne i32 [[HASWORK]], 0 diff --git a/clang/test/OpenMP/parallel_codegen.cpp b/clang/test/OpenMP/parallel_codegen.cpp index d903fdd1542a3..6fd394c0bbc9b 100644 --- a/clang/test/OpenMP/parallel_codegen.cpp +++ b/clang/test/OpenMP/parallel_codegen.cpp @@ -3,7 +3,7 @@ // RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefixes=ALL-DEBUG,CHECK-DEBUG %s // RUN: %clang_cc1 -verify -fopenmp -fopenmp-enable-irbuilder -DIRBUILDER -x c++ -emit-llvm %s -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefixes=ALL,IRBUILDER // RUN: %clang_cc1 -fopenmp -fopenmp-enable-irbuilder -DIRBUILDER -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -fopenmp-enable-irbuilder -DIRBUILDER -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefixes=ALL-DEBUG,IRBUILDER-DEBUG %s +// RUN: %clang_cc1 -fopenmp -fopenmp-enable-irbuilder -DIRBUILDER -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -gno-column-info -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefixes=ALL-DEBUG,IRBUILDER-DEBUG %s // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -emit-llvm %s -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -o - | FileCheck --check-prefix SIMD-ONLY0 %s // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s diff --git a/clang/test/OpenMP/parallel_default_messages.cpp b/clang/test/OpenMP/parallel_default_messages.cpp index 6b8ad67051850..b098c43852a85 100644 --- a/clang/test/OpenMP/parallel_default_messages.cpp +++ b/clang/test/OpenMP/parallel_default_messages.cpp @@ -4,18 +4,25 @@ // RUN: %clang_cc1 -verify=expected,ge40 -fopenmp-version=40 -fopenmp -ferror-limit 100 -o - %s -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp-version=31 -fopenmp -ferror-limit 100 -o - %s -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp-version=30 -fopenmp -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,ge40 -fopenmp-version=51 -fopenmp -DOMP51 -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,ge40 -fopenmp-version=51 -fopenmp-simd -DOMP51 -ferror-limit 100 -o - %s -Wuninitialized void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { const int c = 0; #pragma omp parallel default // expected-error {{expected '(' after 'default'}} - #pragma omp parallel default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp parallel default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} - #pragma omp parallel default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp parallel default (shared), default(shared) // expected-error {{directive '#pragma omp parallel' cannot contain more than one 'default' clause}} - #pragma omp parallel default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp parallel default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} +#pragma omp parallel default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp parallel default(shared), default(shared) // expected-error {{directive '#pragma omp parallel' cannot contain more than one 'default' clause}} +#pragma omp parallel default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} foo(); #pragma omp parallel default(none) // expected-note {{explicit data sharing attribute requested here}} @@ -27,5 +34,14 @@ int main(int argc, char **argv) { #pragma omp parallel default(none) // ge40-note {{explicit data sharing attribute requested here}} (void)c; // ge40-error {{variable 'c' must have explicitly specified data sharing attributes}} + +#ifdef OMP51 +#pragma omp parallel default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif + return 0; } diff --git a/clang/test/OpenMP/parallel_for_codegen.cpp b/clang/test/OpenMP/parallel_for_codegen.cpp index c45f3e911fc66..de445634470bb 100644 --- a/clang/test/OpenMP/parallel_for_codegen.cpp +++ b/clang/test/OpenMP/parallel_for_codegen.cpp @@ -1,7 +1,13 @@ -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefixes=OMP50,CHECK +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefixes=OMP45,CHECK + // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefixes=OMP50,CHECK + +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefixes=OMP45,CHECK + +// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -gno-column-info -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG // RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -O1 -fopenmp -emit-llvm %s -o - | FileCheck %s --check-prefix=CLEANUP // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck --check-prefix SIMD-ONLY0 %s @@ -194,7 +200,8 @@ void dynamic1(float *a, float *b, float *c, float *d) { // CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]], i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, float**, float**, float**, float**)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), // CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* noalias [[GTID_PARAM_ADDR:%.+]], i32* noalias %{{.+}}, float** nonnull align 8 dereferenceable(8) %{{.+}}, float** nonnull align 8 dereferenceable(8) %{{.+}}, float** nonnull align 8 dereferenceable(8) %{{.+}}, float** nonnull align 8 dereferenceable(8) %{{.+}}) // CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]], -// CHECK: call void @__kmpc_dispatch_init_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID:%.+]], i32 35, i64 0, i64 16908287, i64 1, i64 1) +// OMP45: call void @__kmpc_dispatch_init_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID:%.+]], i32 35, i64 0, i64 16908287, i64 1, i64 1) +// OMP50: call void @__kmpc_dispatch_init_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID:%.+]], i32 1073741859, i64 0, i64 16908287, i64 1, i64 1) // // CHECK: [[HASWORK:%.+]] = call i32 @__kmpc_dispatch_next_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32* [[OMP_ISLAST:%[^,]+]], i64* [[OMP_LB:%[^,]+]], i64* [[OMP_UB:%[^,]+]], i64* [[OMP_ST:%[^,]+]]) // CHECK-NEXT: [[O_CMP:%.+]] = icmp ne i32 [[HASWORK]], 0 @@ -237,7 +244,8 @@ void guided7(float *a, float *b, float *c, float *d) { // CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]], i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, float**, float**, float**, float**)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), // CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* noalias [[GTID_PARAM_ADDR:%.+]], i32* noalias %{{.+}}, float** nonnull align 8 dereferenceable(8) %{{.+}}, float** nonnull align 8 dereferenceable(8) %{{.+}}, float** nonnull align 8 dereferenceable(8) %{{.+}}, float** nonnull align 8 dereferenceable(8) %{{.+}}) // CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]], -// CHECK: call void @__kmpc_dispatch_init_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID:%.+]], i32 36, i64 0, i64 16908287, i64 1, i64 7) +// OMP45: call void @__kmpc_dispatch_init_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID:%.+]], i32 36, i64 0, i64 16908287, i64 1, i64 7) +// OMP50: call void @__kmpc_dispatch_init_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID:%.+]], i32 1073741860, i64 0, i64 16908287, i64 1, i64 7) // // CHECK: [[HASWORK:%.+]] = call i32 @__kmpc_dispatch_next_8u([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32* [[OMP_ISLAST:%[^,]+]], i64* [[OMP_LB:%[^,]+]], i64* [[OMP_UB:%[^,]+]], i64* [[OMP_ST:%[^,]+]]) // CHECK-NEXT: [[O_CMP:%.+]] = icmp ne i32 [[HASWORK]], 0 @@ -282,7 +290,8 @@ void test_auto(float *a, float *b, float *c, float *d) { // CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]], i32 5, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, float**, float**, float**, float**)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), // CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* noalias [[GTID_PARAM_ADDR:%.+]], i32* noalias %{{.+}}, i32* nonnull align 4 dereferenceable(4) %{{.+}}, float** nonnull align 8 dereferenceable(8) %{{.+}}, float** nonnull align 8 dereferenceable(8) %{{.+}}, float** nonnull align 8 dereferenceable(8) %{{.+}}, float** nonnull align 8 dereferenceable(8) %{{.+}}) // CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]], -// CHECK: call void @__kmpc_dispatch_init_8([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID:%.+]], i32 38, i64 0, i64 [[LAST_ITER:%[^,]+]], i64 1, i64 1) +// OMP45: call void @__kmpc_dispatch_init_8([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID:%.+]], i32 38, i64 0, i64 [[LAST_ITER:%[^,]+]], i64 1, i64 1) +// OMP50: call void @__kmpc_dispatch_init_8([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID:%.+]], i32 1073741862, i64 0, i64 [[LAST_ITER:%[^,]+]], i64 1, i64 1) // // CHECK: [[HASWORK:%.+]] = call i32 @__kmpc_dispatch_next_8([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID:%.+]], i32* [[OMP_ISLAST:%[^,]+]], i64* [[OMP_LB:%[^,]+]], i64* [[OMP_UB:%[^,]+]], i64* [[OMP_ST:%[^,]+]]) // CHECK-NEXT: [[O_CMP:%.+]] = icmp ne i32 [[HASWORK]], 0 @@ -326,7 +335,8 @@ void runtime(float *a, float *b, float *c, float *d) { // CHECK: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* [[DEFAULT_LOC:[@%].+]], i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, float**, float**, float**, float**)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*), // CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* noalias [[GTID_PARAM_ADDR:%.+]], i32* noalias %{{.+}}, float** nonnull align 8 dereferenceable(8) %{{.+}}, float** nonnull align 8 dereferenceable(8) %{{.+}}, float** nonnull align 8 dereferenceable(8) %{{.+}}, float** nonnull align 8 dereferenceable(8) %{{.+}}) // CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]], -// CHECK: call void @__kmpc_dispatch_init_4([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID:%.+]], i32 37, i32 0, i32 199, i32 1, i32 1) +// OMP45: call void @__kmpc_dispatch_init_4([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID:%.+]], i32 37, i32 0, i32 199, i32 1, i32 1) +// OMP50: call void @__kmpc_dispatch_init_4([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID:%.+]], i32 1073741861, i32 0, i32 199, i32 1, i32 1) // // CHECK: [[HASWORK:%.+]] = call i32 @__kmpc_dispatch_next_4([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], i32* [[OMP_ISLAST:%[^,]+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]]) // CHECK-NEXT: [[O_CMP:%.+]] = icmp ne i32 [[HASWORK]], 0 diff --git a/clang/test/OpenMP/parallel_for_default_messages.cpp b/clang/test/OpenMP/parallel_for_default_messages.cpp index b02fa8803a3b3..c64b76948c018 100644 --- a/clang/test/OpenMP/parallel_for_default_messages.cpp +++ b/clang/test/OpenMP/parallel_for_default_messages.cpp @@ -2,17 +2,26 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -DOMP51 -ferror-limit 100 -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=51 -DOMP51 -ferror-limit 100 -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { int i; #pragma omp parallel for default // expected-error {{expected '(' after 'default'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp parallel for default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel for default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{explicit data sharing attribute requested here}} @@ -21,7 +30,7 @@ int main(int argc, char **argv) { #pragma omp parallel for default(shared), default(shared) // expected-error {{directive '#pragma omp parallel for' cannot contain more than one 'default' clause}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel for default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); @@ -34,5 +43,13 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} foo(); +#ifdef OMP51 +#pragma omp parallel for default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + for (i = 0; i < argc; ++i) { + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + } +#endif + return 0; } diff --git a/clang/test/OpenMP/parallel_for_loop_messages.cpp b/clang/test/OpenMP/parallel_for_loop_messages.cpp index beaf56e7bcb6d..cbcc18419dcc1 100644 --- a/clang/test/OpenMP/parallel_for_loop_messages.cpp +++ b/clang/test/OpenMP/parallel_for_loop_messages.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized class S { diff --git a/clang/test/OpenMP/parallel_for_simd_codegen.cpp b/clang/test/OpenMP/parallel_for_simd_codegen.cpp index 01f2b4c42a243..e9cc2f302eafc 100644 --- a/clang/test/OpenMP/parallel_for_simd_codegen.cpp +++ b/clang/test/OpenMP/parallel_for_simd_codegen.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefix=OMP45 --check-prefix=CHECK +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefix=OMP45 --check-prefix=CHECK // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s // RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG diff --git a/clang/test/OpenMP/parallel_for_simd_default_messages.cpp b/clang/test/OpenMP/parallel_for_simd_default_messages.cpp index 570ee14bbc84b..6368d280de5db 100644 --- a/clang/test/OpenMP/parallel_for_simd_default_messages.cpp +++ b/clang/test/OpenMP/parallel_for_simd_default_messages.cpp @@ -2,17 +2,26 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { int i; #pragma omp parallel for simd default // expected-error {{expected '(' after 'default'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for simd default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp parallel for simd default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for simd default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel for simd default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for simd default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{explicit data sharing attribute requested here}} @@ -21,7 +30,7 @@ int main(int argc, char **argv) { #pragma omp parallel for simd default(shared), default(shared) // expected-error {{directive '#pragma omp parallel for simd' cannot contain more than one 'default' clause}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for simd default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel for simd default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); @@ -34,5 +43,13 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} expected-error {{variable 'i' must have explicitly specified data sharing attributes}} foo(); +#ifdef OMP51 +#pragma omp parallel for default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + for (i = 0; i < argc; ++i) { + x++; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + y++; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif + return 0; } diff --git a/clang/test/OpenMP/parallel_for_simd_loop_messages.cpp b/clang/test/OpenMP/parallel_for_simd_loop_messages.cpp index 5a0202c4e5766..cbc14ed6663a9 100644 --- a/clang/test/OpenMP/parallel_for_simd_loop_messages.cpp +++ b/clang/test/OpenMP/parallel_for_simd_loop_messages.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized class S { diff --git a/clang/test/OpenMP/parallel_for_simd_scan_codegen.cpp b/clang/test/OpenMP/parallel_for_simd_scan_codegen.cpp new file mode 100644 index 0000000000000..42fb9de348649 --- /dev/null +++ b/clang/test/OpenMP/parallel_for_simd_scan_codegen.cpp @@ -0,0 +1,315 @@ +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s +// SIMD-ONLY0-NOT: {{__kmpc|__tgt}} +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +void foo(); +void bar(); + +// CHECK: define void @{{.*}}baz{{.*}}(i32 %n) +void baz(int n) { + static float a[10]; + static double b; + + // CHECK: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call( + // CHECK: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call( + + // CHECK: call i8* @llvm.stacksave() + // CHECK: [[A_BUF_SIZE:%.+]] = mul nuw i64 10, [[NUM_ELEMS:%[^,]+]] + + // float a_buffer[10][n]; + // CHECK: [[A_BUF:%.+]] = alloca float, i64 [[A_BUF_SIZE]], + + // double b_buffer[10]; + // CHECK: [[B_BUF:%.+]] = alloca double, i64 10, +#pragma omp parallel for simd reduction(inscan, +:a[:n], b) + for (int i = 0; i < 10; ++i) { + // CHECK: call void @__kmpc_for_static_init_4( + // CHECK: call i8* @llvm.stacksave() + // CHECK: store float 0.000000e+00, float* % + // CHECK: store double 0.000000e+00, double* [[B_PRIV_ADDR:%.+]], + // CHECK: br label %[[DISPATCH:[^,]+]] + // CHECK: [[INPUT_PHASE:.+]]: + // CHECK: call void @{{.+}}foo{{.+}}() + + // a_buffer[i][0..n] = a_priv[[0..n]; + // CHECK: [[BASE_IDX_I:%.+]] = load i32, i32* [[IV_ADDR:%.+]], + // CHECK: [[BASE_IDX:%.+]] = zext i32 [[BASE_IDX_I]] to i64 + // CHECK: [[IDX:%.+]] = mul nsw i64 [[BASE_IDX]], [[NUM_ELEMS]] + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, float* [[A_BUF]], i64 [[IDX]] + // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds [10 x float], [10 x float]* [[A_PRIV_ADDR:%.+]], i64 0, i64 0 + // CHECK: [[BYTES:%.+]] = mul nuw i64 [[NUM_ELEMS:%.+]], 4 + // CHECK: [[DEST:%.+]] = bitcast float* [[A_BUF_IDX]] to i8* + // CHECK: [[SRC:%.+]] = bitcast float* [[A_PRIV]] to i8* + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}[[DEST]], i8* {{.*}}[[SRC]], i64 [[BYTES]], i1 false) + + // b_buffer[i] = b_priv; + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, double* [[B_BUF]], i64 [[BASE_IDX]] + // CHECK: [[B_PRIV:%.+]] = load double, double* [[B_PRIV_ADDR]], + // CHECK: store double [[B_PRIV]], double* [[B_BUF_IDX]], + // CHECK: br label %[[LOOP_CONTINUE:.+]] + + // CHECK: [[DISPATCH]]: + // CHECK: br label %[[INPUT_PHASE]] + // CHECK: [[LOOP_CONTINUE]]: + // CHECK: call void @llvm.stackrestore(i8* % + // CHECK: call void @__kmpc_for_static_fini( + // CHECK: call void @__kmpc_barrier( + foo(); +#pragma omp scan inclusive(a[:n], b) + // CHECK: [[LOG2_10:%.+]] = call double @llvm.log2.f64(double 1.000000e+01) + // CHECK: [[CEIL_LOG2_10:%.+]] = call double @llvm.ceil.f64(double [[LOG2_10]]) + // CHECK: [[CEIL_LOG2_10_INT:%.+]] = fptoui double [[CEIL_LOG2_10]] to i32 + // CHECK: br label %[[OUTER_BODY:[^,]+]] + // CHECK: [[OUTER_BODY]]: + // CHECK: [[K:%.+]] = phi i32 [ 0, %{{.+}} ], [ [[K_NEXT:%.+]], %{{.+}} ] + // CHECK: [[K2POW:%.+]] = phi i64 [ 1, %{{.+}} ], [ [[K2POW_NEXT:%.+]], %{{.+}} ] + // CHECK: [[CMP:%.+]] = icmp uge i64 9, [[K2POW]] + // CHECK: br i1 [[CMP]], label %[[INNER_BODY:[^,]+]], label %[[INNER_EXIT:[^,]+]] + // CHECK: [[INNER_BODY]]: + // CHECK: [[I:%.+]] = phi i64 [ 9, %[[OUTER_BODY]] ], [ [[I_PREV:%.+]], %{{.+}} ] + + // a_buffer[i] += a_buffer[i-pow(2, k)]; + // CHECK: [[IDX:%.+]] = mul nsw i64 [[I]], [[NUM_ELEMS]] + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, float* [[A_BUF]], i64 [[IDX]] + // CHECK: [[IDX_SUB_K2POW:%.+]] = sub nuw i64 [[I]], [[K2POW]] + // CHECK: [[IDX:%.+]] = mul nsw i64 [[IDX_SUB_K2POW]], [[NUM_ELEMS]] + // CHECK: [[A_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds float, float* [[A_BUF]], i64 [[IDX]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, double* [[B_BUF]], i64 [[I]] + // CHECK: [[IDX_SUB_K2POW:%.+]] = sub nuw i64 [[I]], [[K2POW]] + // CHECK: [[B_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds double, double* [[B_BUF]], i64 [[IDX_SUB_K2POW]] + // CHECK: [[A_BUF_END:%.+]] = getelementptr float, float* [[A_BUF_IDX]], i64 [[NUM_ELEMS]] + // CHECK: [[ISEMPTY:%.+]] = icmp eq float* [[A_BUF_IDX]], [[A_BUF_END]] + // CHECK: br i1 [[ISEMPTY]], label %[[RED_DONE:[^,]+]], label %[[RED_BODY:[^,]+]] + // CHECK: [[RED_BODY]]: + // CHECK: [[A_BUF_IDX_SUB_K2POW_ELEM:%.+]] = phi float* [ [[A_BUF_IDX_SUB_K2POW]], %[[INNER_BODY]] ], [ [[A_BUF_IDX_SUB_K2POW_NEXT:%.+]], %[[RED_BODY]] ] + // CHECK: [[A_BUF_IDX_ELEM:%.+]] = phi float* [ [[A_BUF_IDX]], %[[INNER_BODY]] ], [ [[A_BUF_IDX_NEXT:%.+]], %[[RED_BODY]] ] + // CHECK: [[A_BUF_IDX_VAL:%.+]] = load float, float* [[A_BUF_IDX_ELEM]], + // CHECK: [[A_BUF_IDX_SUB_K2POW_VAL:%.+]] = load float, float* [[A_BUF_IDX_SUB_K2POW_ELEM]], + // CHECK: [[RED:%.+]] = fadd float [[A_BUF_IDX_VAL]], [[A_BUF_IDX_SUB_K2POW_VAL]] + // CHECK: store float [[RED]], float* [[A_BUF_IDX_ELEM]], + // CHECK: [[A_BUF_IDX_NEXT]] = getelementptr float, float* [[A_BUF_IDX_ELEM]], i32 1 + // CHECK: [[A_BUF_IDX_SUB_K2POW_NEXT]] = getelementptr float, float* [[A_BUF_IDX_SUB_K2POW_ELEM]], i32 1 + // CHECK: [[DONE:%.+]] = icmp eq float* [[A_BUF_IDX_NEXT]], [[A_BUF_END]] + // CHECK: br i1 [[DONE]], label %[[RED_DONE]], label %[[RED_BODY]] + // CHECK: [[RED_DONE]]: + + // b_buffer[i] += b_buffer[i-pow(2, k)]; + // CHECK: [[B_BUF_IDX_VAL:%.+]] = load double, double* [[B_BUF_IDX]], + // CHECK: [[B_BUF_IDX_SUB_K2POW_VAL:%.+]] = load double, double* [[B_BUF_IDX_SUB_K2POW]], + // CHECK: [[RED:%.+]] = fadd double [[B_BUF_IDX_VAL]], [[B_BUF_IDX_SUB_K2POW_VAL]] + // CHECK: store double [[RED]], double* [[B_BUF_IDX]], + + // --i; + // CHECK: [[I_PREV:%.+]] = sub nuw i64 [[I]], 1 + // CHECK: [[CMP:%.+]] = icmp uge i64 [[I_PREV]], [[K2POW]] + // CHECK: br i1 [[CMP]], label %[[INNER_BODY]], label %[[INNER_EXIT]] + // CHECK: [[INNER_EXIT]]: + + // ++k; + // CHECK: [[K_NEXT]] = add nuw i32 [[K]], 1 + // k2pow <<= 1; + // CHECK: [[K2POW_NEXT]] = shl nuw i64 [[K2POW]], 1 + // CHECK: [[CMP:%.+]] = icmp ne i32 [[K_NEXT]], [[CEIL_LOG2_10_INT]] + // CHECK: br i1 [[CMP]], label %[[OUTER_BODY]], label %[[OUTER_EXIT:[^,]+]] + // CHECK: [[OUTER_EXIT]]: + bar(); + // CHECK: call void @__kmpc_for_static_init_4( + // CHECK: call i8* @llvm.stacksave() + // CHECK: store float 0.000000e+00, float* % + // CHECK: store double 0.000000e+00, double* [[B_PRIV_ADDR:%.+]], + // CHECK: br label %[[DISPATCH:[^,]+]] + + // Skip the before scan body. + // CHECK: call void @{{.+}}foo{{.+}}() + + // CHECK: [[EXIT_INSCAN:[^,]+]]: + // CHECK: br label %[[LOOP_CONTINUE:[^,]+]] + + // CHECK: [[DISPATCH]]: + // a_priv[[0..n] = a_buffer[i][0..n]; + // CHECK: [[BASE_IDX_I:%.+]] = load i32, i32* [[IV_ADDR:%.+]], + // CHECK: [[BASE_IDX:%.+]] = zext i32 [[BASE_IDX_I]] to i64 + // CHECK: [[IDX:%.+]] = mul nsw i64 [[BASE_IDX]], [[NUM_ELEMS]] + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, float* [[A_BUF]], i64 [[IDX]] + // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds [10 x float], [10 x float]* [[A_PRIV_ADDR:%.+]], i64 0, i64 0 + // CHECK: [[BYTES:%.+]] = mul nuw i64 [[NUM_ELEMS:%.+]], 4 + // CHECK: [[DEST:%.+]] = bitcast float* [[A_PRIV]] to i8* + // CHECK: [[SRC:%.+]] = bitcast float* [[A_BUF_IDX]] to i8* + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}[[DEST]], i8* {{.*}}[[SRC]], i64 [[BYTES]], i1 false) + + // b_priv = b_buffer[i]; + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, double* [[B_BUF]], i64 [[BASE_IDX]] + // CHECK: [[B_BUF_IDX_VAL:%.+]] = load double, double* [[B_BUF_IDX]], + // CHECK: store double [[B_BUF_IDX_VAL]], double* [[B_PRIV_ADDR]], + // CHECK: br label %[[SCAN_PHASE:[^,]+]] + + // CHECK: [[SCAN_PHASE]]: + // CHECK: call void @{{.+}}bar{{.+}}() + // CHECK: br label %[[EXIT_INSCAN]] + + // CHECK: [[LOOP_CONTINUE]]: + // CHECK: call void @llvm.stackrestore(i8* % + // CHECK: call void @__kmpc_for_static_fini( + // CHECK: call void @llvm.stackrestore(i8* + } + + // CHECK: call i8* @llvm.stacksave() + // CHECK: [[A_BUF_SIZE:%.+]] = mul nuw i64 10, [[NUM_ELEMS:%[^,]+]] + + // float a_buffer[10][n]; + // CHECK: [[A_BUF:%.+]] = alloca float, i64 [[A_BUF_SIZE]], + + // double b_buffer[10]; + // CHECK: [[B_BUF:%.+]] = alloca double, i64 10, +#pragma omp parallel for simd reduction(inscan, +:a[:n], b) + for (int i = 0; i < 10; ++i) { + // CHECK: call void @__kmpc_for_static_init_4( + // CHECK: call i8* @llvm.stacksave() + // CHECK: store float 0.000000e+00, float* % + // CHECK: store double 0.000000e+00, double* [[B_PRIV_ADDR:%.+]], + // CHECK: br label %[[DISPATCH:[^,]+]] + + // Skip the before scan body. + // CHECK: call void @{{.+}}foo{{.+}}() + + // CHECK: [[EXIT_INSCAN:[^,]+]]: + + // a_buffer[i][0..n] = a_priv[[0..n]; + // CHECK: [[BASE_IDX_I:%.+]] = load i32, i32* [[IV_ADDR:%.+]], + // CHECK: [[BASE_IDX:%.+]] = zext i32 [[BASE_IDX_I]] to i64 + // CHECK: [[IDX:%.+]] = mul nsw i64 [[BASE_IDX]], [[NUM_ELEMS]] + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, float* [[A_BUF]], i64 [[IDX]] + // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds [10 x float], [10 x float]* [[A_PRIV_ADDR:%.+]], i64 0, i64 0 + // CHECK: [[BYTES:%.+]] = mul nuw i64 [[NUM_ELEMS:%.+]], 4 + // CHECK: [[DEST:%.+]] = bitcast float* [[A_BUF_IDX]] to i8* + // CHECK: [[SRC:%.+]] = bitcast float* [[A_PRIV]] to i8* + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}[[DEST]], i8* {{.*}}[[SRC]], i64 [[BYTES]], i1 false) + + // b_buffer[i] = b_priv; + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, double* [[B_BUF]], i64 [[BASE_IDX]] + // CHECK: [[B_PRIV:%.+]] = load double, double* [[B_PRIV_ADDR]], + // CHECK: store double [[B_PRIV]], double* [[B_BUF_IDX]], + // CHECK: br label %[[LOOP_CONTINUE:[^,]+]] + + // CHECK: [[DISPATCH]]: + // CHECK: br label %[[INPUT_PHASE:[^,]+]] + + // CHECK: [[INPUT_PHASE]]: + // CHECK: call void @{{.+}}bar{{.+}}() + // CHECK: br label %[[EXIT_INSCAN]] + + // CHECK: [[LOOP_CONTINUE]]: + // CHECK: call void @llvm.stackrestore(i8* % + // CHECK: call void @__kmpc_for_static_fini( + // CHECK: call void @__kmpc_barrier( + foo(); +#pragma omp scan exclusive(a[:n], b) + // CHECK: [[LOG2_10:%.+]] = call double @llvm.log2.f64(double 1.000000e+01) + // CHECK: [[CEIL_LOG2_10:%.+]] = call double @llvm.ceil.f64(double [[LOG2_10]]) + // CHECK: [[CEIL_LOG2_10_INT:%.+]] = fptoui double [[CEIL_LOG2_10]] to i32 + // CHECK: br label %[[OUTER_BODY:[^,]+]] + // CHECK: [[OUTER_BODY]]: + // CHECK: [[K:%.+]] = phi i32 [ 0, %{{.+}} ], [ [[K_NEXT:%.+]], %{{.+}} ] + // CHECK: [[K2POW:%.+]] = phi i64 [ 1, %{{.+}} ], [ [[K2POW_NEXT:%.+]], %{{.+}} ] + // CHECK: [[CMP:%.+]] = icmp uge i64 9, [[K2POW]] + // CHECK: br i1 [[CMP]], label %[[INNER_BODY:[^,]+]], label %[[INNER_EXIT:[^,]+]] + // CHECK: [[INNER_BODY]]: + // CHECK: [[I:%.+]] = phi i64 [ 9, %[[OUTER_BODY]] ], [ [[I_PREV:%.+]], %{{.+}} ] + + // a_buffer[i] += a_buffer[i-pow(2, k)]; + // CHECK: [[IDX:%.+]] = mul nsw i64 [[I]], [[NUM_ELEMS]] + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, float* [[A_BUF]], i64 [[IDX]] + // CHECK: [[IDX_SUB_K2POW:%.+]] = sub nuw i64 [[I]], [[K2POW]] + // CHECK: [[IDX:%.+]] = mul nsw i64 [[IDX_SUB_K2POW]], [[NUM_ELEMS]] + // CHECK: [[A_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds float, float* [[A_BUF]], i64 [[IDX]] + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, double* [[B_BUF]], i64 [[I]] + // CHECK: [[IDX_SUB_K2POW:%.+]] = sub nuw i64 [[I]], [[K2POW]] + // CHECK: [[B_BUF_IDX_SUB_K2POW:%.+]] = getelementptr inbounds double, double* [[B_BUF]], i64 [[IDX_SUB_K2POW]] + // CHECK: [[A_BUF_END:%.+]] = getelementptr float, float* [[A_BUF_IDX]], i64 [[NUM_ELEMS]] + // CHECK: [[ISEMPTY:%.+]] = icmp eq float* [[A_BUF_IDX]], [[A_BUF_END]] + // CHECK: br i1 [[ISEMPTY]], label %[[RED_DONE:[^,]+]], label %[[RED_BODY:[^,]+]] + // CHECK: [[RED_BODY]]: + // CHECK: [[A_BUF_IDX_SUB_K2POW_ELEM:%.+]] = phi float* [ [[A_BUF_IDX_SUB_K2POW]], %[[INNER_BODY]] ], [ [[A_BUF_IDX_SUB_K2POW_NEXT:%.+]], %[[RED_BODY]] ] + // CHECK: [[A_BUF_IDX_ELEM:%.+]] = phi float* [ [[A_BUF_IDX]], %[[INNER_BODY]] ], [ [[A_BUF_IDX_NEXT:%.+]], %[[RED_BODY]] ] + // CHECK: [[A_BUF_IDX_VAL:%.+]] = load float, float* [[A_BUF_IDX_ELEM]], + // CHECK: [[A_BUF_IDX_SUB_K2POW_VAL:%.+]] = load float, float* [[A_BUF_IDX_SUB_K2POW_ELEM]], + // CHECK: [[RED:%.+]] = fadd float [[A_BUF_IDX_VAL]], [[A_BUF_IDX_SUB_K2POW_VAL]] + // CHECK: store float [[RED]], float* [[A_BUF_IDX_ELEM]], + // CHECK: [[A_BUF_IDX_NEXT]] = getelementptr float, float* [[A_BUF_IDX_ELEM]], i32 1 + // CHECK: [[A_BUF_IDX_SUB_K2POW_NEXT]] = getelementptr float, float* [[A_BUF_IDX_SUB_K2POW_ELEM]], i32 1 + // CHECK: [[DONE:%.+]] = icmp eq float* [[A_BUF_IDX_NEXT]], [[A_BUF_END]] + // CHECK: br i1 [[DONE]], label %[[RED_DONE]], label %[[RED_BODY]] + // CHECK: [[RED_DONE]]: + + // b_buffer[i] += b_buffer[i-pow(2, k)]; + // CHECK: [[B_BUF_IDX_VAL:%.+]] = load double, double* [[B_BUF_IDX]], + // CHECK: [[B_BUF_IDX_SUB_K2POW_VAL:%.+]] = load double, double* [[B_BUF_IDX_SUB_K2POW]], + // CHECK: [[RED:%.+]] = fadd double [[B_BUF_IDX_VAL]], [[B_BUF_IDX_SUB_K2POW_VAL]] + // CHECK: store double [[RED]], double* [[B_BUF_IDX]], + + // --i; + // CHECK: [[I_PREV:%.+]] = sub nuw i64 [[I]], 1 + // CHECK: [[CMP:%.+]] = icmp uge i64 [[I_PREV]], [[K2POW]] + // CHECK: br i1 [[CMP]], label %[[INNER_BODY]], label %[[INNER_EXIT]] + // CHECK: [[INNER_EXIT]]: + + // ++k; + // CHECK: [[K_NEXT]] = add nuw i32 [[K]], 1 + // k2pow <<= 1; + // CHECK: [[K2POW_NEXT]] = shl nuw i64 [[K2POW]], 1 + // CHECK: [[CMP:%.+]] = icmp ne i32 [[K_NEXT]], [[CEIL_LOG2_10_INT]] + // CHECK: br i1 [[CMP]], label %[[OUTER_BODY]], label %[[OUTER_EXIT:[^,]+]] + // CHECK: [[OUTER_EXIT]]: + bar(); + // CHECK: call void @__kmpc_for_static_init_4( + // CHECK: call i8* @llvm.stacksave() + // CHECK: store float 0.000000e+00, float* % + // CHECK: store double 0.000000e+00, double* [[B_PRIV_ADDR:%.+]], + // CHECK: br label %[[DISPATCH:[^,]+]] + + // CHECK: [[SCAN_PHASE:.+]]: + // CHECK: call void @{{.+}}foo{{.+}}() + // CHECK: br label %[[LOOP_CONTINUE:.+]] + + // CHECK: [[DISPATCH]]: + // if (i >0) + // a_priv[[0..n] = a_buffer[i-1][0..n]; + // CHECK: [[BASE_IDX_I:%.+]] = load i32, i32* [[IV_ADDR:%.+]], + // CHECK: [[BASE_IDX:%.+]] = zext i32 [[BASE_IDX_I]] to i64 + // CHECK: [[CMP:%.+]] = icmp eq i64 [[BASE_IDX]], 0 + // CHECK: br i1 [[CMP]], label %[[IF_DONE:[^,]+]], label %[[IF_THEN:[^,]+]] + // CHECK: [[IF_THEN]]: + // CHECK: [[BASE_IDX_SUB_1:%.+]] = sub nuw i64 [[BASE_IDX]], 1 + // CHECK: [[IDX:%.+]] = mul nsw i64 [[BASE_IDX_SUB_1]], [[NUM_ELEMS]] + // CHECK: [[A_BUF_IDX:%.+]] = getelementptr inbounds float, float* [[A_BUF]], i64 [[IDX]] + // CHECK: [[A_PRIV:%.+]] = getelementptr inbounds [10 x float], [10 x float]* [[A_PRIV_ADDR:%.+]], i64 0, i64 0 + // CHECK: [[BYTES:%.+]] = mul nuw i64 [[NUM_ELEMS:%.+]], 4 + // CHECK: [[DEST:%.+]] = bitcast float* [[A_PRIV]] to i8* + // CHECK: [[SRC:%.+]] = bitcast float* [[A_BUF_IDX]] to i8* + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}[[DEST]], i8* {{.*}}[[SRC]], i64 [[BYTES]], i1 false) + + // b_priv = b_buffer[i]; + // CHECK: [[B_BUF_IDX:%.+]] = getelementptr inbounds double, double* [[B_BUF]], i64 [[BASE_IDX_SUB_1]] + // CHECK: [[B_BUF_IDX_VAL:%.+]] = load double, double* [[B_BUF_IDX]], + // CHECK: store double [[B_BUF_IDX_VAL]], double* [[B_PRIV_ADDR]], + // CHECK: br label %[[SCAN_PHASE]] + + // CHECK: [[LOOP_CONTINUE]]: + // CHECK: call void @llvm.stackrestore(i8* % + // CHECK: call void @__kmpc_for_static_fini( + // CHECK: call void @llvm.stackrestore(i8* + } +} + +// CHECK: !{!"llvm.loop.vectorize.enable", i1 true} + +#endif + diff --git a/clang/test/OpenMP/parallel_master_codegen.cpp b/clang/test/OpenMP/parallel_master_codegen.cpp index 9ffa941314b98..82e18c80f103e 100644 --- a/clang/test/OpenMP/parallel_master_codegen.cpp +++ b/clang/test/OpenMP/parallel_master_codegen.cpp @@ -118,6 +118,162 @@ void parallel_master_private() { #endif +#ifdef CK31 +///==========================================================================/// +// RUN: %clang_cc1 -DCK31 -fopenmp-version=51 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefix CK31 +// RUN: %clang_cc1 -DCK31 -fopenmp-version=51 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK31 -fopenmp-version=51 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK31 + +// RUN: %clang_cc1 -DCK31 -fopenmp-version=51 -verify -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck --check-prefix SIMD-ONLY0 %s +// RUN: %clang_cc1 -DCK31 -fopenmp-version=51 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK31 -fopenmp-version=51 -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s +// SIMD-ONLY0-NOT: {{__kmpc|__tgt}} + +// CK31-DAG: %struct.ident_t = type { i32, i32, i32, i32, i8* } +// CK31-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00" + +void parallel_master_default_firstprivate() { + int a; +#pragma omp parallel master default(firstprivate) + a++; +} + +// CK31-LABEL: define void @{{.+}}parallel_master{{.+}} +// CK31: [[A_VAL:%.+]] = alloca i32{{.+}} +// CK31: [[A_CASTED:%.+]] = alloca i64 +// CK31: [[ZERO_VAL:%.+]] = load i32, i32* [[A_VAL]] +// CK31: [[CONV:%.+]] = bitcast i64* [[A_CASTED]] to i32* +// CK31: store i32 [[ZERO_VAL]], i32* [[CONV]] +// CK31: [[ONE_VAL:%.+]] = load i64, i64* [[A_CASTED]] +// CK31: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @0, i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i64 [[ONE_VAL]]) +// CK31: ret void + +// CK31: [[GLOBAL_TID_ADDR:%.+]] = alloca i32* +// CK31: [[BOUND_TID_ADDR:%.+]] = alloca i32* +// CK31: [[A_ADDR:%.+]] = alloca i64{{.+}} +// CK31: store i32* [[GLOBAL_TID:%.+]], i32** [[GLOBAL_TID_ADDR]]{{.+}} +// CK31: store i32* [[BOUND_TID:%.+]], i32** [[BOUND_TID_ADDR]] +// CK31: store i64 [[A_VAL]], i64* [[A_ADDR]] +// CK31: [[CONV]] = bitcast i64* [[A_ADDR]] +// CK31: [[ZERO_VAL]] = load i32*, i32** [[GLOBAL_TID_ADDR]] +// CK31: [[ONE_VAL]] = load i32, i32* [[ZERO_VAL]] +// CK31: [[TWO_VAL:%.+]] = call i32 @__kmpc_master(%struct.ident_t* @0, i32 [[ONE_VAL]]) +// CK31: [[THREE:%.+]] = icmp ne i32 [[TWO_VAL]], 0 +// CK31: br i1 %3, label [[OMP_IF_THEN:%.+]], label [[OMP_IF_END:%.+]] + +// CK31: [[FOUR:%.+]] = load i32, i32* [[CONV:%.+]] +// CK31: [[INC:%.+]] = add nsw i32 [[FOUR]] +// CK31: store i32 [[INC]], i32* [[CONV]] +// CK31: call void @__kmpc_end_master(%struct.ident_t* @0, i32 [[ONE_VAL]]) +// CK31: br label [[OMP_IF_END]] + +// CK31: ret void + +#endif + +#ifdef CK32 +///==========================================================================/// +// RUN: %clang_cc1 -DCK32 -fopenmp-version=51 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefix CK32 +// RUN: %clang_cc1 -DCK32 -fopenmp-version=51 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK32 -fopenmp-version=51 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK32 + +// RUN: %clang_cc1 -DCK32 -fopenmp-version=51 -verify -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck --check-prefix SIMD-ONLY0 %s +// RUN: %clang_cc1 -DCK32 -fopenmp-version=51 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK32 -fopenmp-version=51 -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s +// SIMD-ONLY0-NOT: {{__kmpc|__tgt}} + +// CK32-DAG: %struct.ident_t = type { i32, i32, i32, i32, i8* } +// CK32-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00" + +struct St { + int a, b; + static int y; + St() : a(0), b(0) {} + ~St() {} +}; +int St::y = 0; + +void parallel_master_default_firstprivate() { + St a = St(); + static int y = 0; +#pragma omp parallel master default(firstprivate) + { + a.a += 1; + a.b += 1; + y++; + a.y++; + } +} + +// CK32-LABEL: define {{.+}} @{{.+}}parallel_master_default_firstprivate{{.+}} +// CK32: [[A_VAL:%.+]] = alloca %struct.St{{.+}} +// CK32: [[Y_CASTED:%.+]] = alloca i64 +// CK32: call void @[[CTOR:.+]](%struct.St* [[A_VAL]]) +// CK32: [[ZERO:%.+]] = load i32, i32* @{{.+}}parallel_master_default_firstprivate{{.+}} +// CK32: [[CONV:%.+]] = bitcast i64* [[Y_CASTED]] to i32* +// CK32: store i32 [[ZERO]], i32* [[CONV]] +// CK32: [[ONE:%.+]] = load i64, i64* [[Y_CASTED]] +// CK32: call void {{.+}}@{{.+}} %struct.St* [[A_VAL]], i64 [[ONE]]) +// CK32: call void [[DTOR:@.+]](%struct.St* [[A_VAL]]) + +// CK32: [[THIS_ADDR:%.+]] = alloca %struct.St* +// CK32: store %struct.St* [[THIS:%.+]], %struct.St** [[THIS_ADDR]] +// CK32: [[THIS_ONE:%.+]] = load %struct.St*, %struct.St** [[THIS_ADDR]] +// CK32: call void [[CTOR_2:.+]](%struct.St* [[THIS_ONE]]) +// CK32: ret void + +// CK32: [[GLOBAL_TID_ADDR:%.+]] = alloca i32* +// CK32: [[BOUND_TID_ADDR:%.+]] = alloca i32* +// CK32: [[A_ADDR:%.+]] = alloca %struct.St +// CK32: [[Y_ADDR:%.+]] = alloca i64 +// CK32: store i32* [[GLOBAL_TID:%.+]], i32** [[GLOBAL_TID_ADDR]] +// CK32: store i32* %.bound_tid., i32** [[BOUND_TID_ADDR]] +// CK32: store %struct.St* [[A_VAL]], %struct.St** [[A_ADDR]]{{.+}} +// CK32: store i64 [[Y:%.+]], i64* [[Y_ADDR]] +// CK32: [[ONE:%.+]] = load i32*, i32** [[GLOBAL_TID_ADDR]] +// CK32: [[TWO:%.+]] = load i32, i32* [[ONE]] +// CK32: [[THREE:%.+]] = call i32 @{{.+}} i32 [[TWO]]) +// CK32: [[FOUR:%.+]] = icmp ne i32 [[THREE]], 0 +// CK32: br i1 [[FOUR]], label [[IF_THEN:%.+]], label [[IF_END:%.+]] + +// CK32: [[A_1:%.+]] = getelementptr inbounds %struct.St, %struct.St* [[ZERO]], i32 0, i32 0 +// CK32: [[FIVE:%.+]] = load i32, i32* [[A_1]] +// CK32: [[ADD:%.+]] = add nsw i32 [[FIVE]], 1 +// CK32: store i32 [[ADD]], i32* [[A_1]] +// CK32: [[B:%.+]] = getelementptr inbounds %struct.St, %struct.St* [[ZERO]], i32 0, i32 1 +// CK32: [[SIX:%.+]] = load i32, i32* [[B]] +// CK32: [[ADD_2:%.+]] = add nsw i32 [[SIX]], 1 +// CK32: store i32 [[ADD_2]], i32* [[B]] +// CK32: [[SEVEN:%.+]] = load i32, i32* [[CONV]] +// CK32: [[INC:%.+]] = add nsw i32 [[SEVEN]], 1 +// CK32: store i32 [[INC]], i32* [[CONV]] +// CK32: [[EIGHT:%.+]] = load i32, i32* [[FUNC:@.+]] +// CK32: [[INC_3:%.+]] = add nsw i32 [[EIGHT]], 1 +// CK32: store i32 [[INC_3]], i32* @{{.+}} +// CK32: call void @{{.+}} i32 [[TWO]]) +// CK32: br label [[IF_END]] + +// CK32: [[DTOR]](%struct.St* [[THIS]]) +// CK32: [[THIS_ADDR]] = alloca %struct.St* +// CK32: store %struct.St* [[THIS]], %struct.St** [[THIS_ADDR]] +// CK32: [[THIS_ONE]] = load %struct.St*, %struct.St** [[THIS_ADDR]] +// CK32: call void @_ZN2StD2Ev(%struct.St* [[THIS_ONE]]) + +// CK32: [[THIS_ADDR]] = alloca %struct.St* +// CK32: store %struct.St* [[THIS]], %struct.St** [[THIS_ADDR]] +// CK32: [[THIS_ONE]] = load %struct.St*, %struct.St** [[THIS_ADDR]] +// CK32: [[A_VAL]] = getelementptr inbounds %struct.St, %struct.St* [[THIS_ONE]], i32 0, i32 0 +// CK32: store i32 0, i32* [[A_VAL]] +// CK32: [[B_VAL:%.+]] = getelementptr inbounds %struct.St, %struct.St* [[THIS_ONE]], i32 0, i32 1 +// CK32: store i32 0, i32* [[B_VAL]] +// CK32: ret void + +// CK32: [[THIS_ADDR:%.+]] = alloca %struct.St* +// CK32: store %struct.St* %this, %struct.St** [[THIS_ADDR]] +// CK32: [[THIS_ONE]] = load %struct.St*, %struct.St** [[THIS_ADDR]] + +#endif + #ifdef CK4 ///==========================================================================/// // RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefix CK4 diff --git a/clang/test/OpenMP/parallel_master_default_messages.cpp b/clang/test/OpenMP/parallel_master_default_messages.cpp index 557cba5aa322a..39f78ea53ae16 100644 --- a/clang/test/OpenMP/parallel_master_default_messages.cpp +++ b/clang/test/OpenMP/parallel_master_default_messages.cpp @@ -2,20 +2,29 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp -ferror-limit 100 -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp parallel master default // expected-error {{expected '(' after 'default'}} { -#pragma omp parallel master default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp parallel master default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} { -#pragma omp parallel master default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel master default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} { #pragma omp parallel master default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} { #pragma omp parallel master default(shared), default(shared) // expected-error {{directive '#pragma omp parallel master' cannot contain more than one 'default' clause}} { -#pragma omp parallel master default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel master default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} { foo(); } @@ -37,5 +46,14 @@ int main(int argc, char **argv) { ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} } } + +#ifdef OMP51 +#pragma omp parallel master default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif + return 0; } diff --git a/clang/test/OpenMP/parallel_master_taskloop_loop_messages.cpp b/clang/test/OpenMP/parallel_master_taskloop_loop_messages.cpp index 76411969924bd..2f0edc4539127 100644 --- a/clang/test/OpenMP/parallel_master_taskloop_loop_messages.cpp +++ b/clang/test/OpenMP/parallel_master_taskloop_loop_messages.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized class S { diff --git a/clang/test/OpenMP/parallel_master_taskloop_simd_loop_messages.cpp b/clang/test/OpenMP/parallel_master_taskloop_simd_loop_messages.cpp index 9f6c55e1c4c54..354844f94ec04 100644 --- a/clang/test/OpenMP/parallel_master_taskloop_simd_loop_messages.cpp +++ b/clang/test/OpenMP/parallel_master_taskloop_simd_loop_messages.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized class S { diff --git a/clang/test/OpenMP/parallel_sections_default_messages.cpp b/clang/test/OpenMP/parallel_sections_default_messages.cpp index d6a10fe56b344..cfa95445fb536 100644 --- a/clang/test/OpenMP/parallel_sections_default_messages.cpp +++ b/clang/test/OpenMP/parallel_sections_default_messages.cpp @@ -7,15 +7,15 @@ void foo(); int main(int argc, char **argv) { #pragma omp parallel sections default // expected-error {{expected '(' after 'default'}} { -#pragma omp parallel sections default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp parallel sections default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} { -#pragma omp parallel sections default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel sections default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} { #pragma omp parallel sections default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} { #pragma omp parallel sections default(shared), default(shared) // expected-error {{directive '#pragma omp parallel sections' cannot contain more than one 'default' clause}} { -#pragma omp parallel sections default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel sections default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} { foo(); } diff --git a/clang/test/OpenMP/simd_loop_messages.cpp b/clang/test/OpenMP/simd_loop_messages.cpp index d905991682829..f046ce3ec7c89 100644 --- a/clang/test/OpenMP/simd_loop_messages.cpp +++ b/clang/test/OpenMP/simd_loop_messages.cpp @@ -1,9 +1,9 @@ -// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4,expectedw %s -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4,expectedw %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4,expectedw %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4,expectedw %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5,expectedw %s -fopenmp-version=50 -DOMP50 -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5,expectedw %s -fopenmp-version=50 -DOMP50 -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized -Wno-openmp-loop-form -// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized -Wno-openmp +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized -Wno-openmp-loop-form +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized -Wno-openmp static int sii; // expected-note@+1 {{defined as threadprivate or thread local}} diff --git a/clang/test/OpenMP/single_codegen.cpp b/clang/test/OpenMP/single_codegen.cpp index ef1e32d27fed2..a56cdb0ae81a4 100644 --- a/clang/test/OpenMP/single_codegen.cpp +++ b/clang/test/OpenMP/single_codegen.cpp @@ -1,6 +1,12 @@ -// RUN: %clang_cc1 -verify -fopenmp -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s -// RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefixes=OMP50,CHECK +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -fopenmp-version=45 -o - | FileCheck %s --check-prefixes=OMP45,CHECK + +// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -fnoopenmp-use-tls -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefixes=OMP50,CHECK + +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fnoopenmp-use-tls -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefixes=OMP45,CHECK + // RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -std=c++11 -fopenmp -fnoopenmp-use-tls -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG // RUN: %clang_cc1 -verify -fopenmp -fnoopenmp-use-tls -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=ARRAY %s @@ -149,6 +155,7 @@ int main() { return a; } +// OMP50-LABEL: declare i8* @__kmpc_threadprivate_cached( // CHECK: void [[COPY_FUNC]](i8* %0, i8* %1) // CHECK: store i8* %0, i8** [[DST_ADDR_REF:%.+]], // CHECK: store i8* %1, i8** [[SRC_ADDR_REF:%.+]], @@ -192,7 +199,58 @@ int main() { // CHECK: br i1 // CHECK: ret void -// CHECK-LABEL: parallel_single + +// OMP50-LABEL: void @_ZN3SSTIdEC2Ev( +// OMP50: getelementptr inbounds [[SST_TY]], [[SST_TY]]* %{{.+}}, i32 0, i32 0 +// OMP50-NEXT: store double 0.000000e+00, double* % +// OMP50-NEXT: getelementptr inbounds [[SST_TY]], [[SST_TY]]* %{{.+}}, i32 0, i32 0 +// OMP50-NEXT: store double* %{{.+}}, double** % +// OMP50-NEXT: load double*, double** % +// OMP50-NEXT: load double, double* % +// OMP50-NEXT: bitcast i64* %{{.+}} to double* +// OMP50-NEXT: store double %{{.+}}, double* % +// OMP50-NEXT: load i64, i64* % +// OMP50-NEXT: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* @{{.+}}, i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[SST_TY]]*, i64)* [[SST_MICROTASK:@.+]] to void +// OMP50-NEXT: ret void + +// OMP50: define internal void [[SST_MICROTASK]](i32* {{[^,]+}}, i32* {{[^,]+}}, [[SST_TY]]* {{.+}}, i64 {{.+}}) +// OMP50: [[RES:%.+]] = call i32 @__kmpc_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}) +// OMP50-NEXT: icmp ne i32 [[RES]], 0 +// OMP50-NEXT: br i1 + +// OMP50: getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 1 +// OMP50-NEXT: load double*, double** % +// OMP50-NEXT: store double* % +// OMP50-LABEL: invoke void @_ZZN3SSTIdEC1EvENKUlvE_clEv( + +// OMP50: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}) +// OMP50-NEXT: store i32 1, i32* [[DID_IT]], +// OMP50-NEXT: br label + +// OMP50: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}) +// OMP50-NEXT: br label + +// OMP50: getelementptr inbounds [1 x i8*], [1 x i8*]* [[LIST:%.+]], i64 0, i64 0 +// OMP50: load double*, double** % +// OMP50-NEXT: bitcast double* % +// OMP50-NEXT: store i8* % +// OMP50-NEXT: bitcast [1 x i8*]* [[LIST]] to i8* +// OMP50-NEXT: load i32, i32* [[DID_IT]], +// OMP50-NEXT: call void @__kmpc_copyprivate([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}, i64 8, i8* %{{.+}}, void (i8*, i8*)* [[COPY_FUNC:@[^,]+]], i32 %{{.+}}) +// OMP50-NEXT: ret void + +// OMP50-LABEL: @_ZZN3SSTIdEC1EvENKUlvE_clEv( +// OMP50: getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 1 +// OMP50-NEXT: getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 1 +// OMP50-NEXT: load double*, double** % +// OMP50-NEXT: store double* % +// OMP50-LABEL: call void @_ZZZN3SSTIdEC1EvENKUlvE_clEvENKUlvE_clEv( +// OMP50-NEXT: ret void + +// OMP50: define internal void [[COPY_FUNC]](i8* %0, i8* %1) +// OMP50: ret void + +// OMP45-LABEL: parallel_single // TERM_DEBUG-LABEL: parallel_single void parallel_single() { #pragma omp parallel @@ -385,54 +443,54 @@ void array_func(int n, int a[n], St s[2]) { // CHECK: define internal void [[COPY_FUNC]](i8* %0, i8* %1) // CHECK: ret void -// CHECK-LABEL: @_ZN3SSTIdEC2Ev -// CHECK: getelementptr inbounds [[SST_TY]], [[SST_TY]]* %{{.+}}, i32 0, i32 0 -// CHECK-NEXT: store double 0.000000e+00, double* % -// CHECK-NEXT: getelementptr inbounds [[SST_TY]], [[SST_TY]]* %{{.+}}, i32 0, i32 0 -// CHECK-NEXT: store double* %{{.+}}, double** % -// CHECK-NEXT: load double*, double** % -// CHECK-NEXT: load double, double* % -// CHECK-NEXT: bitcast i64* %{{.+}} to double* -// CHECK-NEXT: store double %{{.+}}, double* % -// CHECK-NEXT: load i64, i64* % -// CHECK-NEXT: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* @{{.+}}, i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[SST_TY]]*, i64)* [[SST_MICROTASK:@.+]] to void -// CHECK-NEXT: ret void - -// CHECK: define internal void [[SST_MICROTASK]](i32* {{[^,]+}}, i32* {{[^,]+}}, [[SST_TY]]* {{.+}}, i64 {{.+}}) -// CHECK: [[RES:%.+]] = call i32 @__kmpc_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}) -// CHECK-NEXT: icmp ne i32 [[RES]], 0 -// CHECK-NEXT: br i1 - -// CHECK: getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 1 -// CHECK-NEXT: load double*, double** % -// CHECK-NEXT: store double* % -// CHECK-LABEL: invoke void @_ZZN3SSTIdEC1EvENKUlvE_clEv( - -// CHECK: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}) -// CHECK-NEXT: store i32 1, i32* [[DID_IT]], -// CHECK-NEXT: br label - -// CHECK: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}) -// CHECK-NEXT: br label - -// CHECK: getelementptr inbounds [1 x i8*], [1 x i8*]* [[LIST:%.+]], i64 0, i64 0 -// CHECK: load double*, double** % -// CHECK-NEXT: bitcast double* % -// CHECK-NEXT: store i8* % -// CHECK-NEXT: bitcast [1 x i8*]* [[LIST]] to i8* -// CHECK-NEXT: load i32, i32* [[DID_IT]], -// CHECK-NEXT: call void @__kmpc_copyprivate([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}, i64 8, i8* %{{.+}}, void (i8*, i8*)* [[COPY_FUNC:@[^,]+]], i32 %{{.+}}) -// CHECK-NEXT: ret void - -// CHECK-LABEL: @_ZZN3SSTIdEC1EvENKUlvE_clEv( -// CHECK: getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 1 -// CHECK-NEXT: getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 1 -// CHECK-NEXT: load double*, double** % -// CHECK-NEXT: store double* % -// CHECK-LABEL: call void @_ZZZN3SSTIdEC1EvENKUlvE_clEvENKUlvE_clEv( -// CHECK-NEXT: ret void - -// CHECK: define internal void [[COPY_FUNC]](i8* %0, i8* %1) -// CHECK: ret void - -// CHECK-LABEL: @_ZZZN3SSTIdEC1EvENKUlvE_clEvENKUlvE_clEv( +// OMP45-LABEL: void @_ZN3SSTIdEC2Ev( +// OMP45: getelementptr inbounds [[SST_TY]], [[SST_TY]]* %{{.+}}, i32 0, i32 0 +// OMP45-NEXT: store double 0.000000e+00, double* % +// OMP45-NEXT: getelementptr inbounds [[SST_TY]], [[SST_TY]]* %{{.+}}, i32 0, i32 0 +// OMP45-NEXT: store double* %{{.+}}, double** % +// OMP45-NEXT: load double*, double** % +// OMP45-NEXT: load double, double* % +// OMP45-NEXT: bitcast i64* %{{.+}} to double* +// OMP45-NEXT: store double %{{.+}}, double* % +// OMP45-NEXT: load i64, i64* % +// OMP45-NEXT: call void ([[IDENT_T_TY]]*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call([[IDENT_T_TY]]* @{{.+}}, i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[SST_TY]]*, i64)* [[SST_MICROTASK:@.+]] to void +// OMP45-NEXT: ret void + +// OMP45: define internal void [[SST_MICROTASK]](i32* {{[^,]+}}, i32* {{[^,]+}}, [[SST_TY]]* {{.+}}, i64 {{.+}}) +// OMP45: [[RES:%.+]] = call i32 @__kmpc_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}) +// OMP45-NEXT: icmp ne i32 [[RES]], 0 +// OMP45-NEXT: br i1 + +// OMP45: getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 1 +// OMP45-NEXT: load double*, double** % +// OMP45-NEXT: store double* % +// OMP45-LABEL: invoke void @_ZZN3SSTIdEC1EvENKUlvE_clEv( + +// OMP45: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}) +// OMP45-NEXT: store i32 1, i32* [[DID_IT]], +// OMP45-NEXT: br label + +// OMP45: call void @__kmpc_end_single([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}) +// OMP45-NEXT: br label + +// OMP45: getelementptr inbounds [1 x i8*], [1 x i8*]* [[LIST:%.+]], i64 0, i64 0 +// OMP45: load double*, double** % +// OMP45-NEXT: bitcast double* % +// OMP45-NEXT: store i8* % +// OMP45-NEXT: bitcast [1 x i8*]* [[LIST]] to i8* +// OMP45-NEXT: load i32, i32* [[DID_IT]], +// OMP45-NEXT: call void @__kmpc_copyprivate([[IDENT_T_TY]]* @{{.+}}, i32 %{{.+}}, i64 8, i8* %{{.+}}, void (i8*, i8*)* [[COPY_FUNC:@[^,]+]], i32 %{{.+}}) +// OMP45-NEXT: ret void + +// OMP45-LABEL: @_ZZN3SSTIdEC1EvENKUlvE_clEv( +// OMP45: getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 1 +// OMP45-NEXT: getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 1 +// OMP45-NEXT: load double*, double** % +// OMP45-NEXT: store double* % +// OMP45-LABEL: call void @_ZZZN3SSTIdEC1EvENKUlvE_clEvENKUlvE_clEv( +// OMP45-NEXT: ret void + +// OMP45: define internal void [[COPY_FUNC]](i8* %0, i8* %1) +// OMP45: ret void + +// OMP45-LABEL: @_ZZZN3SSTIdEC1EvENKUlvE_clEvENKUlvE_clEv( diff --git a/clang/test/OpenMP/target_codegen.cpp b/clang/test/OpenMP/target_codegen.cpp index 940edc34b1758..b8fd7cf34b37a 100644 --- a/clang/test/OpenMP/target_codegen.cpp +++ b/clang/test/OpenMP/target_codegen.cpp @@ -1,10 +1,17 @@ // Test host codegen. -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix OMP45 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix OMP45 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix OMP45 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix OMP45 + +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix OMP50 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 +// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix OMP50 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix OMP50 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 +// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix OMP50 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s @@ -15,6 +22,15 @@ // SIMD-ONLY0-NOT: {{__kmpc|__tgt}} // Test target codegen - host bc file has to be created first. +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32 + // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s @@ -690,31 +706,31 @@ int bar(int n){ // CHECK: [[IFEND]] -// CHECK: define {{.*}}@{{.*}}zee{{.*}} - -// CHECK: [[LOCAL_THIS:%.+]] = alloca [[S2]]* -// CHECK: [[BP:%.+]] = alloca [1 x i8*] -// CHECK: [[P:%.+]] = alloca [1 x i8*] -// CHECK: [[LOCAL_THIS1:%.+]] = load [[S2]]*, [[S2]]** [[LOCAL_THIS]] -// CHECK: [[ARR_IDX:%.+]] = getelementptr inbounds [[S2]], [[S2]]* [[LOCAL_THIS1]], i[[SZ]] 0 -// CHECK: [[ARR_IDX2:%.+]] = getelementptr inbounds [[S2]], [[S2]]* [[LOCAL_THIS1]], i[[SZ]] 0 - -// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BP]], i32 0, i32 0 -// CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[P]], i32 0, i32 0 -// CHECK-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to [[S2]]** -// CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to [[S2]]** -// CHECK-DAG: store [[S2]]* [[ARR_IDX]], [[S2]]** [[CBPADDR0]] -// CHECK-DAG: store [[S2]]* [[ARR_IDX2]], [[S2]]** [[CPADDR0]] - -// CHECK: [[BPR:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BP]], i32 0, i32 0 -// CHECK: [[PR:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[P]], i32 0, i32 0 -// CHECK: [[RET:%.+]] = call i32 @__tgt_target(i64 -1, i8* @{{[^,]+}}, i32 1, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i64* getelementptr inbounds ([1 x i64], [1 x i64]* [[SIZET9]], i32 0, i32 0), i64* getelementptr inbounds ([1 x i64], [1 x i64]* [[MAPT10]], i32 0, i32 0)) -// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0 -// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]] -// CHECK: [[FAIL]] -// CHECK: call void [[HVT0:@.+]]([[S2]]* [[LOCAL_THIS1]]) -// CHECK-NEXT: br label %[[END]] -// CHECK: [[END]] +// OMP45: define {{.*}}@{{.*}}zee{{.*}} + +// OMP45: [[LOCAL_THIS:%.+]] = alloca [[S2]]* +// OMP45: [[BP:%.+]] = alloca [1 x i8*] +// OMP45: [[P:%.+]] = alloca [1 x i8*] +// OMP45: [[LOCAL_THIS1:%.+]] = load [[S2]]*, [[S2]]** [[LOCAL_THIS]] +// OMP45: [[ARR_IDX:%.+]] = getelementptr inbounds [[S2]], [[S2]]* [[LOCAL_THIS1]], i[[SZ]] 0 +// OMP45: [[ARR_IDX2:%.+]] = getelementptr inbounds [[S2]], [[S2]]* [[LOCAL_THIS1]], i[[SZ]] 0 + +// OMP45-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BP]], i32 0, i32 0 +// OMP45-DAG: [[PADDR0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[P]], i32 0, i32 0 +// OMP45-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to [[S2]]** +// OMP45-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to [[S2]]** +// OMP45-DAG: store [[S2]]* [[ARR_IDX]], [[S2]]** [[CBPADDR0]] +// OMP45-DAG: store [[S2]]* [[ARR_IDX2]], [[S2]]** [[CPADDR0]] + +// OMP45: [[BPR:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BP]], i32 0, i32 0 +// OMP45: [[PR:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[P]], i32 0, i32 0 +// OMP45: [[RET:%.+]] = call i32 @__tgt_target(i64 -1, i8* @{{[^,]+}}, i32 1, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i64* getelementptr inbounds ([1 x i64], [1 x i64]* [[SIZET9]], i32 0, i32 0), i64* getelementptr inbounds ([1 x i64], [1 x i64]* [[MAPT10]], i32 0, i32 0)) +// OMP45-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0 +// OMP45-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]] +// OMP45: [[FAIL]] +// OMP45: call void [[HVT0:@.+]]([[S2]]* [[LOCAL_THIS1]]) +// OMP45-NEXT: br label %[[END]] +// OMP45: [[END]] // Check that the offloading functions are emitted and that the arguments are // correct and loaded correctly for the target regions of the callees of bar(). @@ -784,6 +800,33 @@ int bar(int n){ // CHECK-DAG: load i16, i16* [[REF_AA]] // CHECK-DAG: getelementptr inbounds [10 x i32], [10 x i32]* [[REF_B]], i[[SZ]] 0, i[[SZ]] 2 + +// OMP50: define {{.*}}@{{.*}}zee{{.*}} + +// OMP50: [[LOCAL_THIS:%.+]] = alloca [[S2]]* +// OMP50: [[BP:%.+]] = alloca [1 x i8*] +// OMP50: [[P:%.+]] = alloca [1 x i8*] +// OMP50: [[LOCAL_THIS1:%.+]] = load [[S2]]*, [[S2]]** [[LOCAL_THIS]] +// OMP50: [[ARR_IDX:%.+]] = getelementptr inbounds [[S2]], [[S2]]* [[LOCAL_THIS1]], i[[SZ]] 0 +// OMP50: [[ARR_IDX2:%.+]] = getelementptr inbounds [[S2]], [[S2]]* [[LOCAL_THIS1]], i[[SZ]] 0 + +// OMP50-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BP]], i32 0, i32 0 +// OMP50-DAG: [[PADDR0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[P]], i32 0, i32 0 +// OMP50-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to [[S2]]** +// OMP50-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to [[S2]]** +// OMP50-DAG: store [[S2]]* [[ARR_IDX]], [[S2]]** [[CBPADDR0]] +// OMP50-DAG: store [[S2]]* [[ARR_IDX2]], [[S2]]** [[CPADDR0]] + +// OMP50: [[BPR:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BP]], i32 0, i32 0 +// OMP50: [[PR:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[P]], i32 0, i32 0 +// OMP50: [[RET:%.+]] = call i32 @__tgt_target(i64 -1, i8* @{{[^,]+}}, i32 1, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i64* getelementptr inbounds ([1 x i64], [1 x i64]* [[SIZET9]], i32 0, i32 0), i64* getelementptr inbounds ([1 x i64], [1 x i64]* [[MAPT10]], i32 0, i32 0)) +// OMP50-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0 +// OMP50-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]] +// OMP50: [[FAIL]] +// OMP50: call void [[HVT0:@.+]]([[S2]]* [[LOCAL_THIS1]]) +// OMP50-NEXT: br label %[[END]] +// OMP50: [[END]] + void bar () { #define pragma_target _Pragma("omp target") pragma_target diff --git a/clang/test/OpenMP/target_data_messages.c b/clang/test/OpenMP/target_data_messages.c index 7a7fc0012af2b..bc164c3f1796d 100644 --- a/clang/test/OpenMP/target_data_messages.c +++ b/clang/test/OpenMP/target_data_messages.c @@ -45,5 +45,12 @@ int main(int argc, char **argv) { { foo(); } + + const int b = 5; + int marr[10][10], iarr[5]; +#pragma omp target data map(to: marr[10][0:2:2]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + {} +#pragma omp target data map(alloc: iarr[:2:b]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + {} return 0; } diff --git a/clang/test/OpenMP/target_defaultmap_codegen.cpp b/clang/test/OpenMP/target_defaultmap_codegen.cpp index 140574c18c746..3deff63273d53 100644 --- a/clang/test/OpenMP/target_defaultmap_codegen.cpp +++ b/clang/test/OpenMP/target_defaultmap_codegen.cpp @@ -20,7 +20,7 @@ // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck -allow-deprecated-dag-overlap --check-prefix SIMD-ONLY10 %s // SIMD-ONLY10-NOT: {{__kmpc|__tgt}} -// CK1-LABEL: @.__omp_offloading_{{.*}}implicit_maps_double_complex{{.*}}_l44.region_id = weak constant i8 0 +// CK1-LABEL: @.__omp_offloading_{{.*}}implicit_maps_double_complex{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK1-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] [i64 16] // Map types: OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 544 @@ -70,7 +70,7 @@ void implicit_maps_double_complex (int a){ // SIMD-ONLY10-NOT: {{__kmpc|__tgt}} #ifdef CK2 -// CK2-LABEL: @.__omp_offloading_{{.*}}implicit_maps_double_complex{{.*}}_l94.region_id = weak constant i8 0 +// CK2-LABEL: @.__omp_offloading_{{.*}}implicit_maps_double_complex{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK2-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] [i64 16] // Map types: OMP_MAP_TO | OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 545 @@ -120,7 +120,7 @@ void implicit_maps_double_complex (int a){ // SIMD-ONLY10-NOT: {{__kmpc|__tgt}} #ifdef CK3 -// CK3-LABEL: @.__omp_offloading_{{.*}}implicit_maps_double_complex{{.*}}_l144.region_id = weak constant i8 0 +// CK3-LABEL: @.__omp_offloading_{{.*}}implicit_maps_double_complex{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK3-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] [i64 16] // Map types: OMP_MAP_FROM | OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 546 @@ -173,7 +173,7 @@ void implicit_maps_double_complex (int a){ // For a 32-bit targets, the value doesn't fit the size of the pointer, // therefore it is passed by reference with a map 'to' specification. -// CK4-LABEL: @.__omp_offloading_{{.*}}implicit_maps_double{{.*}}_l209.region_id = weak constant i8 0 +// CK4-LABEL: @.__omp_offloading_{{.*}}implicit_maps_double{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK4-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] [i64 8] // Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 800 @@ -242,7 +242,7 @@ void implicit_maps_double (int a){ // SIMD-ONLY8-NOT: {{__kmpc|__tgt}} #ifdef CK5 -// CK5-LABEL: @.__omp_offloading_{{.*}}implicit_maps_array{{.*}}_l266.region_id = weak constant i8 0 +// CK5-LABEL: @.__omp_offloading_{{.*}}implicit_maps_array{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK5-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] [i64 16] // Map types: OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 544 @@ -293,7 +293,7 @@ void implicit_maps_array (int a){ // SIMD-ONLY8-NOT: {{__kmpc|__tgt}} #ifdef CK6 -// CK6-LABEL: @.__omp_offloading_{{.*}}implicit_maps_array{{.*}}_l317.region_id = weak constant i8 0 +// CK6-LABEL: @.__omp_offloading_{{.*}}implicit_maps_array{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK6-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] [i64 16] // Map types: OMP_MAP_TO | OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 545 @@ -344,7 +344,7 @@ void implicit_maps_array (int a){ // SIMD-ONLY8-NOT: {{__kmpc|__tgt}} #ifdef CK7 -// CK7-LABEL: @.__omp_offloading_{{.*}}implicit_maps_array{{.*}}_l368.region_id = weak constant i8 0 +// CK7-LABEL: @.__omp_offloading_{{.*}}implicit_maps_array{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK7-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] [i64 16] // Map types: OMP_MAP_FROM | OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 546 @@ -395,7 +395,7 @@ void implicit_maps_array (int a){ // SIMD-ONLY8-NOT: {{__kmpc|__tgt}} #ifdef CK8 -// CK8-LABEL: @.__omp_offloading_{{.*}}implicit_maps_array{{.*}}_l419.region_id = weak constant i8 0 +// CK8-LABEL: @.__omp_offloading_{{.*}}implicit_maps_array{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK8-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] [i64 16] // Map types: OMP_MAP_TO | OMP_MAP_FROM | OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 547 @@ -498,7 +498,7 @@ void zero_size_section_and_private_maps (int ii){ #ifdef CK10 -// CK10-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l523.region_id = weak constant i8 0 +// CK10-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK10: [[SIZE:@.+]] = private {{.*}}constant [1 x i64] [i64 {{8|4}}] // Map types: OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 544 @@ -546,7 +546,7 @@ void explicit_maps_single (){ #ifdef CK11 -// CK11-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l571.region_id = weak constant i8 0 +// CK11-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK11: [[SIZE09:@.+]] = private {{.*}}constant [1 x i64] [i64 {{8|4}}] // Map types: OMP_MAP_TO | OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 545 @@ -594,7 +594,7 @@ void explicit_maps_single (){ #ifdef CK12 -// CK12-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l619.region_id = weak constant i8 0 +// CK12-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK12: [[SIZE09:@.+]] = private {{.*}}constant [1 x i64] [i64 {{8|4}}] // Map types: OMP_MAP_FROM | OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 546 @@ -642,7 +642,7 @@ void explicit_maps_single (){ #ifdef CK13 -// CK13-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l667.region_id = weak constant i8 0 +// CK13-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK13: [[SIZE09:@.+]] = private {{.*}}constant [1 x i64] [i64 {{8|4}}] // Map types: OMP_MAP_TO | OMP_MAP_FROM | OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 547 @@ -690,7 +690,7 @@ void explicit_maps_single (){ #ifdef CK14 -// CK14-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l715.region_id = weak constant i8 0 +// CK14-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK14: [[SIZE09:@.+]] = private {{.*}}constant [1 x i64] zeroinitializer // Map types: OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 544 @@ -737,7 +737,7 @@ void explicit_maps_single (){ // SIMD-ONLY12-NOT: {{__kmpc|__tgt}} #ifdef CK15 -// CK15-LABEL: @.__omp_offloading_{{.*}}implicit_maps_variable_length_array{{.*}}_l787.region_id = weak constant i8 0 +// CK15-LABEL: @.__omp_offloading_{{.*}}implicit_maps_variable_length_array{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // We don't have a constant map size for VLAs. // Map types: @@ -820,7 +820,7 @@ void implicit_maps_variable_length_array (int a){ #ifdef CK16 // CK16-DAG: [[ST:%.+]] = type { i32, double } -// CK16-LABEL: @.__omp_offloading_{{.*}}implicit_maps_struct{{.*}}_l849.region_id = weak constant i8 0 +// CK16-LABEL: @.__omp_offloading_{{.*}}implicit_maps_struct{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK16-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] [i64 {{16|12}}] // Map types: OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 544 // CK16-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 544] @@ -877,7 +877,7 @@ void implicit_maps_struct (int a){ #ifdef CK17 // CK17-DAG: [[ST:%.+]] = type { i32, double } -// CK17-LABEL: @.__omp_offloading_{{.*}}implicit_maps_struct{{.*}}_l906.region_id = weak constant i8 0 +// CK17-LABEL: @.__omp_offloading_{{.*}}implicit_maps_struct{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK17-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] [i64 {{16|12}}] // Map types: OMP_MAP_TO | OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 545 // CK17-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 545] @@ -934,7 +934,7 @@ void implicit_maps_struct (int a){ #ifdef CK18 // CK18-DAG: [[ST:%.+]] = type { i32, double } -// CK18-LABEL: @.__omp_offloading_{{.*}}implicit_maps_struct{{.*}}_l963.region_id = weak constant i8 0 +// CK18-LABEL: @.__omp_offloading_{{.*}}implicit_maps_struct{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK18-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] [i64 {{16|12}}] // Map types: OMP_MAP_FROM | OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 546 // CK18-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 546] @@ -991,7 +991,7 @@ void implicit_maps_struct (int a){ #ifdef CK19 // CK19-DAG: [[ST:%.+]] = type { i32, double } -// CK19-LABEL: @.__omp_offloading_{{.*}}implicit_maps_struct{{.*}}_l1020.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}implicit_maps_struct{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] [i64 {{16|12}}] // Map types: OMP_MAP_TO | OMP_MAP_FROM | OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 547 // CK19-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 547] @@ -1050,7 +1050,7 @@ void implicit_maps_struct (int a){ // For a 32-bit targets, the value doesn't fit the size of the pointer, // therefore it is passed by reference with a map 'to' specification. -// CK20-LABEL: @.__omp_offloading_{{.*}}implicit_maps_double{{.*}}_l1086.region_id = weak constant i8 0 +// CK20-LABEL: @.__omp_offloading_{{.*}}implicit_maps_double{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK20-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] [i64 8] // Map types: OMP_MAP_LITERAL | OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 800 @@ -1120,7 +1120,7 @@ void implicit_maps_double (int a){ #ifdef CK21 // CK21-DAG: [[ST:%.+]] = type { i32, double } -// CK21-LABEL: @.__omp_offloading_{{.*}}implicit_maps_struct{{.*}}_l1149.region_id = weak constant i8 0 +// CK21-LABEL: @.__omp_offloading_{{.*}}implicit_maps_struct{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK21-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] [i64 {{16|12}}] // Map types: OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 547 // CK21-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 547] @@ -1176,7 +1176,7 @@ void implicit_maps_struct (int a){ // SIMD-ONLY9-NOT: {{__kmpc|__tgt}} #ifdef CK22 -// CK22-LABEL: @.__omp_offloading_{{.*}}implicit_maps_pointer{{.*}}_l1200.region_id = weak constant i8 0 +// CK22-LABEL: @.__omp_offloading_{{.*}}implicit_maps_pointer{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK22-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] zeroinitializer // Map types: OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 544 @@ -1413,11 +1413,11 @@ void bar(float *&a, int *&b) { // SIMD-ONLY18-NOT: {{__kmpc|__tgt}} #ifdef CK24 -// CK24-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l1443.region_id = weak constant i8 0 +// CK24-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK24: [[SIZE00:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4] // CK24: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i64] [i64 1059] -// CK24-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l1462.region_id = weak constant i8 0 +// CK24-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK24: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4] // CK24: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i64] [i64 1063] @@ -1488,7 +1488,7 @@ void explicit_maps_single (int ii){ extern int x; #pragma omp declare target to(x) -// CK25-LABEL: @.__omp_offloading_{{.*}}declare_target_to{{.*}}_l1499.region_id = weak constant i8 0 +// CK25-LABEL: @.__omp_offloading_{{.*}}declare_target_to{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 void declare_target_to() { diff --git a/clang/test/OpenMP/target_depend_messages.cpp b/clang/test/OpenMP/target_depend_messages.cpp index 3ff6e6860ff83..9e5f28c04f9e4 100644 --- a/clang/test/OpenMP/target_depend_messages.cpp +++ b/clang/test/OpenMP/target_depend_messages.cpp @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp-simd -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized void xxx(int argc) { int x; // expected-note {{initialize the variable 'x' to silence this warning}} @@ -30,27 +32,27 @@ int main(int argc, char **argv, char *env[]) { #pragma omp target depend // expected-error {{expected '(' after 'depend'}} foo(); - #pragma omp target depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target depend( // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); - #pragma omp target depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target depend() // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); - #pragma omp target depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target depend(argc // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); - #pragma omp target depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp target depend(source : argc) // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); - #pragma omp target depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp target depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); #pragma omp target depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target' are ignored}} foo(); #pragma omp target depend (out: ) // expected-error {{expected expression}} foo(); - #pragma omp target depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} +#pragma omp target depend(inout : foobool(argc)), depend(in, argc) // omp4-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} foo(); #pragma omp target depend (out :S1) // expected-error {{'S1' does not refer to a value}} foo(); #pragma omp target depend(in : argv[1][1] = '2') foo(); - #pragma omp target depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}} +#pragma omp target depend(in : vec[1]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} foo(); #pragma omp target depend (in : argv[0]) foo(); @@ -58,7 +60,7 @@ int main(int argc, char **argv, char *env[]) { foo(); #pragma omp target depend (in : main) foo(); - #pragma omp target depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}} +#pragma omp target depend(in : a[0]) // omp4-error{{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} foo(); #pragma omp target depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}} foo(); @@ -78,7 +80,7 @@ int main(int argc, char **argv, char *env[]) { foo(); #pragma omp target depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} foo(); - #pragma omp target depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + #pragma omp target depend(in : argv [3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} foo(); #pragma omp target depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} foo(); diff --git a/clang/test/OpenMP/target_enter_data_depend_messages.cpp b/clang/test/OpenMP/target_enter_data_depend_messages.cpp index 8a4d96f60a23f..4b28067b8eb33 100644 --- a/clang/test/OpenMP/target_enter_data_depend_messages.cpp +++ b/clang/test/OpenMP/target_enter_data_depend_messages.cpp @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp-simd -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized void foo() { } @@ -26,27 +28,27 @@ int tmain(T argc, S **argv, R *env[]) { int i; #pragma omp target enter data map(to: i) depend // expected-error {{expected '(' after 'depend'}} foo(); - #pragma omp target enter data map(to: i) depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target enter data map(to : i) depend( // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); - #pragma omp target enter data map(to: i) depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target enter data map(to : i) depend() // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); - #pragma omp target enter data map(to: i) depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target enter data map(to : i) depend(argc // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); - #pragma omp target enter data map(to: i) depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp target enter data map(to : i) depend(source : argc) // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); - #pragma omp target enter data map(to: i) depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp target enter data map(to : i) depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); #pragma omp target enter data map(to: i) depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}} foo(); - #pragma omp target enter data map(to: i) depend (out: ) // expected-error {{expected expression}} +#pragma omp target enter data map(to : i) depend(out:) // expected-error {{expected expression}} foo(); - #pragma omp target enter data map(to: i) depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} +#pragma omp target enter data map(to : i) depend(inout : foobool(argc)), depend(in, argc) // omp4-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} foo(); #pragma omp target enter data map(to: i) depend (out :S1) // expected-error {{'S1' does not refer to a value}} foo(); - #pragma omp target enter data map(to: i) depend(in : argv[1][1] = '2') // expected-error {{expected addressable lvalue expression, array element or array section}} +#pragma omp target enter data map(to : i) depend(in : argv[1][1] = '2') // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} foo(); - #pragma omp target enter data map(to: i) depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}} +#pragma omp target enter data map(to : i) depend(in : vec[1]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} foo(); #pragma omp target enter data map(to: i) depend (in : argv[0]) foo(); @@ -54,7 +56,7 @@ int tmain(T argc, S **argv, R *env[]) { foo(); #pragma omp target enter data map(to: i) depend (in : tmain) foo(); - #pragma omp target enter data map(to: i) depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}} +#pragma omp target enter data map(to : i) depend(in : a[0]) // omp4-error{{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} foo(); #pragma omp target enter data map(to: i) depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}} foo(); @@ -70,11 +72,11 @@ int tmain(T argc, S **argv, R *env[]) { foo(); #pragma omp target enter data map(to: i) depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} foo(); - #pragma omp target enter data map(to: i) depend (in : argv[-1:0]) // expected-error {{zero-length array section is not allowed in 'depend' clause}} +#pragma omp target enter data map(to : i) depend(in : argv [-1:0]) // expected-error {{zero-length array section is not allowed in 'depend' clause}} foo(); #pragma omp target enter data map(to: i) depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} foo(); - #pragma omp target enter data map(to: i) depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} +#pragma omp target enter data map(to : i) depend(in : argv [3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} foo(); #pragma omp target enter data map(to: i) depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} foo(); @@ -86,7 +88,7 @@ int tmain(T argc, S **argv, R *env[]) { foo(); #pragma omp target enter data map(to: i) depend(in : argv[ : argc][1 : argc - 1]) foo(); - #pragma omp target enter data map(to: i) depend(in : arr[0]) +#pragma omp target enter data map(to : i) depend(in : arr[0]) foo(); return 0; @@ -101,27 +103,27 @@ int main(int argc, char **argv, char *env[]) { int i; #pragma omp target enter data map(to: i) depend // expected-error {{expected '(' after 'depend'}} foo(); - #pragma omp target enter data map(to: i) depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target enter data map(to : i) depend( // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); - #pragma omp target enter data map(to: i) depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target enter data map(to : i) depend() // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); - #pragma omp target enter data map(to: i) depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target enter data map(to : i) depend(argc // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); - #pragma omp target enter data map(to: i) depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp target enter data map(to : i) depend(source : argc) // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); - #pragma omp target enter data map(to: i) depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp target enter data map(to : i) depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); #pragma omp target enter data map(to: i) depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target enter data' are ignored}} foo(); #pragma omp target enter data map(to: i) depend (out: ) // expected-error {{expected expression}} foo(); - #pragma omp target enter data map(to: i) depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} +#pragma omp target enter data map(to : i) depend(inout : foobool(argc)), depend(in, argc) // omp4-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} foo(); #pragma omp target enter data map(to: i) depend (out :S1) // expected-error {{'S1' does not refer to a value}} foo(); #pragma omp target enter data map(to: i) depend(in : argv[1][1] = '2') foo(); - #pragma omp target enter data map(to: i) depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}} +#pragma omp target enter data map(to : i) depend(in : vec[1]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} foo(); #pragma omp target enter data map(to: i) depend (in : argv[0]) foo(); @@ -129,7 +131,7 @@ int main(int argc, char **argv, char *env[]) { foo(); #pragma omp target enter data map(to: i) depend (in : main) foo(); - #pragma omp target enter data map(to: i) depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}} +#pragma omp target enter data map(to : i) depend(in : a[0]) // omp4-error{{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} foo(); #pragma omp target enter data map(to: i) depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}} foo(); @@ -147,9 +149,9 @@ int main(int argc, char **argv, char *env[]) { foo(); #pragma omp target enter data map(to: i) depend (in : argv[-1:0]) // expected-error {{zero-length array section is not allowed in 'depend' clause}} foo(); - #pragma omp target enter data map(to: i) depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + #pragma omp target enter data map(to: i) depend(in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} foo(); - #pragma omp target enter data map(to: i) depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + #pragma omp target enter data map(to : i) depend(in : argv [3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} foo(); #pragma omp target enter data map(to: i) depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} foo(); diff --git a/clang/test/OpenMP/target_exit_data_depend_messages.cpp b/clang/test/OpenMP/target_exit_data_depend_messages.cpp index ae26139d239fc..a1bcdb0f92065 100644 --- a/clang/test/OpenMP/target_exit_data_depend_messages.cpp +++ b/clang/test/OpenMP/target_exit_data_depend_messages.cpp @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp-simd -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized void foo() { } @@ -26,27 +28,27 @@ int tmain(T argc, S **argv, R *env[]) { int i; #pragma omp target exit data map(from: i) depend // expected-error {{expected '(' after 'depend'}} foo(); - #pragma omp target exit data map(from: i) depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target exit data map(from : i) depend( // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); - #pragma omp target exit data map(from: i) depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target exit data map(from : i) depend() // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); - #pragma omp target exit data map(from: i) depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target exit data map(from : i) depend(argc // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); - #pragma omp target exit data map(from: i) depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp target exit data map(from : i) depend(source : argc) // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); - #pragma omp target exit data map(from: i) depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp target exit data map(from : i) depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); #pragma omp target exit data map(from: i) depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target exit data' are ignored}} foo(); - #pragma omp target exit data map(from: i) depend (out: ) // expected-error {{expected expression}} +#pragma omp target exit data map(from : i) depend(out:) // expected-error {{expected expression}} foo(); - #pragma omp target exit data map(from: i) depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} +#pragma omp target exit data map(from : foobool(argc)), depend(in, argc) // omp4-error {{expected expression containing only member accesses and/or array sections based on named variables}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} omp5-error {{expected addressable lvalue in 'map' clause}} foo(); #pragma omp target exit data map(from: i) depend (out :S1) // expected-error {{'S1' does not refer to a value}} foo(); - #pragma omp target exit data map(from: i) depend(in : argv[1][1] = '2') // expected-error {{expected addressable lvalue expression, array element or array section}} +#pragma omp target exit data map(from : i) depend(in : argv[1][1] = '2') // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} foo(); - #pragma omp target exit data map(from: i) depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}} +#pragma omp target exit data map(from : i) depend(in : vec[1]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} foo(); #pragma omp target exit data map(from: i) depend (in : argv[0]) foo(); @@ -54,7 +56,7 @@ int tmain(T argc, S **argv, R *env[]) { foo(); #pragma omp target exit data map(from: i) depend (in : tmain) foo(); - #pragma omp target exit data map(from: i) depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}} +#pragma omp target exit data map(from : i) depend(in : a[0]) // omp4-error{{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} foo(); #pragma omp target exit data map(from: i) depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}} foo(); @@ -70,11 +72,11 @@ int tmain(T argc, S **argv, R *env[]) { foo(); #pragma omp target exit data map(from: i) depend (in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} foo(); - #pragma omp target exit data map(from: i) depend (in : argv[-1:0]) // expected-error {{zero-length array section is not allowed in 'depend' clause}} +#pragma omp target exit data map(from : i) depend(in : argv [-1:0]) // expected-error {{zero-length array section is not allowed in 'depend' clause}} foo(); #pragma omp target exit data map(from: i) depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} foo(); - #pragma omp target exit data map(from: i) depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + #pragma omp target exit data map(from : i) depend(in : argv [3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} foo(); #pragma omp target exit data map(from: i) depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} foo(); @@ -86,7 +88,7 @@ int tmain(T argc, S **argv, R *env[]) { foo(); #pragma omp target exit data map(from: i) depend(in : argv[ : argc][1 : argc - 1]) foo(); - #pragma omp target exit data map(from: i) depend(in : arr[0]) +#pragma omp target exit data map(from : i) depend(in : arr[0]) foo(); return 0; @@ -101,27 +103,27 @@ int main(int argc, char **argv, char *env[]) { int i; #pragma omp target exit data map(from: i) depend // expected-error {{expected '(' after 'depend'}} foo(); - #pragma omp target exit data map(from: i) depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target exit data map(from : i) depend( // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); - #pragma omp target exit data map(from: i) depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target exit data map(from : i) depend() // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); - #pragma omp target exit data map(from: i) depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target exit data map(from : i) depend(argc // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); - #pragma omp target exit data map(from: i) depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp target exit data map(from : i) depend(source : argc) // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); - #pragma omp target exit data map(from: i) depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp target exit data map(from : i) depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); #pragma omp target exit data map(from: i) depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target exit data' are ignored}} foo(); #pragma omp target exit data map(from: i) depend (out: ) // expected-error {{expected expression}} foo(); - #pragma omp target exit data map(from: i) depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} +#pragma omp target exit data map(from : i) depend(inout : foobool(argc)), depend(in, argc) // omp4-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} foo(); #pragma omp target exit data map(from: i) depend (out :S1) // expected-error {{'S1' does not refer to a value}} foo(); #pragma omp target exit data map(from: i) depend(in : argv[1][1] = '2') foo(); - #pragma omp target exit data map(from: i) depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}} +#pragma omp target exit data map(from : i) depend(in : vec[1]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} foo(); #pragma omp target exit data map(from: i) depend (in : argv[0]) foo(); @@ -129,7 +131,7 @@ int main(int argc, char **argv, char *env[]) { foo(); #pragma omp target exit data map(from: i) depend (in : main) foo(); - #pragma omp target exit data map(from: i) depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}} +#pragma omp target exit data map(from : i) depend(in : a[0]) // omp4-error{{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} foo(); #pragma omp target exit data map(from: i) depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}} foo(); @@ -149,7 +151,7 @@ int main(int argc, char **argv, char *env[]) { foo(); #pragma omp target exit data map(from: i) depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} foo(); - #pragma omp target exit data map(from: i) depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + #pragma omp target exit data map(from : i) depend(in : argv [3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} foo(); #pragma omp target exit data map(from: i) depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} foo(); diff --git a/clang/test/OpenMP/target_map_codegen.cpp b/clang/test/OpenMP/target_map_codegen.cpp index ecfe50c01ea6d..92e0224a2de3b 100644 --- a/clang/test/OpenMP/target_map_codegen.cpp +++ b/clang/test/OpenMP/target_map_codegen.cpp @@ -39,7 +39,7 @@ class B { }; double B::VAR = 1.0; -// CK1-LABEL: @.__omp_offloading_{{.*}}implicit_maps_integer{{.*}}_l68.region_id = weak constant i8 0 +// CK1-LABEL: @.__omp_offloading_{{.*}}implicit_maps_integer{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK1-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] [i64 4] // Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 800 @@ -98,12 +98,12 @@ void implicit_maps_integer (int a){ // SIMD-ONLY1-NOT: {{__kmpc|__tgt}} #ifdef CK2 -// CK2-LABEL: @.__omp_offloading_{{.*}}implicit_maps_reference{{.*}}_l128.region_id = weak constant i8 0 +// CK2-LABEL: @.__omp_offloading_{{.*}}implicit_maps_reference{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK2: [[SIZES:@.+]] = {{.+}}constant [1 x i64] [i64 4] // Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 800 // CK2: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 800] -// CK2-LABEL: @.__omp_offloading_{{.*}}implicit_maps_reference{{.*}}_l147.region_id = weak constant i8 0 +// CK2-LABEL: @.__omp_offloading_{{.*}}implicit_maps_reference{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK2: [[SIZES2:@.+]] = {{.+}}constant [1 x i64] zeroinitializer // Map types: OMP_MAP_IS_PTR | OMP_MAP_IMPLICIT = 544 // CK2: [[TYPES2:@.+]] = {{.+}}constant [1 x i64] [i64 544] @@ -188,7 +188,7 @@ void implicit_maps_reference (int a, int *b){ // SIMD-ONLY2-NOT: {{__kmpc|__tgt}} #ifdef CK3 -// CK3-LABEL: @.__omp_offloading_{{.*}}implicit_maps_parameter{{.*}}_l214.region_id = weak constant i8 0 +// CK3-LABEL: @.__omp_offloading_{{.*}}implicit_maps_parameter{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK3-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] [i64 4] // Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 800 @@ -242,7 +242,7 @@ void implicit_maps_parameter (int a){ // SIMD-ONLY3-NOT: {{__kmpc|__tgt}} #ifdef CK4 -// CK4-LABEL: @.__omp_offloading_{{.*}}implicit_maps_nested_integer{{.*}}_l276.region_id = weak constant i8 0 +// CK4-LABEL: @.__omp_offloading_{{.*}}implicit_maps_nested_integer{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK4-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] [i64 4] // Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 800 @@ -308,7 +308,7 @@ void implicit_maps_nested_integer (int a){ // SIMD-ONLY4-NOT: {{__kmpc|__tgt}} #ifdef CK5 -// CK5-LABEL: @.__omp_offloading_{{.*}}implicit_maps_nested_integer_and_enum{{.*}}_l340.region_id = weak constant i8 0 +// CK5-LABEL: @.__omp_offloading_{{.*}}implicit_maps_nested_integer_and_enum{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK5-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] [i64 4] // Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 800 @@ -353,12 +353,12 @@ void implicit_maps_nested_integer_and_enum (int a){ #endif ///==========================================================================/// -// RUN: %clang_cc1 -DCK6 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck -allow-deprecated-dag-overlap %s --check-prefix CK6 --check-prefix CK6-64 -// RUN: %clang_cc1 -DCK6 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck -allow-deprecated-dag-overlap %s --check-prefix CK6 --check-prefix CK6-64 -// RUN: %clang_cc1 -DCK6 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -allow-deprecated-dag-overlap %s --check-prefix CK6 --check-prefix CK6-32 -// RUN: %clang_cc1 -DCK6 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck -allow-deprecated-dag-overlap %s --check-prefix CK6 --check-prefix CK6-32 +// RUN: %clang_cc1 -DCK6 -verify -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck -allow-deprecated-dag-overlap %s --check-prefix CK6 --check-prefix CK6-64 +// RUN: %clang_cc1 -DCK6 -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck -allow-deprecated-dag-overlap %s --check-prefix CK6 --check-prefix CK6-64 +// RUN: %clang_cc1 -DCK6 -verify -fopenmp -fopenmp-version=45 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -allow-deprecated-dag-overlap %s --check-prefix CK6 --check-prefix CK6-32 +// RUN: %clang_cc1 -DCK6 -fopenmp -fopenmp-version=45 -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck -allow-deprecated-dag-overlap %s --check-prefix CK6 --check-prefix CK6-32 // RUN: %clang_cc1 -DCK6 -verify -fopenmp-simd -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck -allow-deprecated-dag-overlap --check-prefix SIMD-ONLY5 %s // RUN: %clang_cc1 -DCK6 -fopenmp-simd -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s @@ -368,7 +368,7 @@ void implicit_maps_nested_integer_and_enum (int a){ // RUN: %clang_cc1 -fopenmp-simd -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck -allow-deprecated-dag-overlap --check-prefix SIMD-ONLY5 %s // SIMD-ONLY5-NOT: {{__kmpc|__tgt}} #ifdef CK6 -// CK6-LABEL: @.__omp_offloading_{{.*}}implicit_maps_host_global{{.*}}_l397.region_id = weak constant i8 0 +// CK6-LABEL: @.__omp_offloading_{{.*}}implicit_maps_host_global{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK6-DAG: [[GBL:@Gi]] = global i32 0 // CK6-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] [i64 4] @@ -428,7 +428,7 @@ void implicit_maps_host_global (int a){ // For a 32-bit targets, the value doesn't fit the size of the pointer, // therefore it is passed by reference with a map 'to' specification. -// CK7-LABEL: @.__omp_offloading_{{.*}}implicit_maps_double{{.*}}_l464.region_id = weak constant i8 0 +// CK7-LABEL: @.__omp_offloading_{{.*}}implicit_maps_double{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK7-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] [i64 8] // Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 800 @@ -497,7 +497,7 @@ void implicit_maps_double (int a){ // SIMD-ONLY7-NOT: {{__kmpc|__tgt}} #ifdef CK8 -// CK8-LABEL: @.__omp_offloading_{{.*}}implicit_maps_float{{.*}}_l524.region_id = weak constant i8 0 +// CK8-LABEL: @.__omp_offloading_{{.*}}implicit_maps_float{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK8-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] [i64 4] // Map types: OMP_MAP_PRIVATE_VAL | OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 800 @@ -551,7 +551,7 @@ void implicit_maps_float (int a){ // SIMD-ONLY8-NOT: {{__kmpc|__tgt}} #ifdef CK9 -// CK9-LABEL: @.__omp_offloading_{{.*}}implicit_maps_array{{.*}}_l575.region_id = weak constant i8 0 +// CK9-LABEL: @.__omp_offloading_{{.*}}implicit_maps_array{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK9-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] [i64 16] // Map types: OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 547 @@ -602,7 +602,7 @@ void implicit_maps_array (int a){ // SIMD-ONLY9-NOT: {{__kmpc|__tgt}} #ifdef CK10 -// CK10-LABEL: @.__omp_offloading_{{.*}}implicit_maps_pointer{{.*}}_l626.region_id = weak constant i8 0 +// CK10-LABEL: @.__omp_offloading_{{.*}}implicit_maps_pointer{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK10-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] zeroinitializer // Map types: OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 544 @@ -638,12 +638,12 @@ void implicit_maps_pointer (){ #endif ///==========================================================================/// -// RUN: %clang_cc1 -DCK11 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck -allow-deprecated-dag-overlap %s --check-prefix CK11 -// RUN: %clang_cc1 -DCK11 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck -allow-deprecated-dag-overlap %s --check-prefix CK11 -// RUN: %clang_cc1 -DCK11 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -allow-deprecated-dag-overlap %s --check-prefix CK11 -// RUN: %clang_cc1 -DCK11 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck -allow-deprecated-dag-overlap %s --check-prefix CK11 +// RUN: %clang_cc1 -DCK11 -verify -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck -allow-deprecated-dag-overlap %s --check-prefix CK11 +// RUN: %clang_cc1 -DCK11 -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck -allow-deprecated-dag-overlap %s --check-prefix CK11 +// RUN: %clang_cc1 -DCK11 -verify -fopenmp -fopenmp-version=45 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -allow-deprecated-dag-overlap %s --check-prefix CK11 +// RUN: %clang_cc1 -DCK11 -fopenmp -fopenmp-version=45 -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck -allow-deprecated-dag-overlap %s --check-prefix CK11 // RUN: %clang_cc1 -DCK11 -verify -fopenmp-simd -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck -allow-deprecated-dag-overlap --check-prefix SIMD-ONLY10 %s // RUN: %clang_cc1 -DCK11 -fopenmp-simd -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s @@ -654,7 +654,7 @@ void implicit_maps_pointer (){ // SIMD-ONLY10-NOT: {{__kmpc|__tgt}} #ifdef CK11 -// CK11-LABEL: @.__omp_offloading_{{.*}}implicit_maps_double_complex{{.*}}_l678.region_id = weak constant i8 0 +// CK11-LABEL: @.__omp_offloading_{{.*}}implicit_maps_double_complex{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK11-DAG: [[SIZES:@.+]] = {{.+}}constant [2 x i64] [i64 16, i64 {{8|4}}] // Map types: OMP_MAP_TO | OMP_MAP_FROM | OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 547 @@ -707,7 +707,7 @@ void implicit_maps_double_complex (int a, int *b){ // For a 32-bit targets, the value doesn't fit the size of the pointer, // therefore it is passed by reference with a map 'to' specification. -// CK12-LABEL: @.__omp_offloading_{{.*}}implicit_maps_float_complex{{.*}}_l743.region_id = weak constant i8 0 +// CK12-LABEL: @.__omp_offloading_{{.*}}implicit_maps_float_complex{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK12-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] [i64 8] // Map types: OMP_MAP_PRIVATE_VAL + OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 800 @@ -775,7 +775,7 @@ void implicit_maps_float_complex (int a){ // SIMD-ONLY12-NOT: {{__kmpc|__tgt}} #ifdef CK13 -// CK13-LABEL: @.__omp_offloading_{{.*}}implicit_maps_variable_length_array{{.*}}_l825.region_id = weak constant i8 0 +// CK13-LABEL: @.__omp_offloading_{{.*}}implicit_maps_variable_length_array{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // We don't have a constant map size for VLAs. // Map types: @@ -859,7 +859,7 @@ void implicit_maps_variable_length_array (int a){ // CK14-DAG: [[ST:%.+]] = type { i32, double } -// CK14-LABEL: @.__omp_offloading_{{.*}}foo{{.*}}_l877.region_id = weak constant i8 0 +// CK14-LABEL: @.__omp_offloading_{{.*}}foo{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // Map types: @@ -1207,7 +1207,7 @@ void implicit_maps_templated_function (int a){ #ifdef CK17 // CK17-DAG: [[ST:%.+]] = type { i32, double } -// CK17-LABEL: @.__omp_offloading_{{.*}}implicit_maps_struct{{.*}}_l1236.region_id = weak constant i8 0 +// CK17-LABEL: @.__omp_offloading_{{.*}}implicit_maps_struct{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK17-DAG: [[SIZES:@.+]] = {{.+}}constant [1 x i64] [i64 {{16|12}}] // Map types: OMP_MAP_TO + OMP_MAP_FROM + OMP_MAP_TARGET_PARAM | OMP_MAP_IMPLICIT = 547 // CK17-DAG: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 547] @@ -1323,173 +1323,173 @@ void implicit_maps_template_type_capture (int a){ // SIMD-ONLY18-NOT: {{__kmpc|__tgt}} #ifdef CK19 -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l1514.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE00:@.+]] = private {{.*}}constant [1 x i64] [i64 4] // CK19: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i64] [i64 32] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l1535.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE00n:@.+]] = private {{.*}}constant [1 x i64] [i64 4] // CK19: [[MTYPE00n:@.+]] = private {{.*}}constant [1 x i64] [i64 32] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l1557.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE01:@.+]] = private {{.*}}constant [1 x i64] [i64 400] // CK19: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i64] [i64 33] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l1576.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE02:@.+]] = private {{.*}}constant [1 x i64] [i64 240] // CK19: [[MTYPE02:@.+]] = private {{.*}}constant [1 x i64] [i64 34] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l1595.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE03:@.+]] = private {{.*}}constant [1 x i64] [i64 240] // CK19: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i64] [i64 35] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l1614.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE04:@.+]] = private {{.*}}constant [1 x i64] [i64 400] // CK19: [[MTYPE04:@.+]] = private {{.*}}constant [1 x i64] [i64 32] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l1633.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE05:@.+]] = private {{.*}}constant [1 x i64] [i64 4] // CK19: [[MTYPE05:@.+]] = private {{.*}}constant [1 x i64] [i64 33] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l1656.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[MTYPE06:@.+]] = private {{.*}}constant [1 x i64] [i64 35] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l1679.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[MTYPE07:@.+]] = private {{.*}}constant [1 x i64] [i64 32] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l1698.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE08:@.+]] = private {{.*}}constant [1 x i64] [i64 4] // CK19: [[MTYPE08:@.+]] = private {{.*}}constant [1 x i64] [i64 35] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l1719.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE09:@.+]] = private {{.*}}constant [1 x i64] [i64 {{8|4}}] // CK19: [[MTYPE09:@.+]] = private {{.*}}constant [1 x i64] [i64 34] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l1740.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE10:@.+]] = private {{.*}}constant [1 x i64] [i64 240] // CK19: [[MTYPE10:@.+]] = private {{.*}}constant [1 x i64] [i64 35] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l1761.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE11:@.+]] = private {{.*}}constant [1 x i64] [i64 240] // CK19: [[MTYPE11:@.+]] = private {{.*}}constant [1 x i64] [i64 32] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l1782.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE12:@.+]] = private {{.*}}constant [1 x i64] [i64 4] // CK19: [[MTYPE12:@.+]] = private {{.*}}constant [1 x i64] [i64 33] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l1807.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[MTYPE13:@.+]] = private {{.*}}constant [1 x i64] [i64 32] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l1832.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[MTYPE14:@.+]] = private {{.*}}constant [1 x i64] [i64 33] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l1853.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE15:@.+]] = private {{.*}}constant [1 x i64] [i64 4] // CK19: [[MTYPE15:@.+]] = private {{.*}}constant [1 x i64] [i64 34] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l1887.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[MTYPE16:@.+]] = private {{.*}}constant [2 x i64] [i64 800, i64 33] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l1913.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE17:@.+]] = private {{.*}}constant [2 x i64] [i64 {{8|4}}, i64 240] // CK19: [[MTYPE17:@.+]] = private {{.*}}constant [2 x i64] [i64 800, i64 34] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l1939.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE18:@.+]] = private {{.*}}constant [2 x i64] [i64 {{8|4}}, i64 240] // CK19: [[MTYPE18:@.+]] = private {{.*}}constant [2 x i64] [i64 800, i64 35] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l1971.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[MTYPE19:@.+]] = private {{.*}}constant [2 x i64] [i64 800, i64 32] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l1997.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE20:@.+]] = private {{.*}}constant [2 x i64] [i64 {{8|4}}, i64 4] // CK19: [[MTYPE20:@.+]] = private {{.*}}constant [2 x i64] [i64 800, i64 33] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l2029.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[MTYPE21:@.+]] = private {{.*}}constant [2 x i64] [i64 800, i64 35] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l2055.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE22:@.+]] = private {{.*}}constant [2 x i64] [i64 {{8|4}}, i64 4] // CK19: [[MTYPE22:@.+]] = private {{.*}}constant [2 x i64] [i64 800, i64 35] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l2074.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE23:@.+]] = private {{.*}}constant [1 x i64] [i64 4] // CK19: [[MTYPE23:@.+]] = private {{.*}}constant [1 x i64] [i64 39] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l2096.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE24:@.+]] = private {{.*}}constant [1 x i64] [i64 480] // CK19: [[MTYPE24:@.+]] = private {{.*}}constant [1 x i64] [i64 35] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l2117.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE25:@.+]] = private {{.*}}constant [1 x i64] [i64 16] // CK19: [[MTYPE25:@.+]] = private {{.*}}constant [1 x i64] [i64 35] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l2138.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE26:@.+]] = private {{.*}}constant [1 x i64] [i64 24] // CK19: [[MTYPE26:@.+]] = private {{.*}}constant [1 x i64] [i64 35] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l2159.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE27:@.+]] = private {{.*}}constant [1 x i64] [i64 4] // CK19: [[MTYPE27:@.+]] = private {{.*}}constant [1 x i64] [i64 35] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l2204.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE28:@.+]] = private {{.*}}constant [3 x i64] [i64 {{8|4}}, i64 {{8|4}}, i64 16] // CK19: [[MTYPE28:@.+]] = private {{.*}}constant [3 x i64] [i64 35, i64 16, i64 19] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l2249.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE29:@.+]] = private {{.*}}constant [3 x i64] [i64 {{8|4}}, i64 {{8|4}}, i64 4] // CK19: [[MTYPE29:@.+]] = private {{.*}}constant [3 x i64] [i64 35, i64 16, i64 19] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l2305.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[MTYPE30:@.+]] = private {{.*}}constant [4 x i64] [i64 800, i64 800, i64 800, i64 35] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l2349.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE31:@.+]] = private {{.*}}constant [4 x i64] [i64 {{8|4}}, i64 {{8|4}}, i64 {{8|4}}, i64 40] // CK19: [[MTYPE31:@.+]] = private {{.*}}constant [4 x i64] [i64 800, i64 800, i64 800, i64 35] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l2372.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE32:@.+]] = private {{.*}}constant [1 x i64] [i64 13728] // CK19: [[MTYPE32:@.+]] = private {{.*}}constant [1 x i64] [i64 35] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l2391.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE33:@.+]] = private {{.*}}constant [1 x i64] [i64 13728] // CK19: [[MTYPE33:@.+]] = private {{.*}}constant [1 x i64] [i64 35] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l2410.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE34:@.+]] = private {{.*}}constant [1 x i64] [i64 13728] // CK19: [[MTYPE34:@.+]] = private {{.*}}constant [1 x i64] [i64 35] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l2435.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[MTYPE35:@.+]] = private {{.*}}constant [1 x i64] [i64 35] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l2456.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE36:@.+]] = private {{.*}}constant [1 x i64] [i64 208] // CK19: [[MTYPE36:@.+]] = private {{.*}}constant [1 x i64] [i64 35] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l2496.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[MTYPE37:@.+]] = private {{.*}}constant [3 x i64] [i64 800, i64 800, i64 35] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l2538.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[MTYPE38:@.+]] = private {{.*}}constant [3 x i64] [i64 800, i64 800, i64 35] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l2580.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[MTYPE39:@.+]] = private {{.*}}constant [3 x i64] [i64 800, i64 800, i64 35] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l2622.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[MTYPE40:@.+]] = private {{.*}}constant [3 x i64] [i64 800, i64 800, i64 35] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l2657.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE41:@.+]] = private {{.*}}constant [3 x i64] [i64 {{8|4}}, i64 {{8|4}}, i64 208] // CK19: [[MTYPE41:@.+]] = private {{.*}}constant [3 x i64] [i64 800, i64 800, i64 35] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l2702.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE42:@.+]] = private {{.*}}constant [3 x i64] [i64 {{8|4}}, i64 {{8|4}}, i64 104] // CK19: [[MTYPE42:@.+]] = private {{.*}}constant [3 x i64] [i64 35, i64 16, i64 19] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l2727.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[MTYPE43:@.+]] = private {{.*}}constant [1 x i64] [i64 35] -// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l2746.region_id = weak constant i8 0 +// CK19-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK19: [[SIZE44:@.+]] = private {{.*}}constant [1 x i64] [i64 320] // CK19: [[MTYPE44:@.+]] = private {{.*}}constant [1 x i64] [i64 34] @@ -2814,19 +2814,19 @@ void explicit_maps_single (int ii){ // SIMD-ONLY19-NOT: {{__kmpc|__tgt}} #ifdef CK20 -// CK20-LABEL: @.__omp_offloading_{{.*}}explicit_maps_references_and_function_args{{.*}}_l2856.region_id = weak constant i8 0 +// CK20-LABEL: @.__omp_offloading_{{.*}}explicit_maps_references_and_function_args{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK20: [[SIZE00:@.+]] = private {{.*}}constant [1 x i64] [i64 4] // CK20: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i64] [i64 33] -// CK20-LABEL: @.__omp_offloading_{{.*}}explicit_maps_references_and_function_args{{.*}}_l2877.region_id = weak constant i8 0 +// CK20-LABEL: @.__omp_offloading_{{.*}}explicit_maps_references_and_function_args{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK20: [[SIZE01:@.+]] = private {{.*}}constant [1 x i64] [i64 20] // CK20: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i64] [i64 33] -// CK20-LABEL: @.__omp_offloading_{{.*}}explicit_maps_references_and_function_args{{.*}}_l2895.region_id = weak constant i8 0 +// CK20-LABEL: @.__omp_offloading_{{.*}}explicit_maps_references_and_function_args{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK20: [[SIZE02:@.+]] = private {{.*}}constant [1 x i64] [i64 4] // CK20: [[MTYPE02:@.+]] = private {{.*}}constant [1 x i64] [i64 34] -// CK20-LABEL: @.__omp_offloading_{{.*}}explicit_maps_references_and_function_args{{.*}}_l2916.region_id = weak constant i8 0 +// CK20-LABEL: @.__omp_offloading_{{.*}}explicit_maps_references_and_function_args{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK20: [[SIZE03:@.+]] = private {{.*}}constant [1 x i64] [i64 12] // CK20: [[MTYPE03:@.+]] = private {{.*}}constant [1 x i64] [i64 34] @@ -5299,11 +5299,11 @@ void map_with_deep_copy() { // SIMD-ONLY18-NOT: {{__kmpc|__tgt}} #ifdef CK31 -// CK31-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l5329.region_id = weak constant i8 0 +// CK31-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK31: [[SIZE00:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4] // CK31: [[MTYPE00:@.+]] = private {{.*}}constant [1 x i64] [i64 1059] -// CK31-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l5348.region_id = weak constant i8 0 +// CK31-LABEL: @.__omp_offloading_{{.*}}explicit_maps_single{{.*}}_l{{[0-9]+}}.region_id = weak constant i8 0 // CK31: [[SIZE01:@.+]] = private {{.*}}constant [1 x i[[Z:64|32]]] [i[[Z:64|32]] 4] // CK31: [[MTYPE01:@.+]] = private {{.*}}constant [1 x i64] [i64 1063] diff --git a/clang/test/OpenMP/target_map_messages.cpp b/clang/test/OpenMP/target_map_messages.cpp index 92edd12e9449e..833f509cd7f0e 100644 --- a/clang/test/OpenMP/target_map_messages.cpp +++ b/clang/test/OpenMP/target_map_messages.cpp @@ -1,10 +1,10 @@ -// RUN: %clang_cc1 -verify=expected,le45 -fopenmp -ferror-limit 200 %s -Wno-openmp-target -Wuninitialized +// RUN: %clang_cc1 -verify=expected,le50 -fopenmp -ferror-limit 200 %s -Wno-openmp-target -Wuninitialized // RUN: %clang_cc1 -verify=expected,le45 -fopenmp -fopenmp-version=40 -ferror-limit 200 %s -Wno-openmp-target -Wuninitialized // RUN: %clang_cc1 -verify=expected,le45 -fopenmp -fopenmp-version=45 -ferror-limit 200 %s -Wno-openmp-target -Wuninitialized // RUN: %clang_cc1 -verify=expected,le50 -fopenmp -fopenmp-version=50 -ferror-limit 200 %s -Wno-openmp-target -Wuninitialized // RUN: %clang_cc1 -DCCODE -verify -fopenmp -ferror-limit 200 -x c %s -Wno-openmp -Wuninitialized -// RUN: %clang_cc1 -verify=expected,le45 -fopenmp-simd -ferror-limit 200 %s -Wno-openmp-target -Wuninitialized +// RUN: %clang_cc1 -verify=expected,le50 -fopenmp-simd -ferror-limit 200 %s -Wno-openmp-target -Wuninitialized // RUN: %clang_cc1 -verify=expected,le45 -fopenmp-simd -fopenmp-version=40 -ferror-limit 200 %s -Wno-openmp-target -Wuninitialized // RUN: %clang_cc1 -verify=expected,le45 -fopenmp-simd -fopenmp-version=45 -ferror-limit 200 %s -Wno-openmp-target -Wuninitialized // RUN: %clang_cc1 -verify=expected,le50 -fopenmp-simd -fopenmp-version=50 -ferror-limit 200 %s -Wno-openmp-target -Wuninitialized @@ -550,6 +550,12 @@ T tmain(T argc) { #pragma omp target data map(tofrom, close: x) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{missing map type}} #pragma omp target data map(close, tofrom: close, tofrom, x) foo(); + + T marr[10][10], iarr[5]; +#pragma omp target data map(marr[10][0:2:2]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + {} +#pragma omp target data map(iarr[:2:d]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + {} return 0; } @@ -737,6 +743,13 @@ int main(int argc, char **argv) { #pragma omp target map(release: a) // expected-error {{map type 'release' is not allowed for '#pragma omp target'}} {} + int marr[10][10], iarr[5]; + +#pragma omp target map(marr[10][0:2:2]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + {} +#pragma omp target map(iarr[:2:d]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + {} + return tmain(argc)+tmain(argc); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} expected-note {{in instantiation of function template specialization 'tmain' requested here}} } #endif diff --git a/clang/test/OpenMP/target_messages.cpp b/clang/test/OpenMP/target_messages.cpp index 5bba976b9f9f6..a40a7d03ac80d 100644 --- a/clang/test/OpenMP/target_messages.cpp +++ b/clang/test/OpenMP/target_messages.cpp @@ -1,7 +1,10 @@ -// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -o - %s +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 -std=c++11 -o - %s +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 -o - -std=c++11 %s -Wuninitialized + // RUN: not %clang_cc1 -fopenmp -std=c++11 -fopenmp-targets=aaa-bbb-ccc-ddd -o - %s 2>&1 | FileCheck %s -// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -o - %s +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 -std=c++11 -o - %s +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp-simd -fopenmp-version=50 -std=c++11 -o - %s // CHECK: error: OpenMP target is invalid: 'aaa-bbb-ccc-ddd' // RUN: not %clang_cc1 -fopenmp -std=c++11 -triple nvptx64-nvidia-cuda -o - %s 2>&1 | FileCheck --check-prefix CHECK-UNSUPPORTED-HOST-TARGET %s // RUN: not %clang_cc1 -fopenmp -std=c++11 -triple nvptx-nvidia-cuda -o - %s 2>&1 | FileCheck --check-prefix CHECK-UNSUPPORTED-HOST-TARGET %s @@ -13,7 +16,8 @@ // NO-HOST-BC: The provided host compiler IR file '1111.bc' is required to generate code for OpenMP target regions but cannot be found. // RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc -DREGION_HOST -// RUN: not %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -DREGION_DEVICE 2>&1 +// RUN: not %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -DREGION_DEVICE 2>&1 +// RUN: not %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -DREGION_DEVICE 2>&1 #if defined(REGION_HOST) || defined(REGION_DEVICE) void foo() { @@ -50,11 +54,11 @@ class S { int b; #pragma omp target map(this[1]) // expected-note {{expected 'this' subscript expression on map clause to be 'this[0]'}} // expected-error {{invalid 'this' expression on 'map' clause}} int c; - #pragma omp target map(foo) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target map(foo) // omp4-error {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error {{expected addressable lvalue in 'map' clause}} int d; - #pragma omp target map(zee) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target map(zee) // omp4-error {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error {{expected addressable lvalue in 'map' clause}} int e; - #pragma omp target map(this->zee) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target map(this->zee) // omp4-error {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error {{expected addressable lvalue in 'map' clause}} int f; } }; @@ -116,12 +120,12 @@ int main(int argc, char **argv) { #pragma omp target for (int n = 0; n < 100; ++n) {} - #pragma omp target map(foo) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target map(foo) // omp4-error {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error {{expected addressable lvalue in 'map' clause}} {} S s; - #pragma omp target map(s.zee) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target map(s.zee) // omp4-error {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error {{expected addressable lvalue in 'map' clause}} {} return 0; diff --git a/clang/test/OpenMP/target_parallel_default_messages.cpp b/clang/test/OpenMP/target_parallel_default_messages.cpp index 0691cdf37e4eb..c8f68659438fe 100644 --- a/clang/test/OpenMP/target_parallel_default_messages.cpp +++ b/clang/test/OpenMP/target_parallel_default_messages.cpp @@ -2,20 +2,29 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp -ferror-limit 100 -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target parallel default // expected-error {{expected '(' after 'default'}} foo(); - #pragma omp target parallel default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target parallel default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} foo(); - #pragma omp target parallel default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target parallel default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} foo(); #pragma omp target parallel default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} foo(); #pragma omp target parallel default (shared), default(shared) // expected-error {{directive '#pragma omp target parallel' cannot contain more than one 'default' clause}} foo(); - #pragma omp target parallel default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target parallel default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} foo(); #pragma omp target parallel default(none) // expected-note {{explicit data sharing attribute requested here}} @@ -28,5 +37,14 @@ int main(int argc, char **argv) { #pragma omp target parallel default(none) // expected-note {{explicit data sharing attribute requested here}} #pragma omp parallel default(shared) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + +#ifndef OMP51 +#pragma omp target parallel default(firstprivate) // expected-error {{data-sharing attribute 'firstprivate' in 'default' clause requires OpenMP version 5.1 or above}} + { + ++x; + ++y; + } +#endif + return 0; } diff --git a/clang/test/OpenMP/target_parallel_depend_messages.cpp b/clang/test/OpenMP/target_parallel_depend_messages.cpp index 85111a8b14b5a..997669922d368 100644 --- a/clang/test/OpenMP/target_parallel_depend_messages.cpp +++ b/clang/test/OpenMP/target_parallel_depend_messages.cpp @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp-simd -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized void foo() { } @@ -24,35 +26,35 @@ int main(int argc, char **argv, char *env[]) { #pragma omp target parallel depend // expected-error {{expected '(' after 'depend'}} foo(); - #pragma omp target parallel depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target parallel depend( // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); - #pragma omp target parallel depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target parallel depend() // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); - #pragma omp target parallel depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target parallel depend(argc // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); - #pragma omp target parallel depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp target parallel depend(source : argc) // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); - #pragma omp target parallel depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp target parallel depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); #pragma omp target parallel depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel' are ignored}} foo(); #pragma omp target parallel depend (out: ) // expected-error {{expected expression}} foo(); - #pragma omp target parallel depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} +#pragma omp target parallel depend(inout : foobool(argc)), depend(in, argc) // omp4-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} foo(); #pragma omp target parallel depend (out :S1) // expected-error {{'S1' does not refer to a value}} foo(); - #pragma omp target parallel depend(in : argv[1][1] = '2') +#pragma omp target parallel depend(in : argv[1][1] = '2') foo(); - #pragma omp target parallel depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}} +#pragma omp target parallel depend(in : vec[1]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} foo(); #pragma omp target parallel depend (in : argv[0]) foo(); - #pragma omp target parallel depend (in : ) // expected-error {{expected expression}} +#pragma omp target parallel depend(in:) // expected-error {{expected expression}} foo(); #pragma omp target parallel depend (in : main) foo(); - #pragma omp target parallel depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}} +#pragma omp target parallel depend(in : a[0]) // omp4-error{{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} foo(); #pragma omp target parallel depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}} foo(); @@ -72,7 +74,7 @@ int main(int argc, char **argv, char *env[]) { foo(); #pragma omp target parallel depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} foo(); - #pragma omp target parallel depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + #pragma omp target parallel depend(in : argv [3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} foo(); #pragma omp target parallel depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} foo(); diff --git a/clang/test/OpenMP/target_parallel_for_default_messages.cpp b/clang/test/OpenMP/target_parallel_for_default_messages.cpp index fc6ba43138d76..4a3aae68e0865 100644 --- a/clang/test/OpenMP/target_parallel_for_default_messages.cpp +++ b/clang/test/OpenMP/target_parallel_for_default_messages.cpp @@ -2,17 +2,26 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -DOMP51 -ferror-limit 100 -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=51 -DOMP51 -ferror-limit 100 -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { int i; #pragma omp target parallel for default // expected-error {{expected '(' after 'default'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target parallel for default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target parallel for default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{explicit data sharing attribute requested here}} @@ -21,7 +30,7 @@ int main(int argc, char **argv) { #pragma omp target parallel for default(shared), default(shared) // expected-error {{directive '#pragma omp target parallel for' cannot contain more than one 'default' clause}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target parallel for default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); @@ -34,5 +43,13 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} foo(); +#ifndef OMP51 +#pragma omp target parallel for default(firstprivate) // expected-error {{data-sharing attribute 'firstprivate' in 'default' clause requires OpenMP version 5.1 or above}} + for (i = 0; i < argc; ++i) { + ++x; + ++y; + } +#endif + return 0; } diff --git a/clang/test/OpenMP/target_parallel_for_depend_messages.cpp b/clang/test/OpenMP/target_parallel_for_depend_messages.cpp index 34d11ea860d6c..bb8a282fb9b05 100644 --- a/clang/test/OpenMP/target_parallel_for_depend_messages.cpp +++ b/clang/test/OpenMP/target_parallel_for_depend_messages.cpp @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp-simd -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized void foo() { } @@ -25,35 +27,42 @@ int main(int argc, char **argv, char *env[]) { #pragma omp target parallel for depend // expected-error {{expected '(' after 'depend'}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target parallel for depend( // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target parallel for depend() // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target parallel for depend(argc // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} - for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp target parallel for depend(source : argc) // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for' are ignored}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for depend (out: ) // expected-error {{expected expression}} - for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} - for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for depend (out :S1) // expected-error {{'S1' does not refer to a value}} - for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for depend(in : argv[1][1] = '2') - for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}} - for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for depend (in : argv[0]) - for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for depend (in : ) // expected-error {{expected expression}} +#pragma omp target parallel for depend(out:) // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for depend(inout : foobool(argc)), depend(in, argc) // omp4-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for depend(out : S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for depend(in : argv[1][1] = '2') + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for depend(in : vec[1]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for depend(in : argv[0]) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for depend(in:) // expected-error {{expected expression}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for depend (in : main) for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}} +#pragma omp target parallel for depend(in : a[0]) // omp4-error{{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}} for (i = 0; i < argc; ++i) foo(); @@ -73,7 +82,7 @@ int main(int argc, char **argv, char *env[]) { for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + #pragma omp target parallel for depend(in : argv [3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} for (i = 0; i < argc; ++i) foo(); diff --git a/clang/test/OpenMP/target_parallel_for_loop_messages.cpp b/clang/test/OpenMP/target_parallel_for_loop_messages.cpp index 671f116adffd8..2cbf858bf66f4 100644 --- a/clang/test/OpenMP/target_parallel_for_loop_messages.cpp +++ b/clang/test/OpenMP/target_parallel_for_loop_messages.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wno-openmp-mapping -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wno-openmp-mapping -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wno-openmp-mapping -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wno-openmp-mapping -Wuninitialized class S { diff --git a/clang/test/OpenMP/target_parallel_for_map_messages.cpp b/clang/test/OpenMP/target_parallel_for_map_messages.cpp index 0d75d702f78cf..b44c330e2260d 100644 --- a/clang/test/OpenMP/target_parallel_for_map_messages.cpp +++ b/clang/test/OpenMP/target_parallel_for_map_messages.cpp @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp-simd -fopenmp-version=50 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized void foo() { } @@ -103,7 +105,7 @@ T tmain(T argc) { for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for map(T) // expected-error {{'T' does not refer to a value}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for map(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target parallel for map(I) // omp4-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error 2 {{expected addressable lvalue in 'map' clause}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for map(S2::S2s) for (i = 0; i < argc; ++i) foo(); @@ -121,7 +123,8 @@ T tmain(T argc) { for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target parallel for map(tofrom \ + : argc > 0 ? x : y) // omp4-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error 2 {{expected addressable lvalue in 'map' clause}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for map(argc) for (i = 0; i < argc; ++i) foo(); @@ -228,8 +231,10 @@ int main(int argc, char **argv) { #pragma omp target parallel for map(to, x) for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} - for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for map(tofrom: argc > 0 ? argv[1] : argv[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for map(tofrom \ + : argc > 0 ? argv[1] : argv[2]) // omp4-error {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error {{expected addressable lvalue in 'map' clause}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for map(argc) for (i = 0; i < argc; ++i) foo(); diff --git a/clang/test/OpenMP/target_parallel_for_simd_default_messages.cpp b/clang/test/OpenMP/target_parallel_for_simd_default_messages.cpp index daa93b9c9050b..48489309ef037 100644 --- a/clang/test/OpenMP/target_parallel_for_simd_default_messages.cpp +++ b/clang/test/OpenMP/target_parallel_for_simd_default_messages.cpp @@ -2,17 +2,26 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp -ferror-limit 100 -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { int i; #pragma omp target parallel for simd default // expected-error {{expected '(' after 'default'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for simd default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target parallel for simd default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for simd default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target parallel for simd default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{explicit data sharing attribute requested here}} @@ -21,7 +30,7 @@ int main(int argc, char **argv) { #pragma omp target parallel for simd default(shared), default(shared) // expected-error {{directive '#pragma omp target parallel for simd' cannot contain more than one 'default' clause}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for simd default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target parallel for simd default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); @@ -34,5 +43,13 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) // expected-error {{variable 'i' must have explicitly specified data sharing attributes}} expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} foo(); +#ifndef OMP51 +#pragma omp target parallel for simd default(firstprivate) // expected-error {{data-sharing attribute 'firstprivate' in 'default' clause requires OpenMP version 5.1 or above}} + for (int i = 0; i < argc; i++) { + ++x; + ++y; + } +#endif + return 0; } diff --git a/clang/test/OpenMP/target_parallel_for_simd_depend_messages.cpp b/clang/test/OpenMP/target_parallel_for_simd_depend_messages.cpp index 14e202ba53b57..64e4c05ab5f0e 100644 --- a/clang/test/OpenMP/target_parallel_for_simd_depend_messages.cpp +++ b/clang/test/OpenMP/target_parallel_for_simd_depend_messages.cpp @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 -std=c++11 %s -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp-simd -fopenmp-version=50 -std=c++11 %s -Wuninitialized void foo() { } @@ -25,35 +27,42 @@ int main(int argc, char **argv, char *env[]) { #pragma omp target parallel for simd depend // expected-error {{expected '(' after 'depend'}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for simd depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target parallel for simd depend( // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for simd depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target parallel for simd depend() // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for simd depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target parallel for simd depend(argc // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for simd depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} - for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for simd depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp target parallel for simd depend(source : argc) // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target parallel for simd' are ignored}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for simd depend (out: ) // expected-error {{expected expression}} - for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for simd depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} - for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for simd depend (out :S1) // expected-error {{'S1' does not refer to a value}} - for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for simd depend(in : argv[1][1] = '2') - for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for simd depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}} - for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for simd depend (in : argv[0]) - for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for simd depend (in : ) // expected-error {{expected expression}} +#pragma omp target parallel for simd depend(out:) // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd depend(inout : foobool(argc)), depend(in, argc) // omp4-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd depend(out : S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd depend(in : argv[1][1] = '2') + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd depend(in : vec[1]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd depend(in : argv[0]) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd depend(in:) // expected-error {{expected expression}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd depend (in : main) for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for simd depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}} +#pragma omp target parallel for simd depend(in : a[0]) // omp4-error{{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}} for (i = 0; i < argc; ++i) foo(); @@ -73,7 +82,7 @@ int main(int argc, char **argv, char *env[]) { for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target parallel for simd depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + #pragma omp target parallel for simd depend(in : argv [3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} for (i = 0; i < argc; ++i) foo(); diff --git a/clang/test/OpenMP/target_parallel_for_simd_is_device_ptr_messages.cpp b/clang/test/OpenMP/target_parallel_for_simd_is_device_ptr_messages.cpp index 47e498a44c6db..77fc1338518c2 100644 --- a/clang/test/OpenMP/target_parallel_for_simd_is_device_ptr_messages.cpp +++ b/clang/test/OpenMP/target_parallel_for_simd_is_device_ptr_messages.cpp @@ -1,6 +1,9 @@ -// RUN: %clang_cc1 -std=c++11 -verify -fopenmp %s -Wuninitialized +// RUN: %clang_cc1 -std=c++11 -verify=expected,omp4 -fopenmp -fopenmp-version=45 %s -Wuninitialized +// RUN: %clang_cc1 -std=c++11 -verify -fopenmp -fopenmp-version=50 %s -Wuninitialized + +// RUN: %clang_cc1 -std=c++11 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 %s -Wuninitialized +// RUN: %clang_cc1 -std=c++11 -verify -fopenmp-simd -fopenmp-version=50 %s -Wuninitialized -// RUN: %clang_cc1 -std=c++11 -verify -fopenmp-simd %s -Wuninitialized struct ST { int *a; }; @@ -228,13 +231,13 @@ T tmain(T argc) { #pragma omp target parallel for simd is_device_ptr(ps) map(ps->a) // expected-error{{pointer cannot be mapped along with a section derived from itself}} expected-note{{used here}} for (int i=0; i<100; i++) ; -#pragma omp target parallel for simd is_device_ptr(ps) firstprivate(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target parallel for simd' directive}} +#pragma omp target parallel for simd is_device_ptr(ps) firstprivate(ps) // omp4-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target parallel for simd' directive}} for (int i=0; i<100; i++) ; #pragma omp target parallel for simd firstprivate(ps) is_device_ptr(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target parallel for simd' directive}} expected-note{{defined as firstprivate}} for (int i=0; i<100; i++) ; -#pragma omp target parallel for simd is_device_ptr(ps) private(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target parallel for simd' directive}} +#pragma omp target parallel for simd is_device_ptr(ps) private(ps) // omp4-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target parallel for simd' directive}} for (int i=0; i<100; i++) ; #pragma omp target parallel for simd private(ps) is_device_ptr(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target parallel for simd' directive}} expected-note{{defined as private}} @@ -323,13 +326,13 @@ int main(int argc, char **argv) { #pragma omp target parallel for simd is_device_ptr(ps) map(ps->a) // expected-error{{pointer cannot be mapped along with a section derived from itself}} expected-note{{used here}} for (int i=0; i<100; i++) ; -#pragma omp target parallel for simd is_device_ptr(ps) firstprivate(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target parallel for simd' directive}} +#pragma omp target parallel for simd is_device_ptr(ps) firstprivate(ps) // omp4-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target parallel for simd' directive}} for (int i=0; i<100; i++) ; #pragma omp target parallel for simd firstprivate(ps) is_device_ptr(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target parallel for simd' directive}} expected-note{{defined as firstprivate}} for (int i=0; i<100; i++) ; -#pragma omp target parallel for simd is_device_ptr(ps) private(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target parallel for simd' directive}} +#pragma omp target parallel for simd is_device_ptr(ps) private(ps) // omp4-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target parallel for simd' directive}} for (int i=0; i<100; i++) ; #pragma omp target parallel for simd private(ps) is_device_ptr(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target parallel for simd' directive}} expected-note{{defined as private}} diff --git a/clang/test/OpenMP/target_parallel_for_simd_map_messages.cpp b/clang/test/OpenMP/target_parallel_for_simd_map_messages.cpp index 8156ad8f308c0..d4c0b30f57664 100644 --- a/clang/test/OpenMP/target_parallel_for_simd_map_messages.cpp +++ b/clang/test/OpenMP/target_parallel_for_simd_map_messages.cpp @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 %s -Wno-openmp-mapping -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp-simd -fopenmp-version=50 %s -Wno-openmp-mapping -Wuninitialized void foo() { } @@ -103,7 +105,7 @@ T tmain(T argc) { for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd map(T) // expected-error {{'T' does not refer to a value}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for simd map(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target parallel for simd map(I) // omp4-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error 2 {{expected addressable lvalue in 'map' clause}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd map(S2::S2s) for (i = 0; i < argc; ++i) foo(); @@ -121,7 +123,8 @@ T tmain(T argc) { for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for simd map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target parallel for simd map(tofrom \ + : argc > 0 ? x : y) // omp4-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error 2 {{expected addressable lvalue in 'map' clause}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd map(argc) for (i = 0; i < argc; ++i) foo(); @@ -228,8 +231,10 @@ int main(int argc, char **argv) { #pragma omp target parallel for simd map(to, x) for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} - for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for simd map(tofrom: argc > 0 ? argv[1] : argv[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target parallel for simd map(tofrom \ + : argc > 0 ? argv[1] : argv[2]) // omp4-error {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error {{expected addressable lvalue in 'map' clause}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd map(argc) for (i = 0; i < argc; ++i) foo(); diff --git a/clang/test/OpenMP/target_parallel_is_device_ptr_messages.cpp b/clang/test/OpenMP/target_parallel_is_device_ptr_messages.cpp index 9913133734a74..c8aef46d703ed 100644 --- a/clang/test/OpenMP/target_parallel_is_device_ptr_messages.cpp +++ b/clang/test/OpenMP/target_parallel_is_device_ptr_messages.cpp @@ -1,6 +1,8 @@ // RUN: %clang_cc1 -std=c++11 -verify -fopenmp -ferror-limit 200 %s -Wuninitialized +// RUN: %clang_cc1 -std=c++11 -verify=expected,omp4 -fopenmp -fopenmp-version=45 -ferror-limit 200 %s -Wuninitialized // RUN: %clang_cc1 -std=c++11 -verify -fopenmp-simd -ferror-limit 200 %s -Wuninitialized +// RUN: %clang_cc1 -std=c++11 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 -ferror-limit 200 %s -Wuninitialized struct ST { int *a; }; @@ -189,11 +191,11 @@ T tmain(T argc) { {} #pragma omp target parallel is_device_ptr(ps) map(ps->a) // expected-error{{pointer cannot be mapped along with a section derived from itself}} expected-note{{used here}} {} -#pragma omp target parallel is_device_ptr(ps) firstprivate(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target parallel' directive}} +#pragma omp target parallel is_device_ptr(ps) firstprivate(ps) // omp4-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target parallel' directive}} {} #pragma omp target parallel firstprivate(ps) is_device_ptr(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target parallel' directive}} expected-note{{defined as firstprivate}} {} -#pragma omp target parallel is_device_ptr(ps) private(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target parallel' directive}} +#pragma omp target parallel is_device_ptr(ps) private(ps) // omp4-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target parallel' directive}} {} #pragma omp target parallel private(ps) is_device_ptr(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target parallel' directive}} expected-note{{defined as private}} {} @@ -258,11 +260,11 @@ int main(int argc, char **argv) { {} #pragma omp target parallel is_device_ptr(ps) map(ps->a) // expected-error{{pointer cannot be mapped along with a section derived from itself}} expected-note{{used here}} {} -#pragma omp target parallel is_device_ptr(ps) firstprivate(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target parallel' directive}} +#pragma omp target parallel is_device_ptr(ps) firstprivate(ps) // omp4-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target parallel' directive}} {} #pragma omp target parallel firstprivate(ps) is_device_ptr(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target parallel' directive}} expected-note{{defined as firstprivate}} {} -#pragma omp target parallel is_device_ptr(ps) private(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target parallel' directive}} +#pragma omp target parallel is_device_ptr(ps) private(ps) // omp4-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target parallel' directive}} {} #pragma omp target parallel private(ps) is_device_ptr(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target parallel' directive}} expected-note{{defined as private}} {} diff --git a/clang/test/OpenMP/target_parallel_map_messages.cpp b/clang/test/OpenMP/target_parallel_map_messages.cpp index c35bb99d8d59a..6e080fda9226b 100644 --- a/clang/test/OpenMP/target_parallel_map_messages.cpp +++ b/clang/test/OpenMP/target_parallel_map_messages.cpp @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp-simd -fopenmp-version=50 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized void foo() { } @@ -103,7 +105,7 @@ T tmain(T argc) { foo(); #pragma omp target parallel map(T) // expected-error {{'T' does not refer to a value}} foo(); -#pragma omp target parallel map(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target parallel map(I) // omp4-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error 2 {{expected addressable lvalue in 'map' clause}} foo(); #pragma omp target parallel map(S2::S2s) foo(); @@ -121,7 +123,8 @@ T tmain(T argc) { foo(); #pragma omp target parallel map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} foo(); -#pragma omp target parallel map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target parallel map(tofrom \ + : argc > 0 ? x : y) // omp4-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error 2 {{expected addressable lvalue in 'map' clause}} foo(); #pragma omp target parallel map(argc) foo(); @@ -228,7 +231,8 @@ int main(int argc, char **argv) { foo(); #pragma omp target parallel map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} foo(); -#pragma omp target parallel map(tofrom: argc > 0 ? argv[1] : argv[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target parallel map(tofrom \ + : argc > 0 ? argv[1] : argv[2]) // omp4-error {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error {{expected addressable lvalue in 'map' clause}} foo(); #pragma omp target parallel map(argc) foo(); diff --git a/clang/test/OpenMP/target_simd_depend_codegen.cpp b/clang/test/OpenMP/target_simd_depend_codegen.cpp index efbb71772b31f..72cd550207b67 100644 --- a/clang/test/OpenMP/target_simd_depend_codegen.cpp +++ b/clang/test/OpenMP/target_simd_depend_codegen.cpp @@ -1,10 +1,10 @@ // Test host codegen. -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s diff --git a/clang/test/OpenMP/target_simd_depend_messages.cpp b/clang/test/OpenMP/target_simd_depend_messages.cpp index f4fefb013325c..a4f6e535194a3 100644 --- a/clang/test/OpenMP/target_simd_depend_messages.cpp +++ b/clang/test/OpenMP/target_simd_depend_messages.cpp @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 -std=c++11 %s -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp-simd -fopenmp-version=50 -std=c++11 %s -Wuninitialized void foo() { } @@ -25,35 +27,42 @@ int main(int argc, char **argv, char *env[]) { #pragma omp target simd depend // expected-error {{expected '(' after 'depend'}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target simd depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target simd depend( // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target simd depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target simd depend() // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target simd depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target simd depend(argc // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target simd depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} - for (i = 0; i < argc; ++i) foo(); - #pragma omp target simd depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp target simd depend(source : argc) // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target simd depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target simd depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target simd' are ignored}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target simd depend (out: ) // expected-error {{expected expression}} - for (i = 0; i < argc; ++i) foo(); - #pragma omp target simd depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} - for (i = 0; i < argc; ++i) foo(); - #pragma omp target simd depend (out :S1) // expected-error {{'S1' does not refer to a value}} - for (i = 0; i < argc; ++i) foo(); - #pragma omp target simd depend(in : argv[1][1] = '2') - for (i = 0; i < argc; ++i) foo(); - #pragma omp target simd depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}} - for (i = 0; i < argc; ++i) foo(); - #pragma omp target simd depend (in : argv[0]) - for (i = 0; i < argc; ++i) foo(); - #pragma omp target simd depend (in : ) // expected-error {{expected expression}} +#pragma omp target simd depend(out:) // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target simd depend(inout : foobool(argc)), depend(in, argc) // omp4-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target simd depend(out : S1) // expected-error {{'S1' does not refer to a value}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target simd depend(in : argv[1][1] = '2') + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target simd depend(in : vec[1]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target simd depend(in : argv[0]) + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target simd depend(in:) // expected-error {{expected expression}} for (i = 0; i < argc; ++i) foo(); #pragma omp target simd depend (in : main) for (i = 0; i < argc; ++i) foo(); - #pragma omp target simd depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}} +#pragma omp target simd depend(in : a[0]) // omp4-error{{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} for (i = 0; i < argc; ++i) foo(); #pragma omp target simd depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}} for (i = 0; i < argc; ++i) foo(); @@ -73,7 +82,7 @@ int main(int argc, char **argv, char *env[]) { for (i = 0; i < argc; ++i) foo(); #pragma omp target simd depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} for (i = 0; i < argc; ++i) foo(); - #pragma omp target simd depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + #pragma omp target simd depend(in : argv [3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} for (i = 0; i < argc; ++i) foo(); #pragma omp target simd depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} for (i = 0; i < argc; ++i) foo(); diff --git a/clang/test/OpenMP/target_simd_map_messages.cpp b/clang/test/OpenMP/target_simd_map_messages.cpp index b8ee39aa03d3d..57929e276260e 100644 --- a/clang/test/OpenMP/target_simd_map_messages.cpp +++ b/clang/test/OpenMP/target_simd_map_messages.cpp @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 %s -Wno-openmp-mapping -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp-simd -fopenmp-version=50 %s -Wno-openmp-mapping -Wuninitialized void foo() { } @@ -97,7 +99,7 @@ T tmain(T argc) { for (i = 0; i < argc; ++i) foo(); #pragma omp target simd map(T) // expected-error {{'T' does not refer to a value}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target simd map(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target simd map(I) // omp4-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error 2 {{expected addressable lvalue in 'map' clause}} for (i = 0; i < argc; ++i) foo(); #pragma omp target simd map(S2::S2s) for (i = 0; i < argc; ++i) foo(); @@ -115,7 +117,8 @@ T tmain(T argc) { for (i = 0; i < argc; ++i) foo(); #pragma omp target simd map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target simd map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target simd map(tofrom \ + : argc > 0 ? x : y) // omp4-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error 2 {{expected addressable lvalue in 'map' clause}} for (i = 0; i < argc; ++i) foo(); #pragma omp target simd map(argc) for (i = 0; i < argc; ++i) foo(); @@ -216,8 +219,10 @@ int main(int argc, char **argv) { #pragma omp target simd map(to, x) for (i = 0; i < argc; ++i) foo(); #pragma omp target simd map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} - for (i = 0; i < argc; ++i) foo(); -#pragma omp target simd map(tofrom: argc > 0 ? argv[1] : argv[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target simd map(tofrom \ + : argc > 0 ? argv[1] : argv[2]) // omp4-error {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error {{expected addressable lvalue in 'map' clause}} for (i = 0; i < argc; ++i) foo(); #pragma omp target simd map(argc) for (i = 0; i < argc; ++i) foo(); diff --git a/clang/test/OpenMP/target_teams_default_messages.cpp b/clang/test/OpenMP/target_teams_default_messages.cpp index 21fa8270ef6a7..85c417f8f9853 100644 --- a/clang/test/OpenMP/target_teams_default_messages.cpp +++ b/clang/test/OpenMP/target_teams_default_messages.cpp @@ -2,20 +2,29 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target teams default // expected-error {{expected '(' after 'default'}} foo(); -#pragma omp target teams default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target teams default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} foo(); -#pragma omp target teams default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target teams default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} foo(); #pragma omp target teams default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} foo(); #pragma omp target teams default (shared), default(shared) // expected-error {{directive '#pragma omp target teams' cannot contain more than one 'default' clause}} foo(); -#pragma omp target teams default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target teams default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} foo(); #pragma omp target teams default(none) // expected-note {{explicit data sharing attribute requested here}} @@ -24,5 +33,14 @@ int main(int argc, char **argv) { #pragma omp target teams default(none) // expected-note {{explicit data sharing attribute requested here}} #pragma omp parallel default(shared) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + +#ifndef OMP51 +#pragma omp target teams default(firstprivate) // expected-error {{data-sharing attribute 'firstprivate' in 'default' clause requires OpenMP version 5.1 or above}} + { + ++x; + ++y; + } +#endif + return 0; } diff --git a/clang/test/OpenMP/target_teams_depend_messages.cpp b/clang/test/OpenMP/target_teams_depend_messages.cpp index 1575e163db827..5baf73a9ba5ea 100644 --- a/clang/test/OpenMP/target_teams_depend_messages.cpp +++ b/clang/test/OpenMP/target_teams_depend_messages.cpp @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp-simd -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized void foo() { } @@ -24,27 +26,27 @@ int main(int argc, char **argv, char *env[]) { #pragma omp target teams depend // expected-error {{expected '(' after 'depend'}} foo(); -#pragma omp target teams depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target teams depend( // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); -#pragma omp target teams depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target teams depend() // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); -#pragma omp target teams depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target teams depend(argc // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); -#pragma omp target teams depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp target teams depend(source : argc) // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); -#pragma omp target teams depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp target teams depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} foo(); #pragma omp target teams depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams' are ignored}} foo(); #pragma omp target teams depend (out: ) // expected-error {{expected expression}} foo(); -#pragma omp target teams depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} +#pragma omp target teams depend(inout : foobool(argc)), depend(in, argc) // omp4-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} foo(); #pragma omp target teams depend (out :S1) // expected-error {{'S1' does not refer to a value}} foo(); #pragma omp target teams depend(in : argv[1][1] = '2') foo(); -#pragma omp target teams depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}} +#pragma omp target teams depend(in : vec[1]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} foo(); #pragma omp target teams depend (in : argv[0]) foo(); @@ -52,7 +54,7 @@ int main(int argc, char **argv, char *env[]) { foo(); #pragma omp target teams depend (in : main) foo(); -#pragma omp target teams depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}} +#pragma omp target teams depend(in : a[0]) // omp4-error{{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} foo(); #pragma omp target teams depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}} foo(); @@ -72,7 +74,7 @@ int main(int argc, char **argv, char *env[]) { foo(); #pragma omp target teams depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} foo(); -#pragma omp target teams depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} +#pragma omp target teams depend(in : argv [3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} foo(); #pragma omp target teams depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} foo(); diff --git a/clang/test/OpenMP/target_teams_distribute_default_messages.cpp b/clang/test/OpenMP/target_teams_distribute_default_messages.cpp index fd834e7cba32c..a490ad61385ff 100644 --- a/clang/test/OpenMP/target_teams_distribute_default_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_default_messages.cpp @@ -2,24 +2,41 @@ // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -DOMP51 %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=51 -DOMP51 %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target teams distribute default // expected-error {{expected '(' after 'default'}} for (int i=0; i<200; i++) foo(); - #pragma omp target teams distribute default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target teams distribute default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); - #pragma omp target teams distribute default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target teams distribute default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target teams distribute default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); #pragma omp target teams distribute default (shared), default(shared) // expected-error {{directive '#pragma omp target teams distribute' cannot contain more than one 'default' clause}} for (int i=0; i<200; i++) foo(); - #pragma omp target teams distribute default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target teams distribute default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target teams distribute default(none) // expected-note {{explicit data sharing attribute requested here}} for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} +#ifndef OMP51 +#pragma omp target teams distribute default(firstprivate) // expected-error {{data-sharing attribute 'firstprivate' in 'default' clause requires OpenMP version 5.1 or above}} + for (int i = 0; i < 200; i++) { + ++x; + ++y; + } +#endif + return 0; } diff --git a/clang/test/OpenMP/target_teams_distribute_depend_messages.cpp b/clang/test/OpenMP/target_teams_distribute_depend_messages.cpp index 740eff22e723d..fab61b34126ec 100644 --- a/clang/test/OpenMP/target_teams_distribute_depend_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_depend_messages.cpp @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp-simd -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized void foo() { } @@ -25,35 +27,38 @@ int main(int argc, char **argv, char *env[]) { #pragma omp target teams distribute depend // expected-error {{expected '(' after 'depend'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target teams distribute depend( // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target teams distribute depend() // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target teams distribute depend(argc // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} - for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp target teams distribute depend(source : argc) // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target teams distribute depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute' are ignored}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute depend (out: ) // expected-error {{expected expression}} - for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target teams distribute depend(inout : foobool(argc)), depend(in, argc) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute depend (out :S1) // expected-error {{'S1' does not refer to a value}} - for (i = 0; i < argc; ++i) foo(); + for (i = 0; i < argc; ++i) + foo(); #pragma omp target teams distribute depend(in : argv[1][1] = '2') for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}} +#pragma omp target teams distribute depend(in : vec[1]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute depend (in : argv[0]) for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute depend (in : ) // expected-error {{expected expression}} +#pragma omp target teams distribute depend(in:) // expected-error {{expected expression}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute depend (in : main) for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}} +#pragma omp target teams distribute depend(in : a[0]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}} for (i = 0; i < argc; ++i) foo(); @@ -73,7 +78,7 @@ int main(int argc, char **argv, char *env[]) { for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} +#pragma omp target teams distribute depend(in : argv [3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} for (i = 0; i < argc; ++i) foo(); diff --git a/clang/test/OpenMP/target_teams_distribute_loop_messages.cpp b/clang/test/OpenMP/target_teams_distribute_loop_messages.cpp index e20b04bd94362..dcaf5824dfaf2 100644 --- a/clang/test/OpenMP/target_teams_distribute_loop_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_loop_messages.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wno-openmp-mapping -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wno-openmp-mapping -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wno-openmp-mapping -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wno-openmp-mapping -Wuninitialized class S { diff --git a/clang/test/OpenMP/target_teams_distribute_map_messages.cpp b/clang/test/OpenMP/target_teams_distribute_map_messages.cpp index d5f87f74672bb..38855680c1fe5 100644 --- a/clang/test/OpenMP/target_teams_distribute_map_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_map_messages.cpp @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp-simd -fopenmp-version=50 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized void foo() { } @@ -103,7 +105,7 @@ T tmain(T argc) { for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute map(T) // expected-error {{'T' does not refer to a value}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute map(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target teams distribute map(I) // omp4-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error 2 {{expected addressable lvalue in 'map' clause}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute map(S2::S2s) for (i = 0; i < argc; ++i) foo(); @@ -121,7 +123,8 @@ T tmain(T argc) { for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target teams distribute map(tofrom \ + : argc > 0 ? x : y) // omp4-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error 2 {{expected addressable lvalue in 'map' clause}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute map(argc) for (i = 0; i < argc; ++i) foo(); @@ -228,8 +231,10 @@ int main(int argc, char **argv) { #pragma omp target teams distribute map(to, x) for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} - for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute map(tofrom: argc > 0 ? argv[1] : argv[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target teams distribute map(tofrom \ + : argc > 0 ? argv[1] : argv[2]) // omp4-error {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error {{expected addressable lvalue in 'map' clause}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute map(argc) for (i = 0; i < argc; ++i) foo(); diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_default_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_default_messages.cpp index 00e0704a6ccac..2fe7931369618 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_default_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_default_messages.cpp @@ -2,24 +2,41 @@ // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target teams distribute parallel for default // expected-error {{expected '(' after 'default'}} for (int i=0; i<200; i++) foo(); - #pragma omp target teams distribute parallel for default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target teams distribute parallel for default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); -#pragma omp target teams distribute parallel for default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target teams distribute parallel for default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target teams distribute parallel for default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); #pragma omp target teams distribute parallel for default (shared), default(shared) // expected-error {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'default' clause}} for (int i=0; i<200; i++) foo(); -#pragma omp target teams distribute parallel for default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target teams distribute parallel for default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target teams distribute parallel for default(none) // expected-note {{explicit data sharing attribute requested here}} for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} +#ifndef OMP51 +#pragma omp target teams distribute parallel for default(firstprivate) // expected-error {{data-sharing attribute 'firstprivate' in 'default' clause requires OpenMP version 5.1 or above}} + for (int i = 0; i < 200; i++) { + ++x; + ++y; + } +#endif + return 0; } diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_depend_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_depend_messages.cpp index 34d655c6a2576..c8adbe53b7423 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_depend_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_depend_messages.cpp @@ -1,7 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized - -// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp-simd -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized void foo() { } @@ -25,35 +26,40 @@ int main(int argc, char **argv, char *env[]) { #pragma omp target teams distribute parallel for depend // expected-error {{expected '(' after 'depend'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} - for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target teams distribute parallel for depend( // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target teams distribute parallel for depend() // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp target teams distribute parallel for depend(argc // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp target teams distribute parallel for depend(source : argc) // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target teams distribute parallel for depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for' are ignored}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for depend (out: ) // expected-error {{expected expression}} - for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} - for (i = 0; i < argc; ++i) foo(); +#pragma omp target teams distribute parallel for depend(out:) // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target teams distribute parallel for depend(inout : foobool(argc)), depend(in, argc) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); #pragma omp target teams distribute parallel for depend (out :S1) // expected-error {{'S1' does not refer to a value}} - for (i = 0; i < argc; ++i) foo(); + for (i = 0; i < argc; ++i) + foo(); #pragma omp target teams distribute parallel for depend(in : argv[1][1] = '2') for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}} - for (i = 0; i < argc; ++i) foo(); +#pragma omp target teams distribute parallel for depend(in : vec[1]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} + for (i = 0; i < argc; ++i) + foo(); #pragma omp target teams distribute parallel for depend (in : argv[0]) for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for depend (in : ) // expected-error {{expected expression}} +#pragma omp target teams distribute parallel for depend(in:) // expected-error {{expected expression}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for depend (in : main) for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}} +#pragma omp target teams distribute parallel for depend(in : a[0]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}} for (i = 0; i < argc; ++i) foo(); @@ -73,7 +79,7 @@ int main(int argc, char **argv, char *env[]) { for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} +#pragma omp target teams distribute parallel for depend(in : argv [3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} for (i = 0; i < argc; ++i) foo(); diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_is_device_ptr_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_is_device_ptr_messages.cpp index fdf98d40ea857..070ca7beaaafe 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_is_device_ptr_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_is_device_ptr_messages.cpp @@ -1,6 +1,8 @@ // RUN: %clang_cc1 -std=c++11 -verify -fopenmp %s -Wuninitialized +// RUN: %clang_cc1 -std=c++11 -verify=expected,omp4 -fopenmp -fopenmp-version=45 %s -Wuninitialized // RUN: %clang_cc1 -std=c++11 -verify -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -std=c++11 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 %s -Wuninitialized struct ST { int *a; }; @@ -228,13 +230,13 @@ T tmain(T argc) { #pragma omp target teams distribute parallel for is_device_ptr(ps) map(ps->a) // expected-error{{pointer cannot be mapped along with a section derived from itself}} expected-note{{used here}} for (int i=0; i<100; i++) ; -#pragma omp target teams distribute parallel for is_device_ptr(ps) firstprivate(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for' directive}} +#pragma omp target teams distribute parallel for is_device_ptr(ps) firstprivate(ps) // omp4-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for' directive}} for (int i=0; i<100; i++) ; #pragma omp target teams distribute parallel for firstprivate(ps) is_device_ptr(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for' directive}} expected-note{{defined as firstprivate}} for (int i=0; i<100; i++) ; -#pragma omp target teams distribute parallel for is_device_ptr(ps) private(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for' directive}} +#pragma omp target teams distribute parallel for is_device_ptr(ps) private(ps) // omp4-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for' directive}} for (int i=0; i<100; i++) ; #pragma omp target teams distribute parallel for private(ps) is_device_ptr(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for' directive}} expected-note{{defined as private}} @@ -323,13 +325,13 @@ int main(int argc, char **argv) { #pragma omp target teams distribute parallel for is_device_ptr(ps) map(ps->a) // expected-error{{pointer cannot be mapped along with a section derived from itself}} expected-note{{used here}} for (int i=0; i<100; i++) ; -#pragma omp target teams distribute parallel for is_device_ptr(ps) firstprivate(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for' directive}} +#pragma omp target teams distribute parallel for is_device_ptr(ps) firstprivate(ps) // omp4-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for' directive}} for (int i=0; i<100; i++) ; #pragma omp target teams distribute parallel for firstprivate(ps) is_device_ptr(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for' directive}} expected-note{{defined as firstprivate}} for (int i=0; i<100; i++) ; -#pragma omp target teams distribute parallel for is_device_ptr(ps) private(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for' directive}} +#pragma omp target teams distribute parallel for is_device_ptr(ps) private(ps) // omp4-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for' directive}} for (int i=0; i<100; i++) ; #pragma omp target teams distribute parallel for private(ps) is_device_ptr(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for' directive}} expected-note{{defined as private}} diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_messages.cpp index 34cd01f3eecc7..ff279dcf8fb91 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify=expected,le45 -fopenmp %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,le45 -fopenmp-version=40 -fopenmp %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,le45 -fopenmp-version=45 -fopenmp %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,omp50 -fopenmp-version=50 -fopenmp %s -Wuninitialized diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_loop_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_loop_messages.cpp index a57f213615bd0..a440cbdcb6234 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_loop_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_loop_messages.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wno-openmp-mapping -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wno-openmp-mapping -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wno-openmp-mapping -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wno-openmp-mapping -Wuninitialized class S { diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_map_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_map_messages.cpp index 0be31256a42a9..a1af4600b59a4 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_map_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_map_messages.cpp @@ -1,6 +1,7 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized void foo() { } @@ -103,7 +104,7 @@ T tmain(T argc) { for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for map(T) // expected-error {{'T' does not refer to a value}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for map(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target teams distribute parallel for map(I) // omp4-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error 2 {{expected addressable lvalue in 'map' clause}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for map(S2::S2s) for (i = 0; i < argc; ++i) foo(); @@ -121,7 +122,8 @@ T tmain(T argc) { for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target teams distribute parallel for map(tofrom \ + : argc > 0 ? x : y) // omp4-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error 2 {{expected addressable lvalue in 'map' clause}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for map(argc) for (i = 0; i < argc; ++i) foo(); @@ -229,7 +231,8 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for map(tofrom: argc > 0 ? argv[1] : argv[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target teams distribute parallel for map(tofrom \ + : argc > 0 ? argv[1] : argv[2]) // omp4-error {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error {{expected addressable lvalue in 'map' clause}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for map(argc) for (i = 0; i < argc; ++i) foo(); diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_schedule_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_schedule_codegen.cpp index 8eb6c443ca2d8..3ec1782f2c09d 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_schedule_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_schedule_codegen.cpp @@ -3,12 +3,19 @@ #define HEADER // Test host codegen. -// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-OMP45 --check-prefix CK1-64 +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-OMP45 --check-prefix CK1-64 +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-OMP45 --check-prefix CK1-32 +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-OMP45 --check-prefix CK1-32 + +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-OMP50 --check-prefix CK1-64 // RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 -// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 +// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-OMP50 --check-prefix CK1-64 +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-OMP50 --check-prefix CK1-32 // RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 +// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-OMP50 --check-prefix CK1-32 // RUN: %clang_cc1 -DCK1 -verify -fopenmp-simd -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix SIMD-ONLY // RUN: %clang_cc1 -DCK1 -fopenmp-simd -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s @@ -116,7 +123,8 @@ struct SS{ // CK1: ret void // CK1: define internal void @[[PAR_OUTL4]]({{.+}}) - // CK1: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, + // CK1-OMP45: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, + // CK1-OMP50: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 1073741859, // CK1: call {{.+}} @__kmpc_dispatch_next_4( // CK1: ret void @@ -131,7 +139,8 @@ struct SS{ // CK1: ret void // CK1: define internal void @[[PAR_OUTL5]]({{.+}}) - // CK1: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, + // CK1-OMP45: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, + // CK1-OMP50: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 1073741859, // CK1: call {{.+}} @__kmpc_dispatch_next_4( // CK1: ret void @@ -147,12 +156,19 @@ int teams_template_struct(void) { #endif // CK1 // Test host codegen. -// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 --check-prefix OMP45 +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 --check-prefix OMP45 +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 --check-prefix OMP45 +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 --check-prefix OMP45 + +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 --check-prefix OMP50 // RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 -// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 +// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 --check-prefix OMP50 +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 --check-prefix OMP50 // RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 +// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 --check-prefix OMP50 // RUN: %clang_cc1 -DCK2 -verify -fopenmp-simd -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix SIMD-ONLY // RUN: %clang_cc1 -DCK2 -fopenmp-simd -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s @@ -287,7 +303,8 @@ int main (int argc, char **argv) { // CK2: ret void // CK2: define internal void @[[PAR_OUTL4]]({{.+}}) -// CK2: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP45: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP50: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 1073741859, // CK2: call {{.+}} @__kmpc_dispatch_next_4( // CK2: ret void @@ -303,7 +320,8 @@ int main (int argc, char **argv) { // CK2: ret void // CK2: define internal void @[[PAR_OUTL5]]({{.+}}) -// CK2: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP45: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP50: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 1073741859, // CK2: call {{.+}} @__kmpc_dispatch_next_4( // CK2: ret void @@ -377,7 +395,8 @@ int main (int argc, char **argv) { // CK2: ret void // CK2: define internal void @[[PAR_OUTLT4]]({{.+}}) -// CK2: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP45: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP50: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 1073741859, // CK2: call {{.+}} @__kmpc_dispatch_next_4( // CK2: ret void @@ -392,7 +411,8 @@ int main (int argc, char **argv) { // CK2: ret void // CK2: define internal void @[[PAR_OUTLT5]]({{.+}}) -// CK2: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP45: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP50: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 1073741859, // CK2: call {{.+}} @__kmpc_dispatch_next_4( // CK2: ret void diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_default_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_default_messages.cpp index 7c46c964d2ec3..e5ff856222501 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_default_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_default_messages.cpp @@ -2,16 +2,25 @@ // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target teams distribute parallel for simd default // expected-error {{expected '(' after 'default'}} for (int i=0; i<200; i++) foo(); -#pragma omp target teams distribute parallel for simd default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target teams distribute parallel for simd default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); -#pragma omp target teams distribute parallel for simd default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target teams distribute parallel for simd default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target teams distribute parallel for simd default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -20,11 +29,19 @@ int main(int argc, char **argv) { #pragma omp target teams distribute parallel for simd default (shared), default(shared) // expected-error {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'default' clause}} for (int i=0; i<200; i++) foo(); -#pragma omp target teams distribute parallel for simd default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target teams distribute parallel for simd default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target teams distribute parallel for simd default(none) // expected-note {{explicit data sharing attribute requested here}} for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} +#ifndef OMP51 +#pragma omp target teams distribute parallel for simd default(firstprivate) // expected-error {{data-sharing attribute 'firstprivate' in 'default' clause requires OpenMP version 5.1 or above}} + for (int i = 0; i < argc; ++i) { + ++x; + ++y; + } +#endif + return 0; } diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_messages.cpp index b0378423aaa06..dc584508e7b59 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_messages.cpp @@ -1,7 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized - -// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp-simd -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized void foo() { } @@ -25,35 +26,40 @@ int main(int argc, char **argv, char *env[]) { #pragma omp target teams distribute parallel for simd depend // expected-error {{expected '(' after 'depend'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} - for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target teams distribute parallel for simd depend( // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target teams distribute parallel for simd depend() // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp target teams distribute parallel for simd depend(argc // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp target teams distribute parallel for simd depend(source : argc) // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target teams distribute parallel for simd depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for simd depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute parallel for simd' are ignored}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd depend (out: ) // expected-error {{expected expression}} - for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} - for (i = 0; i < argc; ++i) foo(); +#pragma omp target teams distribute parallel for simd depend(out:) // expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target teams distribute parallel for simd depend(inout : foobool(argc)), depend(in, argc) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); #pragma omp target teams distribute parallel for simd depend (out :S1) // expected-error {{'S1' does not refer to a value}} - for (i = 0; i < argc; ++i) foo(); + for (i = 0; i < argc; ++i) + foo(); #pragma omp target teams distribute parallel for simd depend(in : argv[1][1] = '2') for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}} - for (i = 0; i < argc; ++i) foo(); +#pragma omp target teams distribute parallel for simd depend(in : vec[1]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} + for (i = 0; i < argc; ++i) + foo(); #pragma omp target teams distribute parallel for simd depend (in : argv[0]) for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd depend (in : ) // expected-error {{expected expression}} +#pragma omp target teams distribute parallel for simd depend(in:) // expected-error {{expected expression}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for simd depend (in : main) for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}} +#pragma omp target teams distribute parallel for simd depend(in : a[0]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for simd depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}} for (i = 0; i < argc; ++i) foo(); @@ -73,7 +79,7 @@ int main(int argc, char **argv, char *env[]) { for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for simd depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} +#pragma omp target teams distribute parallel for simd depend(in : argv [3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for simd depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} for (i = 0; i < argc; ++i) foo(); diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_messages.cpp index 73125b62bb3dd..fb64d4e9ee167 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_messages.cpp @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 %s -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp-simd -fopenmp-version=50 %s -Wuninitialized #pragma omp requires dynamic_allocators typedef void **omp_allocator_handle_t; @@ -133,8 +135,9 @@ int main(int argc, char **argv) { #pragma omp target teams distribute parallel for simd firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd private(i), firstprivate(i) // expected-error {{private variable cannot be firstprivate}} expected-note 2 {{defined as private}} - for (i = 0; i < argc; ++i) foo(); // expected-error {{loop iteration variable in the associated loop of 'omp target teams distribute parallel for simd' directive may not be private, predetermined as linear}} +#pragma omp target teams distribute parallel for simd private(i), firstprivate(i) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}} omp4-note {{defined as private}} + for (i = 0; i < argc; ++i) // omp4-error {{loop iteration variable in the associated loop of 'omp target teams distribute parallel for simd' directive may not be private, predetermined as linear}} + foo(); #pragma omp target teams distribute parallel for simd firstprivate(i) for (j = 0; j < argc; ++j) foo(); diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_is_device_ptr_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_is_device_ptr_messages.cpp index b368f2a3f5486..1f8f71afcd4ab 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_is_device_ptr_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_is_device_ptr_messages.cpp @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -std=c++11 -verify -fopenmp %s -Wuninitialized +// RUN: %clang_cc1 -std=c++11 -verify=expected,omp4 -fopenmp -fopenmp-version=45 %s -Wuninitialized // RUN: %clang_cc1 -std=c++11 -verify -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -std=c++11 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 %s -Wuninitialized + struct ST { int *a; }; @@ -228,13 +231,13 @@ T tmain(T argc) { #pragma omp target teams distribute parallel for simd is_device_ptr(ps) map(ps->a) // expected-error{{pointer cannot be mapped along with a section derived from itself}} expected-note{{used here}} for (int i=0; i<100; i++) ; -#pragma omp target teams distribute parallel for simd is_device_ptr(ps) firstprivate(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for simd' directive}} +#pragma omp target teams distribute parallel for simd is_device_ptr(ps) firstprivate(ps) // omp4-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for simd' directive}} for (int i=0; i<100; i++) ; #pragma omp target teams distribute parallel for simd firstprivate(ps) is_device_ptr(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for simd' directive}} expected-note{{defined as firstprivate}} for (int i=0; i<100; i++) ; -#pragma omp target teams distribute parallel for simd is_device_ptr(ps) private(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for simd' directive}} +#pragma omp target teams distribute parallel for simd is_device_ptr(ps) private(ps) // omp4-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for simd' directive}} for (int i=0; i<100; i++) ; #pragma omp target teams distribute parallel for simd private(ps) is_device_ptr(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for simd' directive}} expected-note{{defined as private}} @@ -323,13 +326,13 @@ int main(int argc, char **argv) { #pragma omp target teams distribute parallel for simd is_device_ptr(ps) map(ps->a) // expected-error{{pointer cannot be mapped along with a section derived from itself}} expected-note{{used here}} for (int i=0; i<100; i++) ; -#pragma omp target teams distribute parallel for simd is_device_ptr(ps) firstprivate(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for simd' directive}} +#pragma omp target teams distribute parallel for simd is_device_ptr(ps) firstprivate(ps) // omp4-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for simd' directive}} for (int i=0; i<100; i++) ; #pragma omp target teams distribute parallel for simd firstprivate(ps) is_device_ptr(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for simd' directive}} expected-note{{defined as firstprivate}} for (int i=0; i<100; i++) ; -#pragma omp target teams distribute parallel for simd is_device_ptr(ps) private(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for simd' directive}} +#pragma omp target teams distribute parallel for simd is_device_ptr(ps) private(ps) // omp4-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for simd' directive}} for (int i=0; i<100; i++) ; #pragma omp target teams distribute parallel for simd private(ps) is_device_ptr(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute parallel for simd' directive}} expected-note{{defined as private}} diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_messages.cpp index 49aa77c953c11..3be5fc7bcdf92 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_messages.cpp @@ -1,9 +1,9 @@ -// RUN: %clang_cc1 -verify=expected,le45 -fopenmp %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,le50 -fopenmp %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,le45 -fopenmp-version=40 -fopenmp %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,le45 -fopenmp-version=45 -fopenmp %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,le50 -fopenmp-version=50 -fopenmp %s -Wuninitialized -// RUN: %clang_cc1 -verify=expected,le45 -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,le50 -fopenmp-simd %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,le50 -fopenmp-version=50 -fopenmp-simd %s -Wuninitialized typedef void **omp_allocator_handle_t; diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_map_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_map_messages.cpp index 25c5d938d9151..b53a506bf234b 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_map_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_map_messages.cpp @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp-simd -fopenmp-version=50 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized void foo() { } @@ -103,7 +105,7 @@ T tmain(T argc) { for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for simd map(T) // expected-error {{'T' does not refer to a value}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd map(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target teams distribute parallel for simd map(I) // omp4-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error 2 {{expected addressable lvalue in 'map' clause}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for simd map(S2::S2s) for (i = 0; i < argc; ++i) foo(); @@ -121,7 +123,8 @@ T tmain(T argc) { for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for simd map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target teams distribute parallel for simd map(tofrom \ + : argc > 0 ? x : y) // omp4-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error 2 {{expected addressable lvalue in 'map' clause}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for simd map(argc) for (i = 0; i < argc; ++i) foo(); @@ -229,7 +232,8 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for simd map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute parallel for simd map(tofrom: argc > 0 ? argv[1] : argv[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target teams distribute parallel for simd map(tofrom \ + : argc > 0 ? argv[1] : argv[2]) // omp4-error {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error {{expected addressable lvalue in 'map' clause}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for simd map(argc) for (i = 0; i < argc; ++i) foo(); diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_schedule_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_schedule_codegen.cpp index 799769739d976..9852a75187481 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_schedule_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_schedule_codegen.cpp @@ -3,12 +3,19 @@ #define HEADER // Test host codegen. -// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 --check-prefix CK1-OMP45 +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 --check-prefix CK1-OMP45 +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 --check-prefix CK1-OMP45 +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 --check-prefix CK1-OMP45 + +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 --check-prefix CK1-OMP50 // RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 -// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 +// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 --check-prefix CK1-OMP50 +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 --check-prefix CK1-OMP50 // RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 +// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 --check-prefix CK1-OMP50 // RUN: %clang_cc1 -DCK1 -verify -fopenmp-simd -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix SIMD-ONLY // RUN: %clang_cc1 -DCK1 -fopenmp-simd -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s @@ -116,7 +123,8 @@ struct SS{ // CK1: ret void // CK1: define internal void @[[PAR_OUTL4]]({{.+}}) - // CK1: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, + // CK1-OMP45: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, + // CK1-OMP50: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 1073741859, // CK1: call {{.+}} @__kmpc_dispatch_next_4( // CK1: ret void @@ -131,7 +139,8 @@ struct SS{ // CK1: ret void // CK1: define internal void @[[PAR_OUTL5]]({{.+}}) - // CK1: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, + // CK1-OMP45: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, + // CK1-OMP50: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 1073741859, // CK1: call {{.+}} @__kmpc_dispatch_next_4( // CK1: ret void @@ -147,12 +156,19 @@ int teams_template_struct(void) { #endif // CK1 // Test host codegen. -// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 --check-prefix CK2-OMP45 +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 --check-prefix CK2-OMP45 +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 --check-prefix CK2-OMP45 +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 --check-prefix CK2-OMP45 + +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 --check-prefix CK2-OMP50 // RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 -// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 +// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 --check-prefix CK2-OMP50 +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 --check-prefix CK2-OMP50 // RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 +// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 --check-prefix CK2-OMP50 // RUN: %clang_cc1 -DCK2 -verify -fopenmp-simd -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix SIMD-ONLY // RUN: %clang_cc1 -DCK2 -fopenmp-simd -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s @@ -287,7 +303,8 @@ int main (int argc, char **argv) { // CK2: ret void // CK2: define internal void @[[PAR_OUTL4]]({{.+}}) -// CK2: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP45: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP50: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 1073741859, // CK2: call {{.+}} @__kmpc_dispatch_next_4( // CK2: ret void @@ -303,7 +320,8 @@ int main (int argc, char **argv) { // CK2: ret void // CK2: define internal void @[[PAR_OUTL5]]({{.+}}) -// CK2: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP45: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP50: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 1073741859, // CK2: call {{.+}} @__kmpc_dispatch_next_4( // CK2: ret void @@ -377,7 +395,8 @@ int main (int argc, char **argv) { // CK2: ret void // CK2: define internal void @[[PAR_OUTLT4]]({{.+}}) -// CK2: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP45: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP50: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 1073741859, // CK2: call {{.+}} @__kmpc_dispatch_next_4( // CK2: ret void @@ -392,7 +411,8 @@ int main (int argc, char **argv) { // CK2: ret void // CK2: define internal void @[[PAR_OUTLT5]]({{.+}}) -// CK2: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP45: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP50: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 1073741859, // CK2: call {{.+}} @__kmpc_dispatch_next_4( // CK2: ret void diff --git a/clang/test/OpenMP/target_teams_distribute_simd_depend_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_simd_depend_codegen.cpp index 8e1240aa596e1..4e8ff2f70234a 100644 --- a/clang/test/OpenMP/target_teams_distribute_simd_depend_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_simd_depend_codegen.cpp @@ -1,10 +1,19 @@ // Test host codegen. -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix OMP50 --check-prefix OMP50-64 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix OMP45 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 +// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix OMP50 --check-prefix OMP50-64 +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix OMP50 --check-prefix OMP50-32 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 +// RUN: %clang_cc1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix OMP50 --check-prefix OMP50-32 + + +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 --check-prefix OMP45 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix OMP45 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 --check-prefix OMP45 + // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s @@ -43,9 +52,14 @@ // TCHECK: [[ENTTY:%.+]] = type { i8*, i8*, i{{32|64}}, i32, i32 } -// CHECK-DAG: [[SIZET:@.+]] = private unnamed_addr constant [2 x i64] [i64 0, i64 4] -// CHECK-DAG: [[MAPT:@.+]] = private unnamed_addr constant [2 x i64] [i64 544, i64 800] -// CHECK-DAG: @{{.*}} = weak constant i8 0 +// OMP45-DAG: [[SIZET:@.+]] = private unnamed_addr constant [2 x i64] [i64 0, i64 4] +// OMP45-DAG: [[MAPT:@.+]] = private unnamed_addr constant [2 x i64] [i64 544, i64 800] +// OMP45-DAG: @{{.*}} = weak constant i8 0 + +// OMP50-DAG: [[SIZET:@.+]] = private unnamed_addr constant [3 x i64] [i64 0, i64 4, i64 1] +// OMP50-DAG: [[MAPT:@.+]] = private unnamed_addr constant [3 x i64] [i64 544, i64 800, i64 800] +// OMP50-DAG: @{{.*}} = weak constant i8 0 + // TCHECK: @{{.+}} = weak constant [[ENTTY]] // TCHECK: @{{.+}} = {{.*}}constant [[ENTTY]] @@ -98,31 +112,52 @@ int foo(int n) { // CHECK: [[ADD:%.+]] = add nsw i32 // CHECK: store i32 [[ADD]], i32* [[DEVICE_CAP:%.+]], - // CHECK: [[BOOL:%.+]] = icmp ne i32 %{{.+}}, 0 - // CHECK: br i1 [[BOOL]], label %[[THEN:.+]], label %[[ELSE:.+]] + // OMP45: [[BOOL:%.+]] = icmp ne i32 %{{.+}}, 0 + // OMP45: br i1 [[BOOL]], label %[[THEN:.+]], label %[[ELSE:.+]] + // OMP50: br i1 {{.+}}, label %[[THEN:.+]], label %[[ELSE:.+]] // CHECK: [[THEN]]: - // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP:%.+]], i32 0, i32 0 - // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P:%.+]], i32 0, i32 0 + // OMP45-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP:%.+]], i32 0, i32 0 + // OMP45-DAG: [[PADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P:%.+]], i32 0, i32 0 + // OMP50-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP:%.+]], i32 0, i32 0 + // OMP50-DAG: [[PADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P:%.+]], i32 0, i32 0 // CHECK-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to i[[SZ]]** // CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to i[[SZ]]** // CHECK-DAG: store i[[SZ]]* [[BP0:%[^,]+]], i[[SZ]]** [[CBPADDR0]] // CHECK-DAG: store i[[SZ]]* [[BP0]], i[[SZ]]** [[CPADDR0]] - // CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 1 - // CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 1 + // OMP45-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 1 + // OMP45-DAG: [[PADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 1 + + // OMP50-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 1 + // OMP50-DAG: [[PADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 1 // CHECK-DAG: [[CBPADDR1:%.+]] = bitcast i8** [[BPADDR1]] to i[[SZ]]* // CHECK-DAG: [[CPADDR1:%.+]] = bitcast i8** [[PADDR1]] to i[[SZ]]* // CHECK-DAG: store i[[SZ]] [[BP1:%[^,]+]], i[[SZ]]* [[CBPADDR1]] // CHECK-DAG: store i[[SZ]] [[BP1]], i[[SZ]]* [[CPADDR1]] - // CHECK-DAG: getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 0 - // CHECK-DAG: getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 0 - // CHECK: [[GEP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 + + // OMP50-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 2 + // OMP50-DAG: [[PADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 2 + // OMP50-DAG: [[CBPADDR2:%.+]] = bitcast i8** [[BPADDR2]] to i[[SZ]]* + // OMP50-DAG: [[CPADDR2:%.+]] = bitcast i8** [[PADDR2]] to i[[SZ]]* + // OMP50-DAG: store i[[SZ]] [[BP2:%[^,]+]], i[[SZ]]* [[CBPADDR2]] + // OMP50-DAG: store i[[SZ]] [[BP2]], i[[SZ]]* [[CPADDR2]] + + + // OMP45-DAG: getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 0 + // OMP45-DAG: getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 0 + // OMP50-DAG: getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 0 + // OMP50-DAG: getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 0 + + // OMP45: [[GEP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 + // OMP50-64: [[GEP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 4 + // OMP50-32: [[GEP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 3 // CHECK: [[DEV:%.+]] = load i32, i32* [[DEVICE_CAP]], // CHECK: store i32 [[DEV]], i32* [[GEP]], // CHECK: [[DEV1:%.+]] = load i32, i32* [[DEVICE_CAP]], // CHECK: [[DEV2:%.+]] = sext i32 [[DEV1]] to i64 - // CHECK: [[TASK:%.+]] = call i8* @__kmpc_omp_target_task_alloc(%struct.ident_t* [[ID]], i32 [[GTID]], i32 1, i[[SZ]] {{104|60}}, i[[SZ]] {{16|12}}, i32 (i32, i8*)* bitcast (i32 (i32, %{{.+}}*)* [[TASK_ENTRY1_:@.+]] to i32 (i32, i8*)*), i64 [[DEV2]]) + // OMP45: [[TASK:%.+]] = call i8* @__kmpc_omp_target_task_alloc(%struct.ident_t* [[ID]], i32 [[GTID]], i32 1, i[[SZ]] {{104|60}}, i[[SZ]] {{16|12}}, i32 (i32, i8*)* bitcast (i32 (i32, %{{.+}}*)* [[TASK_ENTRY1_:@.+]] to i32 (i32, i8*)*), i64 [[DEV2]]) + // OMP50: [[TASK:%.+]] = call i8* @__kmpc_omp_target_task_alloc(%struct.ident_t* [[ID]], i32 [[GTID]], i32 1, i[[SZ]] {{28|128|76}}, i[[SZ]] {{16|12|24}}, i32 (i32, i8*)* bitcast (i32 (i32, %{{.+}}*)* [[TASK_ENTRY1_:@.+]] to i32 (i32, i8*)*), i64 [[DEV2]]) // CHECK: [[BC_TASK:%.+]] = bitcast i8* [[TASK]] to [[TASK_TY1_:%.+]]* // CHECK: getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* %{{.+}}, i[[SZ]] 0 // CHECK: getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* %{{.+}}, i[[SZ]] 1 @@ -132,14 +167,18 @@ int foo(int n) { // CHECK: br label %[[EXIT:.+]] // CHECK: [[ELSE]]: - // CHECK-NOT: getelementptr inbounds [2 x i8*], [2 x i8*]* - // CHECK: [[GEP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 + // OMP45-NOT: getelementptr inbounds [2 x i8*], [2 x i8*]* + // OMP50-NOT: getelementptr inbounds [3 x i8*], [3 x i8*]* + // OMP45: [[GEP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 + // OMP50-64: [[GEP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 4 + // OMP50-32: [[GEP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 3 // CHECK: [[DEV:%.+]] = load i32, i32* [[DEVICE_CAP]], // CHECK: store i32 [[DEV]], i32* [[GEP]], // CHECK: [[DEV1:%.+]] = load i32, i32* [[DEVICE_CAP]], // CHECK: [[DEV2:%.+]] = sext i32 [[DEV1]] to i64 - // CHECK: [[TASK:%.+]] = call i8* @__kmpc_omp_target_task_alloc(%struct.ident_t* [[ID]], i32 [[GTID]], i32 1, i[[SZ]] {{56|28}}, i[[SZ]] {{16|12}}, i32 (i32, i8*)* bitcast (i32 (i32, %{{.+}}*)* [[TASK_ENTRY1__:@.+]] to i32 (i32, i8*)*), i64 [[DEV2]]) + // OMP45: [[TASK:%.+]] = call i8* @__kmpc_omp_target_task_alloc(%struct.ident_t* [[ID]], i32 [[GTID]], i32 1, i[[SZ]] {{56|28}}, i[[SZ]] {{16|12}}, i32 (i32, i8*)* bitcast (i32 (i32, %{{.+}}*)* [[TASK_ENTRY1__:@.+]] to i32 (i32, i8*)*), i64 [[DEV2]]) + // OMP50: [[TASK:%.+]] = call i8* @__kmpc_omp_target_task_alloc(%struct.ident_t* [[ID]], i32 [[GTID]], i32 1, i[[SZ]] {{56|28}}, i[[SZ]] {{16|12|24}}, i32 (i32, i8*)* bitcast (i32 (i32, %{{.+}}*)* [[TASK_ENTRY1__:@.+]] to i32 (i32, i8*)*), i64 [[DEV2]]) // CHECK: [[BC_TASK:%.+]] = bitcast i8* [[TASK]] to [[TASK_TY1__:%.+]]* // CHECK: getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* %{{.+}}, i[[SZ]] 0 // CHECK: getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* %{{.+}}, i[[SZ]] 1 @@ -195,11 +234,15 @@ int foo(int n) { // CHECK: define internal{{.*}} i32 [[TASK_ENTRY1_]](i32{{.*}}, [[TASK_TY1_]]* noalias %1) // CHECK: call void (i8*, ...) % -// CHECK: [[SZT:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0 -// CHECK: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 +// OMP45: [[SZT:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0 +// OMP50: [[SZT:%.+]] = getelementptr inbounds [3 x i64], [3 x i64]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0 +// OMP45: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 +// OMP50-64: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 4 +// OMP50-32: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 3 // CHECK: [[DEV:%.+]] = load i32, i32* [[DEVICE_CAP]], // CHECK: [[DEVICE:%.+]] = sext i32 [[DEV]] to i64 -// CHECK: [[RET:%.+]] = call i32 @__tgt_target_teams_nowait(i64 [[DEVICE]], i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i64* [[SZT]], i64* getelementptr inbounds ([2 x i64], [2 x i64]* [[MAPT]], i32 0, i32 0), i32 0, i32 1) +// OMP45: [[RET:%.+]] = call i32 @__tgt_target_teams_nowait(i64 [[DEVICE]], i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i64* [[SZT]], i64* getelementptr inbounds ([2 x i64], [2 x i64]* [[MAPT]], i32 0, i32 0), i32 0, i32 1) +// OMP50: [[RET:%.+]] = call i32 @__tgt_target_teams_nowait(i64 [[DEVICE]], i8* @{{[^,]+}}, i32 3, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i64* [[SZT]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* [[MAPT]], i32 0, i32 0), i32 0, i32 1) // CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0 // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]] @@ -210,7 +253,10 @@ int foo(int n) { // CHECK-64: store i32 [[BP1_I32]], i32* [[BP1_CAST]], // CHECK-32: store i32 [[BP1_I32]], i32* [[BP1_PTR:%.+]], // CHECK: [[BP1:%.+]] = load i[[SZ]], i[[SZ]]* [[BP1_PTR]], -// CHECK: call void [[HVT1]](i[[SZ]]* [[BP0]], i[[SZ]] [[BP1]]) +// OMP45: call void [[HVT1]](i[[SZ]]* [[BP0]], i[[SZ]] [[BP1]]) + +// OMP50: [[BP2:%.+]] = load i[[SZ]], i[[SZ]]* +// OMP50: call void [[HVT1]](i[[SZ]]* [[BP0]], i[[SZ]] [[BP1]], i[[SZ]] [[BP2]]) // CHECK-NEXT: br label %[[END]] // CHECK: [[END]] // CHECK: ret i32 0 @@ -224,7 +270,10 @@ int foo(int n) { // CHECK-64: store i32 [[BP1_I32]], i32* [[BP1_CAST]], // CHECK-32: store i32 [[BP1_I32]], i32* [[BP1_PTR:%.+]], // CHECK: [[BP1:%.+]] = load i[[SZ]], i[[SZ]]* [[BP1_PTR]], -// CHECK: call void [[HVT1]](i[[SZ]]* [[BP0]], i[[SZ]] [[BP1]]) +// OMP50: [[BP2:%.+]] = load i[[SZ]], i[[SZ]]* +// OMP45: call void [[HVT1]](i[[SZ]]* [[BP0]], i[[SZ]] [[BP1]]) +// OMP50: call void [[HVT1]](i[[SZ]]* [[BP0]], i[[SZ]] [[BP1]], i[[SZ]] [[BP2]]) + // CHECK: ret i32 0 // CHECK: define internal void [[HVT2:@.+]](i[[SZ]] %{{.+}}) diff --git a/clang/test/OpenMP/target_teams_distribute_simd_depend_messages.cpp b/clang/test/OpenMP/target_teams_distribute_simd_depend_messages.cpp index 8c9332a3e1237..a864e21a6968b 100644 --- a/clang/test/OpenMP/target_teams_distribute_simd_depend_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_simd_depend_messages.cpp @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp-simd -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized void foo() { } @@ -25,35 +27,38 @@ int main(int argc, char **argv, char *env[]) { #pragma omp target teams distribute simd depend // expected-error {{expected '(' after 'depend'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute simd depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target teams distribute simd depend( // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute simd depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target teams distribute simd depend() // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute simd depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target teams distribute simd depend(argc // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute simd depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} - for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute simd depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp target teams distribute simd depend(source : argc) // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target teams distribute simd depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute simd depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target teams distribute simd' are ignored}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute simd depend (out: ) // expected-error {{expected expression}} - for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute simd depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target teams distribute simd depend(inout : foobool(argc)), depend(in, argc) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute simd depend (out :S1) // expected-error {{'S1' does not refer to a value}} - for (i = 0; i < argc; ++i) foo(); + for (i = 0; i < argc; ++i) + foo(); #pragma omp target teams distribute simd depend(in : argv[1][1] = '2') for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute simd depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}} +#pragma omp target teams distribute simd depend(in : vec[1]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute simd depend (in : argv[0]) for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute simd depend (in : ) // expected-error {{expected expression}} +#pragma omp target teams distribute simd depend(in:) // expected-error {{expected expression}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute simd depend (in : main) for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute simd depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}} +#pragma omp target teams distribute simd depend(in : a[0]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute simd depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}} for (i = 0; i < argc; ++i) foo(); @@ -73,7 +78,7 @@ int main(int argc, char **argv, char *env[]) { for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute simd depend (in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute simd depend (in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} +#pragma omp target teams distribute simd depend(in : argv [3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute simd depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} for (i = 0; i < argc; ++i) foo(); diff --git a/clang/test/OpenMP/target_teams_distribute_simd_firstprivate_messages.cpp b/clang/test/OpenMP/target_teams_distribute_simd_firstprivate_messages.cpp index 04f993f051f4e..28fb06e4add9e 100644 --- a/clang/test/OpenMP/target_teams_distribute_simd_firstprivate_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_simd_firstprivate_messages.cpp @@ -1,9 +1,9 @@ -// RUN: %clang_cc1 -verify=expected,le45 -fopenmp %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,le50 -fopenmp %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,le45 -fopenmp-version=40 -fopenmp %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,le45 -fopenmp-version=45 -fopenmp %s -Wuninitialized // RUN: %clang_cc1 -verify=expected -fopenmp-version=50 -fopenmp %s -Wuninitialized -// RUN: %clang_cc1 -verify=expected,le45 -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,le50 -fopenmp-simd %s -Wuninitialized #pragma omp requires dynamic_allocators typedef void **omp_allocator_handle_t; diff --git a/clang/test/OpenMP/target_teams_distribute_simd_is_device_ptr_messages.cpp b/clang/test/OpenMP/target_teams_distribute_simd_is_device_ptr_messages.cpp index 3de17bf0ceccd..e311cf1a698e0 100644 --- a/clang/test/OpenMP/target_teams_distribute_simd_is_device_ptr_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_simd_is_device_ptr_messages.cpp @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -std=c++11 -verify -fopenmp %s -Wuninitialized +// RUN: %clang_cc1 -std=c++11 -verify=expected,omp4 -fopenmp -fopenmp-version=45 %s -Wuninitialized +// RUN: %clang_cc1 -std=c++11 -verify -fopenmp -fopenmp-version=50 %s -Wuninitialized -// RUN: %clang_cc1 -std=c++11 -verify -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -std=c++11 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 %s -Wuninitialized +// RUN: %clang_cc1 -std=c++11 -verify -fopenmp-simd -fopenmp-version=50 %s -Wuninitialized struct ST { int *a; }; @@ -228,13 +230,13 @@ T tmain(T argc) { #pragma omp target teams distribute simd is_device_ptr(ps) map(ps->a) // expected-error{{pointer cannot be mapped along with a section derived from itself}} expected-note{{used here}} for (int i=0; i<100; i++) ; -#pragma omp target teams distribute simd is_device_ptr(ps) firstprivate(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute simd' directive}} +#pragma omp target teams distribute simd is_device_ptr(ps) firstprivate(ps) // omp4-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute simd' directive}} for (int i=0; i<100; i++) ; #pragma omp target teams distribute simd firstprivate(ps) is_device_ptr(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute simd' directive}} expected-note{{defined as firstprivate}} for (int i=0; i<100; i++) ; -#pragma omp target teams distribute simd is_device_ptr(ps) private(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute simd' directive}} +#pragma omp target teams distribute simd is_device_ptr(ps) private(ps) // omp4-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute simd' directive}} for (int i=0; i<100; i++) ; #pragma omp target teams distribute simd private(ps) is_device_ptr(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute simd' directive}} expected-note{{defined as private}} @@ -323,13 +325,13 @@ int main(int argc, char **argv) { #pragma omp target teams distribute simd is_device_ptr(ps) map(ps->a) // expected-error{{pointer cannot be mapped along with a section derived from itself}} expected-note{{used here}} for (int i=0; i<100; i++) ; -#pragma omp target teams distribute simd is_device_ptr(ps) firstprivate(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute simd' directive}} +#pragma omp target teams distribute simd is_device_ptr(ps) firstprivate(ps) // omp4-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute simd' directive}} for (int i=0; i<100; i++) ; #pragma omp target teams distribute simd firstprivate(ps) is_device_ptr(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute simd' directive}} expected-note{{defined as firstprivate}} for (int i=0; i<100; i++) ; -#pragma omp target teams distribute simd is_device_ptr(ps) private(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute simd' directive}} +#pragma omp target teams distribute simd is_device_ptr(ps) private(ps) // omp4-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute simd' directive}} for (int i=0; i<100; i++) ; #pragma omp target teams distribute simd private(ps) is_device_ptr(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams distribute simd' directive}} expected-note{{defined as private}} diff --git a/clang/test/OpenMP/target_teams_distribute_simd_lastprivate_messages.cpp b/clang/test/OpenMP/target_teams_distribute_simd_lastprivate_messages.cpp index ac132f6b8f9fb..44295325e0d29 100644 --- a/clang/test/OpenMP/target_teams_distribute_simd_lastprivate_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_simd_lastprivate_messages.cpp @@ -1,9 +1,9 @@ -// RUN: %clang_cc1 -verify=expected,le45 -fopenmp %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,le50 -fopenmp %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,le45 -fopenmp-version=40 -fopenmp %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,le45 -fopenmp-version=45 -fopenmp %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,le50 -fopenmp-version=50 -fopenmp %s -Wuninitialized -// RUN: %clang_cc1 -verify=expected,le45 -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,le50 -fopenmp-simd %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,le50 -fopenmp-version=50 -fopenmp-simd %s -Wuninitialized typedef void **omp_allocator_handle_t; diff --git a/clang/test/OpenMP/target_teams_distribute_simd_loop_messages.cpp b/clang/test/OpenMP/target_teams_distribute_simd_loop_messages.cpp index 46dd35acfab3c..df0a1393a3735 100644 --- a/clang/test/OpenMP/target_teams_distribute_simd_loop_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_simd_loop_messages.cpp @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wno-openmp-mapping -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wno-openmp-mapping -Wuninitialized class S { int a; @@ -93,18 +95,12 @@ int test_iteration_spaces() { c[ii] = a[ii]; #pragma omp target teams distribute simd -// omp4-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} - for (int i = 0; i; i++) - c[i] = a[i]; - -#pragma omp target teams distribute simd -// omp4-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} -// expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'i'}} +// omp4-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} expected-error@+1 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'i'}} omp5-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', '>=', or '!=') of loop variable 'i'}} for (int i = 0; jj < kk; ii++) c[i] = a[i]; #pragma omp target teams distribute simd -// omp4-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +// omp4-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} omp5-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', '>=', or '!=') of loop variable 'i'}} for (int i = 0; !!i; i++) c[i] = a[i]; @@ -114,7 +110,7 @@ int test_iteration_spaces() { c[i] = a[i]; #pragma omp target teams distribute simd -// omp4-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} +// omp4-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}} omp5-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', '>=', or '!=') of loop variable 'i'}} for (int i = 0;; i++) c[i] = a[i]; @@ -244,13 +240,13 @@ int test_iteration_spaces() { for (ii = 0; ii < 10; ii++) c[ii] = a[ii]; -#pragma omp target teams distribute simd private(ii) // expected-note {{defined as private}} -// expected-error@+1 {{loop iteration variable in the associated loop of 'omp target teams distribute simd' directive may not be private, predetermined as linear}} +#pragma omp target teams distribute simd private(ii) // omp4-note {{defined as private}} +// omp4-error@+1 {{loop iteration variable in the associated loop of 'omp target teams distribute simd' directive may not be private, predetermined as linear}} for (ii = 0; ii < 10; ii++) c[ii] = a[ii]; -#pragma omp target teams distribute simd lastprivate(ii) // expected-note {{defined as lastprivate}} -// expected-error@+1 {{loop iteration variable in the associated loop of 'omp target teams distribute simd' directive may not be lastprivate, predetermined as linear}} +#pragma omp target teams distribute simd lastprivate(ii) // omp4-note {{defined as lastprivate}} +// omp4-error@+1 {{loop iteration variable in the associated loop of 'omp target teams distribute simd' directive may not be lastprivate, predetermined as linear}} for (ii = 0; ii < 10; ii++) c[ii] = a[ii]; @@ -267,7 +263,7 @@ int test_iteration_spaces() { } #pragma omp target teams distribute simd -// expected-error@+1 {{statement after '#pragma omp target teams distribute simd' must be a for loop}} +// omp4-error@+1 {{statement after '#pragma omp target teams distribute simd' must be a for loop}} for (auto &item : a) { item = item + 1; } @@ -403,15 +399,15 @@ int test_with_random_access_iterator() { for (begin = end; begin < end; ++begin) ++begin; #pragma omp target teams distribute simd -// omp4-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} +// omp4-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} omp5-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', '>=', or '!=') of loop variable 'I'}} for (GoodIter I = begin; I - I; ++I) ++I; #pragma omp target teams distribute simd -// omp4-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} +// omp4-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} omp5-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', '>=', or '!=') of loop variable 'I'}} for (GoodIter I = begin; begin < end; ++I) ++I; #pragma omp target teams distribute simd -// omp4-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} +// omp4-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}} omp5-error@+1 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', '>=', or '!=') of loop variable 'I'}} for (GoodIter I = begin; !I; ++I) ++I; #pragma omp target teams distribute simd diff --git a/clang/test/OpenMP/target_teams_distribute_simd_map_messages.cpp b/clang/test/OpenMP/target_teams_distribute_simd_map_messages.cpp index 71d2ee68b1d94..3bf612b7637f0 100644 --- a/clang/test/OpenMP/target_teams_distribute_simd_map_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_simd_map_messages.cpp @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp-simd -fopenmp-version=50 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized void foo() { } @@ -103,7 +105,7 @@ T tmain(T argc) { for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute simd map(T) // expected-error {{'T' does not refer to a value}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute simd map(I) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target teams distribute simd map(I) // omp4-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error 2 {{expected addressable lvalue in 'map' clause}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute simd map(S2::S2s) for (i = 0; i < argc; ++i) foo(); @@ -121,7 +123,8 @@ T tmain(T argc) { for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute simd map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute simd map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target teams distribute simd map(tofrom \ + : argc > 0 ? x : y) // omp4-error 2 {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error 2 {{expected addressable lvalue in 'map' clause}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute simd map(argc) for (i = 0; i < argc; ++i) foo(); @@ -228,8 +231,10 @@ int main(int argc, char **argv) { #pragma omp target teams distribute simd map(to, x) for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute simd map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} - for (i = 0; i < argc; ++i) foo(); -#pragma omp target teams distribute simd map(tofrom: argc > 0 ? argv[1] : argv[2]) // expected-error {{expected expression containing only member accesses and/or array sections based on named variables}} + for (i = 0; i < argc; ++i) + foo(); +#pragma omp target teams distribute simd map(tofrom \ + : argc > 0 ? argv[1] : argv[2]) // omp4-error {{expected expression containing only member accesses and/or array sections based on named variables}} omp5-error {{expected addressable lvalue in 'map' clause}} for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute simd map(argc) for (i = 0; i < argc; ++i) foo(); diff --git a/clang/test/OpenMP/target_teams_distribute_simd_private_messages.cpp b/clang/test/OpenMP/target_teams_distribute_simd_private_messages.cpp index fa57ef93b4a74..47d5a8fa6773a 100644 --- a/clang/test/OpenMP/target_teams_distribute_simd_private_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_simd_private_messages.cpp @@ -1,9 +1,9 @@ -// RUN: %clang_cc1 -verify=expected,le45 -fopenmp %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,le50 -fopenmp %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,le45 -fopenmp-version=40 -fopenmp %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,le45 -fopenmp-version=45 -fopenmp %s -Wuninitialized // RUN: %clang_cc1 -verify=expected -fopenmp-version=50 -fopenmp %s -Wuninitialized -// RUN: %clang_cc1 -verify=expected,le45 -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,le50 -fopenmp-simd %s -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 %s -Wuninitialized typedef void **omp_allocator_handle_t; diff --git a/clang/test/OpenMP/target_teams_is_device_ptr_messages.cpp b/clang/test/OpenMP/target_teams_is_device_ptr_messages.cpp index 1885d1e6994bd..d662390cdf1f0 100644 --- a/clang/test/OpenMP/target_teams_is_device_ptr_messages.cpp +++ b/clang/test/OpenMP/target_teams_is_device_ptr_messages.cpp @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -std=c++11 -verify -fopenmp -ferror-limit 200 %s -Wuninitialized +// RUN: %clang_cc1 -std=c++11 -verify=expected,omp4 -fopenmp -fopenmp-version=45 -ferror-limit 200 %s -Wuninitialized +// RUN: %clang_cc1 -std=c++11 -verify -fopenmp -fopenmp-version=50 -ferror-limit 200 %s -Wuninitialized -// RUN: %clang_cc1 -std=c++11 -verify -fopenmp-simd -ferror-limit 200 %s -Wuninitialized +// RUN: %clang_cc1 -std=c++11 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 -ferror-limit 200 %s -Wuninitialized +// RUN: %clang_cc1 -std=c++11 -verify -fopenmp-simd -fopenmp-version=50 -ferror-limit 200 %s -Wuninitialized struct ST { int *a; }; @@ -189,11 +191,11 @@ T tmain(T argc) { {} #pragma omp target teams is_device_ptr(ps) map(ps->a) // expected-error{{pointer cannot be mapped along with a section derived from itself}} expected-note{{used here}} {} -#pragma omp target teams is_device_ptr(ps) firstprivate(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams' directive}} +#pragma omp target teams is_device_ptr(ps) firstprivate(ps) // omp4-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams' directive}} {} #pragma omp target teams firstprivate(ps) is_device_ptr(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams' directive}} expected-note{{defined as firstprivate}} {} -#pragma omp target teams is_device_ptr(ps) private(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams' directive}} +#pragma omp target teams is_device_ptr(ps) private(ps) // omp4-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams' directive}} {} #pragma omp target teams private(ps) is_device_ptr(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams' directive}} expected-note{{defined as private}} {} @@ -258,11 +260,11 @@ int main(int argc, char **argv) { {} #pragma omp target teams is_device_ptr(ps) map(ps->a) // expected-error{{pointer cannot be mapped along with a section derived from itself}} expected-note{{used here}} {} -#pragma omp target teams is_device_ptr(ps) firstprivate(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams' directive}} +#pragma omp target teams is_device_ptr(ps) firstprivate(ps) // omp4-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams' directive}} {} #pragma omp target teams firstprivate(ps) is_device_ptr(ps) // expected-error{{firstprivate variable cannot be in a is_device_ptr clause in '#pragma omp target teams' directive}} expected-note{{defined as firstprivate}} {} -#pragma omp target teams is_device_ptr(ps) private(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams' directive}} +#pragma omp target teams is_device_ptr(ps) private(ps) // omp4-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams' directive}} {} #pragma omp target teams private(ps) is_device_ptr(ps) // expected-error{{private variable cannot be in a is_device_ptr clause in '#pragma omp target teams' directive}} expected-note{{defined as private}} {} diff --git a/clang/test/OpenMP/target_teams_map_messages.cpp b/clang/test/OpenMP/target_teams_map_messages.cpp index 11115d501912a..7828099d3e41e 100644 --- a/clang/test/OpenMP/target_teams_map_messages.cpp +++ b/clang/test/OpenMP/target_teams_map_messages.cpp @@ -1,9 +1,9 @@ -// RUN: %clang_cc1 -verify=expected,le45 -fopenmp -ferror-limit 200 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,le50 -fopenmp -ferror-limit 200 %s -Wno-openmp-mapping -Wuninitialized // RUN: %clang_cc1 -verify=expected,le45 -fopenmp-version=40 -fopenmp -ferror-limit 200 %s -Wno-openmp-mapping -Wuninitialized // RUN: %clang_cc1 -verify=expected,le45 -fopenmp-version=45 -fopenmp -ferror-limit 200 %s -Wno-openmp-mapping -Wuninitialized // RUN: %clang_cc1 -verify=expected,le50 -fopenmp-version=50 -fopenmp -ferror-limit 200 %s -Wno-openmp-mapping -Wuninitialized -// RUN: %clang_cc1 -verify=expected,le45 -fopenmp-simd -ferror-limit 200 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,le50 -fopenmp-simd -ferror-limit 200 %s -Wno-openmp-mapping -Wuninitialized // RUN: %clang_cc1 -DCCODE -verify=expected,le45 -fopenmp -ferror-limit 200 -x c %s -Wno-openmp-mapping -Wuninitialized #ifdef CCODE void foo(int arg) { diff --git a/clang/test/OpenMP/target_update_ast_print.cpp b/clang/test/OpenMP/target_update_ast_print.cpp index fb6440b87cea3..0111432fde8f6 100644 --- a/clang/test/OpenMP/target_update_ast_print.cpp +++ b/clang/test/OpenMP/target_update_ast_print.cpp @@ -20,6 +20,11 @@ T foo(T targ, U uarg) { #pragma omp target update to(([a][targ])p, a) if(l>5) device(l) nowait depend(inout:l) #pragma omp target update from(b, ([a][targ])p) if(l<5) device(l-1) nowait depend(inout:l) + + int arr[100][100]; +#pragma omp target update to(arr[2][0:1:2]) + +#pragma omp target update from(arr[2][0:1:2]) return a + targ + (T)b; } // CHECK: static T a, *p; @@ -37,6 +42,9 @@ T foo(T targ, U uarg) { // CHECK-NEXT: int l; // CHECK-NEXT: #pragma omp target update to(([a][targ])p,a) if(l > 5) device(l) nowait depend(inout : l) // CHECK-NEXT: #pragma omp target update from(b,([a][targ])p) if(l < 5) device(l - 1) nowait depend(inout : l) +// CHECK: int arr[100][100]; +// CHECK-NEXT: #pragma omp target update to(arr[2][0:1:2]) +// CHECK-NEXT: #pragma omp target update from(arr[2][0:1:2]) int main(int argc, char **argv) { static int a; @@ -50,6 +58,11 @@ int main(int argc, char **argv) { // CHECK-NEXT: #pragma omp target update to(a) if(f > 0.) device(n) nowait depend(in : n) #pragma omp target update from(f) if(f<0.0) device(n+1) nowait depend(in:n) // CHECK-NEXT: #pragma omp target update from(f) if(f < 0.) device(n + 1) nowait depend(in : n) +#pragma omp target update to(argv[2][0:1:2]) +// CHECK-NEXT: #pragma omp target update to(argv[2][0:1:2]) +#pragma omp target update from(argv[2][0:1:2]) +// CHECK-NEXT: #pragma omp target update from(argv[2][0:1:2]) + return foo(argc, f) + foo(argv[0][0], f) + a; } diff --git a/clang/test/OpenMP/target_update_depend_messages.cpp b/clang/test/OpenMP/target_update_depend_messages.cpp index b570f0c8672bc..b218d4d21889e 100644 --- a/clang/test/OpenMP/target_update_depend_messages.cpp +++ b/clang/test/OpenMP/target_update_depend_messages.cpp @@ -1,7 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized - -// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp-simd -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized void foo() { } @@ -29,37 +30,37 @@ int tmain(T argc, S **argv, R *env[]) { {} #pragma omp target update to(z) depend // expected-error {{expected '(' after 'depend'}} - #pragma omp target update to(z) depend( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} - #pragma omp target update to(z) depend() // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} - #pragma omp target update to(z) depend(argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp target update to(z) depend(source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} - #pragma omp target update to(z) depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} - #pragma omp target update to(z) depend(in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} - #pragma omp target update to(z) depend(out: ) // expected-error {{expected expression}} - #pragma omp target update to(z) depend(inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} - #pragma omp target update to(z) depend(out :S1) // expected-error {{'S1' does not refer to a value}} - #pragma omp target update to(z) depend(in : argv[1][1] = '2') // expected-error {{expected addressable lvalue expression, array element or array section}} - #pragma omp target update to(z) depend(in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}} - #pragma omp target update to(z) depend(in : argv[0]) - #pragma omp target update to(z) depend(in : ) // expected-error {{expected expression}} - #pragma omp target update to(z) depend(in : tmain) - #pragma omp target update to(z) depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}} - #pragma omp target update to(z) depend(in : vec[1:2]) // expected-error {{ value is not an array or pointer}} - #pragma omp target update to(z) depend(in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} - #pragma omp target update to(z) depend(in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} - #pragma omp target update to(z) depend(in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp target update to(z) depend(in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} - #pragma omp target update to(z) depend(in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp target update to(z) depend(in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} - #pragma omp target update to(z) depend(in : argv[-1:0]) // expected-error {{zero-length array section is not allowed in 'depend' clause}} - #pragma omp target update to(z) depend(in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} - #pragma omp target update to(z) depend(in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} - #pragma omp target update to(z) depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} - #pragma omp target update to(z) depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}} - #pragma omp target update to(z) depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} - #pragma omp target update to(z) depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}} - #pragma omp target update to(z) depend(in : argv[ : argc][1 : argc - 1]) - #pragma omp target update to(z) depend(in : arr[0]) +#pragma omp target update to(z) depend( // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target update to(z) depend() // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target update to(z) depend(argc // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update to(z) depend(source : argc) // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} +#pragma omp target update to(z) depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} +#pragma omp target update to(z) depend(in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} +#pragma omp target update to(z) depend(out:) // expected-error {{expected expression}} +#pragma omp target update to(z) depend(inout : foobool(argc)), depend(in, argc) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} +#pragma omp target update to(z) depend(out : S1) // expected-error {{'S1' does not refer to a value}} +#pragma omp target update to(z) depend(in : argv[1][1] = '2') // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} +#pragma omp target update to(z) depend(in : vec[1]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} +#pragma omp target update to(z) depend(in : argv[0]) +#pragma omp target update to(z) depend(in:) // expected-error {{expected expression}} +#pragma omp target update to(z) depend(in : tmain) +#pragma omp target update to(z) depend(in : a[0]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} +#pragma omp target update to(z) depend(in : vec [1:2]) // expected-error {{ value is not an array or pointer}} +#pragma omp target update to(z) depend(in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} +#pragma omp target update to(z) depend(in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} +#pragma omp target update to(z) depend(in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update to(z) depend(in : argv [argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} +#pragma omp target update to(z) depend(in : argv [argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update to(z) depend(in : argv [0:-1]) // expected-error {{section length is evaluated to a negative value -1}} +#pragma omp target update to(z) depend(in : argv [-1:0]) // expected-error {{zero-length array section is not allowed in 'depend' clause}} +#pragma omp target update to(z) depend(in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} +#pragma omp target update to(z) depend(in : argv [3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} +#pragma omp target update to(z) depend(in : a [0:1]) // expected-error {{subscripted value is not an array or pointer}} +#pragma omp target update to(z) depend(in : argv [argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}} +#pragma omp target update to(z) depend(in : argv [0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} +#pragma omp target update to(z) depend(in : env [0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}} +#pragma omp target update to(z) depend(in : argv[:argc] [1:argc - 1]) +#pragma omp target update to(z) depend(in : arr[0]) return 0; } @@ -76,36 +77,36 @@ int main(int argc, char **argv, char *env[]) { {} #pragma omp target update to(z) depend // expected-error {{expected '(' after 'depend'}} - #pragma omp target update to(z) depend( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} - #pragma omp target update to(z) depend() // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} - #pragma omp target update to(z) depend(argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp target update to(z) depend(source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} - #pragma omp target update to(z) depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} - #pragma omp target update to(z) depend(in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} - #pragma omp target update to(z) depend(out: ) // expected-error {{expected expression}} - #pragma omp target update to(z) depend(inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} - #pragma omp target update to(z) depend(out :S1) // expected-error {{'S1' does not refer to a value}} - #pragma omp target update to(z) depend(in : argv[1][1] = '2') - #pragma omp target update to(z) depend(in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}} - #pragma omp target update to(z) depend(in : argv[0]) - #pragma omp target update to(z) depend(in : ) // expected-error {{expected expression}} - #pragma omp target update to(z) depend(in : main) - #pragma omp target update to(z) depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}} - #pragma omp target update to(z) depend(in : vec[1:2]) // expected-error {{ value is not an array or pointer}} - #pragma omp target update to(z) depend(in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} - #pragma omp target update to(z) depend(in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} - #pragma omp target update to(z) depend(in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp target update to(z) depend(in : argv[argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} - #pragma omp target update to(z) depend(in : argv[argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp target update to(z) depend(in : argv[0:-1]) // expected-error {{section length is evaluated to a negative value -1}} - #pragma omp target update to(z) depend(in : argv[-1:0]) // expected-error {{zero-length array section is not allowed in 'depend' clause}} - #pragma omp target update to(z) depend(in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} - #pragma omp target update to(z) depend(in : argv[3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} - #pragma omp target update to(z) depend(in:a[0:1]) // expected-error {{subscripted value is not an array or pointer}} - #pragma omp target update to(z) depend(in:argv[argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}} - #pragma omp target update to(z) depend(in:argv[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} - #pragma omp target update to(z) depend(in:env[0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}} - #pragma omp target update to(z) depend(in : argv[ : argc][1 : argc - 1]) - #pragma omp target update to(z) depend(in : arr[0]) +#pragma omp target update to(z) depend( // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target update to(z) depend() // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} +#pragma omp target update to(z) depend(argc // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update to(z) depend(source : argc) // omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} +#pragma omp target update to(z) depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} omp4-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp5-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} +#pragma omp target update to(z) depend(in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}} +#pragma omp target update to(z) depend(out:) // expected-error {{expected expression}} +#pragma omp target update to(z) depend(inout : foobool(argc)), depend(in, argc) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} +#pragma omp target update to(z) depend(out : S1) // expected-error {{'S1' does not refer to a value}} +#pragma omp target update to(z) depend(in : argv[1][1] = '2') +#pragma omp target update to(z) depend(in : vec[1]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} +#pragma omp target update to(z) depend(in : argv[0]) +#pragma omp target update to(z) depend(in:) // expected-error {{expected expression}} +#pragma omp target update to(z) depend(in : main) +#pragma omp target update to(z) depend(in : a[0]) // omp4-error {{expected addressable lvalue expression, array element or array section}} omp5-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} +#pragma omp target update to(z) depend(in : vec [1:2]) // expected-error {{ value is not an array or pointer}} +#pragma omp target update to(z) depend(in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} +#pragma omp target update to(z) depend(in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} +#pragma omp target update to(z) depend(in : argv[:] // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update to(z) depend(in : argv [argc: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} +#pragma omp target update to(z) depend(in : argv [argc:argc] // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target update to(z) depend(in : argv [0:-1]) // expected-error {{section length is evaluated to a negative value -1}} +#pragma omp target update to(z) depend(in : argv [-1:0]) // expected-error {{zero-length array section is not allowed in 'depend' clause}} +#pragma omp target update to(z) depend(in : argv[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} +#pragma omp target update to(z) depend(in : argv [3:4:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} +#pragma omp target update to(z) depend(in : a [0:1]) // expected-error {{subscripted value is not an array or pointer}} +#pragma omp target update to(z) depend(in : argv [argv[:2]:1]) // expected-error {{OpenMP array section is not allowed here}} +#pragma omp target update to(z) depend(in : argv [0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} +#pragma omp target update to(z) depend(in : env [0:][:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}} +#pragma omp target update to(z) depend(in : argv[:argc] [1:argc - 1]) +#pragma omp target update to(z) depend(in : arr[0]) return tmain(argc, argv, env); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} } diff --git a/clang/test/OpenMP/target_update_from_messages.cpp b/clang/test/OpenMP/target_update_from_messages.cpp index 141cfc38ffeb1..3dc377c4ca4ce 100644 --- a/clang/test/OpenMP/target_update_from_messages.cpp +++ b/clang/test/OpenMP/target_update_from_messages.cpp @@ -1,9 +1,9 @@ -// RUN: %clang_cc1 -verify=expected,le45 -fopenmp -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,le50 -fopenmp -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized // RUN: %clang_cc1 -verify=expected,le45 -fopenmp -fopenmp-version=40 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized // RUN: %clang_cc1 -verify=expected,le45 -fopenmp -fopenmp-version=45 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized // RUN: %clang_cc1 -verify=expected,le50 -fopenmp -fopenmp-version=50 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized -// RUN: %clang_cc1 -verify=expected,le45 -fopenmp-simd -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,le50 -fopenmp-simd -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized void foo() { } diff --git a/clang/test/OpenMP/target_update_messages.cpp b/clang/test/OpenMP/target_update_messages.cpp index 581fdd8e0a9bd..4092b623bdc97 100644 --- a/clang/test/OpenMP/target_update_messages.cpp +++ b/clang/test/OpenMP/target_update_messages.cpp @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp -fopenmp-version=45 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp-simd -fopenmp-version=45 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp-simd -fopenmp-version=50 -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized void xxx(int argc) { int x; // expected-note {{initialize the variable 'x' to silence this warning}} @@ -36,5 +38,11 @@ int main(int argc, char **argv) { { foo(); } + + int iarr[5][5]; +#pragma omp target update to(iarr[0:][1:2:-1]) // omp50-error {{section stride is evaluated to a non-positive value -1}} omp45-error {{expected ']'}} omp45-note {{to match this '['}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + {} +#pragma omp target update from(iarr[0:][1:2:-1]) // omp50-error {{section stride is evaluated to a non-positive value -1}} omp45-error {{expected ']'}} omp45-note {{to match this '['}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + return tmain(argc, argv); } diff --git a/clang/test/OpenMP/target_update_to_messages.cpp b/clang/test/OpenMP/target_update_to_messages.cpp index 832adc0dd4d09..5b840c056115e 100644 --- a/clang/test/OpenMP/target_update_to_messages.cpp +++ b/clang/test/OpenMP/target_update_to_messages.cpp @@ -1,9 +1,9 @@ -// RUN: %clang_cc1 -verify=expected,le45 -fopenmp -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,le50 -fopenmp -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized // RUN: %clang_cc1 -verify=expected,le45 -fopenmp -fopenmp-version=40 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized // RUN: %clang_cc1 -verify=expected,le45 -fopenmp -fopenmp-version=45 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized // RUN: %clang_cc1 -verify=expected,le50 -fopenmp -fopenmp-version=50 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized -// RUN: %clang_cc1 -verify=expected,le45 -fopenmp-simd -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,le50 -fopenmp-simd -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized // RUN: %clang_cc1 -verify=expected,le45 -fopenmp-simd -fopenmp-version=40 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized // RUN: %clang_cc1 -verify=expected,le45 -fopenmp-simd -fopenmp-version=45 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized // RUN: %clang_cc1 -verify=expected,le50 -fopenmp-simd -fopenmp-version=50 -ferror-limit 100 %s -Wno-openmp-mapping -Wuninitialized diff --git a/clang/test/OpenMP/task_default_messages.cpp b/clang/test/OpenMP/task_default_messages.cpp index 4826c253aa043..8b6809ee05d56 100644 --- a/clang/test/OpenMP/task_default_messages.cpp +++ b/clang/test/OpenMP/task_default_messages.cpp @@ -2,15 +2,24 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp -ferror-limit 100 -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp task default // expected-error {{expected '(' after 'default'}} -#pragma omp task default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} -#pragma omp task default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp task default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp task default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} #pragma omp task default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp task default(shared), default(shared) // expected-error {{directive '#pragma omp task' cannot contain more than one 'default' clause}} -#pragma omp task default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp task default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} foo(); #pragma omp task default(none) // expected-note {{explicit data sharing attribute requested here}} @@ -19,5 +28,13 @@ int main(int argc, char **argv) { #pragma omp task default(none) // expected-note {{explicit data sharing attribute requested here}} #pragma omp task default(shared) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + +#ifdef OMP51 +#pragma omp task default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif return 0; } diff --git a/clang/test/OpenMP/task_messages.cpp b/clang/test/OpenMP/task_messages.cpp index 8b3183e0bd93e..13cbfb6c45693 100644 --- a/clang/test/OpenMP/task_messages.cpp +++ b/clang/test/OpenMP/task_messages.cpp @@ -4,6 +4,9 @@ // RUN: %clang_cc1 -verify=expected,omp45 -fopenmp-version=45 -fopenmp-simd -ferror-limit 200 -std=c++11 -o - %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,omp50 -fopenmp-version=50 -fopenmp-simd -ferror-limit 200 -std=c++11 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp-version=51 -DOMP51 -fopenmp -ferror-limit 100 -std=c++11 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp-version=51 -DOMP51 -fopenmp-simd -ferror-limit 100 -std=c++11 -o - %s -Wuninitialized + void xxx(int argc) { int x; // expected-note {{initialize the variable 'x' to silence this warning}} #pragma omp task @@ -16,6 +19,10 @@ void foo() { } typedef unsigned long omp_event_handle_t; +namespace { +static int y = 0; +} +static int x = 0; #pragma omp task // expected-error {{unexpected OpenMP directive '#pragma omp task'}} @@ -52,6 +59,15 @@ int foo() { #pragma omp task default(none) // expected-note 2 {{explicit data sharing attribute requested here}} #pragma omp task default(shared) ++a; // expected-error 2 {{variable 'a' must have explicitly specified data sharing attributes}} +#ifdef OMP51 +#pragma omp task default(firstprivate) // expected-note 4 {{explicit data sharing attribute requested here}} +#pragma omp task + { + ++x; // expected-error 2 {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error 2 {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif + #pragma omp task default(none) // expected-note 2 {{explicit data sharing attribute requested here}} #pragma omp task // expected-error@+1 {{calling a private constructor of class 'S'}} diff --git a/clang/test/OpenMP/taskloop_loop_messages.cpp b/clang/test/OpenMP/taskloop_loop_messages.cpp index 1783a5265d9f5..b3b24e96abc9d 100644 --- a/clang/test/OpenMP/taskloop_loop_messages.cpp +++ b/clang/test/OpenMP/taskloop_loop_messages.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized class S { diff --git a/clang/test/OpenMP/taskloop_simd_loop_messages.cpp b/clang/test/OpenMP/taskloop_simd_loop_messages.cpp index 9a345d6a6300c..b782525a3bbf0 100644 --- a/clang/test/OpenMP/taskloop_simd_loop_messages.cpp +++ b/clang/test/OpenMP/taskloop_simd_loop_messages.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized class S { diff --git a/clang/test/OpenMP/teams_default_messages.cpp b/clang/test/OpenMP/teams_default_messages.cpp index a025050406000..b117ef4948a0f 100644 --- a/clang/test/OpenMP/teams_default_messages.cpp +++ b/clang/test/OpenMP/teams_default_messages.cpp @@ -2,17 +2,26 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target #pragma omp teams default // expected-error {{expected '(' after 'default'}} foo(); #pragma omp target - #pragma omp teams default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp teams default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} foo(); #pragma omp target - #pragma omp teams default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} foo(); #pragma omp target #pragma omp teams default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -21,7 +30,7 @@ int main(int argc, char **argv) { #pragma omp teams default (shared), default(shared) // expected-error {{directive '#pragma omp teams' cannot contain more than one 'default' clause}} foo(); #pragma omp target - #pragma omp teams default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} foo(); #pragma omp target @@ -32,5 +41,14 @@ int main(int argc, char **argv) { #pragma omp teams default(none) // expected-note {{explicit data sharing attribute requested here}} #pragma omp parallel default(shared) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + +#ifdef OMP51 +#pragma omp target +#pragma omp teams default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif return 0; } diff --git a/clang/test/OpenMP/teams_distribute_default_messages.cpp b/clang/test/OpenMP/teams_distribute_default_messages.cpp index 7f000208303b7..1d5fd40c53a6b 100644 --- a/clang/test/OpenMP/teams_distribute_default_messages.cpp +++ b/clang/test/OpenMP/teams_distribute_default_messages.cpp @@ -2,17 +2,26 @@ // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target #pragma omp teams distribute default // expected-error {{expected '(' after 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp teams distribute default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams distribute default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target #pragma omp teams distribute default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -21,12 +30,21 @@ int main(int argc, char **argv) { #pragma omp teams distribute default (shared), default(shared) // expected-error {{directive '#pragma omp teams distribute' cannot contain more than one 'default' clause}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams distribute default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target #pragma omp teams distribute default(none) // expected-note {{explicit data sharing attribute requested here}} for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} +#ifdef OMP51 +#pragma omp target +#pragma omp teams distribute default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + for (int i = 0; i < 200; i++) { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif + return 0; } diff --git a/clang/test/OpenMP/teams_distribute_loop_messages.cpp b/clang/test/OpenMP/teams_distribute_loop_messages.cpp index 1edc926c6ce14..36f3830829c5e 100644 --- a/clang/test/OpenMP/teams_distribute_loop_messages.cpp +++ b/clang/test/OpenMP/teams_distribute_loop_messages.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized class S { diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_default_messages.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_default_messages.cpp index 2c46623985070..3a414543be806 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_default_messages.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_default_messages.cpp @@ -2,17 +2,26 @@ // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target #pragma omp teams distribute parallel for default // expected-error {{expected '(' after 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute parallel for default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp teams distribute parallel for default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute parallel for default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams distribute parallel for default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target #pragma omp teams distribute parallel for default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -21,12 +30,21 @@ int main(int argc, char **argv) { #pragma omp teams distribute parallel for default (shared), default(shared) // expected-error {{directive '#pragma omp teams distribute parallel for' cannot contain more than one 'default' clause}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute parallel for default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams distribute parallel for default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target #pragma omp teams distribute parallel for default(none) // expected-note {{explicit data sharing attribute requested here}} for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} +#ifdef OMP51 +#pragma omp target +#pragma omp teams distribute parallel for default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + for (int i = 0; i < 200; i++) { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif + return 0; } diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_loop_messages.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_loop_messages.cpp index 5916bedea529b..237addabb50fc 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_loop_messages.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_loop_messages.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized class S { diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_schedule_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_schedule_codegen.cpp index f7b11a7191940..f095296dab5c5 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_schedule_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_schedule_codegen.cpp @@ -3,12 +3,19 @@ #define HEADER // Test host codegen. -// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 --check-prefix CK1-OMP50 // RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 -// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 +// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 --check-prefix CK1-OMP50 +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 --check-prefix CK1-OMP50 // RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 +// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 --check-prefix CK1-OMP50 + +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 --check-prefix CK1-OMP45 +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 --check-prefix CK1-OMP45 +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 --check-prefix CK1-OMP45 +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 --check-prefix CK1-OMP45 // RUN: %clang_cc1 -DCK1 -verify -fopenmp-simd -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s // RUN: %clang_cc1 -DCK1 -fopenmp-simd -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s @@ -120,7 +127,8 @@ struct SS{ // CK1: ret void // CK1: define internal void @[[PAR_OUTL4]]({{.+}}) - // CK1: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, + // CK1-OMP45: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, + // CK1-OMP50: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 1073741859, // CK1: call {{.+}} @__kmpc_dispatch_next_4( // CK1: ret void @@ -135,7 +143,8 @@ struct SS{ // CK1: ret void // CK1: define internal void @[[PAR_OUTL5]]({{.+}}) - // CK1: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, + // CK1-OMP45: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, + // CK1-OMP50: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 1073741859, // CK1: call {{.+}} @__kmpc_dispatch_next_4( // CK1: ret void @@ -151,12 +160,19 @@ int teams_template_struct(void) { #endif // CK1 // Test host codegen. -// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 --check-prefix CK2-OMP50 // RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 -// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 +// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 --check-prefix CK2-OMP50 +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 --check-prefix CK2-OMP50 // RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 +// RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 --check-prefix CK2-OMP50 + +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 --check-prefix CK2-OMP45 +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 --check-prefix CK2-OMP45 +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 --check-prefix CK2-OMP45 +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 --check-prefix CK2-OMP45 // RUN: %clang_cc1 -DCK2 -verify -fopenmp-simd -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY1 %s // RUN: %clang_cc1 -DCK2 -fopenmp-simd -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s @@ -301,7 +317,8 @@ int main (int argc, char **argv) { // CK2: ret void // CK2: define internal void @[[PAR_OUTL4]]({{.+}}) -// CK2: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP45: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP50: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 1073741859, // CK2: call {{.+}} @__kmpc_dispatch_next_4( // CK2: ret void @@ -317,7 +334,8 @@ int main (int argc, char **argv) { // CK2: ret void // CK2: define internal void @[[PAR_OUTL5]]({{.+}}) -// CK2: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP45: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP50: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 1073741859, // CK2: call {{.+}} @__kmpc_dispatch_next_4( // CK2: ret void @@ -391,7 +409,8 @@ int main (int argc, char **argv) { // CK2: ret void // CK2: define internal void @[[PAR_OUTLT4]]({{.+}}) -// CK2: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP45: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP50: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 1073741859, // CK2: call {{.+}} @__kmpc_dispatch_next_4( // CK2: ret void @@ -406,7 +425,8 @@ int main (int argc, char **argv) { // CK2: ret void // CK2: define internal void @[[PAR_OUTLT5]]({{.+}}) -// CK2: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP45: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP50: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 1073741859, // CK2: call {{.+}} @__kmpc_dispatch_next_4( // CK2: ret void diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_default_messages.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_default_messages.cpp index 93017a8233ffe..ce7f35b479592 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_default_messages.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_default_messages.cpp @@ -2,17 +2,26 @@ // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized -fopenmp-version=51 -DOMP51 + +// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized -fopenmp-version=51 -DOMP51 + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target #pragma omp teams distribute parallel for simd default // expected-error {{expected '(' after 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute parallel for simd default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp teams distribute parallel for simd default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute parallel for simd default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams distribute parallel for simd default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target #pragma omp teams distribute parallel for simd default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -21,12 +30,20 @@ int main(int argc, char **argv) { #pragma omp teams distribute parallel for simd default (shared), default(shared) // expected-error {{directive '#pragma omp teams distribute parallel for simd' cannot contain more than one 'default' clause}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute parallel for simd default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams distribute parallel for simd default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target #pragma omp teams distribute parallel for simd default(none) // expected-note {{explicit data sharing attribute requested here}} for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} +#ifdef OpenMP51 +#pragma omp teams distribute parallel for default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + for (int i = 0; i < 200; i++) { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif + return 0; } diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_messages.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_messages.cpp index 898c1e2615074..9d8137b1962ba 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_messages.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_messages.cpp @@ -1,7 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp %s -Wno-openmp-mapping -Wuninitialized - -// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp-simd -fopenmp-version=50 %s -Wno-openmp-mapping -Wuninitialized extern int omp_default_mem_alloc; void foo() { } @@ -140,8 +141,8 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp target -#pragma omp teams distribute parallel for simd private(i), firstprivate(i) // expected-error {{private variable cannot be firstprivate}} expected-note 2 {{defined as private}} - for (i = 0; i < argc; ++i) foo(); // expected-error {{loop iteration variable in the associated loop of 'omp teams distribute parallel for simd' directive may not be private, predetermined as linear}} +#pragma omp teams distribute parallel for simd private(i), firstprivate(i) // expected-error {{private variable cannot be firstprivate}} omp4-note 2 {{defined as private}} omp5-note {{defined as private}} + for (i = 0; i < argc; ++i) foo(); // omp4-error {{loop iteration variable in the associated loop of 'omp teams distribute parallel for simd' directive may not be private, predetermined as linear}} #pragma omp target #pragma omp teams distribute parallel for simd firstprivate(i) diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_loop_messages.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_loop_messages.cpp index 0b2d46211cc85..6e741ce00b678 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_loop_messages.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_loop_messages.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized class S { diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_schedule_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_schedule_codegen.cpp index ea99cc7b569d2..4662c46fcce34 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_schedule_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_schedule_codegen.cpp @@ -3,10 +3,18 @@ #define HEADER // Test host codegen. -// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 --check-prefix CK1-OMP45 +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 --check-prefix CK1-OMP50 +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 + // RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s // RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 +// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 // RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 + +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 // RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s // RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32 @@ -120,7 +128,8 @@ struct SS{ // CK1: ret void // CK1: define internal void @[[PAR_OUTL4]]({{.+}}) - // CK1: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, + // CK1-OMP45: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, + // CK1-OMP50: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 1073741859, // CK1: call {{.+}} @__kmpc_dispatch_next_4( // CK1: ret void @@ -135,7 +144,8 @@ struct SS{ // CK1: ret void // CK1: define internal void @[[PAR_OUTL5]]({{.+}}) - // CK1: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, + // CK1-OMP45: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, + // CK1-OMP50: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 1073741859, // CK1: call {{.+}} @__kmpc_dispatch_next_4( // CK1: ret void @@ -153,9 +163,20 @@ int teams_template_struct(void) { #endif // CK1 // Test host codegen. -// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 --check-prefix CK2-OMP45 + +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 --check-prefix CK2-OMP50 + +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 // RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s // RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64 + + +// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 + // RUN: %clang_cc1 -DCK2 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 // RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s // RUN: %clang_cc1 -DCK2 -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32 @@ -303,7 +324,8 @@ int main (int argc, char **argv) { // CK2: ret void // CK2: define internal void @[[PAR_OUTL4]]({{.+}}) -// CK2: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP45: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP50: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 1073741859, // CK2: call {{.+}} @__kmpc_dispatch_next_4( // CK2: ret void @@ -319,7 +341,9 @@ int main (int argc, char **argv) { // CK2: ret void // CK2: define internal void @[[PAR_OUTL5]]({{.+}}) -// CK2: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP45: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP50: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 1073741859, + // CK2: call {{.+}} @__kmpc_dispatch_next_4( // CK2: ret void @@ -393,7 +417,9 @@ int main (int argc, char **argv) { // CK2: ret void // CK2: define internal void @[[PAR_OUTLT4]]({{.+}}) -// CK2: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP45: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP50: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 1073741859, + // CK2: call {{.+}} @__kmpc_dispatch_next_4( // CK2: ret void @@ -408,7 +434,9 @@ int main (int argc, char **argv) { // CK2: ret void // CK2: define internal void @[[PAR_OUTLT5]]({{.+}}) -// CK2: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP45: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 35, +// CK2-OMP50: call void @__kmpc_dispatch_init_4({{.+}}, {{.+}}, i32 1073741859, + // CK2: call {{.+}} @__kmpc_dispatch_next_4( // CK2: ret void diff --git a/clang/test/OpenMP/teams_distribute_simd_default_messages.cpp b/clang/test/OpenMP/teams_distribute_simd_default_messages.cpp index 2775210ae048f..11f5d1cd1fc8f 100644 --- a/clang/test/OpenMP/teams_distribute_simd_default_messages.cpp +++ b/clang/test/OpenMP/teams_distribute_simd_default_messages.cpp @@ -1,18 +1,23 @@ -// RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized -fopenmp-version=51 -// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized -fopenmp-version=51 void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target #pragma omp teams distribute simd default // expected-error {{expected '(' after 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute simd default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp teams distribute simd default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute simd default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams distribute simd default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target #pragma omp teams distribute simd default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -21,12 +26,22 @@ int main(int argc, char **argv) { #pragma omp teams distribute simd default (shared), default(shared) // expected-error {{directive '#pragma omp teams distribute simd' cannot contain more than one 'default' clause}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute simd default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams distribute simd default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target #pragma omp teams distribute simd default(none) // expected-note {{explicit data sharing attribute requested here}} for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} +#pragma omp target +#pragma omp teams distribute simd default(firstprivate) // expected-note {{explicit data sharing attribute requested here}} + for (int i = 0; i < 200; i++) + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + +#pragma omp target +#pragma omp teams distribute simd default(firstprivate) // expected-note {{explicit data sharing attribute requested here}} + for (int i = 0; i < 200; i++) + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + return 0; } diff --git a/clang/test/OpenMP/teams_distribute_simd_firstprivate_messages.cpp b/clang/test/OpenMP/teams_distribute_simd_firstprivate_messages.cpp index 23eeb5efc17ac..c8a95c2f1553e 100644 --- a/clang/test/OpenMP/teams_distribute_simd_firstprivate_messages.cpp +++ b/clang/test/OpenMP/teams_distribute_simd_firstprivate_messages.cpp @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -verify -fopenmp %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp -fopenmp-version=45 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp -fopenmp-version=50 %s -Wno-openmp-mapping -Wuninitialized -// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp4 -fopenmp-simd -fopenmp-version=45 %s -Wno-openmp-mapping -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp5 -fopenmp-simd -fopenmp-version=50 %s -Wno-openmp-mapping -Wuninitialized extern int omp_default_mem_alloc; void foo() { @@ -140,8 +142,8 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp target -#pragma omp teams distribute simd private(i), firstprivate(i) // expected-error {{private variable cannot be firstprivate}} expected-note 2 {{defined as private}} - for (i = 0; i < argc; ++i) foo(); // expected-error {{loop iteration variable in the associated loop of 'omp teams distribute simd' directive may not be private, predetermined as linear}} +#pragma omp teams distribute simd private(i), firstprivate(i) // expected-error {{private variable cannot be firstprivate}} omp4-note 2 {{defined as private}} omp5-note {{defined as private}} + for (i = 0; i < argc; ++i) foo(); // omp4-error {{loop iteration variable in the associated loop of 'omp teams distribute simd' directive may not be private, predetermined as linear}} #pragma omp target #pragma omp teams distribute simd firstprivate(i) diff --git a/clang/test/OpenMP/teams_distribute_simd_loop_messages.cpp b/clang/test/OpenMP/teams_distribute_simd_loop_messages.cpp index 7ab32c94da586..a79afb2260732 100644 --- a/clang/test/OpenMP/teams_distribute_simd_loop_messages.cpp +++ b/clang/test/OpenMP/teams_distribute_simd_loop_messages.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp4 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify=expected,omp5 %s -Wuninitialized class S { diff --git a/clang/test/OpenMP/teams_messages.cpp b/clang/test/OpenMP/teams_messages.cpp index 1154220a18c5c..9a37ac7b78fd0 100644 --- a/clang/test/OpenMP/teams_messages.cpp +++ b/clang/test/OpenMP/teams_messages.cpp @@ -1,7 +1,8 @@ -// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp -std=c++11 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp-version=45 -fopenmp -std=c++11 -o - %s -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -std=c++11 -o - %s -Wuninitialized -// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp-simd -std=c++11 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp-version=45 -fopenmp-simd -std=c++11 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=50 -fopenmp-simd -std=c++11 -o - %s -Wuninitialized void xxx(int argc) { int x; // expected-note {{initialize the variable 'x' to silence this warning}} diff --git a/clang/test/OpenMP/threadprivate_codegen.cpp b/clang/test/OpenMP/threadprivate_codegen.cpp index 52ed8bb4b1aa6..c24d1ea787454 100644 --- a/clang/test/OpenMP/threadprivate_codegen.cpp +++ b/clang/test/OpenMP/threadprivate_codegen.cpp @@ -1,19 +1,27 @@ -// RUN: %clang_cc1 -verify -fopenmp -fnoopenmp-use-tls -DBODY -triple x86_64-unknown-unknown -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s -// RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -DBODY -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix=CHECK-DEBUG %s +// RUN: %clang_cc1 -verify -fopenmp -fnoopenmp-use-tls -DBODY -triple x86_64-unknown-unknown -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefixes=CHECK,OMP50 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fnoopenmp-use-tls -DBODY -triple x86_64-unknown-unknown -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefixes=CHECK,OMP45 // RUN: %clang_cc1 -verify -fopenmp-simd -fnoopenmp-use-tls -DBODY -triple x86_64-unknown-unknown -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck --check-prefix SIMD-ONLY0 %s // RUN: %clang_cc1 -fopenmp-simd -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s // RUN: %clang_cc1 -fopenmp-simd -fnoopenmp-use-tls -DBODY -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s // SIMD-ONLY0-NOT: {{__kmpc|__tgt}} -// RUN: %clang_cc1 -verify -fopenmp -DBODY -triple x86_64-unknown-unknown -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefix=CHECK-TLS +// RUN: %clang_cc1 -verify -fopenmp -DBODY -triple x86_64-unknown-unknown -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefixes=CHECK-TLS,OMP50-TLS +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -DBODY -triple x86_64-unknown-unknown -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefixes=CHECK-TLS,OMP45-TLS // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -DBODY -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix=CHECK-TLS %s +// RUN: %clang_cc1 -fopenmp -DBODY -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefixes=CHECK-TLS,OMP50-TLS %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -DBODY -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefixes=CHECK-TLS,OMP45-TLS %s // RUN: %clang_cc1 -verify -fopenmp-simd -DBODY -triple x86_64-unknown-unknown -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck --check-prefix SIMD-ONLY1 %s // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s // RUN: %clang_cc1 -fopenmp-simd -DBODY -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY1 %s + +// RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -DBODY -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefixes=CHECK-DEBUG,OMP50-DEBUG %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fnoopenmp-use-tls -DBODY -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefixes=CHECK-DEBUG,OMP45-DEBUG %s + // SIMD-ONLY1-NOT: {{__kmpc|__tgt}} // expected-no-diagnostics @@ -154,26 +162,28 @@ struct S5 { // CHECK-DEBUG-DAG: [[ST_INT_ST:@.+]] = linkonce_odr global i32 23 // CHECK-DEBUG-DAG: [[ST_FLOAT_ST:@.+]] = linkonce_odr global float 2.300000e+01 // CHECK-DEBUG-DAG: [[ST_S4_ST:@.+]] = linkonce_odr global %struct.S4 zeroinitializer -// CHECK-DEBUG-DAG: [[LOC1:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;;201;1;;\00" -// CHECK-DEBUG-DAG: [[LOC2:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;;256;1;;\00" -// CHECK-DEBUG-DAG: [[LOC3:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;;343;19;;\00" -// CHECK-DEBUG-DAG: [[LOC4:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;380;1;;\00" -// CHECK-DEBUG-DAG: [[LOC5:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;397;9;;\00" -// CHECK-DEBUG-DAG: [[LOC6:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;419;10;;\00" -// CHECK-DEBUG-DAG: [[LOC7:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;442;10;;\00" -// CHECK-DEBUG-DAG: [[LOC8:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;478;10;;\00" -// CHECK-DEBUG-DAG: [[LOC9:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;507;10;;\00" -// CHECK-DEBUG-DAG: [[LOC10:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;527;10;;\00" -// CHECK-DEBUG-DAG: [[LOC11:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;550;27;;\00" -// CHECK-DEBUG-DAG: [[LOC12:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;573;10;;\00" -// CHECK-DEBUG-DAG: [[LOC13:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;693;9;;\00" -// CHECK-DEBUG-DAG: [[LOC14:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;716;10;;\00" -// CHECK-DEBUG-DAG: [[LOC15:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;752;10;;\00" -// CHECK-DEBUG-DAG: [[LOC16:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;781;10;;\00" -// CHECK-DEBUG-DAG: [[LOC17:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;801;10;;\00" -// CHECK-DEBUG-DAG: [[LOC18:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;824;27;;\00" -// CHECK-DEBUG-DAG: [[LOC19:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;847;10;;\00" -// CHECK-DEBUG-DAG: [[LOC20:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;;315;1;;\00" + +// CHECK-DEBUG-DAG: [[LOC1:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;;249;1;;\00" +// CHECK-DEBUG-DAG: [[LOC2:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;;304;1;;\00" +// CHECK-DEBUG-DAG: [[LOC3:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;;422;19;;\00" +// CHECK-DEBUG-DAG: [[LOC4:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;459;1;;\00" +// CHECK-DEBUG-DAG: [[LOC5:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;476;9;;\00" +// CHECK-DEBUG-DAG: [[LOC6:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;498;10;;\00" +// CHECK-DEBUG-DAG: [[LOC7:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;521;10;;\00" +// CHECK-DEBUG-DAG: [[LOC8:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;557;10;;\00" +// CHECK-DEBUG-DAG: [[LOC9:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;586;10;;\00" +// CHECK-DEBUG-DAG: [[LOC10:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;606;10;;\00" +// CHECK-DEBUG-DAG: [[LOC11:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;629;27;;\00" +// CHECK-DEBUG-DAG: [[LOC12:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;main;652;10;;\00" +// CHECK-DEBUG-DAG: [[LOC13:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;774;9;;\00" +// CHECK-DEBUG-DAG: [[LOC14:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;797;10;;\00" +// CHECK-DEBUG-DAG: [[LOC15:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;833;10;;\00" +// CHECK-DEBUG-DAG: [[LOC16:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;862;10;;\00" +// CHECK-DEBUG-DAG: [[LOC17:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;882;10;;\00" +// CHECK-DEBUG-DAG: [[LOC18:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;905;27;;\00" +// CHECK-DEBUG-DAG: [[LOC19:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;foobar;928;10;;\00" +// CHECK-DEBUG-DAG: [[LOC20:@.*]] = private unnamed_addr constant [{{[0-9]+}} x i8] c";{{.*}}threadprivate_codegen.cpp;;363;1;;\00" + // CHECK-TLS-DAG: [[GS1:@.+]] = internal thread_local global [[S1]] zeroinitializer // CHECK-TLS-DAG: [[GS2:@.+]] = internal global [[S2]] zeroinitializer // CHECK-TLS-DAG: [[ARR_X:@.+]] = thread_local global [2 x [3 x [[S1]]]] zeroinitializer @@ -192,6 +202,44 @@ struct S5 { // CHECK-TLS-DAG: [[ST_S4_ST_TLS_INIT:@_ZTHN2STI2S4E2stE]] = linkonce_odr alias void (), void ()* [[ST_S4_ST_CXX_INIT:@[^, ]*]] + +// OMP50-TLS: define internal void [[GS1_CXX_INIT:@.*]]() +// OMP50-TLS: call void [[GS1_CTOR1:@.*]]([[S1]]* [[GS1]], i32 5) +// OMP50-TLS: call i32 @__cxa_thread_atexit(void (i8*)* bitcast (void ([[S1]]*)* [[GS1_DTOR1:.*]] to void (i8*)*), i8* bitcast ([[S1]]* [[GS1]] to i8*) +// OMP50-TLS: } +// OMP50-TLS: define {{.*}}void [[GS1_CTOR1]]([[S1]]* {{.*}}, i32 {{.*}}) +// OMP50-TLS: call void [[GS1_CTOR2:@.*]]([[S1]]* {{.*}}, i32 {{.*}}) +// OMP50-TLS: } +// OMP50-TLS: define {{.*}}void [[GS1_DTOR1]]([[S1]]* {{.*}}) +// OMP50-TLS: call void [[GS1_DTOR2:@.*]]([[S1]]* {{.*}}) +// OMP50-TLS: } +// OMP50-TLS: define {{.*}}void [[GS1_CTOR2]]([[S1]]* {{.*}}, i32 {{.*}}) +// OMP50-TLS: define {{.*}}void [[GS1_DTOR2]]([[S1]]* {{.*}}) + +// OMP50-TLS: define internal void [[GS2_CXX_INIT:@.*]]() +// OMP50-TLS: call void [[GS2_CTOR1:@.*]]([[S2]]* [[GS2]], i32 27) +// OMP50-TLS: call i32 @__cxa_atexit(void (i8*)* bitcast (void ([[S2]]*)* [[GS2_DTOR1:.*]] to void (i8*)*), i8* bitcast ([[S2]]* [[GS2]] to i8*) +// OMP50-TLS: } +// OMP50-TLS: define {{.*}}void [[GS2_CTOR1]]([[S2]]* {{.*}}, i32 {{.*}}) +// OMP50-TLS: call void [[GS2_CTOR2:@.*]]([[S2]]* {{.*}}, i32 {{.*}}) +// OMP50-TLS: } +// OMP50-TLS: define {{.*}}void [[GS2_DTOR1]]([[S2]]* {{.*}}) +// OMP50-TLS: call void [[GS2_DTOR2:@.*]]([[S2]]* {{.*}}) +// OMP50-TLS: } +// OMP50-TLS: define {{.*}}void [[GS2_CTOR2]]([[S2]]* {{.*}}, i32 {{.*}}) +// OMP50-TLS: define {{.*}}void [[GS2_DTOR2]]([[S2]]* {{.*}}) + +// OMP50-TLS: define internal void [[ARR_X_CXX_INIT:@.*]]() +// OMP50-TLS: invoke void [[GS1_CTOR1]]([[S1]]* getelementptr inbounds ([2 x [3 x [[S1]]]], [2 x [3 x [[S1]]]]* [[ARR_X]], i{{.*}} 0, i{{.*}} 0, i{{.*}} 0), i{{.*}} 1) +// OMP50-TLS: invoke void [[GS1_CTOR1]]([[S1]]* getelementptr inbounds ([2 x [3 x [[S1]]]], [2 x [3 x [[S1]]]]* [[ARR_X]], i{{.*}} 0, i{{.*}} 0, i{{.*}} 1), i{{.*}} 2) +// OMP50-TLS: invoke void [[GS1_CTOR1]]([[S1]]* getelementptr inbounds ([2 x [3 x [[S1]]]], [2 x [3 x [[S1]]]]* [[ARR_X]], i{{.*}} 0, i{{.*}} 0, i{{.*}} 2), i{{.*}} 3) +// OMP50-TLS: invoke void [[GS1_CTOR1]]([[S1]]* getelementptr inbounds ([2 x [3 x [[S1]]]], [2 x [3 x [[S1]]]]* [[ARR_X]], i{{.*}} 0, i{{.*}} 1, i{{.*}} 0), i{{.*}} 4) +// OMP50-TLS: invoke void [[GS1_CTOR1]]([[S1]]* getelementptr inbounds ([2 x [3 x [[S1]]]], [2 x [3 x [[S1]]]]* [[ARR_X]], i{{.*}} 0, i{{.*}} 1, i{{.*}} 1), i{{.*}} 5) +// OMP50-TLS: invoke void [[GS1_CTOR1]]([[S1]]* getelementptr inbounds ([2 x [3 x [[S1]]]], [2 x [3 x [[S1]]]]* [[ARR_X]], i{{.*}} 0, i{{.*}} 1, i{{.*}} 2), i{{.*}} 6) +// OMP50-TLS: call i32 @__cxa_thread_atexit(void (i8*)* [[ARR_X_CXX_DTOR:@[^,]+]] +// OMP50-TLS: define internal void [[ARR_X_CXX_DTOR]](i8* %0) +// OMP50-TLS: void [[GS1_DTOR1]]([[S1]]* {{.*}}) + struct Static { static S3 s; #pragma omp threadprivate(s) @@ -315,6 +363,37 @@ struct ST { #pragma omp threadprivate(st) }; + +// OMP50-DEBUG: [[KMPC_LOC_ADDR:%.*]] = alloca [[IDENT]] +// OMP50-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]], [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 +// OMP50-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[LOC20]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] +// OMP50-DEBUG: @__kmpc_global_thread_num +// OMP50-DEBUG: call {{.*}}void @__kmpc_threadprivate_register([[IDENT]]* [[KMPC_LOC_ADDR]], i8* bitcast ([[S4]]* [[ST_S4_ST]] to i8*), i8* (i8*)* [[ST_S4_ST_CTOR:@\.__kmpc_global_ctor_\..+]], i8* (i8*, i8*)* null, void (i8*)* [[ST_S4_ST_DTOR:@\.__kmpc_global_dtor_\..+]]) +// OMP50-DEBUG: define internal {{.*}}i8* [[ST_S4_ST_CTOR]](i8* %0) +// OMP50-DEBUG: } +// OMP50-DEBUG: define {{.*}} [[S4_CTOR:@.*]]([[S4]]* {{.*}}, +// OMP50-DEBUG: define internal {{.*}}void [[ST_S4_ST_DTOR]](i8* %0) +// OMP50-DEBUG: } +// OMP50-DEBUG: define {{.*}} [[S4_DTOR:@.*]]([[S4]]* {{.*}}) + +// OMP50: call {{.*}}void @__kmpc_threadprivate_register([[IDENT]]* [[DEFAULT_LOC]], i8* bitcast ([[S4]]* [[ST_S4_ST]] to i8*), i8* (i8*)* [[ST_S4_ST_CTOR:@\.__kmpc_global_ctor_\..+]], i8* (i8*, i8*)* null, void (i8*)* [[ST_S4_ST_DTOR:@\.__kmpc_global_dtor_\..+]]) +// OMP50: define internal {{.*}}i8* [[ST_S4_ST_CTOR]](i8* %0) +// OMP50: store i8* %0, i8** [[ARG_ADDR:%.*]], +// OMP50: [[ARG:%.+]] = load i8*, i8** [[ARG_ADDR]] +// OMP50: [[RES:%.*]] = bitcast i8* [[ARG]] to [[S4]]* +// OMP50-NEXT: call {{.*}} [[S4_CTOR:@.+]]([[S4]]* [[RES]], {{.*}} 23) +// OMP50: [[ARG:%.+]] = load i8*, i8** [[ARG_ADDR]] +// OMP50-NEXT: ret i8* [[ARG]] +// OMP50-NEXT: } +// OMP50: define {{.*}} [[S4_CTOR]]([[S4]]* {{.*}}, +// OMP50: define internal {{.*}}void [[ST_S4_ST_DTOR]](i8* %0) +// OMP50: store i8* %0, i8** [[ARG_ADDR:%.*]], +// OMP50: [[ARG:%.+]] = load i8*, i8** [[ARG_ADDR]] +// OMP50: [[RES:%.*]] = bitcast i8* [[ARG]] to [[S4]]* +// OMP50-NEXT: call {{.*}} [[S4_DTOR:@.+]]([[S4]]* [[RES]]) +// OMP50-NEXT: ret void +// OMP50-NEXT: } +// OMP50: define {{.*}} [[S4_DTOR]]([[S4]]* {{.*}}) template T ST::st(23); @@ -662,11 +741,13 @@ int main() { // CHECK-TLS: } #endif +// OMP50-TLS: define {{.*}}void [[SM_CTOR2]]([[SMAIN]]* {{.*}}, i32 {{.*}}) +// OMP50-TLS: define {{.*}}void [[SM_DTOR2]]([[SMAIN]]* {{.*}}) #ifdef BODY // CHECK-LABEL: @{{.*}}foobar{{.*}}() // CHECK-DEBUG-LABEL: @{{.*}}foobar{{.*}}() -// CHECK-TLS: @{{.*}}foobar{{.*}}() +// CHECK-TLS-LABEL: @{{.*}}foobar{{.*}}() int foobar() { // CHECK-DEBUG: [[KMPC_LOC_ADDR:%.*]] = alloca [[IDENT]] int Res; @@ -793,11 +874,11 @@ int foobar() { // CHECK-DEBUG-NEXT: [[RES:%.*]] = load [[INT]], [[INT]]* [[RES_ADDR]] // CHECK-DEBUG-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[ST_INT_ST_VAL]] // CHECK-DEBUG-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] - // CHECK-TLS: [[ST_INT_ST_ADDR:%.*]] = call i32* [[ST_INT_ST_TLS_INITD]] - // CHECK-TLS-NEXT: [[ST_INT_ST_VAL:%.*]] = load [[INT]], [[INT]]* [[ST_INT_ST_ADDR]] - // CHECK-TLS-NEXT: [[RES:%.*]] = load [[INT]], [[INT]]* [[RES_ADDR]] - // CHECK-TLS-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[ST_INT_ST_VAL]] - // CHECK-TLS-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + // OMP45-TLS: [[ST_INT_ST_ADDR:%.*]] = call i32* [[ST_INT_ST_TLS_INITD]] + // OMP45-TLS-NEXT: [[ST_INT_ST_VAL:%.*]] = load [[INT]], [[INT]]* [[ST_INT_ST_ADDR]] + // OMP45-TLS-NEXT: [[RES:%.*]] = load [[INT]], [[INT]]* [[RES_ADDR]] + // OMP45-TLS-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[ST_INT_ST_VAL]] + // OMP45-TLS-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] Res += ST::st; // CHECK: [[ST_FLOAT_ST_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[DEFAULT_LOC]], i32 [[THREAD_NUM]], i8* bitcast (float* [[ST_FLOAT_ST]] to i8*), i{{.*}} {{[0-9]+}}, i8*** [[ST_FLOAT_ST]].cache.) // CHECK-NEXT: [[ST_FLOAT_ST_ADDR:%.*]] = bitcast i8* [[ST_FLOAT_ST_TEMP_ADDR]] to float* @@ -815,12 +896,12 @@ int foobar() { // CHECK-DEBUG-NEXT: [[RES:%.*]] = load [[INT]], [[INT]]* [[RES_ADDR]] // CHECK-DEBUG-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[FLOAT_TO_INT_CONV]] // CHECK-DEBUG-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] - // CHECK-TLS: [[ST_FLOAT_ST_ADDR:%.*]] = call float* [[ST_FLOAT_ST_TLS_INITD]] - // CHECK-TLS-NEXT: [[ST_FLOAT_ST_VAL:%.*]] = load float, float* [[ST_FLOAT_ST_ADDR]] - // CHECK-TLS-NEXT: [[FLOAT_TO_INT_CONV:%.*]] = fptosi float [[ST_FLOAT_ST_VAL]] to [[INT]] - // CHECK-TLS-NEXT: [[RES:%.*]] = load [[INT]], [[INT]]* [[RES_ADDR]] - // CHECK-TLS-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[FLOAT_TO_INT_CONV]] - // CHECK-TLS-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] + // OMP45-TLS: [[ST_FLOAT_ST_ADDR:%.*]] = call float* [[ST_FLOAT_ST_TLS_INITD]] + // OMP45-TLS-NEXT: [[ST_FLOAT_ST_VAL:%.*]] = load float, float* [[ST_FLOAT_ST_ADDR]] + // OMP45-TLS-NEXT: [[FLOAT_TO_INT_CONV:%.*]] = fptosi float [[ST_FLOAT_ST_VAL]] to [[INT]] + // OMP45-TLS-NEXT: [[RES:%.*]] = load [[INT]], [[INT]]* [[RES_ADDR]] + // OMP45-TLS-NEXT: [[ADD:%.*]] = add {{.*}} [[INT]] [[RES]], [[FLOAT_TO_INT_CONV]] + // OMP45-TLS-NEXT: store [[INT]] [[ADD]], [[INT]]* [[RES:.+]] Res += static_cast(ST::st); // CHECK: [[ST_S4_ST_TEMP_ADDR:%.*]] = call {{.*}}i8* @__kmpc_threadprivate_cached([[IDENT]]* [[DEFAULT_LOC]], i32 [[THREAD_NUM]], i8* bitcast ([[S4]]* [[ST_S4_ST]] to i8*), i{{.*}} {{[0-9]+}}, i8*** [[ST_S4_ST]].cache.) // CHECK-NEXT: [[ST_S4_ST_ADDR:%.*]] = bitcast i8* [[ST_S4_ST_TEMP_ADDR]] to [[S4]]* @@ -855,35 +936,36 @@ int foobar() { } #endif -// CHECK: call {{.*}}void @__kmpc_threadprivate_register([[IDENT]]* [[DEFAULT_LOC]], i8* bitcast ([[S4]]* [[ST_S4_ST]] to i8*), i8* (i8*)* [[ST_S4_ST_CTOR:@\.__kmpc_global_ctor_\..+]], i8* (i8*, i8*)* null, void (i8*)* [[ST_S4_ST_DTOR:@\.__kmpc_global_dtor_\..+]]) -// CHECK: define internal {{.*}}i8* [[ST_S4_ST_CTOR]](i8* %0) -// CHECK: store i8* %0, i8** [[ARG_ADDR:%.*]], -// CHECK: [[ARG:%.+]] = load i8*, i8** [[ARG_ADDR]] -// CHECK: [[RES:%.*]] = bitcast i8* [[ARG]] to [[S4]]* -// CHECK-NEXT: call {{.*}} [[S4_CTOR:@.+]]([[S4]]* [[RES]], {{.*}} 23) -// CHECK: [[ARG:%.+]] = load i8*, i8** [[ARG_ADDR]] -// CHECK-NEXT: ret i8* [[ARG]] -// CHECK-NEXT: } -// CHECK: define {{.*}} [[S4_CTOR]]([[S4]]* {{.*}}, -// CHECK: define internal {{.*}}void [[ST_S4_ST_DTOR]](i8* %0) -// CHECK: store i8* %0, i8** [[ARG_ADDR:%.*]], -// CHECK: [[ARG:%.+]] = load i8*, i8** [[ARG_ADDR]] -// CHECK: [[RES:%.*]] = bitcast i8* [[ARG]] to [[S4]]* -// CHECK-NEXT: call {{.*}} [[S4_DTOR:@.+]]([[S4]]* [[RES]]) -// CHECK-NEXT: ret void -// CHECK-NEXT: } -// CHECK: define {{.*}} [[S4_DTOR]]([[S4]]* {{.*}}) -// CHECK-DEBUG: [[KMPC_LOC_ADDR:%.*]] = alloca [[IDENT]] -// CHECK-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]], [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 -// CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[LOC20]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] -// CHECK-DEBUG: @__kmpc_global_thread_num -// CHECK-DEBUG: call {{.*}}void @__kmpc_threadprivate_register([[IDENT]]* [[KMPC_LOC_ADDR]], i8* bitcast ([[S4]]* [[ST_S4_ST]] to i8*), i8* (i8*)* [[ST_S4_ST_CTOR:@\.__kmpc_global_ctor_\..+]], i8* (i8*, i8*)* null, void (i8*)* [[ST_S4_ST_DTOR:@\.__kmpc_global_dtor_\..+]]) -// CHECK-DEBUG: define internal {{.*}}i8* [[ST_S4_ST_CTOR]](i8* %0) -// CHECK-DEBUG: } -// CHECK-DEBUG: define {{.*}} [[S4_CTOR:@.*]]([[S4]]* {{.*}}, -// CHECK-DEBUG: define internal {{.*}}void [[ST_S4_ST_DTOR]](i8* %0) -// CHECK-DEBUG: } -// CHECK-DEBUG: define {{.*}} [[S4_DTOR:@.*]]([[S4]]* {{.*}}) +// OMP45: call {{.*}}void @__kmpc_threadprivate_register([[IDENT]]* [[DEFAULT_LOC]], i8* bitcast ([[S4]]* [[ST_S4_ST]] to i8*), i8* (i8*)* [[ST_S4_ST_CTOR:@\.__kmpc_global_ctor_\..+]], i8* (i8*, i8*)* null, void (i8*)* [[ST_S4_ST_DTOR:@\.__kmpc_global_dtor_\..+]]) +// OMP45: define internal {{.*}}i8* [[ST_S4_ST_CTOR]](i8* %0) +// OMP45: store i8* %0, i8** [[ARG_ADDR:%.*]], +// OMP45: [[ARG:%.+]] = load i8*, i8** [[ARG_ADDR]] +// OMP45: [[RES:%.*]] = bitcast i8* [[ARG]] to [[S4]]* +// OMP45-NEXT: call {{.*}} [[S4_CTOR:@.+]]([[S4]]* [[RES]], {{.*}} 23) +// OMP45: [[ARG:%.+]] = load i8*, i8** [[ARG_ADDR]] +// OMP45-NEXT: ret i8* [[ARG]] +// OMP45-NEXT: } +// OMP45: define {{.*}} [[S4_CTOR]]([[S4]]* {{.*}}, +// OMP45: define internal {{.*}}void [[ST_S4_ST_DTOR]](i8* %0) +// OMP45: store i8* %0, i8** [[ARG_ADDR:%.*]], +// OMP45: [[ARG:%.+]] = load i8*, i8** [[ARG_ADDR]] +// OMP45: [[RES:%.*]] = bitcast i8* [[ARG]] to [[S4]]* +// OMP45-NEXT: call {{.*}} [[S4_DTOR:@.+]]([[S4]]* [[RES]]) +// OMP45-NEXT: ret void +// OMP45-NEXT: } +// OMP45: define {{.*}} [[S4_DTOR]]([[S4]]* {{.*}}) + +// OMP45-DEBUG: [[KMPC_LOC_ADDR:%.*]] = alloca [[IDENT]] +// OMP45-DEBUG: [[KMPC_LOC_ADDR_PSOURCE:%.*]] = getelementptr inbounds [[IDENT]], [[IDENT]]* [[KMPC_LOC_ADDR]], i{{.*}} 0, i{{.*}} 4 +// OMP45-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.*}} x i8], [{{.*}} x i8]* [[LOC20]], i{{.*}} 0, i{{.*}} 0), i8** [[KMPC_LOC_ADDR_PSOURCE]] +// OMP45-DEBUG: @__kmpc_global_thread_num +// OMP45-DEBUG: call {{.*}}void @__kmpc_threadprivate_register([[IDENT]]* [[KMPC_LOC_ADDR]], i8* bitcast ([[S4]]* [[ST_S4_ST]] to i8*), i8* (i8*)* [[ST_S4_ST_CTOR:@\.__kmpc_global_ctor_\..+]], i8* (i8*, i8*)* null, void (i8*)* [[ST_S4_ST_DTOR:@\.__kmpc_global_dtor_\..+]]) +// OMP45-DEBUG: define internal {{.*}}i8* [[ST_S4_ST_CTOR]](i8* %0) +// OMP45-DEBUG: } +// OMP45-DEBUG: define {{.*}} [[S4_CTOR:@.*]]([[S4]]* {{.*}}, +// OMP45-DEBUG: define internal {{.*}}void [[ST_S4_ST_DTOR]](i8* %0) +// OMP45-DEBUG: } +// OMP45-DEBUG: define {{.*}} [[S4_DTOR:@.*]]([[S4]]* {{.*}}) // CHECK: define internal {{.*}}void {{@.*}}() // CHECK-DAG: call {{.*}}void [[GS1_INIT]]() @@ -892,58 +974,72 @@ int foobar() { // CHECK-DEBUG: define internal {{.*}}void {{@.*}}() // CHECK-DEBUG: ret void -// CHECK-TLS: define internal void [[GS1_CXX_INIT:@.*]]() -// CHECK-TLS: call void [[GS1_CTOR1:@.*]]([[S1]]* [[GS1]], i32 5) -// CHECK-TLS: call i32 @__cxa_thread_atexit(void (i8*)* bitcast (void ([[S1]]*)* [[GS1_DTOR1:.*]] to void (i8*)*), i8* bitcast ([[S1]]* [[GS1]] to i8*) -// CHECK-TLS: } -// CHECK-TLS: define {{.*}}void [[GS1_CTOR1]]([[S1]]* {{.*}}, i32 {{.*}}) -// CHECK-TLS: call void [[GS1_CTOR2:@.*]]([[S1]]* {{.*}}, i32 {{.*}}) -// CHECK-TLS: } -// CHECK-TLS: define {{.*}}void [[GS1_DTOR1]]([[S1]]* {{.*}}) -// CHECK-TLS: call void [[GS1_DTOR2:@.*]]([[S1]]* {{.*}}) -// CHECK-TLS: } -// CHECK-TLS: define {{.*}}void [[GS1_CTOR2]]([[S1]]* {{.*}}, i32 {{.*}}) -// CHECK-TLS: define {{.*}}void [[GS1_DTOR2]]([[S1]]* {{.*}}) +// OMP45-TLS: define internal void [[GS1_CXX_INIT:@.*]]() +// OMP45-TLS: call void [[GS1_CTOR1:@.*]]([[S1]]* [[GS1]], i32 5) +// OMP45-TLS: call i32 @__cxa_thread_atexit(void (i8*)* bitcast (void ([[S1]]*)* [[GS1_DTOR1:.*]] to void (i8*)*), i8* bitcast ([[S1]]* [[GS1]] to i8*) +// OMP45-TLS: } +// OMP45-TLS: define {{.*}}void [[GS1_CTOR1]]([[S1]]* {{.*}}, i32 {{.*}}) +// OMP45-TLS: call void [[GS1_CTOR2:@.*]]([[S1]]* {{.*}}, i32 {{.*}}) +// OMP45-TLS: } +// OMP45-TLS: define {{.*}}void [[GS1_DTOR1]]([[S1]]* {{.*}}) +// OMP45-TLS: call void [[GS1_DTOR2:@.*]]([[S1]]* {{.*}}) +// OMP45-TLS: } +// OMP45-TLS: define {{.*}}void [[GS1_CTOR2]]([[S1]]* {{.*}}, i32 {{.*}}) +// OMP45-TLS: define {{.*}}void [[GS1_DTOR2]]([[S1]]* {{.*}}) -// CHECK-TLS: define internal void [[GS2_CXX_INIT:@.*]]() -// CHECK-TLS: call void [[GS2_CTOR1:@.*]]([[S2]]* [[GS2]], i32 27) -// CHECK-TLS: call i32 @__cxa_atexit(void (i8*)* bitcast (void ([[S2]]*)* [[GS2_DTOR1:.*]] to void (i8*)*), i8* bitcast ([[S2]]* [[GS2]] to i8*) -// CHECK-TLS: } -// CHECK-TLS: define {{.*}}void [[GS2_CTOR1]]([[S2]]* {{.*}}, i32 {{.*}}) -// CHECK-TLS: call void [[GS2_CTOR2:@.*]]([[S2]]* {{.*}}, i32 {{.*}}) -// CHECK-TLS: } -// CHECK-TLS: define {{.*}}void [[GS2_DTOR1]]([[S2]]* {{.*}}) -// CHECK-TLS: call void [[GS2_DTOR2:@.*]]([[S2]]* {{.*}}) -// CHECK-TLS: } -// CHECK-TLS: define {{.*}}void [[GS2_CTOR2]]([[S2]]* {{.*}}, i32 {{.*}}) -// CHECK-TLS: define {{.*}}void [[GS2_DTOR2]]([[S2]]* {{.*}}) - -// CHECK-TLS: define internal void [[ARR_X_CXX_INIT:@.*]]() -// CHECK-TLS: invoke void [[GS1_CTOR1]]([[S1]]* getelementptr inbounds ([2 x [3 x [[S1]]]], [2 x [3 x [[S1]]]]* [[ARR_X]], i{{.*}} 0, i{{.*}} 0, i{{.*}} 0), i{{.*}} 1) -// CHECK-TLS: invoke void [[GS1_CTOR1]]([[S1]]* getelementptr inbounds ([2 x [3 x [[S1]]]], [2 x [3 x [[S1]]]]* [[ARR_X]], i{{.*}} 0, i{{.*}} 0, i{{.*}} 1), i{{.*}} 2) -// CHECK-TLS: invoke void [[GS1_CTOR1]]([[S1]]* getelementptr inbounds ([2 x [3 x [[S1]]]], [2 x [3 x [[S1]]]]* [[ARR_X]], i{{.*}} 0, i{{.*}} 0, i{{.*}} 2), i{{.*}} 3) -// CHECK-TLS: invoke void [[GS1_CTOR1]]([[S1]]* getelementptr inbounds ([2 x [3 x [[S1]]]], [2 x [3 x [[S1]]]]* [[ARR_X]], i{{.*}} 0, i{{.*}} 1, i{{.*}} 0), i{{.*}} 4) -// CHECK-TLS: invoke void [[GS1_CTOR1]]([[S1]]* getelementptr inbounds ([2 x [3 x [[S1]]]], [2 x [3 x [[S1]]]]* [[ARR_X]], i{{.*}} 0, i{{.*}} 1, i{{.*}} 1), i{{.*}} 5) -// CHECK-TLS: invoke void [[GS1_CTOR1]]([[S1]]* getelementptr inbounds ([2 x [3 x [[S1]]]], [2 x [3 x [[S1]]]]* [[ARR_X]], i{{.*}} 0, i{{.*}} 1, i{{.*}} 2), i{{.*}} 6) -// CHECK-TLS: call i32 @__cxa_thread_atexit(void (i8*)* [[ARR_X_CXX_DTOR:@[^,]+]] -// CHECK-TLS: define internal void [[ARR_X_CXX_DTOR]](i8* %0) -// CHECK-TLS: void [[GS1_DTOR1]]([[S1]]* {{.*}}) - -// CHECK-TLS: define {{.*}}void [[SM_CTOR2]]([[SMAIN]]* {{.*}}, i32 {{.*}}) -// CHECK-TLS: define {{.*}}void [[SM_DTOR2]]([[SMAIN]]* {{.*}}) - -// CHECK-TLS: define internal void [[ST_S4_ST_CXX_INIT]]() -// CHECK-TLS: call void [[ST_S4_ST_CTOR1:@.*]]([[S4]]* [[ST_S4_ST]], i32 23) -// CHECK-TLS: call i32 @__cxa_thread_atexit(void (i8*)* bitcast (void ([[S4]]*)* [[ST_S4_ST_DTOR1:.*]] to void (i8*)*), i8* bitcast ([[S4]]* [[ST_S4_ST]] to i8*) -// CHECK-TLS: } -// CHECK-TLS: define {{.*}}void [[ST_S4_ST_CTOR1]]([[S4]]* {{.*}}, i32 {{.*}}) -// CHECK-TLS: call void [[ST_S4_ST_CTOR2:@.*]]([[S4]]* {{.*}}, i32 {{.*}}) -// CHECK-TLS: } -// CHECK-TLS: define {{.*}}void [[ST_S4_ST_DTOR1]]([[S4]]* {{.*}}) -// CHECK-TLS: call void [[ST_S4_ST_DTOR2:@.*]]([[S4]]* {{.*}}) -// CHECK-TLS: } -// CHECK-TLS: define {{.*}}void [[ST_S4_ST_CTOR2]]([[S4]]* {{.*}}, i32 {{.*}}) -// CHECK-TLS: define {{.*}}void [[ST_S4_ST_DTOR2]]([[S4]]* {{.*}}) +// OMP45-TLS: define internal void [[GS2_CXX_INIT:@.*]]() +// OMP45-TLS: call void [[GS2_CTOR1:@.*]]([[S2]]* [[GS2]], i32 27) +// OMP45-TLS: call i32 @__cxa_atexit(void (i8*)* bitcast (void ([[S2]]*)* [[GS2_DTOR1:.*]] to void (i8*)*), i8* bitcast ([[S2]]* [[GS2]] to i8*) +// OMP45-TLS: } +// OMP45-TLS: define {{.*}}void [[GS2_CTOR1]]([[S2]]* {{.*}}, i32 {{.*}}) +// OMP45-TLS: call void [[GS2_CTOR2:@.*]]([[S2]]* {{.*}}, i32 {{.*}}) +// OMP45-TLS: } +// OMP45-TLS: define {{.*}}void [[GS2_DTOR1]]([[S2]]* {{.*}}) +// OMP45-TLS: call void [[GS2_DTOR2:@.*]]([[S2]]* {{.*}}) +// OMP45-TLS: } +// OMP45-TLS: define {{.*}}void [[GS2_CTOR2]]([[S2]]* {{.*}}, i32 {{.*}}) +// OMP45-TLS: define {{.*}}void [[GS2_DTOR2]]([[S2]]* {{.*}}) + +// OMP45-TLS: define internal void [[ARR_X_CXX_INIT:@.*]]() +// OMP45-TLS: invoke void [[GS1_CTOR1]]([[S1]]* getelementptr inbounds ([2 x [3 x [[S1]]]], [2 x [3 x [[S1]]]]* [[ARR_X]], i{{.*}} 0, i{{.*}} 0, i{{.*}} 0), i{{.*}} 1) +// OMP45-TLS: invoke void [[GS1_CTOR1]]([[S1]]* getelementptr inbounds ([2 x [3 x [[S1]]]], [2 x [3 x [[S1]]]]* [[ARR_X]], i{{.*}} 0, i{{.*}} 0, i{{.*}} 1), i{{.*}} 2) +// OMP45-TLS: invoke void [[GS1_CTOR1]]([[S1]]* getelementptr inbounds ([2 x [3 x [[S1]]]], [2 x [3 x [[S1]]]]* [[ARR_X]], i{{.*}} 0, i{{.*}} 0, i{{.*}} 2), i{{.*}} 3) +// OMP45-TLS: invoke void [[GS1_CTOR1]]([[S1]]* getelementptr inbounds ([2 x [3 x [[S1]]]], [2 x [3 x [[S1]]]]* [[ARR_X]], i{{.*}} 0, i{{.*}} 1, i{{.*}} 0), i{{.*}} 4) +// OMP45-TLS: invoke void [[GS1_CTOR1]]([[S1]]* getelementptr inbounds ([2 x [3 x [[S1]]]], [2 x [3 x [[S1]]]]* [[ARR_X]], i{{.*}} 0, i{{.*}} 1, i{{.*}} 1), i{{.*}} 5) +// OMP45-TLS: invoke void [[GS1_CTOR1]]([[S1]]* getelementptr inbounds ([2 x [3 x [[S1]]]], [2 x [3 x [[S1]]]]* [[ARR_X]], i{{.*}} 0, i{{.*}} 1, i{{.*}} 2), i{{.*}} 6) +// OMP45-TLS: call i32 @__cxa_thread_atexit(void (i8*)* [[ARR_X_CXX_DTOR:@[^,]+]] +// OMP45-TLS: define internal void [[ARR_X_CXX_DTOR]](i8* %0) +// OMP45-TLS: void [[GS1_DTOR1]]([[S1]]* {{.*}}) + +// OMP45-TLS: define {{.*}}void [[SM_CTOR2]]([[SMAIN]]* {{.*}}, i32 {{.*}}) +// OMP45-TLS: define {{.*}}void [[SM_DTOR2]]([[SMAIN]]* {{.*}}) + +// OMP45-TLS: define internal void [[ST_S4_ST_CXX_INIT]]() +// OMP45-TLS: call void [[ST_S4_ST_CTOR1:@.*]]([[S4]]* [[ST_S4_ST]], i32 23) +// OMP45-TLS: call i32 @__cxa_thread_atexit(void (i8*)* bitcast (void ([[S4]]*)* [[ST_S4_ST_DTOR1:.*]] to void (i8*)*), i8* bitcast ([[S4]]* [[ST_S4_ST]] to i8*) +// OMP45-TLS: } +// OMP45-TLS: define {{.*}}void [[ST_S4_ST_CTOR1]]([[S4]]* {{.*}}, i32 {{.*}}) +// OMP45-TLS: call void [[ST_S4_ST_CTOR2:@.*]]([[S4]]* {{.*}}, i32 {{.*}}) +// OMP45-TLS: } +// OMP45-TLS: define {{.*}}void [[ST_S4_ST_DTOR1]]([[S4]]* {{.*}}) +// OMP45-TLS: call void [[ST_S4_ST_DTOR2:@.*]]([[S4]]* {{.*}}) +// OMP45-TLS: } +// OMP45-TLS: define {{.*}}void [[ST_S4_ST_CTOR2]]([[S4]]* {{.*}}, i32 {{.*}}) +// OMP45-TLS: define {{.*}}void [[ST_S4_ST_DTOR2]]([[S4]]* {{.*}}) + +// OMP50-TLS: define internal void [[ST_S4_ST_CXX_INIT]]() +// OMP50-TLS: call void [[ST_S4_ST_CTOR1:@.*]]([[S4]]* [[ST_S4_ST]], i32 23) + +// OMP50-TLS: call i32 @__cxa_thread_atexit(void (i8*)* bitcast (void ([[S4]]*)* [[ST_S4_ST_DTOR1:.*]] to void (i8*)*), i8* bitcast ([[S4]]* [[ST_S4_ST]] to i8*) +// OMP50-TLS: } +// OMP50-TLS: define {{.*}}void [[ST_S4_ST_CTOR1]]([[S4]]* {{.*}}, i32 {{.*}}) +// OMP50-TLS: call void [[ST_S4_ST_CTOR2:@.*]]([[S4]]* {{.*}}, i32 {{.*}}) +// OMP50-TLS: } +// OMP50-TLS: define {{.*}}void [[ST_S4_ST_DTOR1]]([[S4]]* {{.*}}) +// OMP50-TLS: call void [[ST_S4_ST_DTOR2:@.*]]([[S4]]* {{.*}}) +// OMP50-TLS: } +// OMP50-TLS: define {{.*}}void [[ST_S4_ST_CTOR2]]([[S4]]* {{.*}}, i32 {{.*}}) +// OMP50-TLS: define {{.*}}void [[ST_S4_ST_DTOR2]]([[S4]]* {{.*}}) // CHECK-TLS: define internal void @__tls_init() // CHECK-TLS: [[GRD:%.*]] = load i8, i8* @__tls_guard diff --git a/clang/test/PCH/aarch64-sve-types.c b/clang/test/PCH/aarch64-sve-types.c index 27f16306927d4..d9be6daa127e7 100644 --- a/clang/test/PCH/aarch64-sve-types.c +++ b/clang/test/PCH/aarch64-sve-types.c @@ -18,4 +18,6 @@ __SVFloat16_t *f16; __SVFloat32_t *f32; __SVFloat64_t *f64; +__SVBFloat16_t *bf16; + __SVBool_t *b8; diff --git a/clang/test/PCH/codegen.cpp b/clang/test/PCH/codegen.cpp new file mode 100644 index 0000000000000..49ed30aeaf054 --- /dev/null +++ b/clang/test/PCH/codegen.cpp @@ -0,0 +1,42 @@ +// This test is the PCH version of Modules/codegen-flags.test . It uses its inputs. +// The purpose of this test is just verify that the codegen options work with PCH as well. +// All the codegen functionality should be tested in Modules/. + +// RUN: rm -rf %t +// RUN: mkdir -p %t +// REQUIRES: x86-registered-target + +// RUN: %clang_cc1 -triple=x86_64-linux-gnu -fmodules-codegen -x c++-header -building-pch-with-obj -emit-pch %S/../Modules/Inputs/codegen-flags/foo.h -o %t/foo-cg.pch +// RUN: %clang_cc1 -triple=x86_64-linux-gnu -fmodules-debuginfo -x c++-header -building-pch-with-obj -emit-pch %S/../Modules/Inputs/codegen-flags/foo.h -o %t/foo-di.pch + +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - %s -include-pch %t/foo-cg.pch -building-pch-with-obj -fmodules-codegen | FileCheck --check-prefix=CG %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - %s -include-pch %t/foo-di.pch -building-pch-with-obj -fmodules-debuginfo | FileCheck --check-prefix=DI %s + +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - -include-pch %t/foo-cg.pch %S/../Modules/Inputs/codegen-flags/use.cpp | FileCheck --check-prefix=CG-USE %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - -include-pch %t/foo-di.pch %S/../Modules/Inputs/codegen-flags/use.cpp | FileCheck --check-prefix=DI-USE %s + +// Test with template instantiation in the pch. + +// RUN: %clang_cc1 -triple=x86_64-linux-gnu -fmodules-codegen -x c++-header -building-pch-with-obj -emit-pch -fpch-instantiate-templates %S/../Modules/Inputs/codegen-flags/foo.h -o %t/foo-cg.pch +// RUN: %clang_cc1 -triple=x86_64-linux-gnu -fmodules-debuginfo -x c++-header -building-pch-with-obj -emit-pch -fpch-instantiate-templates %S/../Modules/Inputs/codegen-flags/foo.h -o %t/foo-di.pch + +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - %s -include-pch %t/foo-cg.pch -building-pch-with-obj -fmodules-codegen | FileCheck --check-prefix=CG %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - %s -include-pch %t/foo-di.pch -building-pch-with-obj -fmodules-debuginfo | FileCheck --check-prefix=DI %s + +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - -include-pch %t/foo-cg.pch %S/../Modules/Inputs/codegen-flags/use.cpp | FileCheck --check-prefix=CG-USE %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - -include-pch %t/foo-di.pch %S/../Modules/Inputs/codegen-flags/use.cpp | FileCheck --check-prefix=DI-USE %s + + +// CG: define weak_odr void @_Z2f1v +// CG: DICompileUnit +// CG-NOT: DICompositeType + +// CG-USE: declare void @_Z2f1v +// CG-USE: DICompileUnit +// CG-USE: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo" + +// DI-NOT: define +// DI: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo" + +// DI-USE: define linkonce_odr void @_Z2f1v +// DI-USE: = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", {{.*}}, flags: DIFlagFwdDecl diff --git a/clang/test/PCH/cxx2a-defaulted-comparison.cpp b/clang/test/PCH/cxx2a-defaulted-comparison.cpp index 8fea0fb028478..8aeb1683961af 100644 --- a/clang/test/PCH/cxx2a-defaulted-comparison.cpp +++ b/clang/test/PCH/cxx2a-defaulted-comparison.cpp @@ -1,4 +1,4 @@ -// RxN: %clang_cc1 -std=c++2a -verify -Wno-defaulted-function-deleted -include %s %s +// RUN: %clang_cc1 -std=c++2a -verify -Wno-defaulted-function-deleted -include %s %s // // RUN: %clang_cc1 -std=c++2a -emit-pch %s -o %t.pch // RUN: %clang_cc1 -std=c++2a -include-pch %t.pch %s -verify diff --git a/clang/test/PCH/pragma-floatcontrol.c b/clang/test/PCH/pragma-floatcontrol.c index a0918dd53597b..8be46dbd16550 100644 --- a/clang/test/PCH/pragma-floatcontrol.c +++ b/clang/test/PCH/pragma-floatcontrol.c @@ -6,6 +6,18 @@ // Test with pch. // RUN: %clang_cc1 %s -DSET -emit-pch -o %t // RUN: %clang_cc1 %s -DSET -include-pch %t -emit-llvm -o - | FileCheck --check-prefix=CHECK-EBSTRICT %s +// RUN: %clang_cc1 %s -ffp-contract=on -DSET -emit-pch -o %t +// RUN: %clang_cc1 %s -DSET -include-pch %t -emit-llvm -o - | FileCheck --check-prefix=CHECK-EBSTRICT %s +// RUN: %clang_cc1 %s -menable-no-nans -DSET -emit-pch -o %t +// RUN: %clang_cc1 %s -DSET -include-pch %t -emit-llvm -o - | FileCheck --check-prefix=CHECK-EBSTRICT %s +// RUN: %clang_cc1 %s -frounding-math -DSET -emit-pch -o %t +// RUN: %clang_cc1 %s -DSET -include-pch %t -emit-llvm -o - | FileCheck --check-prefix=CHECK-EBSTRICT %s +// RUN: %clang_cc1 %s -ffp-exception-behavior=maytrap -DSET -emit-pch -o %t +// RUN: %clang_cc1 %s -DSET -include-pch %t -emit-llvm -o - | FileCheck --check-prefix=CHECK-EBSTRICT %s +// RUN: %clang_cc1 %s -ffp-contract=fast -DSET -emit-pch -o %t +// RUN: %clang_cc1 %s -DSET -include-pch %t -emit-llvm -o - | FileCheck --check-prefix=CHECK-EBSTRICT %s +// RUN: %clang_cc1 %s -DSET -emit-pch -o %t +// RUN: %clang_cc1 %s -ffp-contract=on -DSET -include-pch %t -emit-llvm -o - | FileCheck --check-prefix=CHECK-CONTRACT %s // RUN: %clang_cc1 %s -DPUSH -emit-pch -o %t // RUN: %clang_cc1 %s -DPUSH -verify -include-pch %t // RUN: %clang_cc1 %s -DPUSH_POP -emit-pch -o %t @@ -36,6 +48,7 @@ float fun(float a, float b) { // CHECK-LABEL: define float @fun{{.*}} //CHECK-EBSTRICT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict //CHECK-EBSTRICT: llvm.experimental.constrained.fadd{{.*}}tonearest{{.*}}strict + //CHECK-CONTRACT: llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict return a * b + 2; } #pragma float_control(pop) // expected-warning {{#pragma float_control(pop, ...) failed: stack empty}} diff --git a/clang/test/Parser/altivec-bool-128.c b/clang/test/Parser/altivec-bool-128.c new file mode 100644 index 0000000000000..049ca3cc839d2 --- /dev/null +++ b/clang/test/Parser/altivec-bool-128.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple=powerpc64-unknown-linux-gnu \ +// RUN: -target-feature +altivec -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple=powerpc64le-unknown-linux-gnu \ +// RUN: -target-feature +altivec -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple=powerpc64le-unknown-linux-gnu -target-cpu pwr10 \ +// RUN: -target-feature +vsx -target-feature -power10-vector \ +// RUN: -fsyntax-only -verify %s + +// Test 'vector bool __int128' type. + +// These should have errors. +__vector bool __int128 v1_bi128; // expected-error {{use of '__int128' with '__vector bool' requires VSX support enabled (on POWER10 or later)}} +__vector __bool __int128 v2_bi128; // expected-error {{use of '__int128' with '__vector bool' requires VSX support enabled (on POWER10 or later)}} +vector bool __int128 v3_bi128; // expected-error {{use of '__int128' with '__vector bool' requires VSX support enabled (on POWER10 or later)}} +vector __bool __int128 v4_bi128; // expected-error {{use of '__int128' with '__vector bool' requires VSX support enabled (on POWER10 or later)}} +__vector bool unsigned __int128 v5_bi128; // expected-error {{cannot use 'unsigned' with '__vector bool'}} expected-error {{use of '__int128' with '__vector bool' requires VSX support enabled (on POWER10 or later)}} +__vector bool signed __int128 v6_bi128; // expected-error {{cannot use 'signed' with '__vector bool'}} expected-error {{use of '__int128' with '__vector bool' requires VSX support enabled (on POWER10 or later)}} +vector bool unsigned __int128 v7_bi128; // expected-error {{cannot use 'unsigned' with '__vector bool'}} expected-error {{use of '__int128' with '__vector bool' requires VSX support enabled (on POWER10 or later)}} +vector bool signed __int128 v8_bi128; // expected-error {{cannot use 'signed' with '__vector bool'}} expected-error {{use of '__int128' with '__vector bool' requires VSX support enabled (on POWER10 or later)}} +__vector __bool signed __int128 v9_bi128; // expected-error {{cannot use 'signed' with '__vector bool'}} expected-error {{use of '__int128' with '__vector bool' requires VSX support enabled (on POWER10 or later)}} +vector __bool signed __int128 v10_bi128; // expected-error {{cannot use 'signed' with '__vector bool'}} expected-error {{use of '__int128' with '__vector bool' requires VSX support enabled (on POWER10 or later)}} diff --git a/clang/test/Parser/cxx-altivec-bool-128.cpp b/clang/test/Parser/cxx-altivec-bool-128.cpp new file mode 100644 index 0000000000000..36ffefc9a18bf --- /dev/null +++ b/clang/test/Parser/cxx-altivec-bool-128.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple=powerpc64-unknown-linux-gnu \ +// RUN: -target-feature +altivec -fsyntax-only -verify -std=c++11 %s +// RUN: %clang_cc1 -triple=powerpc64le-unknown-linux-gnu \ +// RUN: -target-feature +altivec -fsyntax-only -verify -std=c++11 %s +// RUN: %clang_cc1 -triple=powerpc64le-unknown-linux-gnu -target-cpu pwr10 \ +// RUN: -target-feature +altivec -target-feature +vsx \ +// RUN: -target-feature -power10-vector -fsyntax-only -verify %s + +#include + +// Test 'vector bool __int128' type. + +// These should have errors. +__vector bool __int128 v1_bi128; // expected-error {{use of '__int128' with '__vector bool' requires VSX support enabled (on POWER10 or later)}} +__vector __bool __int128 v2_bi128; // expected-error {{use of '__int128' with '__vector bool' requires VSX support enabled (on POWER10 or later)}} +vector bool __int128 v3_bi128; // expected-error {{use of '__int128' with '__vector bool' requires VSX support enabled (on POWER10 or later)}} +vector __bool __int128 v4_bi128; // expected-error {{use of '__int128' with '__vector bool' requires VSX support enabled (on POWER10 or later)}} +__vector bool unsigned __int128 v5_bi128; // expected-error {{cannot use 'unsigned' with '__vector bool'}} expected-error {{use of '__int128' with '__vector bool' requires VSX support enabled (on POWER10 or later)}} +__vector bool signed __int128 v6_bi128; // expected-error {{cannot use 'signed' with '__vector bool'}} expected-error {{use of '__int128' with '__vector bool' requires VSX support enabled (on POWER10 or later)}} +vector bool unsigned __int128 v7_bi128; // expected-error {{cannot use 'unsigned' with '__vector bool'}} expected-error {{use of '__int128' with '__vector bool' requires VSX support enabled (on POWER10 or later)}} +vector bool signed __int128 v8_bi128; // expected-error {{cannot use 'signed' with '__vector bool'}} expected-error {{use of '__int128' with '__vector bool' requires VSX support enabled (on POWER10 or later)}} +__vector __bool signed __int128 v9_bi128; // expected-error {{cannot use 'signed' with '__vector bool'}} expected-error {{use of '__int128' with '__vector bool' requires VSX support enabled (on POWER10 or later)}} +vector __bool signed __int128 v10_bi128; // expected-error {{cannot use 'signed' with '__vector bool'}} expected-error {{use of '__int128' with '__vector bool' requires VSX support enabled (on POWER10 or later)}} diff --git a/clang/test/Parser/cxx-template-decl.cpp b/clang/test/Parser/cxx-template-decl.cpp index 64e7ca921f575..24cc13cde91fa 100644 --- a/clang/test/Parser/cxx-template-decl.cpp +++ b/clang/test/Parser/cxx-template-decl.cpp @@ -286,3 +286,17 @@ namespace PR45239 { template int b; template auto f() -> b<0>; // expected-error +{{}} } + +namespace NoCrashOnNullNNSTypoCorrection { + +int AddObservation(); // expected-note {{declared here}} + +template // expected-note {{template parameter is declared here}} +class UsingImpl {}; +class AddObservation { + using Using = + UsingImpl; // expected-error {{use of undeclared identifier 'AddObservationFn'; did you mean}} \ + expected-error {{template argument for template type parameter must be a type}} +}; + +} diff --git a/clang/test/Parser/expressions.cpp b/clang/test/Parser/expressions.cpp new file mode 100644 index 0000000000000..6d3123bd1de7c --- /dev/null +++ b/clang/test/Parser/expressions.cpp @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -std=c++2a -verify %s + +void *operator new(__SIZE_TYPE__, void*); + +// Check that we give a good diagnostic for an attempt to use a postfix +// operator after a unary-expression. +namespace postfix_after_unary { + struct A { int n; }; + int &a = new A->n; // expected-error {{expression cannot be followed by a postfix '->' operator; add parentheses}} + + struct B { B(int); int operator()(int); }; + int n = new (0) (B) (int()) (int()); // expected-error {{cannot be followed by a postfix '(}} expected-error {{not a function or function pointer}} + + char x = sizeof(int)["hello"]; // expected-error {{cannot be followed by a postfix '[}} + char y = alignof(int)["hello"]; // expected-error {{cannot be followed by a postfix '[}} + char z = noexcept(0)["hello"]; // expected-error {{cannot be followed by a postfix '[}} + char w = requires { x == x; }["ny"]; // expected-error {{cannot be followed by a postfix '[}} + + int f() { + label: + return &&label->n; // expected-error {{cannot be followed by a postfix}} expected-error {{not a structure or union}} + } + + char k = sizeof(int) // expected-error {{expected ';'}} + [[noreturn]] void g(); +} + +// Check that we do parse postfix-expression suffixes after some more unusual +// kinds of postfix-expressions (null literals and builtin calls). +namespace unusual_primary_exprs { + int a = nullptr["foo"]; // expected-error {{array subscript is not an integer}} + int b = __builtin_COLUMN()["sufficiently long string constant"]; + int c = __builtin_available(*)["ny"]; + static_assert(__null["foo"] == 'f'); // FIXME: Warn about converting __null to integer in array subscripting. + static_assert(__is_standard_layout(int)["ny"] == 'y'); + static_assert(__array_rank(int[1][2])["0123"] == '2'); + static_assert(__is_lvalue_expr(a)["ny"] == 'y'); +} diff --git a/clang/test/Parser/p10-vector-bool-128.c b/clang/test/Parser/p10-vector-bool-128.c new file mode 100644 index 0000000000000..df14b04e7e37c --- /dev/null +++ b/clang/test/Parser/p10-vector-bool-128.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple=powerpc64-unknown-linux-gnu -target-cpu pwr10 \ +// RUN: -target-feature +vsx -target-feature +power10-vector \ +// RUN: -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple=powerpc64le-unknown-linux-gnu -target-cpu pwr10 \ +// RUN: -target-feature +power10-vector -fsyntax-only -verify %s +// expected-no-diagnostics + +// Test legitimate uses of 'vector bool __int128' with VSX. +__vector bool __int128 v1_bi128; +__vector __bool __int128 v2_bi128; +vector bool __int128 v3_bi128; +vector __bool __int128 v4_bi128; diff --git a/clang/test/Preprocessor/aarch64-target-features.c b/clang/test/Preprocessor/aarch64-target-features.c index 784c67cd643d1..bef145930697f 100644 --- a/clang/test/Preprocessor/aarch64-target-features.c +++ b/clang/test/Preprocessor/aarch64-target-features.c @@ -93,7 +93,39 @@ // RUN: %clang -target aarch64 -mtune=cyclone -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MTUNE-CYCLONE %s // RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+sve -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE %s -// CHECK-SVE-NOT: __ARM_FEATURE_SVE 1 +// CHECK-SVE: __ARM_FEATURE_SVE 1 + +// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+sve+bf16 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE-BF16 %s +// CHECK-SVE-BF16: __ARM_FEATURE_BF16_SCALAR_ARITHMETIC 1 +// CHECK-SVE-BF16: __ARM_FEATURE_SVE 1 +// CHECK-SVE-BF16: __ARM_FEATURE_SVE_BF16 1 + +// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+sve+i8mm -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE-I8MM %s +// CHECK-SVE-I8MM: __ARM_FEATURE_SVE 1 +// CHECK-SVE-I8MM: __ARM_FEATURE_SVE_MATMUL_INT8 1 + +// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+sve+f32mm -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE-F32MM %s +// CHECK-SVE-F32MM: __ARM_FEATURE_SVE 1 +// CHECK-SVE-F32MM: __ARM_FEATURE_SVE_MATMUL_FP32 1 + +// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+sve+f64mm -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE-F64MM %s +// CHECK-SVE-F64MM: __ARM_FEATURE_SVE 1 +// CHECK-SVE-F64MM: __ARM_FEATURE_SVE_MATMUL_FP64 1 + +// The following tests may need to be revised in the future since +// SVE2 is currently still part of Future Architecture Technologies +// (https://developer.arm.com/docs/ddi0602/latest) +// +// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+sve2 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2 %s +// CHECK-SVE2: __ARM_FEATURE_SVE2 1 +// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+sve2-aes -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2AES %s +// CHECK-SVE2AES: __ARM_FEATURE_SVE2_AES 1 +// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+sve2-sha3 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2SHA3 %s +// CHECK-SVE2SHA3: __ARM_FEATURE_SVE2_SHA3 1 +// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+sve2-sm4 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2SM4 %s +// CHECK-SVE2SM4: __ARM_FEATURE_SVE2_SM4 1 +// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+sve2-bitperm -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2BITPERM %s +// CHECK-SVE2BITPERM: __ARM_FEATURE_SVE2_BITPERM 1 // RUN: %clang -target aarch64-none-linux-gnu -march=armv8.2a+dotprod -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-DOTPROD %s // CHECK-DOTPROD: __ARM_FEATURE_DOTPROD 1 diff --git a/clang/test/Preprocessor/init-ve.c b/clang/test/Preprocessor/init-ve.c new file mode 100644 index 0000000000000..4686315f4ea06 --- /dev/null +++ b/clang/test/Preprocessor/init-ve.c @@ -0,0 +1,274 @@ +/// Check predefinitions for NEC Aurora VE +/// REQUIRES: ve-registered-target + +// RUN: %clang_cc1 -E -dM -triple=ve < /dev/null | \ +// RUN: FileCheck -match-full-lines -check-prefix VE %s +// RUN: %clang_cc1 -x c++ -E -dM -triple=ve < /dev/null | \ +// RUN: FileCheck -match-full-lines -check-prefix VE -check-prefix VE-CXX %s +// +// VE:#define _LP64 1 +// VE:#define __BIGGEST_ALIGNMENT__ 8 +// VE:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ +// VE:#define __CHAR16_TYPE__ unsigned short +// VE:#define __CHAR32_TYPE__ unsigned int +// VE:#define __CHAR_BIT__ 8 +// VE:#define __DBL_DECIMAL_DIG__ 17 +// VE:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324 +// VE:#define __DBL_DIG__ 15 +// VE:#define __DBL_EPSILON__ 2.2204460492503131e-16 +// VE:#define __DBL_HAS_DENORM__ 1 +// VE:#define __DBL_HAS_INFINITY__ 1 +// VE:#define __DBL_HAS_QUIET_NAN__ 1 +// VE:#define __DBL_MANT_DIG__ 53 +// VE:#define __DBL_MAX_10_EXP__ 308 +// VE:#define __DBL_MAX_EXP__ 1024 +// VE:#define __DBL_MAX__ 1.7976931348623157e+308 +// VE:#define __DBL_MIN_10_EXP__ (-307) +// VE:#define __DBL_MIN_EXP__ (-1021) +// VE:#define __DBL_MIN__ 2.2250738585072014e-308 +// VE:#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__ +// VE-NOT:#define __FAST_MATH__ 1 +// VE:#define __FLT_DECIMAL_DIG__ 9 +// VE:#define __FLT_DENORM_MIN__ 1.40129846e-45F +// VE:#define __FLT_DIG__ 6 +// VE:#define __FLT_EPSILON__ 1.19209290e-7F +// VE:#define __FLT_EVAL_METHOD__ 0 +// VE:#define __FLT_HAS_DENORM__ 1 +// VE:#define __FLT_HAS_INFINITY__ 1 +// VE:#define __FLT_HAS_QUIET_NAN__ 1 +// VE:#define __FLT_MANT_DIG__ 24 +// VE:#define __FLT_MAX_10_EXP__ 38 +// VE:#define __FLT_MAX_EXP__ 128 +// VE:#define __FLT_MAX__ 3.40282347e+38F +// VE:#define __FLT_MIN_10_EXP__ (-37) +// VE:#define __FLT_MIN_EXP__ (-125) +// VE:#define __FLT_MIN__ 1.17549435e-38F +// VE:#define __FLT_RADIX__ 2 +// VE:#define __INT16_C_SUFFIX__ +// VE:#define __INT16_FMTd__ "hd" +// VE:#define __INT16_FMTi__ "hi" +// VE:#define __INT16_MAX__ 32767 +// VE:#define __INT16_TYPE__ short +// VE:#define __INT32_C_SUFFIX__ +// VE:#define __INT32_FMTd__ "d" +// VE:#define __INT32_FMTi__ "i" +// VE:#define __INT32_MAX__ 2147483647 +// VE:#define __INT32_TYPE__ int +// VE:#define __INT64_C_SUFFIX__ L +// VE:#define __INT64_FMTd__ "ld" +// VE:#define __INT64_FMTi__ "li" +// VE:#define __INT64_MAX__ 9223372036854775807L +// VE:#define __INT64_TYPE__ long int +// VE:#define __INT8_C_SUFFIX__ +// VE:#define __INT8_FMTd__ "hhd" +// VE:#define __INT8_FMTi__ "hhi" +// VE:#define __INT8_MAX__ 127 +// VE:#define __INT8_TYPE__ signed char +// VE:#define __INTMAX_C_SUFFIX__ L +// VE:#define __INTMAX_FMTd__ "ld" +// VE:#define __INTMAX_FMTi__ "li" +// VE:#define __INTMAX_MAX__ 9223372036854775807L +// VE:#define __INTMAX_TYPE__ long int +// VE:#define __INTMAX_WIDTH__ 64 +// VE:#define __INTPTR_FMTd__ "ld" +// VE:#define __INTPTR_FMTi__ "li" +// VE:#define __INTPTR_MAX__ 9223372036854775807L +// VE:#define __INTPTR_TYPE__ long int +// VE:#define __INTPTR_WIDTH__ 64 +// VE:#define __INT_FAST16_FMTd__ "hd" +// VE:#define __INT_FAST16_FMTi__ "hi" +// VE:#define __INT_FAST16_MAX__ 32767 +// VE:#define __INT_FAST16_TYPE__ short +// VE:#define __INT_FAST32_FMTd__ "d" +// VE:#define __INT_FAST32_FMTi__ "i" +// VE:#define __INT_FAST32_MAX__ 2147483647 +// VE:#define __INT_FAST32_TYPE__ int +// VE:#define __INT_FAST64_FMTd__ "ld" +// VE:#define __INT_FAST64_FMTi__ "li" +// VE:#define __INT_FAST64_MAX__ 9223372036854775807L +// VE:#define __INT_FAST64_TYPE__ long int +// VE:#define __INT_FAST8_FMTd__ "hhd" +// VE:#define __INT_FAST8_FMTi__ "hhi" +// VE:#define __INT_FAST8_MAX__ 127 +// VE:#define __INT_FAST8_TYPE__ signed char +// VE:#define __INT_LEAST16_FMTd__ "hd" +// VE:#define __INT_LEAST16_FMTi__ "hi" +// VE:#define __INT_LEAST16_MAX__ 32767 +// VE:#define __INT_LEAST16_TYPE__ short +// VE:#define __INT_LEAST32_FMTd__ "d" +// VE:#define __INT_LEAST32_FMTi__ "i" +// VE:#define __INT_LEAST32_MAX__ 2147483647 +// VE:#define __INT_LEAST32_TYPE__ int +// VE:#define __INT_LEAST64_FMTd__ "ld" +// VE:#define __INT_LEAST64_FMTi__ "li" +// VE:#define __INT_LEAST64_MAX__ 9223372036854775807L +// VE:#define __INT_LEAST64_TYPE__ long int +// VE:#define __INT_LEAST8_FMTd__ "hhd" +// VE:#define __INT_LEAST8_FMTi__ "hhi" +// VE:#define __INT_LEAST8_MAX__ 127 +// VE:#define __INT_LEAST8_TYPE__ signed char +// VE:#define __INT_MAX__ 2147483647 +// VE:#define __LDBL_DECIMAL_DIG__ 36 +// VE:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L +// VE:#define __LDBL_DIG__ 33 +// VE:#define __LDBL_EPSILON__ 1.92592994438723585305597794258492732e-34L +// VE:#define __LDBL_HAS_DENORM__ 1 +// VE:#define __LDBL_HAS_INFINITY__ 1 +// VE:#define __LDBL_HAS_QUIET_NAN__ 1 +// VE:#define __LDBL_MANT_DIG__ 113 +// VE:#define __LDBL_MAX_10_EXP__ 4932 +// VE:#define __LDBL_MAX_EXP__ 16384 +// VE:#define __LDBL_MAX__ 1.18973149535723176508575932662800702e+4932L +// VE:#define __LDBL_MIN_10_EXP__ (-4931) +// VE:#define __LDBL_MIN_EXP__ (-16381) +// VE:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L +// VE:#define __LITTLE_ENDIAN__ 1 +// VE-NOT:#define __LONGDOUBLE128 1 +// VE-NOT:#define __LONG_DOUBLE_128__ 1 +// VE:#define __LONG_LONG_MAX__ 9223372036854775807LL +// VE:#define __LONG_MAX__ 9223372036854775807L +// VE:#define __LP64__ 1 +// VE:#define __NEC__ 1 +// VE-NOT:#define __OPTIMIZE__ +// VE:#define __POINTER_WIDTH__ 64 +// VE:#define __PTRDIFF_FMTd__ "ld" +// VE:#define __PTRDIFF_FMTi__ "li" +// VE:#define __PTRDIFF_MAX__ 9223372036854775807L +// VE:#define __PTRDIFF_TYPE__ long int +// VE:#define __PTRDIFF_WIDTH__ 64 +// VE:#define __SCHAR_MAX__ 127 +// VE:#define __SHRT_MAX__ 32767 +// VE:#define __SIG_ATOMIC_MAX__ 2147483647 +// VE:#define __SIG_ATOMIC_WIDTH__ 32 +// VE:#define __SIZEOF_DOUBLE__ 8 +// VE:#define __SIZEOF_FLOAT__ 4 +// VE:#define __SIZEOF_INT128__ 16 +// VE:#define __SIZEOF_INT__ 4 +// VE:#define __SIZEOF_LONG_DOUBLE__ 16 +// VE:#define __SIZEOF_LONG_LONG__ 8 +// VE:#define __SIZEOF_LONG__ 8 +// VE:#define __SIZEOF_POINTER__ 8 +// VE:#define __SIZEOF_PTRDIFF_T__ 8 +// VE:#define __SIZEOF_SHORT__ 2 +// VE:#define __SIZEOF_SIZE_T__ 8 +// VE:#define __SIZEOF_WCHAR_T__ 4 +// VE:#define __SIZEOF_WINT_T__ 4 +// VE:#define __SIZE_FMTX__ "lX" +// VE:#define __SIZE_FMTo__ "lo" +// VE:#define __SIZE_FMTu__ "lu" +// VE:#define __SIZE_FMTx__ "lx" +// VE:#define __SIZE_MAX__ 18446744073709551615UL +// VE:#define __SIZE_TYPE__ long unsigned int +// VE:#define __SIZE_WIDTH__ 64 +// VE-CXX:#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16UL +// VE:#define __STDC_HOSTED__ 1 +// VE:#define __UINT16_C_SUFFIX__ +// VE:#define __UINT16_FMTX__ "hX" +// VE:#define __UINT16_FMTo__ "ho" +// VE:#define __UINT16_FMTu__ "hu" +// VE:#define __UINT16_FMTx__ "hx" +// VE:#define __UINT16_MAX__ 65535 +// VE:#define __UINT16_TYPE__ unsigned short +// VE:#define __UINT32_C_SUFFIX__ U +// VE:#define __UINT32_FMTX__ "X" +// VE:#define __UINT32_FMTo__ "o" +// VE:#define __UINT32_FMTu__ "u" +// VE:#define __UINT32_FMTx__ "x" +// VE:#define __UINT32_MAX__ 4294967295U +// VE:#define __UINT32_TYPE__ unsigned int +// VE:#define __UINT64_C_SUFFIX__ UL +// VE:#define __UINT64_FMTX__ "lX" +// VE:#define __UINT64_FMTo__ "lo" +// VE:#define __UINT64_FMTu__ "lu" +// VE:#define __UINT64_FMTx__ "lx" +// VE:#define __UINT64_MAX__ 18446744073709551615UL +// VE:#define __UINT64_TYPE__ long unsigned int +// VE:#define __UINT8_C_SUFFIX__ +// VE:#define __UINT8_FMTX__ "hhX" +// VE:#define __UINT8_FMTo__ "hho" +// VE:#define __UINT8_FMTu__ "hhu" +// VE:#define __UINT8_FMTx__ "hhx" +// VE:#define __UINT8_MAX__ 255 +// VE:#define __UINT8_TYPE__ unsigned char +// VE:#define __UINTMAX_C_SUFFIX__ UL +// VE:#define __UINTMAX_FMTX__ "lX" +// VE:#define __UINTMAX_FMTo__ "lo" +// VE:#define __UINTMAX_FMTu__ "lu" +// VE:#define __UINTMAX_FMTx__ "lx" +// VE:#define __UINTMAX_MAX__ 18446744073709551615UL +// VE:#define __UINTMAX_TYPE__ long unsigned int +// VE:#define __UINTMAX_WIDTH__ 64 +// VE:#define __UINTPTR_FMTX__ "lX" +// VE:#define __UINTPTR_FMTo__ "lo" +// VE:#define __UINTPTR_FMTu__ "lu" +// VE:#define __UINTPTR_FMTx__ "lx" +// VE:#define __UINTPTR_MAX__ 18446744073709551615UL +// VE:#define __UINTPTR_TYPE__ long unsigned int +// VE:#define __UINTPTR_WIDTH__ 64 +// VE:#define __UINT_FAST16_FMTX__ "hX" +// VE:#define __UINT_FAST16_FMTo__ "ho" +// VE:#define __UINT_FAST16_FMTu__ "hu" +// VE:#define __UINT_FAST16_FMTx__ "hx" +// VE:#define __UINT_FAST16_MAX__ 65535 +// VE:#define __UINT_FAST16_TYPE__ unsigned short +// VE:#define __UINT_FAST32_FMTX__ "X" +// VE:#define __UINT_FAST32_FMTo__ "o" +// VE:#define __UINT_FAST32_FMTu__ "u" +// VE:#define __UINT_FAST32_FMTx__ "x" +// VE:#define __UINT_FAST32_MAX__ 4294967295U +// VE:#define __UINT_FAST32_TYPE__ unsigned int +// VE:#define __UINT_FAST64_FMTX__ "lX" +// VE:#define __UINT_FAST64_FMTo__ "lo" +// VE:#define __UINT_FAST64_FMTu__ "lu" +// VE:#define __UINT_FAST64_FMTx__ "lx" +// VE:#define __UINT_FAST64_MAX__ 18446744073709551615UL +// VE:#define __UINT_FAST64_TYPE__ long unsigned int +// VE:#define __UINT_FAST8_FMTX__ "hhX" +// VE:#define __UINT_FAST8_FMTo__ "hho" +// VE:#define __UINT_FAST8_FMTu__ "hhu" +// VE:#define __UINT_FAST8_FMTx__ "hhx" +// VE:#define __UINT_FAST8_MAX__ 255 +// VE:#define __UINT_FAST8_TYPE__ unsigned char +// VE:#define __UINT_LEAST16_FMTX__ "hX" +// VE:#define __UINT_LEAST16_FMTo__ "ho" +// VE:#define __UINT_LEAST16_FMTu__ "hu" +// VE:#define __UINT_LEAST16_FMTx__ "hx" +// VE:#define __UINT_LEAST16_MAX__ 65535 +// VE:#define __UINT_LEAST16_TYPE__ unsigned short +// VE:#define __UINT_LEAST32_FMTX__ "X" +// VE:#define __UINT_LEAST32_FMTo__ "o" +// VE:#define __UINT_LEAST32_FMTu__ "u" +// VE:#define __UINT_LEAST32_FMTx__ "x" +// VE:#define __UINT_LEAST32_MAX__ 4294967295U +// VE:#define __UINT_LEAST32_TYPE__ unsigned int +// VE:#define __UINT_LEAST64_FMTX__ "lX" +// VE:#define __UINT_LEAST64_FMTo__ "lo" +// VE:#define __UINT_LEAST64_FMTu__ "lu" +// VE:#define __UINT_LEAST64_FMTx__ "lx" +// VE:#define __UINT_LEAST64_MAX__ 18446744073709551615UL +// VE:#define __UINT_LEAST64_TYPE__ long unsigned int +// VE:#define __UINT_LEAST8_FMTX__ "hhX" +// VE:#define __UINT_LEAST8_FMTo__ "hho" +// VE:#define __UINT_LEAST8_FMTu__ "hhu" +// VE:#define __UINT_LEAST8_FMTx__ "hhx" +// VE:#define __UINT_LEAST8_MAX__ 255 +// VE:#define __UINT_LEAST8_TYPE__ unsigned char +// VE:#define __USER_LABEL_PREFIX__ +// VE-NOT:#define __VECTOR__ +// VE:#define __WCHAR_MAX__ 4294967295U +// VE:#define __WCHAR_TYPE__ unsigned int +// VE:#define __WCHAR_UNSIGNED__ 1 +// VE:#define __WCHAR_WIDTH__ 32 +// VE:#define __WINT_MAX__ 4294967295U +// VE:#define __WINT_TYPE__ unsigned int +// VE:#define __WINT_UNSIGNED__ 1 +// VE:#define __WINT_WIDTH__ 32 +// VE:#define __linux 1 +// VE:#define __linux__ 1 +// VE:#define __llvm__ 1 +// VE:#define __unix 1 +// VE:#define __unix__ 1 +// VE:#define __ve 1 +// VE:#define __ve__ 1 +// VE:#define linux 1 +// VE:#define unix 1 diff --git a/clang/test/Preprocessor/predefined-arch-macros.c b/clang/test/Preprocessor/predefined-arch-macros.c index f7de81028327e..e457a0479b330 100644 --- a/clang/test/Preprocessor/predefined-arch-macros.c +++ b/clang/test/Preprocessor/predefined-arch-macros.c @@ -2379,6 +2379,7 @@ // CHECK_AMDFAM10_M32: #define __LZCNT__ 1 // CHECK_AMDFAM10_M32: #define __MMX__ 1 // CHECK_AMDFAM10_M32: #define __POPCNT__ 1 +// CHECK_AMDFAM10_M32: #define __PRFCHW__ 1 // CHECK_AMDFAM10_M32: #define __SSE2_MATH__ 1 // CHECK_AMDFAM10_M32: #define __SSE2__ 1 // CHECK_AMDFAM10_M32: #define __SSE3__ 1 @@ -2396,9 +2397,11 @@ // RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_AMDFAM10_M64 // CHECK_AMDFAM10_M64: #define __3dNOW_A__ 1 // CHECK_AMDFAM10_M64: #define __3dNOW__ 1 +// CHECK_AMDFAM10_M64: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 1 // CHECK_AMDFAM10_M64: #define __LZCNT__ 1 // CHECK_AMDFAM10_M64: #define __MMX__ 1 // CHECK_AMDFAM10_M64: #define __POPCNT__ 1 +// CHECK_AMDFAM10_M64: #define __PRFCHW__ 1 // CHECK_AMDFAM10_M64: #define __SSE2_MATH__ 1 // CHECK_AMDFAM10_M64: #define __SSE2__ 1 // CHECK_AMDFAM10_M64: #define __SSE3__ 1 @@ -2750,9 +2753,11 @@ // CHECK_BDVER4_M32: #define __LWP__ 1 // CHECK_BDVER4_M32: #define __LZCNT__ 1 // CHECK_BDVER4_M32: #define __MMX__ 1 +// CHECK_BDVER4_M32: #define __MOVBE__ 1 // CHECK_BDVER4_M32: #define __PCLMUL__ 1 // CHECK_BDVER4_M32: #define __POPCNT__ 1 // CHECK_BDVER4_M32: #define __PRFCHW__ 1 +// CHECK_BDVER4_M32: #define __RDRND__ 1 // CHECK_BDVER4_M32: #define __SSE2_MATH__ 1 // CHECK_BDVER4_M32: #define __SSE2__ 1 // CHECK_BDVER4_M32: #define __SSE3__ 1 @@ -2788,9 +2793,11 @@ // CHECK_BDVER4_M64: #define __LWP__ 1 // CHECK_BDVER4_M64: #define __LZCNT__ 1 // CHECK_BDVER4_M64: #define __MMX__ 1 +// CHECK_BDVER4_M64: #define __MOVBE__ 1 // CHECK_BDVER4_M64: #define __PCLMUL__ 1 // CHECK_BDVER4_M64: #define __POPCNT__ 1 // CHECK_BDVER4_M64: #define __PRFCHW__ 1 +// CHECK_BDVER4_M64: #define __RDRND__ 1 // CHECK_BDVER4_M64: #define __SSE2_MATH__ 1 // CHECK_BDVER4_M64: #define __SSE2__ 1 // CHECK_BDVER4_M64: #define __SSE3__ 1 @@ -2825,6 +2832,7 @@ // CHECK_ZNVER1_M32: #define __CLFLUSHOPT__ 1 // CHECK_ZNVER1_M32: #define __CLZERO__ 1 // CHECK_ZNVER1_M32: #define __F16C__ 1 +// CHECK_ZNVER1_M32-NOT: #define __FMA4__ 1 // CHECK_ZNVER1_M32: #define __FMA__ 1 // CHECK_ZNVER1_M32: #define __FSGSBASE__ 1 // CHECK_ZNVER1_M32: #define __LZCNT__ 1 @@ -2845,6 +2853,8 @@ // CHECK_ZNVER1_M32: #define __SSE_MATH__ 1 // CHECK_ZNVER1_M32: #define __SSE__ 1 // CHECK_ZNVER1_M32: #define __SSSE3__ 1 +// CHECK_ZNVER1_M32-NOT: #define __TBM__ 1 +// CHECK_ZNVER1_M32-NOT: #define __XOP__ 1 // CHECK_ZNVER1_M32: #define __XSAVEC__ 1 // CHECK_ZNVER1_M32: #define __XSAVEOPT__ 1 // CHECK_ZNVER1_M32: #define __XSAVES__ 1 @@ -2869,6 +2879,7 @@ // CHECK_ZNVER1_M64: #define __CLFLUSHOPT__ 1 // CHECK_ZNVER1_M64: #define __CLZERO__ 1 // CHECK_ZNVER1_M64: #define __F16C__ 1 +// CHECK_ZNVER1_M64-NOT: #define __FMA4__ 1 // CHECK_ZNVER1_M64: #define __FMA__ 1 // CHECK_ZNVER1_M64: #define __FSGSBASE__ 1 // CHECK_ZNVER1_M64: #define __LZCNT__ 1 @@ -2889,6 +2900,8 @@ // CHECK_ZNVER1_M64: #define __SSE_MATH__ 1 // CHECK_ZNVER1_M64: #define __SSE__ 1 // CHECK_ZNVER1_M64: #define __SSSE3__ 1 +// CHECK_ZNVER1_M64-NOT: #define __TBM__ 1 +// CHECK_ZNVER1_M64-NOT: #define __XOP__ 1 // CHECK_ZNVER1_M64: #define __XSAVEC__ 1 // CHECK_ZNVER1_M64: #define __XSAVEOPT__ 1 // CHECK_ZNVER1_M64: #define __XSAVES__ 1 @@ -2916,6 +2929,7 @@ // CHECK_ZNVER2_M32: #define __CLWB__ 1 // CHECK_ZNVER2_M32: #define __CLZERO__ 1 // CHECK_ZNVER2_M32: #define __F16C__ 1 +// CHECK_ZNVER2_M32-NOT: #define __FMA4__ 1 // CHECK_ZNVER2_M32: #define __FMA__ 1 // CHECK_ZNVER2_M32: #define __FSGSBASE__ 1 // CHECK_ZNVER2_M32: #define __LZCNT__ 1 @@ -2936,7 +2950,9 @@ // CHECK_ZNVER2_M32: #define __SSE_MATH__ 1 // CHECK_ZNVER2_M32: #define __SSE__ 1 // CHECK_ZNVER2_M32: #define __SSSE3__ 1 +// CHECK_ZNVER2_M32-NOT: #define __TBM__ 1 // CHECK_ZNVER2_M32: #define __WBNOINVD__ 1 +// CHECK_ZNVER2_M32-NOT: #define __XOP__ 1 // CHECK_ZNVER2_M32: #define __XSAVEC__ 1 // CHECK_ZNVER2_M32: #define __XSAVEOPT__ 1 // CHECK_ZNVER2_M32: #define __XSAVES__ 1 @@ -2962,6 +2978,7 @@ // CHECK_ZNVER2_M64: #define __CLWB__ 1 // CHECK_ZNVER2_M64: #define __CLZERO__ 1 // CHECK_ZNVER2_M64: #define __F16C__ 1 +// CHECK_ZNVER2_M64-NOT: #define __FMA4__ 1 // CHECK_ZNVER2_M64: #define __FMA__ 1 // CHECK_ZNVER2_M64: #define __FSGSBASE__ 1 // CHECK_ZNVER2_M64: #define __LZCNT__ 1 @@ -2982,7 +2999,9 @@ // CHECK_ZNVER2_M64: #define __SSE_MATH__ 1 // CHECK_ZNVER2_M64: #define __SSE__ 1 // CHECK_ZNVER2_M64: #define __SSSE3__ 1 +// CHECK_ZNVER2_M64-NOT: #define __TBM__ 1 // CHECK_ZNVER2_M64: #define __WBNOINVD__ 1 +// CHECK_ZNVER2_M64-NOT: #define __XOP__ 1 // CHECK_ZNVER2_M64: #define __XSAVEC__ 1 // CHECK_ZNVER2_M64: #define __XSAVEOPT__ 1 // CHECK_ZNVER2_M64: #define __XSAVES__ 1 diff --git a/clang/test/Preprocessor/warn-macro-undef.c b/clang/test/Preprocessor/warn-macro-undef.c new file mode 100644 index 0000000000000..e7d16c836076a --- /dev/null +++ b/clang/test/Preprocessor/warn-macro-undef.c @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 %s -Eonly -Wundef -verify=undef +// RUN: %clang_cc1 %s -Eonly -Wundef-prefix=A,BC -verify=undef-prefix +// RUN: %clang_cc1 %s -Eonly -Wundef -Wundef-prefix=A,BC -verify=both +// RUN: %clang_cc1 %s -Eonly -Werror=undef -verify=undef-error +// RUN: %clang_cc1 %s -Eonly -Werror=undef-prefix -Wundef-prefix=A,BC -verify=undef-prefix-error +// RUN: %clang_cc1 %s -Eonly -Werror=undef -Wundef-prefix=A,BC -verify=both-error + +extern int x; + +#if AB // #1 +#endif +// undef-warning@#1 {{'AB' is not defined, evaluates to 0}} +// undef-prefix-warning@#1 {{'AB' is not defined, evaluates to 0}} +// both-warning@#1 {{'AB' is not defined, evaluates to 0}} +// undef-error-error@#1 {{'AB' is not defined, evaluates to 0}} +// undef-prefix-error-error@#1 {{'AB' is not defined, evaluates to 0}} +// both-error-error@#1 {{'AB' is not defined, evaluates to 0}} + +#if B // #2 +#endif +// undef-warning@#2 {{'B' is not defined, evaluates to 0}} +// no warning for undef-prefix +// both-warning@#2 {{'B' is not defined, evaluates to 0}} +// undef-error-error@#2 {{'B' is not defined, evaluates to 0}} +// no error for undef-prefix +// both-error-error@#2 {{'B' is not defined, evaluates to 0}} + +#define BC 0 +#if BC // no warning/error +#endif + +#undef BC +#if BC // #3 +#endif +// undef-warning@#3 {{'BC' is not defined, evaluates to 0}} +// undef-prefix-warning@#3 {{'BC' is not defined, evaluates to 0}} +// both-warning@#3 {{'BC' is not defined, evaluates to 0}} +// undef-error-error@#3 {{'BC' is not defined, evaluates to 0}} +// undef-prefix-error-error@#3 {{'BC' is not defined, evaluates to 0}} +// both-error-error@#3 {{'BC' is not defined, evaluates to 0}} + +// Test that #pragma-enabled 'Wundef' can override 'Wundef-prefix' +#pragma clang diagnostic error "-Wundef" + +#if C // #4 +#endif +// undef-error@#4 {{'C' is not defined, evaluates to 0}} +// undef-prefix-error@#4 {{'C' is not defined, evaluates to 0}} +// both-error@#4 {{'C' is not defined, evaluates to 0}} +// undef-error-error@#4 {{'C' is not defined, evaluates to 0}} +// undef-prefix-error-error@#4 {{'C' is not defined, evaluates to 0}} +// both-error-error@#4 {{'C' is not defined, evaluates to 0}} diff --git a/clang/test/Preprocessor/x86_amx_target_features.c b/clang/test/Preprocessor/x86_amx_target_features.c new file mode 100644 index 0000000000000..68a3d7f950b10 --- /dev/null +++ b/clang/test/Preprocessor/x86_amx_target_features.c @@ -0,0 +1,35 @@ +// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mamx-tile -x c -E -dM -o - %s | FileCheck -check-prefix=AMX-TILE %s + +// AMX-TILE: #define __AMXTILE__ 1 + +// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mamx-bf16 -x c -E -dM -o - %s | FileCheck -check-prefix=AMX-BF16 %s + +// AMX-BF16: #define __AMXBF16__ 1 +// AMX-BF16: #define __AMXTILE__ 1 + +// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mamx-int8 -x c -E -dM -o - %s | FileCheck -check-prefix=AMX-INT8 %s + +// AMX-INT8: #define __AMXINT8__ 1 +// AMX-INT8: #define __AMXTILE__ 1 + +// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-amx-tile -x c -E -dM -o - %s | FileCheck -check-prefix=NOAMX-TILE %s + +// NOAMX-TILE-NOT: #define __AMXTILE__ 1 + +// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-amx-bf16 -x c -E -dM -o - %s | FileCheck -check-prefix=NOAMX-BF16 %s + +// NOAMX-BF16-NOT: #define __AMXBF16__ 1 + +// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -amx-bf16 -mno-amx-tile -x c -E -dM -o - %s | FileCheck -check-prefix=NOAMX-BF16 %s + +// NOAMX-BF16-NOT: #define __AMXTILE__ 1 +// NOAMX-BF16-NOT: #define __AMXBF16__ 1 + +// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-amx-int8 -x c -E -dM -o - %s | FileCheck -check-prefix=NOAMX-INT8 %s + +// NOAMX-INT8-NOT: #define __AMXINT8__ 1 + +// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -amx-int8 -mno-amx-tile -x c -E -dM -o - %s | FileCheck -check-prefix=NOAMX-INT8 %s + +// NOAMX-INT8-NOT: #define __AMXTILE__ 1 +// NOAMX-INT8-NOT: #define __AMXINT8__ 1 diff --git a/clang/test/Preprocessor/x86_target_features.c b/clang/test/Preprocessor/x86_target_features.c index 8e24c15187208..4a46a131afa74 100644 --- a/clang/test/Preprocessor/x86_target_features.c +++ b/clang/test/Preprocessor/x86_target_features.c @@ -269,6 +269,12 @@ // NOSSE42POPCNT: #define __POPCNT__ 1 +// RUN: %clang -target i386-unknown-unknown -march=nehalem -mno-sse4.2 -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=CPUPOPCNT %s +// RUN: %clang -target i386-unknown-unknown -march=silvermont -mno-sse4.2 -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=CPUPOPCNT %s +// RUN: %clang -target i386-unknown-unknown -march=knl -mno-sse4.2 -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=CPUPOPCNT %s + +// CPUPOPCNT: #define __POPCNT__ 1 + // RUN: %clang -target i386-unknown-unknown -march=pentium -msse -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=SSEMMX %s // SSEMMX: #define __MMX__ 1 @@ -374,10 +380,12 @@ // RUN: %clang -target i386-unknown-unknown -march=atom -m3dnow -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=3DNOWPRFCHW %s -// 3DNOWPRFCHW: #define __PRFCHW__ 1 +// 3DNOWPRFCHW: #define __3dNOW__ 1 +// 3DNOWPRFCHW-NOT: #define __PRFCHW__ 1 // RUN: %clang -target i386-unknown-unknown -march=atom -mno-prfchw -m3dnow -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=3DNOWNOPRFCHW %s +// 3DNOWNOPRFCHW: #define __3dNOW__ 1 // 3DNOWNOPRFCHW-NOT: #define __PRFCHW__ 1 // RUN: %clang -target i386-unknown-unknown -march=atom -mprfchw -mno-3dnow -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=NO3DNOWPRFCHW %s @@ -415,9 +423,11 @@ // XSAVES: #define __XSAVES__ 1 // XSAVES: #define __XSAVE__ 1 -// RUN: %clang -target i386-unknown-unknown -march=atom -mxsaveopt -mno-xsave -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=NOXSAVE %s +// RUN: %clang -target i386-unknown-unknown -march=atom -mxsaveopt -mxsavec -mxsaves -mno-xsave -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=NOXSAVE %s +// NOXSAVE-NOT: #define __XSAVEC__ 1 // NOXSAVE-NOT: #define __XSAVEOPT__ 1 +// NOXSAVE-NOT: #define __XSAVES__ 1 // NOXSAVE-NOT: #define __XSAVE__ 1 // RUN: %clang -target i386-unknown-unknown -march=atom -mclflushopt -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=CLFLUSHOPT %s diff --git a/clang/test/Sema/aarch64-neon-bf16-ranges.c b/clang/test/Sema/aarch64-neon-bf16-ranges.c new file mode 100644 index 0000000000000..bbed036846e57 --- /dev/null +++ b/clang/test/Sema/aarch64-neon-bf16-ranges.c @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -fsyntax-only -verify \ +// RUN: -triple aarch64-arm-none-eabi -target-feature +neon \ +// RUN: -target-feature +bf16 %s + +#include + +int x; + +void test_vcopy_lane_bf16(bfloat16x4_t a, bfloat16x8_t b) { + // 0 <= lane1 <= 3; 0 <= lane2 <= 3 + (void)vcopy_lane_bf16(a, 3, a, 3); + (void)vcopy_lane_bf16(a, 0, a, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + (void)vcopy_lane_bf16(a, 1, a, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} + (void)vcopy_lane_bf16(a, 4, a, 0); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + (void)vcopy_lane_bf16(a, -1, a, 1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} + (void)vcopy_lane_bf16(a, 0, a, x); // expected-error-re {{argument {{.*}} must be a constant integer}} + (void)vcopy_lane_bf16(a, x, a, 0); // expected-error-re {{argument {{.*}} must be a constant integer}} + + // 0 <= lane1 <= 7; 0 <= lane2 <= 3 + (void)vcopyq_lane_bf16(b, 7, a, 3); + (void)vcopyq_lane_bf16(b, 0, a, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + (void)vcopyq_lane_bf16(b, 1, a, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} + (void)vcopyq_lane_bf16(b, 8, a, 0); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + (void)vcopyq_lane_bf16(b, -1, a, 1); // expected-error {{argument value -1 is outside the valid range [0, 7]}} + (void)vcopyq_lane_bf16(b, 0, a, x); // expected-error-re {{argument {{.*}} must be a constant integer}} + (void)vcopyq_lane_bf16(b, x, a, 0); // expected-error-re {{argument {{.*}} must be a constant integer}} + + // 0 <= lane1 <= 3; 0 <= lane2 <= 7 + (void)vcopy_laneq_bf16(a, 3, b, 7); + (void)vcopy_laneq_bf16(a, 0, b, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + (void)vcopy_laneq_bf16(a, 1, b, -1); // expected-error {{argument value -1 is outside the valid range [0, 7]}} + (void)vcopy_laneq_bf16(a, 4, b, 0); // expected-error {{argument value 4 is outside the valid range [0, 3]}} + (void)vcopy_laneq_bf16(a, -1, b, 1); // expected-error {{argument value -1 is outside the valid range [0, 3]}} + (void)vcopy_laneq_bf16(a, 0, b, x); // expected-error-re {{argument {{.*}} must be a constant integer}} + (void)vcopy_laneq_bf16(a, x, b, 0); // expected-error-re {{argument {{.*}} must be a constant integer}} + + + // 0 <= lane1 <= 7; 0 <= lane2 <= 7 + (void)vcopyq_laneq_bf16(b, 7, b, 7); + (void)vcopyq_laneq_bf16(b, 0, b, 8); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + (void)vcopyq_laneq_bf16(b, 1, b, -1); // expected-error {{argument value -1 is outside the valid range [0, 7]}} + (void)vcopyq_laneq_bf16(b, 8, b, 0); // expected-error {{argument value 8 is outside the valid range [0, 7]}} + (void)vcopyq_laneq_bf16(b, -1, b, 1); // expected-error {{argument value -1 is outside the valid range [0, 7]}} + (void)vcopyq_laneq_bf16(b, 0, b, x); // expected-error-re {{argument {{.*}} must be a constant integer}} + (void)vcopyq_laneq_bf16(b, x, b, 0); // expected-error-re {{argument {{.*}} must be a constant integer}} +} + diff --git a/clang/test/Sema/aarch64-sve-types.c b/clang/test/Sema/aarch64-sve-types.c index 989bc71d33c12..54233005f9344 100644 --- a/clang/test/Sema/aarch64-sve-types.c +++ b/clang/test/Sema/aarch64-sve-types.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple aarch64-none-linux-gnu -target-feature +sve -fsyntax-only -verify +// RUN: %clang_cc1 %s -triple aarch64-none-linux-gnu -target-feature +sve,+bf16 -fsyntax-only -verify void f() { int size_s8[sizeof(__SVInt8_t) == 0 ? 1 : -1]; // expected-error {{invalid application of 'sizeof' to sizeless type '__SVInt8_t'}} @@ -34,6 +34,9 @@ void f() { int size_f64[sizeof(__SVFloat64_t) == 0 ? 1 : -1]; // expected-error {{invalid application of 'sizeof' to sizeless type '__SVFloat64_t'}} int align_f64[__alignof__(__SVFloat64_t) == 16 ? 1 : -1]; // expected-error {{invalid application of '__alignof' to sizeless type '__SVFloat64_t'}} + int size_bf16[sizeof(__SVBFloat16_t) == 0 ? 1 : -1]; // expected-error {{invalid application of 'sizeof' to sizeless type '__SVBFloat16_t'}} + int align_bf16[__alignof__(__SVBFloat16_t) == 16 ? 1 : -1]; // expected-error {{invalid application of '__alignof' to sizeless type '__SVBFloat16_t'}} + int size_b8[sizeof(__SVBool_t) == 0 ? 1 : -1]; // expected-error {{invalid application of 'sizeof' to sizeless type '__SVBool_t'}} int align_b8[__alignof__(__SVBool_t) == 2 ? 1 : -1]; // expected-error {{invalid application of '__alignof' to sizeless type '__SVBool_t'}} } diff --git a/clang/test/Sema/attr-handles.cpp b/clang/test/Sema/attr-handles.cpp index 5abb1e8d00bc6..135467b6c0a8c 100644 --- a/clang/test/Sema/attr-handles.cpp +++ b/clang/test/Sema/attr-handles.cpp @@ -17,6 +17,7 @@ int (* __attribute__((acquire_handle("Fuchsia"))) fpt)(char *); // expected-warn auto lambdat = [](int handle __attribute__((use_handle("Fuchsia")))) __attribute__((acquire_handle("Fuchsia"))) -> int { return 0; }; int __attribute((acquire_handle("Fuchsia"))) ta; // expected-warning {{'acquire_handle' attribute only applies to functions, typedefs, and parameters}} +int open(const char *path, int flags, ...) [[clang::acquire_handle]]; // expected-error {{'acquire_handle' attribute takes one argument}} // Typedefs. typedef int callback(char *) __attribute__((acquire_handle("Fuchsia"))); diff --git a/clang/test/Sema/builtin-amdgcn-atomic-inc-dec-failure.cpp b/clang/test/Sema/builtin-amdgcn-atomic-inc-dec-failure.cpp index c08b00bac0cf2..9351b4ecb032d 100644 --- a/clang/test/Sema/builtin-amdgcn-atomic-inc-dec-failure.cpp +++ b/clang/test/Sema/builtin-amdgcn-atomic-inc-dec-failure.cpp @@ -2,17 +2,18 @@ // RUN: not %clang_cc1 %s -x hip -fcuda-is-device -o - -emit-llvm -triple=amdgcn-amd-amdhsa 2>&1 | FileCheck %s void test_host() { - int val; + __UINT32_TYPE__ val32; + __UINT64_TYPE__ val64; // CHECK: error: reference to __device__ function '__builtin_amdgcn_atomic_inc32' in __host__ function - val = __builtin_amdgcn_atomic_inc32(&val, val, __ATOMIC_SEQ_CST, ""); + val32 = __builtin_amdgcn_atomic_inc32(&val32, val32, __ATOMIC_SEQ_CST, ""); // CHECK: error: reference to __device__ function '__builtin_amdgcn_atomic_inc64' in __host__ function - val = __builtin_amdgcn_atomic_inc64(&val, val, __ATOMIC_SEQ_CST, ""); + val64 = __builtin_amdgcn_atomic_inc64(&val64, val64, __ATOMIC_SEQ_CST, ""); // CHECK: error: reference to __device__ function '__builtin_amdgcn_atomic_dec32' in __host__ function - val = __builtin_amdgcn_atomic_dec32(&val, val, __ATOMIC_SEQ_CST, ""); + val32 = __builtin_amdgcn_atomic_dec32(&val32, val32, __ATOMIC_SEQ_CST, ""); // CHECK: error: reference to __device__ function '__builtin_amdgcn_atomic_dec64' in __host__ function - val = __builtin_amdgcn_atomic_dec64(&val, val, __ATOMIC_SEQ_CST, ""); + val64 = __builtin_amdgcn_atomic_dec64(&val64, val64, __ATOMIC_SEQ_CST, ""); } diff --git a/clang/test/Sema/builtin-expect-with-probability-avr.cpp b/clang/test/Sema/builtin-expect-with-probability-avr.cpp new file mode 100644 index 0000000000000..1dbb1d52396ad --- /dev/null +++ b/clang/test/Sema/builtin-expect-with-probability-avr.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -triple avr -fsyntax-only -verify %s + +void test(int x, double p) { // expected-note {{declared here}} + bool dummy = false; + dummy = __builtin_expect_with_probability(x > 0, 1, 0.9); + dummy = __builtin_expect_with_probability(x > 0, 1, 1.1); // expected-error {{probability argument to __builtin_expect_with_probability is outside the range [0.0, 1.0]}} + dummy = __builtin_expect_with_probability(x > 0, 1, -1); // expected-error {{probability argument to __builtin_expect_with_probability is outside the range [0.0, 1.0]}} + dummy = __builtin_expect_with_probability(x > 0, 1, p); // expected-error {{probability argument to __builtin_expect_with_probability must be constant floating-point expression}} expected-note {{read of non-constexpr variable 'p' is not allowed in a constant expression}} + dummy = __builtin_expect_with_probability(x > 0, 1, "aa"); // expected-error {{cannot initialize a parameter of type 'double' with an lvalue of type 'const char [3]'}} + dummy = __builtin_expect_with_probability(x > 0, 1, __builtin_nan("")); // expected-error {{probability argument to __builtin_expect_with_probability is outside the range [0.0, 1.0]}} + dummy = __builtin_expect_with_probability(x > 0, 1, __builtin_inf()); // expected-error {{probability argument to __builtin_expect_with_probability is outside the range [0.0, 1.0]}} + dummy = __builtin_expect_with_probability(x > 0, 1, -0.0); + dummy = __builtin_expect_with_probability(x > 0, 1, 1.0 + __DBL_EPSILON__); // expected-error {{probability argument to __builtin_expect_with_probability is outside the range [0.0, 1.0]}} + dummy = __builtin_expect_with_probability(x > 0, 1, -__DBL_DENORM_MIN__); // expected-error {{probability argument to __builtin_expect_with_probability is outside the range [0.0, 1.0]}} +} diff --git a/clang/test/Sema/builtin-expect-with-probability.cpp b/clang/test/Sema/builtin-expect-with-probability.cpp new file mode 100644 index 0000000000000..3aa20cb0e6dd7 --- /dev/null +++ b/clang/test/Sema/builtin-expect-with-probability.cpp @@ -0,0 +1,58 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +__attribute__((noreturn)) extern void bar(); + +int test_no_warn(int x) { + if (x) { + if (__builtin_expect_with_probability(1, 1, 1)) + bar(); + } else { + return 0; + } +} // should not emit warn "control may reach end of non-void function" here since expr is constantly true, so the "if(__bui..)" should be constantly true condition and be ignored + +template void tempf() { + static_assert(b == 1, "should be evaluated as 1"); // should not have error here +} + +constexpr int constf() { + return __builtin_expect_with_probability(1, 1, 1); +} + +void foo() { + tempf<__builtin_expect_with_probability(1, 1, 1)>(); + constexpr int f = constf(); + static_assert(f == 1, "should be evaluated as 1"); // should not have error here +} + +extern int global; + +struct S { + static constexpr float prob = 0.7; +}; + +template +void expect_taken(int x) { + if (__builtin_expect_with_probability(x > 0, 1, T::prob)) { + global++; + } +} + +void test(int x, double p) { // expected-note {{declared here}} + bool dummy; + dummy = __builtin_expect_with_probability(x > 0, 1, 0.9); + dummy = __builtin_expect_with_probability(x > 0, 1, 1.1); // expected-error {{probability argument to __builtin_expect_with_probability is outside the range [0.0, 1.0]}} + dummy = __builtin_expect_with_probability(x > 0, 1, -1); // expected-error {{probability argument to __builtin_expect_with_probability is outside the range [0.0, 1.0]}} + dummy = __builtin_expect_with_probability(x > 0, 1, p); // expected-error {{probability argument to __builtin_expect_with_probability must be constant floating-point expression}} expected-note {{read of non-constexpr variable 'p' is not allowed in a constant expression}} + dummy = __builtin_expect_with_probability(x > 0, 1, "aa"); // expected-error {{cannot initialize a parameter of type 'double' with an lvalue of type 'const char [3]'}} + dummy = __builtin_expect_with_probability(x > 0, 1, __builtin_nan("")); // expected-error {{probability argument to __builtin_expect_with_probability is outside the range [0.0, 1.0]}} + dummy = __builtin_expect_with_probability(x > 0, 1, __builtin_inf()); // expected-error {{probability argument to __builtin_expect_with_probability is outside the range [0.0, 1.0]}} + dummy = __builtin_expect_with_probability(x > 0, 1, -0.0); + dummy = __builtin_expect_with_probability(x > 0, 1, 1.0 + __DBL_EPSILON__); // expected-error {{probability argument to __builtin_expect_with_probability is outside the range [0.0, 1.0]}} + dummy = __builtin_expect_with_probability(x > 0, 1, -__DBL_DENORM_MIN__); // expected-error {{probability argument to __builtin_expect_with_probability is outside the range [0.0, 1.0]}} + constexpr double pd = 0.7; + dummy = __builtin_expect_with_probability(x > 0, 1, pd); + constexpr int pi = 1; + dummy = __builtin_expect_with_probability(x > 0, 1, pi); + expect_taken(x); +} diff --git a/clang/test/Sema/format-strings.c b/clang/test/Sema/format-strings.c index 11acfcd1b9a62..e8cd478d25126 100644 --- a/clang/test/Sema/format-strings.c +++ b/clang/test/Sema/format-strings.c @@ -290,8 +290,11 @@ void test11(void *p, char *s) { printf("%0p", p); // expected-warning{{flag '0' results in undefined behavior with 'p' conversion specifier}} printf("%s", s); // no-warning printf("%+s", p); // expected-warning{{flag '+' results in undefined behavior with 's' conversion specifier}} + // expected-warning@-1 {{format specifies type 'char *' but the argument has type 'void *'}} printf("% s", p); // expected-warning{{flag ' ' results in undefined behavior with 's' conversion specifier}} + // expected-warning@-1 {{format specifies type 'char *' but the argument has type 'void *'}} printf("%0s", p); // expected-warning{{flag '0' results in undefined behavior with 's' conversion specifier}} + // expected-warning@-1 {{format specifies type 'char *' but the argument has type 'void *'}} } void test12(char *b) { @@ -707,3 +710,7 @@ void PR30481() { // This caused crashes due to invalid casts. printf(1 > 0); // expected-warning{{format string is not a string literal}} expected-warning{{incompatible integer to pointer conversion}} expected-note@format-strings.c:*{{passing argument to parameter here}} expected-note{{to avoid this}} } + +void test_printf_opaque_ptr(void *op) { + printf("%s", op); // expected-warning{{format specifies type 'char *' but the argument has type 'void *'}} +} diff --git a/clang/test/Sema/init-ref-c.c b/clang/test/Sema/init-ref-c.c new file mode 100644 index 0000000000000..38d8c44e2fdf5 --- /dev/null +++ b/clang/test/Sema/init-ref-c.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -triple arm-unknown-gnu -fsyntax-only -verify %s + +void f() { + struct EmptyStruct {}; + struct EmptyStruct S; + __builtin_va_end(S); // no-crash, expected-error {{non-const lvalue reference to type '__builtin_va_list' cannot bind to a value of unrelated type 'struct EmptyStruct'}} +} \ No newline at end of file diff --git a/clang/test/Sema/inline-asm-validate-amdgpu.cl b/clang/test/Sema/inline-asm-validate-amdgpu.cl index 3d6488227ef29..418952c0e7272 100644 --- a/clang/test/Sema/inline-asm-validate-amdgpu.cl +++ b/clang/test/Sema/inline-asm-validate-amdgpu.cl @@ -18,9 +18,35 @@ kernel void test () { // vgpr constraints __asm__ ("v_mov_b32 %0, %1" : "=v" (vgpr) : "v" (imm) : ); - // 'A' constraint + // 'I' constraint (an immediate integer in the range -16 to 64) + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "I" (imm) : ); + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "I" (-16) : ); + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "I" (64) : ); + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "I" (-17) : ); // expected-error {{value '-17' out of range for constraint 'I'}} + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "I" (65) : ); // expected-error {{value '65' out of range for constraint 'I'}} + + // 'J' constraint (an immediate 16-bit signed integer) + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "J" (imm) : ); + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "J" (-32768) : ); + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "J" (32767) : ); + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "J" (-32769) : ); // expected-error {{value '-32769' out of range for constraint 'J'}} + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "J" (32768) : ); // expected-error {{value '32768' out of range for constraint 'J'}} + + // 'A' constraint (an immediate constant that can be inlined) __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "A" (imm) : ); + // 'B' constraint (an immediate 32-bit signed integer) + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "B" (imm) : ); + + // 'C' constraint (an immediate 32-bit unsigned integer or 'A' constraint) + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "C" (imm) : ); + + // 'DA' constraint (an immediate 64-bit constant that can be split into two 'A' constants) + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "DA" (imm) : ); + + // 'DB' constraint (an immediate 64-bit constant that can be split into two 'B' constants) + __asm__ ("s_mov_b32 %0, %1" : "=s" (sgpr) : "DB" (imm) : ); + } __kernel void diff --git a/clang/test/Sema/invalid-bitwidth-expr.mm b/clang/test/Sema/invalid-bitwidth-expr.mm index 63aced1a3bf4d..41ca9496de4f9 100644 --- a/clang/test/Sema/invalid-bitwidth-expr.mm +++ b/clang/test/Sema/invalid-bitwidth-expr.mm @@ -18,3 +18,22 @@ auto func() { int X : func(); }; constexpr int sss = sizeof(Y); + +bool Foo(int *); // expected-note {{candidate function not viable}} +template +struct Base {}; +template +auto func() { + // error-bit should be propagated from TemplateArgument to NestNameSpecifier. + class Base::type C; // expected-error {{no matching function for call to 'Foo'}} + return C; +} +struct Z { + int X : func(); // expected-note {{in instantiation of function template}} +}; +constexpr int ssss = sizeof(Z); + +struct Z2 { + int X : sizeof(_ExtInt(invalid())); // expected-error {{use of undeclared identifier}} +}; +constexpr int sssss = sizeof(Z2); diff --git a/clang/test/Sema/matrix-type-builtins.c b/clang/test/Sema/matrix-type-builtins.c index d8da11aa05aa6..2f7e4549e4950 100644 --- a/clang/test/Sema/matrix-type-builtins.c +++ b/clang/test/Sema/matrix-type-builtins.c @@ -11,11 +11,11 @@ void transpose(sx5x10_t a, ix3x2_t b, dx3x3 c, int *d, int e) { b = __builtin_matrix_transpose(b); // expected-error@-1 {{assigning to 'ix3x2_t' (aka 'int __attribute__((matrix_type(3, 2)))') from incompatible type 'int __attribute__((matrix_type(2, 3)))'}} __builtin_matrix_transpose(d); - // expected-error@-1 {{first argument must be a matrix}} + // expected-error@-1 {{1st argument must be a matrix}} __builtin_matrix_transpose(e); - // expected-error@-1 {{first argument must be a matrix}} + // expected-error@-1 {{1st argument must be a matrix}} __builtin_matrix_transpose("test"); - // expected-error@-1 {{first argument must be a matrix}} + // expected-error@-1 {{1st argument must be a matrix}} ix3x3 m = __builtin_matrix_transpose(c); // expected-error@-1 {{initializing 'ix3x3' (aka 'unsigned int __attribute__((matrix_type(3, 3)))') with an expression of incompatible type 'double __attribute__((matrix_type(3, 3)))'}} @@ -43,10 +43,10 @@ void column_major_load(float *p1, int *p2, _Bool *p3, struct Foo *p4) { // expected-error@-1 {{stride must be greater or equal to the number of rows}} sx5x10_t a8 = __builtin_matrix_column_major_load(p3, 5, 10, 6); - // expected-error@-1 {{first argument must be a pointer to a valid matrix element type}} + // expected-error@-1 {{1st argument must be a pointer to a valid matrix element type}} sx5x10_t a9 = __builtin_matrix_column_major_load(p4, 5, 10, 6); - // expected-error@-1 {{first argument must be a pointer to a valid matrix element type}} + // expected-error@-1 {{1st argument must be a pointer to a valid matrix element type}} sx5x10_t a10 = __builtin_matrix_column_major_load(p1, 1ull << 21, 10, 6); // expected-error@-1 {{row dimension is outside the allowed range [1, 1048575}} @@ -54,13 +54,13 @@ void column_major_load(float *p1, int *p2, _Bool *p3, struct Foo *p4) { // expected-error@-1 {{column dimension is outside the allowed range [1, 1048575}} sx5x10_t a12 = __builtin_matrix_column_major_load( - 10, // expected-error {{first argument must be a pointer to a valid matrix element type}} + 10, // expected-error {{1st argument must be a pointer to a valid matrix element type}} 1ull << 21, // expected-error {{row dimension is outside the allowed range [1, 1048575]}} 1ull << 21, // expected-error {{column dimension is outside the allowed range [1, 1048575]}} ""); // expected-warning {{incompatible pointer to integer conversion casting 'char [1]' to type 'unsigned long'}} sx5x10_t a13 = __builtin_matrix_column_major_load( - 10, // expected-error {{first argument must be a pointer to a valid matrix element type}} + 10, // expected-error {{1st argument must be a pointer to a valid matrix element type}} *p4, // expected-error {{casting 'struct Foo' to incompatible type 'unsigned long'}} "", // expected-error {{column argument must be a constant unsigned integer expression}} // expected-warning@-1 {{incompatible pointer to integer conversion casting 'char [1]' to type 'unsigned long'}} @@ -73,18 +73,18 @@ void column_major_store(sx5x10_t *m1, ix3x2_t *m2, float *p1, int *p2, struct Fo __builtin_matrix_column_major_store(*m1, p1, 0); // expected-error@-1 {{stride must be greater or equal to the number of rows}} __builtin_matrix_column_major_store(*m1, p2, 10); - // expected-error@-1 {{the pointee of the second argument must match the element type of the first argument ('int' != 'float')}} + // expected-error@-1 {{the pointee of the 2nd argument must match the element type of the 1st argument ('int' != 'float')}} __builtin_matrix_column_major_store(p1, p2, 10); - // expected-error@-1 {{first argument must be a matrix}} + // expected-error@-1 {{1st argument must be a matrix}} __builtin_matrix_column_major_store( - "", // expected-error {{first argument must be a matrix}} - 10, // expected-error {{second argument must be a pointer to a valid matrix element type}} + "", // expected-error {{1st argument must be a matrix}} + 10, // expected-error {{2nd argument must be a pointer to a valid matrix element type}} *p3); // expected-error {{casting 'struct Foo' to incompatible type 'unsigned long'}} __builtin_matrix_column_major_store( *m1, - 10, // expected-error {{second argument must be a pointer to a valid matrix element type}} + 10, // expected-error {{2nd argument must be a pointer to a valid matrix element type}} 10); *m1 = __builtin_matrix_column_major_store(*m1, p1, 10); diff --git a/clang/test/Sema/static-array.c b/clang/test/Sema/static-array.c index cc1043fe9c471..ef070718dc63f 100644 --- a/clang/test/Sema/static-array.c +++ b/clang/test/Sema/static-array.c @@ -1,6 +1,7 @@ -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -fsyntax-only -fblocks -verify %s +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -fsyntax-only -fblocks -pedantic -verify %s -void cat0(int a[static 0]) {} // expected-warning {{'static' has no effect on zero-length arrays}} +void cat0(int a[static 0]) {} // expected-warning {{zero size arrays are an extension}} \ + // expected-note {{callee declares array parameter as static here}} void cat(int a[static 3]) {} // expected-note 4 {{callee declares array parameter as static here}} expected-note 2 {{passing argument to parameter 'a' here}} @@ -9,7 +10,7 @@ void vat(int i, int a[static i]) {} // expected-note {{callee declares array par void f(int *p) { int a[2], b[3], c[4]; - cat0(0); + cat0(0); // expected-warning {{null passed to a callee that requires a non-null argument}} cat(0); // expected-warning {{null passed to a callee that requires a non-null argument}} cat(a); // expected-warning {{array argument is too small; contains 2 elements, callee requires at least 3}} diff --git a/clang/test/SemaCUDA/Inputs/cuda.h b/clang/test/SemaCUDA/Inputs/cuda.h index 2600bfa9c470b..901f8e0c17cff 100644 --- a/clang/test/SemaCUDA/Inputs/cuda.h +++ b/clang/test/SemaCUDA/Inputs/cuda.h @@ -17,6 +17,19 @@ struct dim3 { __host__ __device__ dim3(unsigned x, unsigned y = 1, unsigned z = 1) : x(x), y(y), z(z) {} }; +#ifdef __HIP__ +typedef struct hipStream *hipStream_t; +typedef enum hipError {} hipError_t; +int hipConfigureCall(dim3 gridSize, dim3 blockSize, size_t sharedSize = 0, + hipStream_t stream = 0); +extern "C" hipError_t __hipPushCallConfiguration(dim3 gridSize, dim3 blockSize, + size_t sharedSize = 0, + hipStream_t stream = 0); +extern "C" hipError_t hipLaunchKernel(const void *func, dim3 gridDim, + dim3 blockDim, void **args, + size_t sharedMem, + hipStream_t stream); +#else typedef struct cudaStream *cudaStream_t; typedef enum cudaError {} cudaError_t; @@ -29,6 +42,7 @@ extern "C" int __cudaPushCallConfiguration(dim3 gridSize, dim3 blockSize, extern "C" cudaError_t cudaLaunchKernel(const void *func, dim3 gridDim, dim3 blockDim, void **args, size_t sharedMem, cudaStream_t stream); +#endif // Host- and device-side placement new overloads. void *operator new(__SIZE_TYPE__, void *p) { return p; } diff --git a/clang/test/SemaCUDA/lambda.cu b/clang/test/SemaCUDA/lambda.cu new file mode 100644 index 0000000000000..6f305a683c009 --- /dev/null +++ b/clang/test/SemaCUDA/lambda.cu @@ -0,0 +1,73 @@ +// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify=com %s +// RUN: %clang_cc1 -std=c++17 -fsyntax-only -fcuda-is-device -verify=com,dev %s + +#include "Inputs/cuda.h" + +auto global_lambda = [] () { return 123; }; + +template +__global__ void kernel(F f) { f(); } +// dev-note@-1 7{{called by 'kernel<(lambda}} + +__host__ __device__ void hd(int x); + +class A { + int b; +public: + void test() { + [=](){ hd(b); }(); + + [&](){ hd(b); }(); + + kernel<<<1,1>>>([](){ hd(0); }); + + kernel<<<1,1>>>([=](){ hd(b); }); + // dev-error@-1 {{capture host side class data member by this pointer in device or host device lambda function}} + + kernel<<<1,1>>>([&](){ hd(b); }); + // dev-error@-1 {{capture host side class data member by this pointer in device or host device lambda function}} + + kernel<<<1,1>>>([&] __device__ (){ hd(b); }); + // dev-error@-1 {{capture host side class data member by this pointer in device or host device lambda function}} + + kernel<<<1,1>>>([&](){ + auto f = [&]{ hd(b); }; + // dev-error@-1 {{capture host side class data member by this pointer in device or host device lambda function}} + f(); + }); + } +}; + +int main(void) { + auto lambda_kernel = [&]__global__(){}; + // com-error@-1 {{kernel function 'operator()' must be a free function or static member function}} + + int b; + [&](){ hd(b); }(); + + [=, &b](){ hd(b); }(); + + kernel<<<1,1>>>(global_lambda); + + kernel<<<1,1>>>([](){ hd(0); }); + + kernel<<<1,1>>>([=](){ hd(b); }); + + kernel<<<1,1>>>([b](){ hd(b); }); + + kernel<<<1,1>>>([&](){ hd(b); }); + // dev-error@-1 {{capture host variable 'b' by reference in device or host device lambda function}} + + kernel<<<1,1>>>([=, &b](){ hd(b); }); + // dev-error@-1 {{capture host variable 'b' by reference in device or host device lambda function}} + + kernel<<<1,1>>>([&, b](){ hd(b); }); + + kernel<<<1,1>>>([&](){ + auto f = [&]{ hd(b); }; + // dev-error@-1 {{capture host variable 'b' by reference in device or host device lambda function}} + f(); + }); + + return 0; +} diff --git a/clang/test/SemaCXX/Inputs/std-coroutine.h b/clang/test/SemaCXX/Inputs/std-coroutine.h index 7a424f1e99cf0..e9af21aa51945 100644 --- a/clang/test/SemaCXX/Inputs/std-coroutine.h +++ b/clang/test/SemaCXX/Inputs/std-coroutine.h @@ -10,25 +10,25 @@ struct coroutine_traits { using promise_type = typename Ret::promise_type; }; template struct coroutine_handle { - static coroutine_handle from_address(void *); + static coroutine_handle from_address(void *) noexcept; }; template <> struct coroutine_handle { template - coroutine_handle(coroutine_handle); + coroutine_handle(coroutine_handle) noexcept; static coroutine_handle from_address(void *); }; struct suspend_always { - bool await_ready() { return false; } - void await_suspend(coroutine_handle<>) {} - void await_resume() {} + bool await_ready() noexcept { return false; } + void await_suspend(coroutine_handle<>) noexcept {} + void await_resume() noexcept {} }; struct suspend_never { - bool await_ready() { return true; } - void await_suspend(coroutine_handle<>) {} - void await_resume() {} + bool await_ready() noexcept { return true; } + void await_suspend(coroutine_handle<>) noexcept {} + void await_resume() noexcept {} }; } // namespace experimental diff --git a/clang/test/SemaCXX/attr-trivial-abi.cpp b/clang/test/SemaCXX/attr-trivial-abi.cpp new file mode 100644 index 0000000000000..334b471d2ab87 --- /dev/null +++ b/clang/test/SemaCXX/attr-trivial-abi.cpp @@ -0,0 +1,112 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 + +void __attribute__((trivial_abi)) foo(); // expected-warning {{'trivial_abi' attribute only applies to classes}} + +// Should not crash. +template +class __attribute__((trivial_abi)) a { a(a &&); }; + +struct [[clang::trivial_abi]] S0 { + int a; +}; + +struct __attribute__((trivial_abi)) S1 { + int a; +}; + +struct __attribute__((trivial_abi)) S3 { // expected-warning {{'trivial_abi' cannot be applied to 'S3'}} expected-note {{is polymorphic}} + virtual void m(); +}; + +struct S3_2 { + virtual void m(); +} __attribute__((trivial_abi)); // expected-warning {{'trivial_abi' cannot be applied to 'S3_2'}} expected-note {{is polymorphic}} + +struct __attribute__((trivial_abi)) S3_3 { // expected-warning {{'trivial_abi' cannot be applied to 'S3_3'}} expected-note {{has a field of a non-trivial class type}} + S3_3(S3_3 &&); + S3_2 s32; +}; + +// Diagnose invalid trivial_abi even when the type is templated because it has a non-trivial field. +template +struct __attribute__((trivial_abi)) S3_4 { // expected-warning {{'trivial_abi' cannot be applied to 'S3_4'}} expected-note {{has a field of a non-trivial class type}} + S3_4(S3_4 &&); + S3_2 s32; +}; + +struct S4 { + int a; +}; + +struct __attribute__((trivial_abi)) S5 : public virtual S4 { // expected-warning {{'trivial_abi' cannot be applied to 'S5'}} expected-note {{has a virtual base}} +}; + +struct __attribute__((trivial_abi)) S9 : public S4 { +}; + +struct __attribute__((trivial_abi(1))) S8 { // expected-error {{'trivial_abi' attribute takes no arguments}} + int a; +}; + +// Do not warn about deleted ctors when 'trivial_abi' is used to annotate a template class. +template +struct __attribute__((trivial_abi)) S10 { + T p; +}; + +S10 p1; + +template +struct S14 { + T a; +}; + +template +struct __attribute__((trivial_abi)) S15 : S14 { +}; + +S15 s15; + +template +struct __attribute__((trivial_abi)) S16 { + S14 a; +}; + +S16 s16; + +template +struct __attribute__((trivial_abi)) S17 { +}; + +S17 s17; + +namespace deletedCopyMoveConstructor { +struct __attribute__((trivial_abi)) CopyMoveDeleted { // expected-warning {{'trivial_abi' cannot be applied to 'CopyMoveDeleted'}} expected-note {{copy constructors and move constructors are all deleted}} + CopyMoveDeleted(const CopyMoveDeleted &) = delete; + CopyMoveDeleted(CopyMoveDeleted &&) = delete; +}; + +struct __attribute__((trivial_abi)) S18 { // expected-warning {{'trivial_abi' cannot be applied to 'S18'}} expected-note {{copy constructors and move constructors are all deleted}} + CopyMoveDeleted a; +}; + +struct __attribute__((trivial_abi)) CopyDeleted { + CopyDeleted(const CopyDeleted &) = delete; + CopyDeleted(CopyDeleted &&) = default; +}; + +struct __attribute__((trivial_abi)) MoveDeleted { + MoveDeleted(const MoveDeleted &) = default; + MoveDeleted(MoveDeleted &&) = delete; +}; + +struct __attribute__((trivial_abi)) S19 { // expected-warning {{'trivial_abi' cannot be applied to 'S19'}} expected-note {{copy constructors and move constructors are all deleted}} + CopyDeleted a; + MoveDeleted b; +}; + +// This is fine since the move constructor isn't deleted. +struct __attribute__((trivial_abi)) S20 { + int &&a; // a member of rvalue reference type deletes the copy constructor. +}; +} // namespace deletedCopyMoveConstructor diff --git a/clang/test/SemaCXX/builtin-align-cxx.cpp b/clang/test/SemaCXX/builtin-align-cxx.cpp index 190f352c26d4a..848ed86525bbe 100644 --- a/clang/test/SemaCXX/builtin-align-cxx.cpp +++ b/clang/test/SemaCXX/builtin-align-cxx.cpp @@ -37,7 +37,7 @@ void test() { // expected-note@-1{{in instantiation of function template specialization 'test_templated_arguments'}} } -template +template void test_incorrect_alignment_without_instatiation(T value) { int array[32]; static_assert(__is_same(decltype(__builtin_align_up(array, 31)), int *), // expected-error{{requested alignment is not a power of 2}} @@ -52,6 +52,10 @@ void test_incorrect_alignment_without_instatiation(T value) { __builtin_align_up(array, 31); // expected-error{{requested alignment is not a power of 2}} __builtin_align_up(value, 31); // This shouldn't want since the type is dependent __builtin_align_up(value); // Same here + + __builtin_align_up(array, sizeof(sizeof(value)) - 1); // expected-error{{requested alignment is not a power of 2}} + __builtin_align_up(array, value); // no diagnostic as the alignment is value dependent. + (void)__builtin_align_up(array, ArraySize); // The same above here } // The original fix for the issue above broke some legitimate code. diff --git a/clang/test/SemaCXX/co_await-range-for.cpp b/clang/test/SemaCXX/co_await-range-for.cpp index 4d999ea7db5e5..b6c6e6c40f977 100644 --- a/clang/test/SemaCXX/co_await-range-for.cpp +++ b/clang/test/SemaCXX/co_await-range-for.cpp @@ -44,7 +44,7 @@ struct MyForLoopArrayAwaiter { void return_void(); void unhandled_exception(); suspend_never initial_suspend(); - suspend_never final_suspend(); + suspend_never final_suspend() noexcept; template Awaiter await_transform(T *) = delete; // expected-note {{explicitly deleted}} }; @@ -62,7 +62,7 @@ struct ForLoopAwaiterBadBeginTransform { void return_void(); void unhandled_exception(); suspend_never initial_suspend(); - suspend_never final_suspend(); + suspend_never final_suspend() noexcept; template Awaiter await_transform(BeginTag) = delete; // expected-note 1+ {{explicitly deleted}} @@ -96,7 +96,7 @@ struct ForLoopAwaiterBadIncTransform { void return_void(); void unhandled_exception(); suspend_never initial_suspend(); - suspend_never final_suspend(); + suspend_never final_suspend() noexcept; template Awaiter await_transform(BeginTag e); @@ -137,7 +137,7 @@ struct ForLoopAwaiterCoawaitLookup { void return_void(); void unhandled_exception(); suspend_never initial_suspend(); - suspend_never final_suspend(); + suspend_never final_suspend() noexcept; template CoawaitTag await_transform(BeginTag e); template diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp index dd6d7ccba19f8..78e9fef96c8da 100644 --- a/clang/test/SemaCXX/constant-expression-cxx11.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp @@ -682,12 +682,12 @@ template struct S : T { } }; -extern const int n; +extern const int n; // expected-note {{declared here}} template void f() { // This is ill-formed, because a hypothetical instantiation at the point of // template definition would be ill-formed due to a construct that does not // depend on a template parameter. - constexpr int k = n; // expected-error {{must be initialized by a constant expression}} + constexpr int k = n; // expected-error {{must be initialized by a constant expression}} expected-note {{initializer of 'n' is unknown}} } // It doesn't matter that the instantiation could later become valid: constexpr int n = 4; @@ -1258,7 +1258,7 @@ constexpr int m1b = const_cast(n1); // expected-error {{constant exp constexpr int m2b = const_cast(n2); // expected-error {{constant expression}} expected-note {{read of volatile object 'n2'}} struct T { int n; }; -const T t = { 42 }; +const T t = { 42 }; // expected-note {{declared here}} constexpr int f(volatile int &&r) { return r; // expected-note {{read of volatile-qualified type 'volatile int'}} @@ -1372,7 +1372,7 @@ namespace InstantiateCaseStmt { namespace ConvertedConstantExpr { extern int &m; - extern int &n; + extern int &n; // expected-note 2{{declared here}} constexpr int k = 4; int &m = const_cast(k); @@ -1381,9 +1381,9 @@ namespace ConvertedConstantExpr { // useless note and instead just point to the non-constant subexpression. enum class E { em = m, - en = n, // expected-error {{not a constant expression}} - eo = (m + - n // expected-error {{not a constant expression}} + en = n, // expected-error {{not a constant expression}} expected-note {{initializer of 'n' is unknown}} + eo = (m + // expected-error {{not a constant expression}} + n // expected-note {{initializer of 'n' is unknown}} ), eq = reinterpret_cast((int*)0) // expected-error {{not a constant expression}} expected-note {{reinterpret_cast}} }; @@ -2302,3 +2302,23 @@ namespace PR41854 { f &d = reinterpret_cast(a); unsigned b = d.c; } + +namespace array_size { + template struct array { + static constexpr int size() { return N; } + }; + template void f1(T t) { + constexpr int k = t.size(); + } + template void f2(const T &t) { + constexpr int k = t.size(); // expected-error {{constant}} expected-note {{function parameter 't' with unknown value cannot be used in a constant expression}} + } + template void f3(const T &t) { + constexpr int k = T::size(); + } + void g(array<3> a) { + f1(a); + f2(a); // expected-note {{instantiation of}} + f3(a); + } +} diff --git a/clang/test/SemaCXX/constant-expression-cxx1y.cpp b/clang/test/SemaCXX/constant-expression-cxx1y.cpp index 5a414799f7552..8bc4f88a63a96 100644 --- a/clang/test/SemaCXX/constant-expression-cxx1y.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx1y.cpp @@ -1009,7 +1009,7 @@ constexpr int sum(const char (&Arr)[N]) { // As an extension, we support evaluating some things that are `const` as though // they were `constexpr` when folding, but it should not be allowed in normal // constexpr evaluation. -const char Cs[] = {'a', 'b'}; +const char Cs[] = {'a', 'b'}; // expected-note 2{{declared here}} void foo() __attribute__((enable_if(sum(Cs) == 'a' + 'b', ""))); void run() { foo(); } diff --git a/clang/test/SemaCXX/constexpr-default-init-value-crash.cpp b/clang/test/SemaCXX/constexpr-default-init-value-crash.cpp new file mode 100644 index 0000000000000..d20d28d199d41 --- /dev/null +++ b/clang/test/SemaCXX/constexpr-default-init-value-crash.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 %s -std=c++20 -fsyntax-only -verify +// RUN: %clang_cc1 %s -std=c++20 -fsyntax-only -verify -fno-recovery-ast + +namespace NoCrash { +struct ForwardDecl; // expected-note {{forward declaration of}} +struct Foo { // expected-note 2{{candidate constructor}} + ForwardDecl f; // expected-error {{field has incomplete type}} +}; + +constexpr Foo getFoo() { + Foo e = 123; // expected-error {{no viable conversion from 'int' to 'NoCrash::Foo'}} + return e; +} +} diff --git a/clang/test/SemaCXX/constexpr-vectors.cpp b/clang/test/SemaCXX/constexpr-vectors.cpp new file mode 100644 index 0000000000000..1ba0e33253321 --- /dev/null +++ b/clang/test/SemaCXX/constexpr-vectors.cpp @@ -0,0 +1,616 @@ +// RUN: %clang_cc1 -std=c++14 -Wno-unused-value %s -disable-llvm-passes -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s + +// FIXME: Unfortunately there is no good way to validate that our values are +// correct since Vector types don't have operator [] implemented for constexpr. +// Instead, we need to use filecheck to ensure the emitted IR is correct. Once +// someone implements array subscript operator for these types as constexpr, +// this test should modified to jsut use static asserts. + +using FourCharsVecSize __attribute__((vector_size(4))) = char; +using FourIntsVecSize __attribute__((vector_size(16))) = int; +using FourLongLongsVecSize __attribute__((vector_size(32))) = long long; +using FourFloatsVecSize __attribute__((vector_size(16))) = float; +using FourDoublesVecSize __attribute__((vector_size(32))) = double; + +using FourCharsExtVec __attribute__((ext_vector_type(4))) = char; +using FourIntsExtVec __attribute__((ext_vector_type(4))) = int; +using FourLongLongsExtVec __attribute__((ext_vector_type(4))) = long long; +using FourFloatsExtVec __attribute__((ext_vector_type(4))) = float; +using FourDoublesExtVec __attribute__((ext_vector_type(4))) = double; + +// Next a series of tests to make sure these operations are usable in +// constexpr functions. Template instantiations don't emit Winvalid-constexpr, +// so we have to do these as macros. +#define MathShiftOps(Type) \ + constexpr auto MathShiftOps##Type(Type a, Type b) { \ + a = a + b; \ + a = a - b; \ + a = a * b; \ + a = a / b; \ + b = a + 1; \ + b = a - 1; \ + b = a * 1; \ + b = a / 1; \ + a += a; \ + a -= a; \ + a *= a; \ + a /= a; \ + b += a; \ + b -= a; \ + b *= a; \ + b /= a; \ + a < b; \ + a > b; \ + a <= b; \ + a >= b; \ + a == b; \ + a != b; \ + a &&b; \ + a || b; \ + auto c = (a, b); \ + return c; \ + } + +// Ops specific to Integers. +#define MathShiftOpsInts(Type) \ + constexpr auto MathShiftopsInts##Type(Type a, Type b) { \ + a = a << b; \ + a = a >> b; \ + a = a << 3; \ + a = a >> 3; \ + a = 3 << b; \ + a = 3 >> b; \ + a <<= b; \ + a >>= b; \ + a <<= 3; \ + a >>= 3; \ + a = a % b; \ + a &b; \ + a | b; \ + a ^ b; \ + return a; \ + } + +MathShiftOps(FourCharsVecSize); +MathShiftOps(FourIntsVecSize); +MathShiftOps(FourLongLongsVecSize); +MathShiftOps(FourFloatsVecSize); +MathShiftOps(FourDoublesVecSize); +MathShiftOps(FourCharsExtVec); +MathShiftOps(FourIntsExtVec); +MathShiftOps(FourLongLongsExtVec); +MathShiftOps(FourFloatsExtVec); +MathShiftOps(FourDoublesExtVec); + +MathShiftOpsInts(FourCharsVecSize); +MathShiftOpsInts(FourIntsVecSize); +MathShiftOpsInts(FourLongLongsVecSize); +MathShiftOpsInts(FourCharsExtVec); +MathShiftOpsInts(FourIntsExtVec); +MathShiftOpsInts(FourLongLongsExtVec); + +template +constexpr auto CmpMul(T t, U u) { + t *= u; + return t; +} +template +constexpr auto CmpDiv(T t, U u) { + t /= u; + return t; +} +template +constexpr auto CmpRem(T t, U u) { + t %= u; + return t; +} + +template +constexpr auto CmpAdd(T t, U u) { + t += u; + return t; +} + +template +constexpr auto CmpSub(T t, U u) { + t -= u; + return t; +} + +template +constexpr auto CmpLSH(T t, U u) { + t <<= u; + return t; +} + +template +constexpr auto CmpRSH(T t, U u) { + t >>= u; + return t; +} + +template +constexpr auto CmpBinAnd(T t, U u) { + t &= u; + return t; +} + +template +constexpr auto CmpBinXOr(T t, U u) { + t ^= u; + return t; +} + +template +constexpr auto CmpBinOr(T t, U u) { + t |= u; + return t; +} + +// Only int vs float makes a difference here, so we only need to test 1 of each. +// Test Char to make sure the mixed-nature of shifts around char is evident. +void CharUsage() { + constexpr auto a = FourCharsVecSize{6, 3, 2, 1} + + FourCharsVecSize{12, 15, 5, 7}; + // CHECK: store <4 x i8> + constexpr auto b = FourCharsVecSize{19, 15, 13, 12} - + FourCharsVecSize{13, 14, 5, 3}; + // CHECK: store <4 x i8> + constexpr auto c = FourCharsVecSize{8, 4, 2, 1} * + FourCharsVecSize{3, 4, 5, 6}; + // CHECK: store <4 x i8> + constexpr auto d = FourCharsVecSize{12, 12, 10, 10} / + FourCharsVecSize{6, 4, 5, 2}; + // CHECK: store <4 x i8> + constexpr auto e = FourCharsVecSize{12, 12, 10, 10} % + FourCharsVecSize{6, 4, 4, 3}; + // CHECK: store <4 x i8> + + constexpr auto f = FourCharsVecSize{6, 3, 2, 1} + 3; + // CHECK: store <4 x i8> + constexpr auto g = FourCharsVecSize{19, 15, 12, 10} - 3; + // CHECK: store <4 x i8> + constexpr auto h = FourCharsVecSize{8, 4, 2, 1} * 3; + // CHECK: store <4 x i8> + constexpr auto j = FourCharsVecSize{12, 15, 18, 21} / 3; + // CHECK: store <4 x i8> + constexpr auto k = FourCharsVecSize{12, 17, 19, 22} % 3; + // CHECK: store <4 x i8> + + constexpr auto l = 3 + FourCharsVecSize{6, 3, 2, 1}; + // CHECK: store <4 x i8> + constexpr auto m = 20 - FourCharsVecSize{19, 15, 12, 10}; + // CHECK: store <4 x i8> + constexpr auto n = 3 * FourCharsVecSize{8, 4, 2, 1}; + // CHECK: store <4 x i8> + constexpr auto o = 100 / FourCharsVecSize{12, 15, 18, 21}; + // CHECK: store <4 x i8> + constexpr auto p = 100 % FourCharsVecSize{12, 15, 18, 21}; + // CHECK: store <4 x i8> + + constexpr auto q = FourCharsVecSize{6, 3, 2, 1} << FourCharsVecSize{1, 1, 2, 2}; + // CHECK: store <4 x i8> + constexpr auto r = FourCharsVecSize{19, 15, 12, 10} >> + FourCharsVecSize{1, 1, 2, 2}; + // CHECK: store <4 x i8> + constexpr auto s = FourCharsVecSize{6, 3, 5, 10} << 1; + // CHECK: store <4 x i8> + constexpr auto t = FourCharsVecSize{19, 15, 10, 20} >> 1; + // CHECK: store <4 x i8> + constexpr auto u = 12 << FourCharsVecSize{1, 2, 3, 3}; + // CHECK: store <4 x i8> + constexpr auto v = 12 >> FourCharsVecSize{1, 2, 2, 1}; + // CHECK: store <4 x i8> + + constexpr auto w = FourCharsVecSize{1, 2, 3, 4} < + FourCharsVecSize{4, 3, 2, 1}; + // CHECK: store <4 x i8> + constexpr auto x = FourCharsVecSize{1, 2, 3, 4} > + FourCharsVecSize{4, 3, 2, 1}; + // CHECK: store <4 x i8> + constexpr auto y = FourCharsVecSize{1, 2, 3, 4} <= + FourCharsVecSize{4, 3, 3, 1}; + // CHECK: store <4 x i8> + constexpr auto z = FourCharsVecSize{1, 2, 3, 4} >= + FourCharsVecSize{4, 3, 3, 1}; + // CHECK: store <4 x i8> + constexpr auto A = FourCharsVecSize{1, 2, 3, 4} == + FourCharsVecSize{4, 3, 3, 1}; + // CHECK: store <4 x i8> + constexpr auto B = FourCharsVecSize{1, 2, 3, 4} != + FourCharsVecSize{4, 3, 3, 1}; + // CHECK: store <4 x i8> + + constexpr auto C = FourCharsVecSize{1, 2, 3, 4} < 3; + // CHECK: store <4 x i8> + constexpr auto D = FourCharsVecSize{1, 2, 3, 4} > 3; + // CHECK: store <4 x i8> + constexpr auto E = FourCharsVecSize{1, 2, 3, 4} <= 3; + // CHECK: store <4 x i8> + constexpr auto F = FourCharsVecSize{1, 2, 3, 4} >= 3; + // CHECK: store <4 x i8> + constexpr auto G = FourCharsVecSize{1, 2, 3, 4} == 3; + // CHECK: store <4 x i8> + constexpr auto H = FourCharsVecSize{1, 2, 3, 4} != 3; + // CHECK: store <4 x i8> + + constexpr auto I = FourCharsVecSize{1, 2, 3, 4} & + FourCharsVecSize{4, 3, 2, 1}; + // CHECK: store <4 x i8> + constexpr auto J = FourCharsVecSize{1, 2, 3, 4} ^ + FourCharsVecSize { 4, 3, 2, 1 }; + // CHECK: store <4 x i8> + constexpr auto K = FourCharsVecSize{1, 2, 3, 4} | + FourCharsVecSize{4, 3, 2, 1}; + // CHECK: store <4 x i8> + constexpr auto L = FourCharsVecSize{1, 2, 3, 4} & 3; + // CHECK: store <4 x i8> + constexpr auto M = FourCharsVecSize{1, 2, 3, 4} ^ 3; + // CHECK: store <4 x i8> + constexpr auto N = FourCharsVecSize{1, 2, 3, 4} | 3; + // CHECK: store <4 x i8> + + constexpr auto O = FourCharsVecSize{5, 0, 6, 0} && + FourCharsVecSize{5, 5, 0, 0}; + // CHECK: store <4 x i8> + constexpr auto P = FourCharsVecSize{5, 0, 6, 0} || + FourCharsVecSize{5, 5, 0, 0}; + // CHECK: store <4 x i8> + + constexpr auto Q = FourCharsVecSize{5, 0, 6, 0} && 3; + // CHECK: store <4 x i8> + constexpr auto R = FourCharsVecSize{5, 0, 6, 0} || 3; + // CHECK: store <4 x i8> + + constexpr auto T = CmpMul(a, b); + // CHECK: store <4 x i8> + + constexpr auto U = CmpDiv(a, b); + // CHECK: store <4 x i8> + + constexpr auto V = CmpRem(a, b); + // CHECK: store <4 x i8> + + constexpr auto X = CmpAdd(a, b); + // CHECK: store <4 x i8> + + constexpr auto Y = CmpSub(a, b); + // CHECK: store <4 x i8> + + constexpr auto Z = CmpLSH(a, H); + // CHECK: store <4 x i8> + + constexpr auto aa = CmpRSH(a, H); + // CHECK: store <4 x i8> + + constexpr auto ab = CmpBinAnd(a, b); + // CHECK: store <4 x i8> + + constexpr auto ac = CmpBinXOr(a, b); + // CHECK: store <4 x i8> + + constexpr auto ad = CmpBinOr(a, b); + // CHECK: store <4 x i8> +} + +void CharExtVecUsage() { + constexpr auto a = FourCharsExtVec{6, 3, 2, 1} + + FourCharsExtVec{12, 15, 5, 7}; + // CHECK: store <4 x i8> + constexpr auto b = FourCharsExtVec{19, 15, 13, 12} - + FourCharsExtVec{13, 14, 5, 3}; + // CHECK: store <4 x i8> + constexpr auto c = FourCharsExtVec{8, 4, 2, 1} * + FourCharsExtVec{3, 4, 5, 6}; + // CHECK: store <4 x i8> + constexpr auto d = FourCharsExtVec{12, 12, 10, 10} / + FourCharsExtVec{6, 4, 5, 2}; + // CHECK: store <4 x i8> + constexpr auto e = FourCharsExtVec{12, 12, 10, 10} % + FourCharsExtVec{6, 4, 4, 3}; + // CHECK: store <4 x i8> + + constexpr auto f = FourCharsExtVec{6, 3, 2, 1} + 3; + // CHECK: store <4 x i8> + constexpr auto g = FourCharsExtVec{19, 15, 12, 10} - 3; + // CHECK: store <4 x i8> + constexpr auto h = FourCharsExtVec{8, 4, 2, 1} * 3; + // CHECK: store <4 x i8> + constexpr auto j = FourCharsExtVec{12, 15, 18, 21} / 3; + // CHECK: store <4 x i8> + constexpr auto k = FourCharsExtVec{12, 17, 19, 22} % 3; + // CHECK: store <4 x i8> + + constexpr auto l = 3 + FourCharsExtVec{6, 3, 2, 1}; + // CHECK: store <4 x i8> + constexpr auto m = 20 - FourCharsExtVec{19, 15, 12, 10}; + // CHECK: store <4 x i8> + constexpr auto n = 3 * FourCharsExtVec{8, 4, 2, 1}; + // CHECK: store <4 x i8> + constexpr auto o = 100 / FourCharsExtVec{12, 15, 18, 21}; + // CHECK: store <4 x i8> + constexpr auto p = 100 % FourCharsExtVec{12, 15, 18, 21}; + // CHECK: store <4 x i8> + + constexpr auto q = FourCharsExtVec{6, 3, 2, 1} << FourCharsVecSize{1, 1, 2, 2}; + // CHECK: store <4 x i8> + constexpr auto r = FourCharsExtVec{19, 15, 12, 10} >> + FourCharsExtVec{1, 1, 2, 2}; + // CHECK: store <4 x i8> + constexpr auto s = FourCharsExtVec{6, 3, 5, 10} << 1; + // CHECK: store <4 x i8> + constexpr auto t = FourCharsExtVec{19, 15, 10, 20} >> 1; + // CHECK: store <4 x i8> + constexpr auto u = 12 << FourCharsExtVec{1, 2, 3, 3}; + // CHECK: store <4 x i8> + constexpr auto v = 12 >> FourCharsExtVec{1, 2, 2, 1}; + // CHECK: store <4 x i8> + + constexpr auto w = FourCharsExtVec{1, 2, 3, 4} < + FourCharsExtVec{4, 3, 2, 1}; + // CHECK: store <4 x i8> + constexpr auto x = FourCharsExtVec{1, 2, 3, 4} > + FourCharsExtVec{4, 3, 2, 1}; + // CHECK: store <4 x i8> + constexpr auto y = FourCharsExtVec{1, 2, 3, 4} <= + FourCharsExtVec{4, 3, 3, 1}; + // CHECK: store <4 x i8> + constexpr auto z = FourCharsExtVec{1, 2, 3, 4} >= + FourCharsExtVec{4, 3, 3, 1}; + // CHECK: store <4 x i8> + constexpr auto A = FourCharsExtVec{1, 2, 3, 4} == + FourCharsExtVec{4, 3, 3, 1}; + // CHECK: store <4 x i8> + constexpr auto B = FourCharsExtVec{1, 2, 3, 4} != + FourCharsExtVec{4, 3, 3, 1}; + // CHECK: store <4 x i8> + + constexpr auto C = FourCharsExtVec{1, 2, 3, 4} < 3; + // CHECK: store <4 x i8> + constexpr auto D = FourCharsExtVec{1, 2, 3, 4} > 3; + // CHECK: store <4 x i8> + constexpr auto E = FourCharsExtVec{1, 2, 3, 4} <= 3; + // CHECK: store <4 x i8> + constexpr auto F = FourCharsExtVec{1, 2, 3, 4} >= 3; + // CHECK: store <4 x i8> + constexpr auto G = FourCharsExtVec{1, 2, 3, 4} == 3; + // CHECK: store <4 x i8> + constexpr auto H = FourCharsExtVec{1, 2, 3, 4} != 3; + // CHECK: store <4 x i8> + + constexpr auto I = FourCharsExtVec{1, 2, 3, 4} & + FourCharsExtVec{4, 3, 2, 1}; + // CHECK: store <4 x i8> + constexpr auto J = FourCharsExtVec{1, 2, 3, 4} ^ + FourCharsExtVec { 4, 3, 2, 1 }; + // CHECK: store <4 x i8> + constexpr auto K = FourCharsExtVec{1, 2, 3, 4} | + FourCharsExtVec{4, 3, 2, 1}; + // CHECK: store <4 x i8> + constexpr auto L = FourCharsExtVec{1, 2, 3, 4} & 3; + // CHECK: store <4 x i8> + constexpr auto M = FourCharsExtVec{1, 2, 3, 4} ^ 3; + // CHECK: store <4 x i8> + constexpr auto N = FourCharsExtVec{1, 2, 3, 4} | 3; + // CHECK: store <4 x i8> + + constexpr auto O = FourCharsExtVec{5, 0, 6, 0} && + FourCharsExtVec{5, 5, 0, 0}; + // CHECK: store <4 x i8> + constexpr auto P = FourCharsExtVec{5, 0, 6, 0} || + FourCharsExtVec{5, 5, 0, 0}; + // CHECK: store <4 x i8> + + constexpr auto Q = FourCharsExtVec{5, 0, 6, 0} && 3; + // CHECK: store <4 x i8> + constexpr auto R = FourCharsExtVec{5, 0, 6, 0} || 3; + // CHECK: store <4 x i8> + + constexpr auto T = CmpMul(a, b); + // CHECK: store <4 x i8> + + constexpr auto U = CmpDiv(a, b); + // CHECK: store <4 x i8> + + constexpr auto V = CmpRem(a, b); + // CHECK: store <4 x i8> + + constexpr auto X = CmpAdd(a, b); + // CHECK: store <4 x i8> + + constexpr auto Y = CmpSub(a, b); + // CHECK: store <4 x i8> + + constexpr auto Z = CmpLSH(a, H); + // CHECK: store <4 x i8> + + constexpr auto aa = CmpRSH(a, H); + // CHECK: store <4 x i8> + + constexpr auto ab = CmpBinAnd(a, b); + // CHECK: store <4 x i8> + + constexpr auto ac = CmpBinXOr(a, b); + // CHECK: store <4 x i8> + + constexpr auto ad = CmpBinOr(a, b); + // CHECK: store <4 x i8> +} + +void FloatUsage() { + constexpr auto a = FourFloatsVecSize{6, 3, 2, 1} + + FourFloatsVecSize{12, 15, 5, 7}; + // CHECK: <4 x float> + constexpr auto b = FourFloatsVecSize{19, 15, 13, 12} - + FourFloatsVecSize{13, 14, 5, 3}; + // CHECK: store <4 x float> + constexpr auto c = FourFloatsVecSize{8, 4, 2, 1} * + FourFloatsVecSize{3, 4, 5, 6}; + // CHECK: store <4 x float> + constexpr auto d = FourFloatsVecSize{12, 12, 10, 10} / + FourFloatsVecSize{6, 4, 5, 2}; + // CHECK: store <4 x float> + + constexpr auto f = FourFloatsVecSize{6, 3, 2, 1} + 3; + // CHECK: store <4 x float> + constexpr auto g = FourFloatsVecSize{19, 15, 12, 10} - 3; + // CHECK: store <4 x float> + constexpr auto h = FourFloatsVecSize{8, 4, 2, 1} * 3; + // CHECK: store <4 x float> + constexpr auto j = FourFloatsVecSize{12, 15, 18, 21} / 3; + // CHECK: store <4 x float> + + constexpr auto l = 3 + FourFloatsVecSize{6, 3, 2, 1}; + // CHECK: store <4 x float> + constexpr auto m = 20 - FourFloatsVecSize{19, 15, 12, 10}; + // CHECK: store <4 x float> + constexpr auto n = 3 * FourFloatsVecSize{8, 4, 2, 1}; + // CHECK: store <4 x float> + constexpr auto o = 100 / FourFloatsVecSize{12, 15, 18, 21}; + // CHECK: store <4 x float> + + constexpr auto w = FourFloatsVecSize{1, 2, 3, 4} < + FourFloatsVecSize{4, 3, 2, 1}; + // CHECK: store <4 x i32> + constexpr auto x = FourFloatsVecSize{1, 2, 3, 4} > + FourFloatsVecSize{4, 3, 2, 1}; + // CHECK: store <4 x i32> + constexpr auto y = FourFloatsVecSize{1, 2, 3, 4} <= + FourFloatsVecSize{4, 3, 3, 1}; + // CHECK: store <4 x i32> + constexpr auto z = FourFloatsVecSize{1, 2, 3, 4} >= + FourFloatsVecSize{4, 3, 3, 1}; + // CHECK: store <4 x i32> + constexpr auto A = FourFloatsVecSize{1, 2, 3, 4} == + FourFloatsVecSize{4, 3, 3, 1}; + // CHECK: store <4 x i32> + constexpr auto B = FourFloatsVecSize{1, 2, 3, 4} != + FourFloatsVecSize{4, 3, 3, 1}; + // CHECK: store <4 x i32> + + constexpr auto C = FourFloatsVecSize{1, 2, 3, 4} < 3; + // CHECK: store <4 x i32> + constexpr auto D = FourFloatsVecSize{1, 2, 3, 4} > 3; + // CHECK: store <4 x i32> + constexpr auto E = FourFloatsVecSize{1, 2, 3, 4} <= 3; + // CHECK: store <4 x i32> + constexpr auto F = FourFloatsVecSize{1, 2, 3, 4} >= 3; + // CHECK: store <4 x i32> + constexpr auto G = FourFloatsVecSize{1, 2, 3, 4} == 3; + // CHECK: store <4 x i32> + constexpr auto H = FourFloatsVecSize{1, 2, 3, 4} != 3; + // CHECK: store <4 x i32> + + constexpr auto O = FourFloatsVecSize{5, 0, 6, 0} && + FourFloatsVecSize{5, 5, 0, 0}; + // CHECK: store <4 x i32> + constexpr auto P = FourFloatsVecSize{5, 0, 6, 0} || + FourFloatsVecSize{5, 5, 0, 0}; + // CHECK: store <4 x i32> + + constexpr auto Q = FourFloatsVecSize{5, 0, 6, 0} && 3; + // CHECK: store <4 x i32> + constexpr auto R = FourFloatsVecSize{5, 0, 6, 0} || 3; + // CHECK: store <4 x i32> + + constexpr auto T = CmpMul(a, b); + // CHECK: store <4 x float> + + constexpr auto U = CmpDiv(a, b); + // CHECK: store <4 x float> + + constexpr auto X = CmpAdd(a, b); + // CHECK: store <4 x float> + + constexpr auto Y = CmpSub(a, b); + // CHECK: store <4 x float> +} + +void FloatVecUsage() { + constexpr auto a = FourFloatsVecSize{6, 3, 2, 1} + + FourFloatsVecSize{12, 15, 5, 7}; + // CHECK: <4 x float> + constexpr auto b = FourFloatsVecSize{19, 15, 13, 12} - + FourFloatsVecSize{13, 14, 5, 3}; + // CHECK: store <4 x float> + constexpr auto c = FourFloatsVecSize{8, 4, 2, 1} * + FourFloatsVecSize{3, 4, 5, 6}; + // CHECK: store <4 x float> + constexpr auto d = FourFloatsVecSize{12, 12, 10, 10} / + FourFloatsVecSize{6, 4, 5, 2}; + // CHECK: store <4 x float> + + constexpr auto f = FourFloatsVecSize{6, 3, 2, 1} + 3; + // CHECK: store <4 x float> + constexpr auto g = FourFloatsVecSize{19, 15, 12, 10} - 3; + // CHECK: store <4 x float> + constexpr auto h = FourFloatsVecSize{8, 4, 2, 1} * 3; + // CHECK: store <4 x float> + constexpr auto j = FourFloatsVecSize{12, 15, 18, 21} / 3; + // CHECK: store <4 x float> + + constexpr auto l = 3 + FourFloatsVecSize{6, 3, 2, 1}; + // CHECK: store <4 x float> + constexpr auto m = 20 - FourFloatsVecSize{19, 15, 12, 10}; + // CHECK: store <4 x float> + constexpr auto n = 3 * FourFloatsVecSize{8, 4, 2, 1}; + // CHECK: store <4 x float> + constexpr auto o = 100 / FourFloatsVecSize{12, 15, 18, 21}; + // CHECK: store <4 x float> + + constexpr auto w = FourFloatsVecSize{1, 2, 3, 4} < + FourFloatsVecSize{4, 3, 2, 1}; + // CHECK: store <4 x i32> + constexpr auto x = FourFloatsVecSize{1, 2, 3, 4} > + FourFloatsVecSize{4, 3, 2, 1}; + // CHECK: store <4 x i32> + constexpr auto y = FourFloatsVecSize{1, 2, 3, 4} <= + FourFloatsVecSize{4, 3, 3, 1}; + // CHECK: store <4 x i32> + constexpr auto z = FourFloatsVecSize{1, 2, 3, 4} >= + FourFloatsVecSize{4, 3, 3, 1}; + // CHECK: store <4 x i32> + constexpr auto A = FourFloatsVecSize{1, 2, 3, 4} == + FourFloatsVecSize{4, 3, 3, 1}; + // CHECK: store <4 x i32> + constexpr auto B = FourFloatsVecSize{1, 2, 3, 4} != + FourFloatsVecSize{4, 3, 3, 1}; + // CHECK: store <4 x i32> + + constexpr auto C = FourFloatsVecSize{1, 2, 3, 4} < 3; + // CHECK: store <4 x i32> + constexpr auto D = FourFloatsVecSize{1, 2, 3, 4} > 3; + // CHECK: store <4 x i32> + constexpr auto E = FourFloatsVecSize{1, 2, 3, 4} <= 3; + // CHECK: store <4 x i32> + constexpr auto F = FourFloatsVecSize{1, 2, 3, 4} >= 3; + // CHECK: store <4 x i32> + constexpr auto G = FourFloatsVecSize{1, 2, 3, 4} == 3; + // CHECK: store <4 x i32> + constexpr auto H = FourFloatsVecSize{1, 2, 3, 4} != 3; + // CHECK: store <4 x i32> + + constexpr auto O = FourFloatsVecSize{5, 0, 6, 0} && + FourFloatsVecSize{5, 5, 0, 0}; + // CHECK: store <4 x i32> + constexpr auto P = FourFloatsVecSize{5, 0, 6, 0} || + FourFloatsVecSize{5, 5, 0, 0}; + // CHECK: store <4 x i32> + + constexpr auto Q = FourFloatsVecSize{5, 0, 6, 0} && 3; + // CHECK: store <4 x i32> + constexpr auto R = FourFloatsVecSize{5, 0, 6, 0} || 3; + // CHECK: store <4 x i32> + + constexpr auto T = CmpMul(a, b); + // CHECK: store <4 x float> + + constexpr auto U = CmpDiv(a, b); + // CHECK: store <4 x float> + + constexpr auto X = CmpAdd(a, b); + // CHECK: store <4 x float> + + constexpr auto Y = CmpSub(a, b); + // CHECK: store <4 x float> +} diff --git a/clang/test/SemaCXX/coreturn-eh.cpp b/clang/test/SemaCXX/coreturn-eh.cpp index 79065736c0a41..591ab8ec5c5e4 100644 --- a/clang/test/SemaCXX/coreturn-eh.cpp +++ b/clang/test/SemaCXX/coreturn-eh.cpp @@ -17,7 +17,7 @@ struct object { ~object() {} }; struct promise_void_return_value { void get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void unhandled_exception(); void return_value(object); }; @@ -26,7 +26,7 @@ struct VoidTagReturnValue { struct promise_type { VoidTagReturnValue get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void unhandled_exception(); void return_value(object); }; diff --git a/clang/test/SemaCXX/coreturn.cpp b/clang/test/SemaCXX/coreturn.cpp index 4d8bfa11d832c..eaa462016de55 100644 --- a/clang/test/SemaCXX/coreturn.cpp +++ b/clang/test/SemaCXX/coreturn.cpp @@ -13,7 +13,7 @@ struct awaitable { struct promise_void { void get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void return_void(); void unhandled_exception(); }; @@ -21,7 +21,7 @@ struct promise_void { struct promise_void_return_value { void get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void unhandled_exception(); void return_value(int); }; @@ -30,7 +30,7 @@ struct VoidTagNoReturn { struct promise_type { VoidTagNoReturn get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void unhandled_exception(); }; }; @@ -39,7 +39,7 @@ struct VoidTagReturnValue { struct promise_type { VoidTagReturnValue get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void unhandled_exception(); void return_value(int); }; @@ -49,7 +49,7 @@ struct VoidTagReturnVoid { struct promise_type { VoidTagReturnVoid get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void unhandled_exception(); void return_void(); }; @@ -58,7 +58,7 @@ struct VoidTagReturnVoid { struct promise_float { float get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void return_void(); void unhandled_exception(); }; @@ -66,7 +66,7 @@ struct promise_float { struct promise_int { int get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void return_value(int); void unhandled_exception(); }; diff --git a/clang/test/SemaCXX/coroutine-final-suspend-noexcept.cpp b/clang/test/SemaCXX/coroutine-final-suspend-noexcept.cpp new file mode 100644 index 0000000000000..48c65f8afb951 --- /dev/null +++ b/clang/test/SemaCXX/coroutine-final-suspend-noexcept.cpp @@ -0,0 +1,72 @@ +// This file contains references to sections of the Coroutines TS, which can be +// found at http://wg21.link/coroutines. + +// RUN: %clang_cc1 -std=c++14 -fcoroutines-ts -verify %s -fcxx-exceptions -fexceptions -Wunused-result + +namespace std { +namespace experimental { + +template +struct coroutine_traits { using promise_type = typename Ret::promise_type; }; + +template +struct coroutine_handle { + static coroutine_handle from_address(void *); // expected-note 2 {{must be declared with 'noexcept'}} +}; +template <> +struct coroutine_handle { + template + coroutine_handle(coroutine_handle); // expected-note 2 {{must be declared with 'noexcept'}} +}; + +struct suspend_never { + bool await_ready() { return true; } // expected-note 2 {{must be declared with 'noexcept'}} + void await_suspend(coroutine_handle<>) {} // expected-note 2 {{must be declared with 'noexcept'}} + void await_resume() {} // expected-note 2 {{must be declared with 'noexcept'}} + ~suspend_never() noexcept(false); // expected-note 2 {{must be declared with 'noexcept'}} +}; + +struct suspend_always { + bool await_ready() { return false; } + void await_suspend(coroutine_handle<>) {} + void await_resume() {} + suspend_never operator co_await(); // expected-note 2 {{must be declared with 'noexcept'}} + ~suspend_always() noexcept(false); // expected-note 2 {{must be declared with 'noexcept'}} +}; + +} // namespace experimental +} // namespace std + +using namespace std::experimental; + +struct A { + bool await_ready(); + void await_resume(); + template + void await_suspend(F); +}; + +struct coro_t { + struct promise_type { + coro_t get_return_object(); + suspend_never initial_suspend(); + suspend_always final_suspend(); // expected-note 2 {{must be declared with 'noexcept'}} + void return_void(); + static void unhandled_exception(); + }; +}; + +coro_t f(int n) { // expected-error {{the expression 'co_await __promise.final_suspend()' is required to be non-throwing}} + A a{}; + co_await a; +} + +template +coro_t f_dep(T n) { // expected-error {{the expression 'co_await __promise.final_suspend()' is required to be non-throwing}} + A a{}; + co_await a; +} + +void foo() { + f_dep(5); // expected-note {{in instantiation of function template specialization 'f_dep' requested here}} +} diff --git a/clang/test/SemaCXX/coroutine-rvo.cpp b/clang/test/SemaCXX/coroutine-rvo.cpp index 8521b8506fd04..1cd025052dca8 100644 --- a/clang/test/SemaCXX/coroutine-rvo.cpp +++ b/clang/test/SemaCXX/coroutine-rvo.cpp @@ -49,7 +49,7 @@ template struct task { struct promise_type { auto initial_suspend() { return suspend_never{}; } - auto final_suspend() { return suspend_never{}; } + auto final_suspend() noexcept { return suspend_never{}; } auto get_return_object() { return task{}; } static void unhandled_exception() {} void return_value(T&& value) {} diff --git a/clang/test/SemaCXX/coroutine-unhandled_exception-warning.cpp b/clang/test/SemaCXX/coroutine-unhandled_exception-warning.cpp index d819580462c8e..88fae2e8acb26 100644 --- a/clang/test/SemaCXX/coroutine-unhandled_exception-warning.cpp +++ b/clang/test/SemaCXX/coroutine-unhandled_exception-warning.cpp @@ -23,7 +23,7 @@ struct promise_void { #endif void get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void return_void(); }; diff --git a/clang/test/SemaCXX/coroutine-uninitialized-warning-crash.cpp b/clang/test/SemaCXX/coroutine-uninitialized-warning-crash.cpp index 5bdb232d5307c..391f64d37e5bf 100644 --- a/clang/test/SemaCXX/coroutine-uninitialized-warning-crash.cpp +++ b/clang/test/SemaCXX/coroutine-uninitialized-warning-crash.cpp @@ -16,7 +16,7 @@ struct coro_t { struct promise_type { coro_t get_return_object() { return {}; } suspend_never initial_suspend() { return {}; } - suspend_never final_suspend() { return {}; } + suspend_never final_suspend() noexcept { return {}; } A yield_value(int) { return {}; } void return_void() {} static void unhandled_exception() {} diff --git a/clang/test/SemaCXX/coroutine_handle-addres-return-type.cpp b/clang/test/SemaCXX/coroutine_handle-addres-return-type.cpp new file mode 100644 index 0000000000000..a951383652344 --- /dev/null +++ b/clang/test/SemaCXX/coroutine_handle-addres-return-type.cpp @@ -0,0 +1,75 @@ +// RUN: %clang_cc1 -verify %s -stdlib=libc++ -std=c++1z -fcoroutines-ts -fsyntax-only + +namespace std::experimental { +template +struct coroutine_handle; + +template <> +struct coroutine_handle { + coroutine_handle() = default; + static coroutine_handle from_address(void *) noexcept; + void *address() const; +}; + +template +struct coroutine_handle : public coroutine_handle<> { +}; + +template +struct void_t_imp { + using type = void; +}; +template +using void_t = typename void_t_imp::type; + +template +struct traits_sfinae_base {}; + +template +struct traits_sfinae_base> { + using promise_type = typename T::promise_type; +}; + +template +struct coroutine_traits : public traits_sfinae_base {}; +} // namespace std::experimental + +struct suspend_never { + bool await_ready() noexcept; + void await_suspend(std::experimental::coroutine_handle<>) noexcept; + void await_resume() noexcept; +}; + +struct task { + struct promise_type { + auto initial_suspend() { return suspend_never{}; } + auto final_suspend() noexcept { return suspend_never{}; } + auto get_return_object() { return task{}; } + static void unhandled_exception() {} + void return_void() {} + }; +}; + +namespace std::experimental { +template <> +struct coroutine_handle : public coroutine_handle<> { + coroutine_handle *address() const; // expected-warning {{return type of 'coroutine_handle<>::address should be 'void*'}} +}; +} // namespace std::experimental + +struct awaitable { + bool await_ready(); + + std::experimental::coroutine_handle + await_suspend(std::experimental::coroutine_handle<> handle); + void await_resume(); +} a; + +task f() { + co_await a; +} + +int main() { + f(); + return 0; +} diff --git a/clang/test/SemaCXX/coroutines.cpp b/clang/test/SemaCXX/coroutines.cpp index 9e94fe8c9c109..f354b1f2a4bb0 100644 --- a/clang/test/SemaCXX/coroutines.cpp +++ b/clang/test/SemaCXX/coroutines.cpp @@ -52,21 +52,24 @@ struct std::experimental::coroutine_traits, Ps...> { }; struct awaitable { - bool await_ready(); - template void await_suspend(F); - void await_resume(); + bool await_ready() noexcept; + template + void await_suspend(F) noexcept; + void await_resume() noexcept; } a; struct suspend_always { - bool await_ready() { return false; } - template void await_suspend(F); - void await_resume() {} + bool await_ready() noexcept { return false; } + template + void await_suspend(F) noexcept; + void await_resume() noexcept {} }; struct suspend_never { - bool await_ready() { return true; } - template void await_suspend(F); - void await_resume() {} + bool await_ready() noexcept { return true; } + template + void await_suspend(F) noexcept; + void await_resume() noexcept {} }; struct auto_await_suspend { @@ -127,7 +130,7 @@ struct not_awaitable {}; struct promise { void get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; awaitable yield_value(int); // expected-note 2{{candidate}} awaitable yield_value(yielded_thing); // expected-note 2{{candidate}} not_awaitable yield_value(void()); // expected-note 2{{candidate}} @@ -138,7 +141,7 @@ struct promise { struct promise_void { void get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void return_void(); void unhandled_exception(); }; @@ -152,13 +155,13 @@ namespace std { namespace experimental { template struct coroutine_handle { - static coroutine_handle from_address(void *); + static coroutine_handle from_address(void *) noexcept; }; template <> struct coroutine_handle { template - coroutine_handle(coroutine_handle); - static coroutine_handle from_address(void *); + coroutine_handle(coroutine_handle) noexcept; + static coroutine_handle from_address(void *) noexcept; }; }} // namespace std::experimental @@ -402,7 +405,7 @@ struct await_arg_2 {}; namespace adl_ns { struct coawait_arg_type {}; -awaitable operator co_await(coawait_arg_type); +awaitable operator co_await(coawait_arg_type) noexcept; } namespace dependent_operator_co_await_lookup { @@ -434,7 +437,7 @@ namespace dependent_operator_co_await_lookup { typedef transform_awaitable await_arg; coro get_return_object(); transformed initial_suspend(); - ::adl_ns::coawait_arg_type final_suspend(); + ::adl_ns::coawait_arg_type final_suspend() noexcept; transformed await_transform(transform_awaitable); void unhandled_exception(); void return_void(); @@ -444,7 +447,7 @@ namespace dependent_operator_co_await_lookup { typedef AwaitArg await_arg; coro get_return_object(); awaitable initial_suspend(); - awaitable final_suspend(); + awaitable final_suspend() noexcept; void unhandled_exception(); void return_void(); }; @@ -529,7 +532,7 @@ struct std::experimental::coroutine_traits { void return_value(int()); suspend_never initial_suspend(); - suspend_never final_suspend(); + suspend_never final_suspend() noexcept; void get_return_object(); void unhandled_exception(); }; @@ -563,7 +566,7 @@ namespace placeholder { struct bad_promise_1 { suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void unhandled_exception(); void return_void(); }; @@ -573,7 +576,7 @@ coro missing_get_return_object() { // expected-error {{no member struct bad_promise_2 { coro get_return_object(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void unhandled_exception(); void return_void(); }; @@ -588,14 +591,14 @@ struct bad_promise_3 { void unhandled_exception(); void return_void(); }; -coro missing_final_suspend() { // expected-error {{no member named 'final_suspend' in 'bad_promise_3'}} +coro missing_final_suspend() noexcept { // expected-error {{no member named 'final_suspend' in 'bad_promise_3'}} co_await a; } struct bad_promise_4 { coro get_return_object(); not_awaitable initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void return_void(); }; // FIXME: This diagnostic is terrible. @@ -607,7 +610,7 @@ coro bad_initial_suspend() { // expected-error {{no member named struct bad_promise_5 { coro get_return_object(); suspend_always initial_suspend(); - not_awaitable final_suspend(); + not_awaitable final_suspend() noexcept; void return_void(); }; // FIXME: This diagnostic is terrible. @@ -619,7 +622,7 @@ coro bad_final_suspend() { // expected-error {{no member named 'a struct bad_promise_6 { coro get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void unhandled_exception(); void return_void(); // expected-note 2 {{member 'return_void' first declared here}} void return_value(int) const; // expected-note 2 {{member 'return_value' first declared here}} @@ -638,7 +641,7 @@ template coro bad_implicit_return_dependent(bad_promise_6); // ex struct bad_promise_7 { // expected-note 2 {{defined here}} coro get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void return_void(); }; coro no_unhandled_exception() { // expected-error {{'bad_promise_7' is required to declare the member 'unhandled_exception()'}} @@ -658,7 +661,7 @@ struct bad_promise_base { struct bad_promise_8 : bad_promise_base { coro get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void unhandled_exception() __attribute__((unavailable)); // expected-note 2 {{marked unavailable here}} void unhandled_exception() const; void unhandled_exception(void *) const; @@ -680,7 +683,7 @@ template coro calls_unhandled_exception_dependent(bad_promise_8); struct bad_promise_9 { coro get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void await_transform(void *); awaitable await_transform(int) __attribute__((unavailable)); // expected-note {{explicitly marked unavailable}} void return_void(); @@ -693,7 +696,7 @@ coro calls_await_transform() { struct bad_promise_10 { coro get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; int await_transform; void return_void(); void unhandled_exception(); @@ -712,7 +715,7 @@ void ret_void(); struct good_promise_1 { coro get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void unhandled_exception(); static const call_operator await_transform; using Fn = void (*)(); @@ -750,7 +753,7 @@ int main(int, const char**) { struct good_promise_2 { float get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void return_void(); void unhandled_exception(); }; @@ -783,7 +786,7 @@ struct std::experimental::coroutine_traits { struct promise_type { int get_return_object() {} suspend_always initial_suspend() { return {}; } - suspend_always final_suspend() { return {}; } + suspend_always final_suspend() noexcept { return {}; } void return_void() {} int get_return_object_on_allocation_failure(); // expected-error{{'promise_type': 'get_return_object_on_allocation_failure()' must be a static member function}} void unhandled_exception(); @@ -797,7 +800,7 @@ extern "C" int f(promise_on_alloc_failure_tag) { struct bad_promise_11 { coro get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void unhandled_exception(); void return_void(); @@ -820,7 +823,7 @@ template coro dependent_private_alloc_failure_handler(bad_promis struct bad_promise_12 { coro get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void unhandled_exception(); void return_void(); static coro get_return_object_on_allocation_failure(); @@ -842,7 +845,7 @@ template coro dependent_throwing_in_class_new(bad_promise_12); / struct good_promise_13 { coro get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void unhandled_exception(); void return_void(); static coro get_return_object_on_allocation_failure(); @@ -860,7 +863,7 @@ template coro dependent_uses_nothrow_new(good_promise_13); struct good_promise_custom_new_operator { coro get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void return_void(); void unhandled_exception(); void *operator new(SizeT, double, float, int); @@ -876,7 +879,7 @@ struct coroutine_nonstatic_member_struct; struct good_promise_nonstatic_member_custom_new_operator { coro get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void return_void(); void unhandled_exception(); void *operator new(SizeT, coroutine_nonstatic_member_struct &, double); @@ -886,7 +889,7 @@ struct good_promise_noexcept_custom_new_operator { static coro get_return_object_on_allocation_failure(); coro get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void return_void(); void unhandled_exception(); void *operator new(SizeT, double, float, int) noexcept; @@ -903,7 +906,7 @@ struct std::experimental::coroutine_traits { struct promise_type { void get_return_object() {} //expected-note {{member 'get_return_object' declared here}} suspend_always initial_suspend() { return {}; } - suspend_always final_suspend() { return {}; } + suspend_always final_suspend() noexcept { return {}; } void return_void() {} void unhandled_exception(); }; @@ -920,7 +923,7 @@ struct std::experimental::coroutine_traits { struct promise_type { void *get_return_object() {} //expected-note {{member 'get_return_object' declared here}} suspend_always initial_suspend() { return {}; } - suspend_always final_suspend() { return {}; } + suspend_always final_suspend() noexcept { return {}; } void return_void() {} void unhandled_exception(); }; @@ -938,7 +941,7 @@ struct std::experimental::coroutine_traits { int get_return_object() {} static void get_return_object_on_allocation_failure() {} //expected-note {{member 'get_return_object_on_allocation_failure' declared here}} suspend_always initial_suspend() { return {}; } - suspend_always final_suspend() { return {}; } + suspend_always final_suspend() noexcept { return {}; } void return_void() {} void unhandled_exception(); }; @@ -957,7 +960,7 @@ struct std::experimental::coroutine_traits { int get_return_object() {} static char *get_return_object_on_allocation_failure() {} //expected-note {{member 'get_return_object_on_allocation_failure' declared}} suspend_always initial_suspend() { return {}; } - suspend_always final_suspend() { return {}; } + suspend_always final_suspend() noexcept { return {}; } void return_void() {} void unhandled_exception(); }; @@ -971,7 +974,7 @@ extern "C" int f(mismatch_gro_type_tag4) { struct bad_promise_no_return_func { // expected-note {{'bad_promise_no_return_func' defined here}} coro get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void unhandled_exception(); }; // FIXME: The PDTS currently specifies this as UB, technically forbidding a @@ -1083,7 +1086,7 @@ struct CoroMemberPromise { CoroMemberTag get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; AwaitTestT yield_value(int); @@ -1292,7 +1295,7 @@ struct bad_promise_deleted_constructor { bad_promise_deleted_constructor() = delete; coro get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void return_void(); void unhandled_exception(); }; @@ -1314,7 +1317,7 @@ struct good_promise_default_constructor { good_promise_default_constructor() = default; coro get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void return_void(); void unhandled_exception(); }; @@ -1332,7 +1335,7 @@ struct good_promise_custom_constructor { good_promise_custom_constructor() = delete; coro get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void return_void(); void unhandled_exception(); }; @@ -1359,7 +1362,7 @@ struct bad_promise_no_matching_constructor { bad_promise_no_matching_constructor() = delete; coro get_return_object(); suspend_always initial_suspend(); - suspend_always final_suspend(); + suspend_always final_suspend() noexcept; void return_void(); void unhandled_exception(); }; @@ -1383,26 +1386,25 @@ bad_coroutine_calls_with_no_matching_constructor(int, int, int) { class awaitable_no_unused_warn { public: using handle_type = std::experimental::coroutine_handle<>; - constexpr bool await_ready() { return false; } + constexpr bool await_ready() noexcept { return false; } void await_suspend(handle_type) noexcept {} - int await_resume() { return 1; } + int await_resume() noexcept { return 1; } }; class awaitable_unused_warn { public: using handle_type = std::experimental::coroutine_handle<>; - constexpr bool await_ready() { return false; } + constexpr bool await_ready() noexcept { return false; } void await_suspend(handle_type) noexcept {} - [[nodiscard]] - int await_resume() { return 1; } + [[nodiscard]] int await_resume() noexcept { return 1; } }; template struct check_warning_promise { coro get_return_object(); Await initial_suspend(); - Await final_suspend(); + Await final_suspend() noexcept; Await yield_value(int); void return_void(); void unhandled_exception(); diff --git a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp index a16a5b54d8e0d..fc49ec88d5537 100644 --- a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp +++ b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp @@ -5,7 +5,7 @@ #define CONST const #ifdef PRECXX11 -#define static_assert(expr, msg) typedef int static_assert[(expr) ? 1 : -1]; +#define static_assert _Static_assert #endif class A { @@ -237,7 +237,7 @@ namespace in_class_template { namespace definition_after_outer_instantiation { template struct S { template static const int V1; - template static const int V2; + template static const int V2; // expected-note 3{{here}} }; template struct S; template template const int S::V1 = 123; @@ -250,11 +250,11 @@ namespace in_class_template { // is instantiated. This is kind of implied by [temp.class.spec.mfunc]/2, // and matches our behavior for member class templates, but it's not clear // that this is intentional. See PR17294 and core-24030. - static_assert(S::V2 == 456, ""); // FIXME expected-error {{}} - static_assert(S::V2 == 789, ""); // expected-error {{}} + static_assert(S::V2 == 456, ""); // FIXME expected-error {{}} expected-note {{initializer of 'V2' is unknown}} + static_assert(S::V2 == 789, ""); // expected-error {{}} expected-note {{initializer of 'V2' is unknown}} template template const int S::V2 = 789; - static_assert(S::V2 == 789, ""); // FIXME expected-error {{}} + static_assert(S::V2 == 789, ""); // FIXME expected-error {{}} expected-note {{initializer of 'V2' is unknown}} // All is OK if the partial specialization is declared before the implicit // instantiation of the class template specialization. diff --git a/clang/test/SemaCXX/cxx2a-consteval.cpp b/clang/test/SemaCXX/cxx2a-consteval.cpp index 0a6d137e96709..3231107add09c 100644 --- a/clang/test/SemaCXX/cxx2a-consteval.cpp +++ b/clang/test/SemaCXX/cxx2a-consteval.cpp @@ -476,6 +476,25 @@ namespace override { } } +namespace operator_rewrite { + struct A { + friend consteval int operator<=>(const A&, const A&) { return 0; } + }; + const bool k = A() < A(); + static_assert(!k); + + A a; + bool k2 = A() < a; // OK, does not access 'a'. + + struct B { + friend consteval int operator<=>(const B &l, const B &r) { return r.n - l.n; } // expected-note {{read of }} + int n; + }; + static_assert(B() >= B()); + B b; // expected-note {{here}} + bool k3 = B() < b; // expected-error-re {{call to consteval function '{{.*}}::operator<=>' is not a constant expression}} expected-note {{in call}} +} + struct A { int(*ptr)(); consteval A(int(*p)() = nullptr) : ptr(p) {} diff --git a/clang/test/SemaCXX/cxx2a-destroying-delete.cpp b/clang/test/SemaCXX/cxx2a-destroying-delete.cpp index 553b7a7080fe5..015d11e655262 100644 --- a/clang/test/SemaCXX/cxx2a-destroying-delete.cpp +++ b/clang/test/SemaCXX/cxx2a-destroying-delete.cpp @@ -123,3 +123,21 @@ namespace first_param_conversion { delete e; // expected-error {{ambiguous conversion from derived class 'first_param_conversion::E' to base class 'first_param_conversion::B':}} } } + +namespace templated { + template using id_alias = T; + template struct id_struct { using type = T; }; + + template struct A { + void operator delete(A *, std::destroying_delete_t); + }; + template struct B { + void operator delete(B *, std::destroying_delete_t); + }; + template struct C { + void operator delete(id_alias *, std::destroying_delete_t); + }; + template struct D { + void operator delete(typename id_struct::type *, std::destroying_delete_t); // expected-error {{use 'D *'}} + }; +} diff --git a/clang/test/SemaCXX/invalid-template-base-specifier.cpp b/clang/test/SemaCXX/invalid-template-base-specifier.cpp new file mode 100644 index 0000000000000..7a1a7f801c45e --- /dev/null +++ b/clang/test/SemaCXX/invalid-template-base-specifier.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -frecovery-ast -verify %s + +bool Foo(int *); // expected-note 3{{candidate function not viable}} + +template +struct Crash : decltype(Foo(T())) { // expected-error {{no matching function for call to 'Foo'}} + Crash(){}; +}; + +void test() { Crash(); } // expected-note {{in instantiation of template class}} + +template +using Alias = decltype(Foo(T())); // expected-error {{no matching function for call to 'Foo'}} +template +struct Crash2 : decltype(Alias()) { // expected-note {{in instantiation of template type alias 'Alias' requested here}} + Crash2(){}; +}; + +void test2() { Crash2(); } // expected-note {{in instantiation of template class 'Crash2' requested here}} + +template +class Base {}; +template +struct Crash3 : Base { // expected-error {{no matching function for call to 'Foo'}} + Crash3(){}; +}; + +void test3() { Crash3(); } // expected-note {{in instantiation of template class}} diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp index 0f4edc4d1f343..3240d5351fc5b 100644 --- a/clang/test/SemaCXX/lambda-expressions.cpp +++ b/clang/test/SemaCXX/lambda-expressions.cpp @@ -601,16 +601,24 @@ namespace ConversionOperatorDoesNotHaveDeducedReturnType { #if __cplusplus > 201402L friend constexpr auto T::operator()(int) const; friend constexpr T::operator ExpectedTypeT() const noexcept; + + template + friend constexpr void U::operator()(T&) const; + // FIXME: This should not match; the return type is specified as behaving + // "as if it were a decltype-specifier denoting the return type of + // [operator()]", which is not equivalent to this alias template. + template + friend constexpr U::operator ExpectedTypeU() const noexcept; #else friend auto T::operator()(int) const; friend T::operator ExpectedTypeT() const; -#endif - // FIXME: The first of these should match. The second should not. template - friend void U::operator()(T&) const; // expected-error {{does not match}} + friend void U::operator()(T&) const; + // FIXME: This should not match, as above. template - friend U::operator ExpectedTypeU() const; // expected-error {{does not match}} + friend U::operator ExpectedTypeU() const; +#endif private: int n; diff --git a/clang/test/SemaCXX/matrix-type-builtins.cpp b/clang/test/SemaCXX/matrix-type-builtins.cpp index 3850e4ff901b9..fce4d6fb2162b 100644 --- a/clang/test/SemaCXX/matrix-type-builtins.cpp +++ b/clang/test/SemaCXX/matrix-type-builtins.cpp @@ -15,9 +15,9 @@ typename MyMatrix::matrix_t transpose(MyMatrix & // expected-error@-3 {{cannot initialize a variable of type 'char *' with an rvalue of type 'unsigned int __attribute__((matrix_type(3, 3)))'}} __builtin_matrix_transpose(A); - // expected-error@-1 {{first argument must be a matrix}} - // expected-error@-2 {{first argument must be a matrix}} - // expected-error@-3 {{first argument must be a matrix}} + // expected-error@-1 {{1st argument must be a matrix}} + // expected-error@-2 {{1st argument must be a matrix}} + // expected-error@-3 {{1st argument must be a matrix}} return __builtin_matrix_transpose(A.value); // expected-error@-1 {{cannot initialize return object of type 'typename MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 3)))') with an rvalue of type 'unsigned int __attribute__((matrix_type(3, 2)))'}} @@ -99,13 +99,13 @@ void call_column_major_load_temp(unsigned *Ptr, unsigned X) { // expected-error@-1 {{row argument must be a constant unsigned integer expression}} // expected-error@-2 {{column argument must be a constant unsigned integer expression}} (void)__builtin_matrix_column_major_load(X, 2, 2, 2); - // expected-error@-1 {{first argument must be a pointer to a valid matrix element type}} + // expected-error@-1 {{1st argument must be a pointer to a valid matrix element type}} } template void column_major_store(MyMatrix &A, PtrTy Ptr, unsigned Stride) { __builtin_matrix_column_major_store(A.value, Ptr, Stride); - // expected-error@-1 {{the pointee of the second argument must match the element type of the first argument ('float' != 'unsigned int')}} + // expected-error@-1 {{the pointee of the 2nd argument must match the element type of the 1st argument ('float' != 'unsigned int')}} } template @@ -126,14 +126,14 @@ template void column_major_store(MyMatrix &A, EltTy1 *Ptr) { __builtin_matrix_column_major_store(A.value, Ptr, 1); // expected-error@-1 3 {{stride must be greater or equal to the number of rows}} - // expected-error@-2 {{the pointee of the second argument must match the element type of the first argument ('float' != 'unsigned int')}} - // expected-error@-3 {{the pointee of the second argument must match the element type of the first argument ('unsigned int' != 'float')}} + // expected-error@-2 {{the pointee of the 2nd argument must match the element type of the 1st argument ('float' != 'unsigned int')}} + // expected-error@-3 {{the pointee of the 2nd argument must match the element type of the 1st argument ('unsigned int' != 'float')}} char *s; return __builtin_matrix_column_major_store(A.value, s, 20); - // expected-error@-1 {{the pointee of the second argument must match the element type of the first argument ('char' != 'unsigned int')}} - // expected-error@-2 {{the pointee of the second argument must match the element type of the first argument ('char' != 'unsigned int')}} - // expected-error@-3 {{he pointee of the second argument must match the element type of the first argument ('char' != 'float')}} + // expected-error@-1 {{the pointee of the 2nd argument must match the element type of the 1st argument ('char' != 'unsigned int')}} + // expected-error@-2 {{the pointee of the 2nd argument must match the element type of the 1st argument ('char' != 'unsigned int')}} + // expected-error@-3 {{he pointee of the 2nd argument must match the element type of the 1st argument ('char' != 'float')}} } void test_column_major_store_template(unsigned *Ptr1, float *Ptr2) { @@ -152,9 +152,9 @@ void test_column_major_store_constexpr(unsigned *Ptr, MyMatrix & __builtin_matrix_column_major_store(M.value, Ptr, constexpr1()); // expected-error@-1 {{stride must be greater or equal to the number of rows}} __builtin_matrix_column_major_store(constexpr1(), Ptr, 1); - // expected-error@-1 {{first argument must be a matrix}} + // expected-error@-1 {{1st argument must be a matrix}} __builtin_matrix_column_major_store(M.value, constexpr1(), 1); - // expected-error@-1 {{second argument must be a pointer to a valid matrix element type}} + // expected-error@-1 {{2nd argument must be a pointer to a valid matrix element type}} // expected-error@-2 {{stride must be greater or equal to the number of rows}} } @@ -162,5 +162,5 @@ void test_column_major_store_wrapper(unsigned *Ptr, MyMatrix &M, __builtin_matrix_column_major_store(M.value, Ptr, W); __builtin_matrix_column_major_store(W, Ptr, W); - // expected-error@-1 {{first argument must be a matrix}} + // expected-error@-1 {{1st argument must be a matrix}} } diff --git a/clang/test/SemaCXX/recovery-expr-type.cpp b/clang/test/SemaCXX/recovery-expr-type.cpp index df40e5cd60218..6cd79326e8c34 100644 --- a/clang/test/SemaCXX/recovery-expr-type.cpp +++ b/clang/test/SemaCXX/recovery-expr-type.cpp @@ -62,3 +62,9 @@ constexpr auto x2 = AA::foo2(); // expected-error {{be initialized by a con // expected-note {{in instantiation of member function}} \ // expected-note {{in call to}} } + +// verify no assertion failure on violating value category. +namespace test4 { +int &&f(int); // expected-note {{candidate function not viable}} +int &&k = f(); // expected-error {{no matching function for call}} +} diff --git a/clang/test/SemaCXX/references.cpp b/clang/test/SemaCXX/references.cpp index f30e16d990ebe..eaab1ae833e4e 100644 --- a/clang/test/SemaCXX/references.cpp +++ b/clang/test/SemaCXX/references.cpp @@ -201,3 +201,9 @@ namespace RefCollapseTypePrinting { template void add_rref(); // expected-note {{instantiation of}} template void add_rref(); // expected-note {{instantiation of}} } + +namespace PR45521 { + struct a { template a(const b * const&); }; + int *d; + const a &r = d; +} diff --git a/clang/test/SemaCXX/warn-cast-align.cpp b/clang/test/SemaCXX/warn-cast-align.cpp index 53cd75fb14052..1e84ba9cd67af 100644 --- a/clang/test/SemaCXX/warn-cast-align.cpp +++ b/clang/test/SemaCXX/warn-cast-align.cpp @@ -44,9 +44,16 @@ void test1(void *P) { c = IntPtr(P); } +struct __attribute__((aligned(16))) AlignedS { + char m[16]; +}; + struct __attribute__((aligned(16))) A { char m0[16]; char m1[16]; + AlignedS *getAlignedS() { + return (AlignedS *)m1; + } }; struct B0 { @@ -92,6 +99,9 @@ struct __attribute__((aligned(16))) D4 : virtual D2 { struct D5 : virtual D0 { char m0[16]; + AlignedS *get() { + return (AlignedS *)m0; // expected-warning {{cast from 'char *' to 'AlignedS *'}} + } }; struct D6 : virtual D5 { diff --git a/clang/test/SemaCXX/warn-inline-namespace-reopened-noninline-disable.cpp b/clang/test/SemaCXX/warn-inline-namespace-reopened-noninline-disable.cpp new file mode 100644 index 0000000000000..3cc683006c412 --- /dev/null +++ b/clang/test/SemaCXX/warn-inline-namespace-reopened-noninline-disable.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -Wall -verify -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -Wall -Wno-inline-namespace-reopened-noninline -DSILENCE -verify -std=c++11 %s + +namespace X { + #ifndef SILENCE + inline namespace {} // expected-note {{previous definition}} + namespace {} // expected-warning {{inline namespace reopened as a non-inline namespace}} + #else + // expected-no-diagnostics + inline namespace {} + namespace {} + #endif +} diff --git a/clang/test/SemaCXX/warn-suggest-destructor-override b/clang/test/SemaCXX/warn-suggest-destructor-override new file mode 100644 index 0000000000000..1cfff748678f2 --- /dev/null +++ b/clang/test/SemaCXX/warn-suggest-destructor-override @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify -Wsuggest-destructor-override + +struct A { + ~A(); + virtual void run(); +}; + +struct B : public A { + ~B(); +}; + +struct C { + virtual void run(); + virtual ~C(); // expected-note 2{{overridden virtual function is here}} +}; + +struct D : public C { + void run(); + ~D(); + // expected-warning@-1 {{'~D' overrides a destructor but is not marked 'override'}} +}; + +struct E : public C { + void run(); + virtual ~E(); + // expected-warning@-1 {{'~E' overrides a destructor but is not marked 'override'}} +}; diff --git a/clang/test/SemaCXX/warn-suggest-override b/clang/test/SemaCXX/warn-suggest-override new file mode 100644 index 0000000000000..e06c939ff001f --- /dev/null +++ b/clang/test/SemaCXX/warn-suggest-override @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify -Wsuggest-override + +struct A { + ~A(); + void run(); +}; + +struct B : public A { + ~B(); + void run(); +}; + +struct C { + virtual void run(); // expected-note 2{{overridden virtual function is here}} + virtual ~C(); +}; + +struct D : public C { + void run(); + // expected-warning@-1 {{'run()' overrides a member function but is not marked 'override'}} + ~D(); +}; + +struct E : public C { + virtual void run(); + // expected-warning@-1 {{'run()' overrides a member function but is not marked 'override'}} + virtual ~E(); +}; + +struct F : public C { + void run() override; + ~F() override; +}; + +struct G : public C { + void run() final; + ~G() final; +}; diff --git a/clang/test/SemaCXX/warn-uninitialized-const-reference.cpp b/clang/test/SemaCXX/warn-uninitialized-const-reference.cpp index 292793ba483a6..d24b561441d8f 100644 --- a/clang/test/SemaCXX/warn-uninitialized-const-reference.cpp +++ b/clang/test/SemaCXX/warn-uninitialized-const-reference.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -Wuninitialized-const-reference -verify %s +// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -fexceptions -Wuninitialized-const-reference -verify %s class A { public: @@ -9,6 +9,16 @@ class A { bool operator!=(const A &); }; +template +void ignore_template(const T &) {} +void ignore(const int &i) {} +void dont_ignore_non_empty(const int &i) { ; } // Calling this won't silence the warning for you +void dont_ignore_block(const int &i) { + {} +} // Calling this won't silence the warning for you +void ignore_function_try_block_maybe_who_knows(const int &) try { +} catch (...) { +} A const_ref_use_A(const A &a); int const_ref_use(const int &i); A const_use_A(const A a); @@ -33,4 +43,13 @@ void f(int a) { if (a < 42) m = 1; const_ref_use(m); + + int l; + ignore_template(l); // This is a pattern to avoid "unused variable" warnings (e.g. boost::ignore_unused). + ignore(l); + dont_ignore_non_empty(l); // expected-warning {{variable 'l' is uninitialized when passed as a const reference argument here}} + int l1; + dont_ignore_block(l1); // expected-warning {{variable 'l1' is uninitialized when passed as a const reference argument here}} + int l2; + ignore_function_try_block_maybe_who_knows(l2); // expected-warning {{variable 'l2' is uninitialized when passed as a const reference argument here}} } diff --git a/clang/test/SemaObjC/aarch64-sve-types.m b/clang/test/SemaObjC/aarch64-sve-types.m index 9e1af311de6fb..376ffe648e2c2 100644 --- a/clang/test/SemaObjC/aarch64-sve-types.m +++ b/clang/test/SemaObjC/aarch64-sve-types.m @@ -18,5 +18,7 @@ @interface foo @property(nullable) __SVFloat32_t f32; // expected-error {{cannot be applied to non-pointer type}} @property(nullable) __SVFloat64_t f64; // expected-error {{cannot be applied to non-pointer type}} +@property(nullable) __SVBFloat16_t bf16; // expected-error {{cannot be applied to non-pointer type}} + @property(nullable) __SVBool_t b8; // expected-error {{cannot be applied to non-pointer type}} @end diff --git a/clang/test/SemaObjC/matrix-type-builtins.m b/clang/test/SemaObjC/matrix-type-builtins.m index dc18905963e40..21b8bf864271d 100644 --- a/clang/test/SemaObjC/matrix-type-builtins.m +++ b/clang/test/SemaObjC/matrix-type-builtins.m @@ -22,10 +22,10 @@ void test_element_type_mismatch(u4x4 m, MatrixValue *mv) { double test_store(MatrixValue *mv, float *Ptr) { __builtin_matrix_column_major_store(mv.value, Ptr, 1); - // expected-error@-1 {{the pointee of the second argument must match the element type of the first argument ('float' != 'double')}} + // expected-error@-1 {{the pointee of the 2nd argument must match the element type of the 1st argument ('float' != 'double')}} // expected-error@-2 {{stride must be greater or equal to the number of rows}} __builtin_matrix_column_major_store(mv.value, mv.value, mv.value); - // expected-error@-1 {{second argument must be a pointer to a valid matrix element type}} + // expected-error@-1 {{2nd argument must be a pointer to a valid matrix element type}} // expected-error@-2 {{casting 'double4x4' (aka 'double __attribute__((matrix_type(4, 4)))') to incompatible type 'unsigned long}} } diff --git a/clang/test/SemaObjC/potentially-direct-selector.m b/clang/test/SemaObjC/potentially-direct-selector.m new file mode 100644 index 0000000000000..04f9d2111c9b1 --- /dev/null +++ b/clang/test/SemaObjC/potentially-direct-selector.m @@ -0,0 +1,157 @@ +// RUN: %clang_cc1 %s -Wpotentially-direct-selector -verify +// RUN: %clang_cc1 %s -Wstrict-potentially-direct-selector -verify=expected,strict + +#define NS_DIRECT __attribute__((objc_direct)) + +__attribute__((objc_root_class)) +@interface Dummies +-(void)inBase; +-(void)inBaseImpl; +-(void)inBaseCat; +-(void)inBaseCatImpl; +-(void)inDerived; +-(void)inDerivedImpl; +-(void)inDerivedCat; +-(void)inDerivedCatImpl; ++(void)inBaseClass; ++(void)inDerivedClass; ++(void)inDerivedCatClass; +@end + +__attribute__((objc_root_class)) +@interface Base +-(void)inBase NS_DIRECT; // expected-note + {{direct method}} ++(void)inBaseClass NS_DIRECT; // expected-note + {{direct method}} +@end + +@implementation Base +-(void)inBaseImpl NS_DIRECT { // expected-note + {{direct method}} +} +-(void)inBase {} ++(void)inBaseClass {} +@end + +@interface Base (Cat) +-(void)inBaseCat NS_DIRECT; // expected-note + {{direct method}} +@end + +@implementation Base (Cat) +-(void)inBaseCatImpl NS_DIRECT { // expected-note + {{direct method}} +} +-(void)inBaseCat {} +@end + +@interface Derived : Base +-(void)inDerived NS_DIRECT; // expected-note + {{direct method}} ++(void)inDerivedClass NS_DIRECT; // expected-note + {{direct method}} +@end + +@implementation Derived +-(void)inDerivedImpl NS_DIRECT { // expected-note + {{direct method}} +} +-(void)inDerived {} ++(void)inDerivedClass {} +@end + +@interface Derived (Cat) +-(void)inDerivedCat NS_DIRECT; // expected-note + {{direct method}} ++(void)inDerivedCatClass NS_DIRECT; // expected-note + {{direct method}} +@end + +@implementation Derived (Cat) +-(void)inDerivedCatImpl NS_DIRECT { // expected-note + {{direct method}} +} +-(void)inDerivedCat {} ++(void)inDerivedCatClass {} + +-(void)test1 { + (void)@selector(inBase); // expected-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inBaseImpl); // expected-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inBaseCat); // expected-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inBaseCatImpl); // expected-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inDerived); // expected-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inDerivedImpl); // expected-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inDerivedCat); // expected-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inDerivedCatImpl); // expected-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inDerivedClass); // expected-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inBaseClass); // expected-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inDerivedCatClass); // expected-warning{{@selector expression formed with potentially direct selector}} +} +@end + +void test2() { + (void)@selector(inBase); // strict-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inBaseImpl); // strict-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inBaseCat); // strict-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inBaseCatImpl); // strict-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inDerived); // strict-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inDerivedImpl); // strict-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inDerivedCat); // strict-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inDerivedCatImpl); // strict-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inDerivedClass); // strict-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inBaseClass); // strict-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inDerivedCatClass); // strict-warning{{@selector expression formed with potentially direct selector}} +} + +@interface OnlyBase : Base @end +@implementation OnlyBase +-(void)test3 { + (void)@selector(inBase); // expected-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inBaseImpl); // expected-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inBaseCat); // expected-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inBaseCatImpl); // expected-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inDerived); // strict-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inDerivedImpl); // strict-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inDerivedCat); // strict-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inDerivedCatImpl); // strict-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inDerivedClass); // strict-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inBaseClass); // expected-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inDerivedCatClass); // strict-warning{{@selector expression formed with potentially direct selector}} +} +@end + +__attribute__((objc_root_class)) +@interface Unrelated @end +@implementation Unrelated +-(void)test4 { + (void)@selector(inBase); // strict-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inBaseImpl); // strict-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inBaseCat); // strict-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inBaseCatImpl); // strict-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inDerived); // strict-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inDerivedImpl); // strict-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inDerivedCat); // strict-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inDerivedCatImpl); // strict-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inDerivedClass); // strict-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inBaseClass); // strict-warning{{@selector expression formed with potentially direct selector}} + (void)@selector(inDerivedCatClass); // strict-warning{{@selector expression formed with potentially direct selector}} +} +@end + +@implementation Dummies +-(void)inBase {} +-(void)inBaseImpl {} +-(void)inBaseCat {} +-(void)inBaseCatImpl {} +-(void)inDerived {} +-(void)inDerivedImpl {} +-(void)inDerivedCat {} +-(void)inDerivedCatImpl {} ++(void)inBaseClass {} ++(void)inDerivedClass {} ++(void)inDerivedCatClass {} + +-(void)test5 { + (void)@selector(inBase); + (void)@selector(inBaseImpl); + (void)@selector(inBaseCat); + (void)@selector(inBaseCatImpl); + (void)@selector(inDerived); + (void)@selector(inDerivedImpl); + (void)@selector(inDerivedCat); + (void)@selector(inDerivedCatImpl); + (void)@selector(inDerivedClass); + (void)@selector(inBaseClass); + (void)@selector(inDerivedCatClass); +} +@end diff --git a/clang/test/SemaObjC/signed-char-bool-conversion.m b/clang/test/SemaObjC/signed-char-bool-conversion.m index 183f60fafcd5a..9442d8fa86a90 100644 --- a/clang/test/SemaObjC/signed-char-bool-conversion.m +++ b/clang/test/SemaObjC/signed-char-bool-conversion.m @@ -108,3 +108,15 @@ int main() { f(); // expected-note {{in instantiation of function template specialization 'f' requested here}} } #endif + +void t5(BOOL b) { + int i; + b = b ?: YES; // no warning + b = b ?: i; // expected-warning {{implicit conversion from integral type 'int' to 'BOOL'}} + b = (b = i) // expected-warning {{implicit conversion from integral type 'int' to 'BOOL'}} + ?: YES; + b = (1 ? YES : i) ?: YES; // expected-warning {{implicit conversion from integral type 'int' to 'BOOL'}} + b = b ?: (1 ? i : i); // expected-warning 2 {{implicit conversion from integral type 'int' to 'BOOL'}} + + b = b ? YES : (i ?: 0); // expected-warning {{implicit conversion from integral type 'int' to 'BOOL'}} +} diff --git a/clang/test/SemaObjCXX/attr-trivial-abi.mm b/clang/test/SemaObjCXX/attr-trivial-abi.mm index 537c1390a54a2..87b79c14d07a6 100644 --- a/clang/test/SemaObjCXX/attr-trivial-abi.mm +++ b/clang/test/SemaObjCXX/attr-trivial-abi.mm @@ -57,7 +57,7 @@ struct __attribute__((trivial_abi(1))) S8 { // expected-error {{'trivial_abi' at }; // Do not warn when 'trivial_abi' is used to annotate a template class. -template +template struct __attribute__((trivial_abi)) S10 { T p; }; @@ -76,21 +76,27 @@ struct __attribute__((trivial_abi)) S10 { // expected-warning {{'trivial_abi __weak id b; }; -template +template struct __attribute__((trivial_abi)) S15 : S14 { }; S15 s15; -template +template struct __attribute__((trivial_abi)) S16 { S14 a; }; S16 s16; -template +template struct __attribute__((trivial_abi)) S17 { // expected-warning {{'trivial_abi' cannot be applied to 'S17'}} expected-note {{has a __weak field}} + S17(); + S17(S17 &&); + __weak id a; +}; + +struct __attribute__((trivial_abi)) S18 { // expected-warning {{'trivial_abi' cannot be applied to 'S18'}} expected-note {{has a __weak field}} __weak id a; }; diff --git a/clang/test/SemaObjCXX/property-invalid-type.mm b/clang/test/SemaObjCXX/property-invalid-type.mm index 9122426f4c300..35a5f3a5a525f 100644 --- a/clang/test/SemaObjCXX/property-invalid-type.mm +++ b/clang/test/SemaObjCXX/property-invalid-type.mm @@ -21,3 +21,13 @@ void foo(I *i) { i.helper; // expected-warning{{property access result unused - getters should not be used for side effects}} } + +@interface J +@property (nonnull) auto a; // expected-error {{'auto' not allowed in interface member}} +@property auto b; // expected-error {{'auto' not allowed in interface member}} +@property (nullable) auto c; // expected-error {{'auto' not allowed in interface member}} +@end + +@interface J (Cat) +@property (nonnull) auto catprop; // expected-error {{'auto' not allowed in interface member}} +@end diff --git a/clang/test/SemaOpenCL/block-array-capturing.cl b/clang/test/SemaOpenCL/block-array-capturing.cl index e8073fce11e83..6ad4d1e493af0 100644 --- a/clang/test/SemaOpenCL/block-array-capturing.cl +++ b/clang/test/SemaOpenCL/block-array-capturing.cl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -triple spir64-unkown-unkown -emit-llvm %s -o -| FileCheck %s +// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -triple spir64-unknown-unknown -emit-llvm %s -o -| FileCheck %s // expected-no-diagnostics typedef int (^block_t)(); diff --git a/clang/test/SemaOpenCL/builtins-amdgcn-error-f16.cl b/clang/test/SemaOpenCL/builtins-amdgcn-error-f16.cl index 3487b1a5a8038..fdb2f3f3c9816 100644 --- a/clang/test/SemaOpenCL/builtins-amdgcn-error-f16.cl +++ b/clang/test/SemaOpenCL/builtins-amdgcn-error-f16.cl @@ -8,6 +8,7 @@ void test_f16_tahiti(global half *out, half a, half b, half c) { *out = __builtin_amdgcn_div_fixuph(a, b, c); // expected-error {{'__builtin_amdgcn_div_fixuph' needs target feature 16-bit-insts}} *out = __builtin_amdgcn_rcph(a); // expected-error {{'__builtin_amdgcn_rcph' needs target feature 16-bit-insts}} + *out = __builtin_amdgcn_sqrth(a); // expected-error {{'__builtin_amdgcn_sqrth' needs target feature 16-bit-insts}} *out = __builtin_amdgcn_rsqh(a); // expected-error {{'__builtin_amdgcn_rsqh' needs target feature 16-bit-insts}} *out = __builtin_amdgcn_sinh(a); // expected-error {{'__builtin_amdgcn_sinh' needs target feature 16-bit-insts}} *out = __builtin_amdgcn_cosh(a); // expected-error {{'__builtin_amdgcn_cosh' needs target feature 16-bit-insts}} diff --git a/clang/test/SemaOpenCL/builtins-amdgcn-error.cl b/clang/test/SemaOpenCL/builtins-amdgcn-error.cl index e2d9082f8f723..8001cf3b59e00 100644 --- a/clang/test/SemaOpenCL/builtins-amdgcn-error.cl +++ b/clang/test/SemaOpenCL/builtins-amdgcn-error.cl @@ -146,7 +146,7 @@ void test_s_setreg(int x, int y) { } void test_atomic_inc32() { - int val = 17; + uint val = 17; val = __builtin_amdgcn_atomic_inc32(&val, val, __ATOMIC_SEQ_CST + 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}} val = __builtin_amdgcn_atomic_inc32(&val, val, __ATOMIC_ACQUIRE - 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}} val = __builtin_amdgcn_atomic_inc32(4); // expected-error {{too few arguments to function call, expected 4}} @@ -155,10 +155,12 @@ void test_atomic_inc32() { val = __builtin_amdgcn_atomic_inc32(&val, val, __ATOMIC_ACQUIRE, 5); // expected-warning {{incompatible integer to pointer conversion passing 'int' to parameter of type 'const char *'}} const char ptr[] = "workgroup"; val = __builtin_amdgcn_atomic_inc32(&val, val, __ATOMIC_ACQUIRE, ptr); // expected-error {{expression is not a string literal}} + int signedVal = 15; + signedVal = __builtin_amdgcn_atomic_inc32(&signedVal, signedVal, __ATOMIC_ACQUIRE, ""); // expected-warning {{passing '__private int *' to parameter of type 'volatile __private unsigned int *' converts between pointers to integer types with different sign}} } void test_atomic_inc64() { - __INT64_TYPE__ val = 17; + __UINT64_TYPE__ val = 17; val = __builtin_amdgcn_atomic_inc64(&val, val, __ATOMIC_SEQ_CST + 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}} val = __builtin_amdgcn_atomic_inc64(&val, val, __ATOMIC_ACQUIRE - 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}} val = __builtin_amdgcn_atomic_inc64(4); // expected-error {{too few arguments to function call, expected 4}} @@ -167,10 +169,12 @@ void test_atomic_inc64() { val = __builtin_amdgcn_atomic_inc64(&val, val, __ATOMIC_ACQUIRE, 5); // expected-warning {{incompatible integer to pointer conversion passing 'int' to parameter of type 'const char *'}} const char ptr[] = "workgroup"; val = __builtin_amdgcn_atomic_inc64(&val, val, __ATOMIC_ACQUIRE, ptr); // expected-error {{expression is not a string literal}} + __INT64_TYPE__ signedVal = 15; + signedVal = __builtin_amdgcn_atomic_inc64(&signedVal, signedVal, __ATOMIC_ACQUIRE, ""); // expected-warning {{passing '__private long *' to parameter of type 'volatile __private unsigned long *' converts between pointers to integer types with different sign}} } void test_atomic_dec32() { - int val = 17; + uint val = 17; val = __builtin_amdgcn_atomic_dec32(&val, val, __ATOMIC_SEQ_CST + 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}} val = __builtin_amdgcn_atomic_dec32(&val, val, __ATOMIC_ACQUIRE - 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}} val = __builtin_amdgcn_atomic_dec32(4); // expected-error {{too few arguments to function call, expected 4}} @@ -179,10 +183,12 @@ void test_atomic_dec32() { val = __builtin_amdgcn_atomic_dec32(&val, val, __ATOMIC_ACQUIRE, 5); // expected-warning {{incompatible integer to pointer conversion passing 'int' to parameter of type 'const char *'}} const char ptr[] = "workgroup"; val = __builtin_amdgcn_atomic_dec32(&val, val, __ATOMIC_ACQUIRE, ptr); // expected-error {{expression is not a string literal}} + int signedVal = 15; + signedVal = __builtin_amdgcn_atomic_dec32(&signedVal, signedVal, __ATOMIC_ACQUIRE, ""); // expected-warning {{passing '__private int *' to parameter of type 'volatile __private unsigned int *' converts between pointers to integer types with different sign}} } void test_atomic_dec64() { - __INT64_TYPE__ val = 17; + __UINT64_TYPE__ val = 17; val = __builtin_amdgcn_atomic_dec64(&val, val, __ATOMIC_SEQ_CST + 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}} val = __builtin_amdgcn_atomic_dec64(&val, val, __ATOMIC_ACQUIRE - 1, "workgroup"); // expected-warning {{memory order argument to atomic operation is invalid}} val = __builtin_amdgcn_atomic_dec64(4); // expected-error {{too few arguments to function call, expected 4}} @@ -191,4 +197,6 @@ void test_atomic_dec64() { val = __builtin_amdgcn_atomic_dec64(&val, val, __ATOMIC_ACQUIRE, 5); // expected-warning {{incompatible integer to pointer conversion passing 'int' to parameter of type 'const char *'}} const char ptr[] = "workgroup"; val = __builtin_amdgcn_atomic_dec64(&val, val, __ATOMIC_ACQUIRE, ptr); // expected-error {{expression is not a string literal}} + __INT64_TYPE__ signedVal = 15; + signedVal = __builtin_amdgcn_atomic_dec64(&signedVal, signedVal, __ATOMIC_ACQUIRE, ""); // expected-warning {{passing '__private long *' to parameter of type 'volatile __private unsigned long *' converts between pointers to integer types with different sign}} } diff --git a/clang/test/SemaOpenCL/fp-options.cl b/clang/test/SemaOpenCL/fp-options.cl new file mode 100644 index 0000000000000..413afd61819d3 --- /dev/null +++ b/clang/test/SemaOpenCL/fp-options.cl @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 %s -finclude-default-header -triple spir-unknown-unknown -emit-pch -o %t.pch +// RUN: %clang_cc1 %s -finclude-default-header -cl-no-signed-zeros -triple spir-unknown-unknown -include-pch %t.pch -fsyntax-only -verify +// expected-no-diagnostics + diff --git a/clang/test/SemaOpenCL/invalid-block.cl b/clang/test/SemaOpenCL/invalid-block.cl index ec74d16cc9b8c..0fb2e26920736 100644 --- a/clang/test/SemaOpenCL/invalid-block.cl +++ b/clang/test/SemaOpenCL/invalid-block.cl @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -verify -fblocks -cl-std=CL2.0 %s // OpenCL v2.0 s6.12.5 -void f0(int (^const bl)()); +void f0(int (^const bl)()); // expected-error{{declaring function parameter of type 'int (__generic ^const __private)(void)' is not allowed}} // All blocks declarations must be const qualified and initialized. void f1() { int (^bl1)(void) = ^() { @@ -26,9 +26,18 @@ void f2() { }; } -// A block cannot be the return value of a function. +// A block cannot be the return value or parameter of a function. typedef int (^bl_t)(void); -bl_t f3(bl_t bl); // expected-error{{declaring function return value of type 'bl_t' (aka 'int (__generic ^const)(void)') is not allowed}} +bl_t f3a(int); // expected-error{{declaring function return value of type 'bl_t' (aka 'int (__generic ^const)(void)') is not allowed}} +bl_t f3b(bl_t bl); +// expected-error@-1{{declaring function return value of type 'bl_t' (aka 'int (__generic ^const)(void)') is not allowed}} +// expected-error@-2{{declaring function parameter of type '__private bl_t' (aka 'int (__generic ^const __private)(void)') is not allowed}} +void f3c() { + // Block with a block argument. + int (^const bl2)(bl_t block_arg) = ^() { // expected-error{{declaring function parameter of type '__private bl_t' (aka 'int (__generic ^const __private)(void)') is not allowed}} + return block_arg(); // expected-error{{implicit declaration of function 'block_arg' is invalid in OpenCL}} + }; +} struct bl_s { int (^bl)(void); // expected-error {{the 'int (__generic ^const)(void)' type cannot be used to declare a structure or union field}} diff --git a/clang/test/SemaTemplate/alias-templates.cpp b/clang/test/SemaTemplate/alias-templates.cpp index 80678bf229852..6dffd94892943 100644 --- a/clang/test/SemaTemplate/alias-templates.cpp +++ b/clang/test/SemaTemplate/alias-templates.cpp @@ -265,3 +265,28 @@ namespace an_alias_template_is_not_a_class_template { int z = Bar(); // expected-error {{use of template template parameter 'Bar' requires template arguments}} } } + +namespace resolved_nttp { + template struct A { + template using Arr = T[N]; + Arr<3> a; + }; + using TA = decltype(A::a); + using TA = int[3]; + + template struct B { + template using Fn = T(int(*...A)[N]); + Fn<1, 2, 3> *p; + }; + using TB = decltype(B::p); + using TB = int (*)(int (*)[1], int (*)[2], int (*)[3]); + + template struct C { + template using Fn = T(int(*...A)[N]); + Fn<1, M..., 4> *p; // expected-error-re 3{{evaluates to {{[234]}}, which cannot be narrowed to type 'bool'}} + }; + using TC = decltype(C::p); + using TC = int (*)(int (*)[1], int (*)[2], int (*)[3], int (*)[4]); + + using TC2 = decltype(C::p); // expected-note {{instantiation of}} +} diff --git a/clang/test/SemaTemplate/deduction-guide.cpp b/clang/test/SemaTemplate/deduction-guide.cpp new file mode 100644 index 0000000000000..8a964903ebfcc --- /dev/null +++ b/clang/test/SemaTemplate/deduction-guide.cpp @@ -0,0 +1,208 @@ +// RUN: %clang_cc1 -std=c++2a -verify -ast-dump -ast-dump-decl-types -ast-dump-filter "deduction guide" %s | FileCheck %s --strict-whitespace + +template struct X {}; +template typename> struct Y {}; +template struct Z {}; + +template struct A { + template A(X, Ts (*...qs)[Ns]); +}; +int arr1[3], arr2[3]; +short arr3[4]; +A a(X<&arr1, &arr2>{}, &arr1, &arr2, &arr3); +using AT = decltype(a); +using AT = A; + +// CHECK-LABEL: Dumping : +// CHECK: FunctionTemplateDecl +// CHECK: |-TemplateTypeParmDecl {{.*}} typename depth 0 index 0 T +// CHECK: |-TemplateTypeParmDecl {{.*}} typename depth 0 index 1 ... Ts +// CHECK: |-NonTypeTemplateParmDecl {{.*}} 'Ts...' depth 0 index 2 ... Ns +// CHECK: |-NonTypeTemplateParmDecl {{.*}} 'T *' depth 0 index 3 ... Ps +// CHECK: |-CXXDeductionGuideDecl +// CHECK: | |-ParmVarDecl {{.*}} 'X' +// CHECK: | `-ParmVarDecl {{.*}} 'Ts (*)[Ns]...' pack +// CHECK: `-CXXDeductionGuideDecl +// CHECK: |-TemplateArgument type 'int [3]' +// CHECK: |-TemplateArgument pack +// CHECK: | |-TemplateArgument type 'int' +// CHECK: | |-TemplateArgument type 'int' +// CHECK: | `-TemplateArgument type 'short' +// CHECK: |-TemplateArgument pack +// CHECK: | |-TemplateArgument integral 3 +// CHECK: | |-TemplateArgument integral 3 +// CHECK: | `-TemplateArgument integral 4 +// CHECK: |-TemplateArgument pack +// CHECK: | |-TemplateArgument decl +// CHECK: | | `-Var {{.*}} 'arr1' 'int [3]' +// CHECK: | `-TemplateArgument decl +// CHECK: | `-Var {{.*}} 'arr2' 'int [3]' +// CHECK: |-ParmVarDecl {{.*}} 'X<&arr1, &arr2>':'X<&arr1, &arr2>' +// CHECK: |-ParmVarDecl {{.*}} 'int (*)[3]' +// CHECK: |-ParmVarDecl {{.*}} 'int (*)[3]' +// CHECK: `-ParmVarDecl {{.*}} 'short (*)[4]' +// CHECK: FunctionProtoType {{.*}} 'auto (X, Ts (*)[Ns]...) -> A' dependent trailing_return +// CHECK: |-InjectedClassNameType {{.*}} 'A' dependent +// CHECK: |-TemplateSpecializationType {{.*}} 'X' dependent X +// CHECK: | `-TemplateArgument expr +// CHECK: | `-PackExpansionExpr {{.*}} 'T *' +// CHECK: | `-DeclRefExpr {{.*}} 'T *' NonTypeTemplateParm {{.*}} 'Ps' 'T *' +// CHECK: `-PackExpansionType {{.*}} 'Ts (*)[Ns]...' dependent +// CHECK: `-PointerType {{.*}} 'Ts (*)[Ns]' dependent contains_unexpanded_pack +// CHECK: `-ParenType {{.*}} 'Ts [Ns]' sugar dependent contains_unexpanded_pack +// CHECK: `-DependentSizedArrayType {{.*}} 'Ts [Ns]' dependent contains_unexpanded_pack +// CHECK: |-TemplateTypeParmType {{.*}} 'Ts' dependent contains_unexpanded_pack depth 0 index 1 pack +// CHECK: | `-TemplateTypeParm {{.*}} 'Ts' +// CHECK: `-DeclRefExpr {{.*}} 'Ts' NonTypeTemplateParm {{.*}} 'Ns' 'Ts...' + +template struct B { + template B(X); +}; +B b(X{}); +using BT = decltype(b); +using BT = B; + +// CHECK-LABEL: Dumping : +// CHECK: FunctionTemplateDecl +// CHECK: |-TemplateTypeParmDecl {{.*}} typename depth 0 index 0 T +// CHECK: |-NonTypeTemplateParmDecl {{.*}} 'T' depth 0 index 1 V +// CHECK: |-TemplateTypeParmDecl {{.*}} typename depth 0 index 2 U +// CHECK: |-NonTypeTemplateParmDecl {{.*}} 'type-parameter-0-2' depth 0 index 3 W +// CHECK: |-CXXDeductionGuideDecl {{.*}} 'auto (X) -> B' +// CHECK: | `-ParmVarDecl {{.*}} 'X' +// CHECK: `-CXXDeductionGuideDecl {{.*}} 'auto (X) -> B' +// CHECK: |-TemplateArgument type 'char' +// CHECK: |-TemplateArgument integral 120 +// CHECK: |-TemplateArgument type 'nullptr_t' +// CHECK: |-TemplateArgument nullptr +// CHECK: `-ParmVarDecl {{.*}} 'X':'X' +// CHECK: FunctionProtoType {{.*}} 'auto (X) -> B' dependent trailing_return +// CHECK: |-InjectedClassNameType {{.*}} 'B' dependent +// CHECK: `-TemplateSpecializationType {{.*}} 'X' dependent X +// CHECK: |-TemplateArgument expr +// CHECK: | `-DeclRefExpr {{.*}} 'type-parameter-0-2' NonTypeTemplateParm {{.*}} 'W' 'type-parameter-0-2' +// CHECK: `-TemplateArgument expr +// CHECK: `-DeclRefExpr {{.*}} 'T' NonTypeTemplateParm {{.*}} 'V' 'T' + +template struct C { + template typename T, typename U, U V = 0> C(A, Y, U); +}; +C c(1, Y{}, 2); +using CT = decltype(c); +using CT = C; + +// CHECK-LABEL: Dumping : +// CHECK: FunctionTemplateDecl +// CHECK: |-TemplateTypeParmDecl {{.*}} typename depth 0 index 0 A +// CHECK: |-TemplateTemplateParmDecl {{.*}} depth 0 index 1 T +// CHECK: | |-TemplateTypeParmDecl {{.*}} typename depth 1 index 0 X +// CHECK: | `-NonTypeTemplateParmDecl {{.*}} 'X' depth 1 index 1 +// CHECK: |-TemplateTypeParmDecl {{.*}} typename depth 0 index 2 U +// CHECK: |-NonTypeTemplateParmDecl {{.*}} 'type-parameter-0-2' depth 0 index 3 V +// CHECK: | `-TemplateArgument expr +// CHECK: | `-IntegerLiteral {{.*}} 'int' 0 +// CHECK: |-CXXDeductionGuideDecl {{.*}} 'auto (A, Y<>, type-parameter-0-2) -> C' +// CHECK: | |-ParmVarDecl {{.*}} 'A' +// CHECK: | |-ParmVarDecl {{.*}} 'Y<>' +// CHECK: | `-ParmVarDecl {{.*}} 'type-parameter-0-2' +// CHECK: `-CXXDeductionGuideDecl {{.*}} 'auto (int, Y, int) -> C' +// CHECK: |-TemplateArgument type 'int' +// CHECK: |-TemplateArgument template B +// CHECK: |-TemplateArgument type 'int' +// CHECK: |-TemplateArgument integral 0 +// CHECK: |-ParmVarDecl {{.*}} 'int':'int' +// CHECK: |-ParmVarDecl {{.*}} 'Y':'Y' +// CHECK: `-ParmVarDecl {{.*}} 'int':'int' +// CHECK: FunctionProtoType {{.*}} 'auto (A, Y<>, type-parameter-0-2) -> C' dependent trailing_return cdecl +// CHECK: |-InjectedClassNameType {{.*}} 'C' dependent +// CHECK: |-TemplateTypeParmType {{.*}} 'A' dependent depth 0 index 0 +// CHECK: | `-TemplateTypeParm {{.*}} 'A' +// CHECK: |-TemplateSpecializationType {{.*}} 'Y<>' dependent Y +// CHECK: | `-TemplateArgument template +// CHECK: `-TemplateTypeParmType {{.*}} 'type-parameter-0-2' dependent depth 0 index 2 + +template struct D { // expected-note {{candidate}} + template using B = int(int (*...p)(T, U)); + template D(B*); // expected-note {{candidate}} +}; +int f(int(int, int), int(int, int)); +// FIXME: We can't deduce this because we can't deduce through a +// SubstTemplateTypeParmPackType. +D d = f; // expected-error {{no viable}} +using DT = decltype(d); +using DT = D; + +// CHECK-LABEL: Dumping : +// CHECK: FunctionTemplateDecl +// CHECK: |-TemplateTypeParmDecl {{.*}} typename depth 0 index 0 ... T +// CHECK: |-TemplateTypeParmDecl {{.*}} typename depth 0 index 1 U1 +// CHECK: |-TemplateTypeParmDecl {{.*}} typename depth 0 index 2 U2 +// CHECK: `-CXXDeductionGuideDecl {{.*}} 'auto (B *) -> D' +// CHECK: `-ParmVarDecl {{.*}} 'B *' +// CHECK: FunctionProtoType {{.*}} 'auto (B *) -> D' dependent trailing_return +// CHECK: |-InjectedClassNameType {{.*}} 'D' dependent +// CHECK: `-PointerType {{.*}} 'B *' dependent +// CHECK: `-TemplateSpecializationType {{.*}} 'B' sugar dependent alias B +// CHECK: |-TemplateArgument type 'type-parameter-0-1' +// CHECK: |-TemplateArgument type 'type-parameter-0-2' +// CHECK: `-FunctionProtoType {{.*}} 'int (int (*)(T, U)...)' dependent cdecl +// CHECK: |-BuiltinType {{.*}} 'int' +// CHECK: `-PackExpansionType {{.*}} 'int (*)(T, U)...' dependent expansions 2 +// CHECK: `-PointerType {{.*}} 'int (*)(T, U)' dependent contains_unexpanded_pack +// CHECK: `-ParenType {{.*}} 'int (T, U)' sugar dependent contains_unexpanded_pack +// CHECK: `-FunctionProtoType {{.*}} 'int (T, U)' dependent contains_unexpanded_pack cdecl +// CHECK: |-BuiltinType {{.*}} 'int' +// CHECK: |-TemplateTypeParmType {{.*}} 'T' dependent contains_unexpanded_pack depth 0 index 0 pack +// CHECK: | `-TemplateTypeParm {{.*}} 'T' +// CHECK: `-SubstTemplateTypeParmPackType {{.*}} 'U' dependent contains_unexpanded_pack +// CHECK: |-TemplateTypeParmType {{.*}} 'U' dependent contains_unexpanded_pack depth 1 index 0 pack +// CHECK: | `-TemplateTypeParm {{.*}} 'U' +// CHECK: `-TemplateArgument pack +// CHECK: |-TemplateArgument type 'type-parameter-0-1' +// CHECK-NOT: Subst +// CHECK: | `-TemplateTypeParmType +// CHECK: `-TemplateArgument type 'type-parameter-0-2' +// CHECK-NOT: Subst +// CHECK: `-TemplateTypeParmType + +template struct E { // expected-note {{candidate}} + template using B = Z...>; + template E(B); // expected-note {{candidate}} +}; +// FIXME: We can't deduce this because we can't deduce through a +// SubstNonTypeTemplateParmPackExpr. +E e = Z, X<3, 4>>(); // expected-error {{no viable}} +using ET = decltype(e); +using ET = E<1, 3>; + +// CHECK-LABEL: Dumping : +// CHECK: FunctionTemplateDecl +// CHECK: |-NonTypeTemplateParmDecl [[N:0x[0-9a-f]*]] {{.*}} 'int' depth 0 index 0 ... N +// CHECK: |-NonTypeTemplateParmDecl [[M1:0x[0-9a-f]*]] {{.*}} 'int' depth 0 index 1 M1 +// CHECK: |-NonTypeTemplateParmDecl [[M2:0x[0-9a-f]*]] {{.*}} 'int' depth 0 index 2 M2 +// CHECK: `-CXXDeductionGuideDecl {{.*}} 'auto (B) -> E' +// CHECK: `-ParmVarDecl {{.*}} 'B':'Z...>' +// CHECK: FunctionProtoType {{.*}} 'auto (B) -> E' dependent trailing_return +// CHECK: |-InjectedClassNameType {{.*}} 'E' dependent +// CHECK: `-TemplateSpecializationType {{.*}} 'B' sugar dependent alias B +// CHECK: |-TemplateArgument expr +// CHECK: | `-DeclRefExpr {{.*}} 'int' NonTypeTemplateParm {{.*}} 'M1' 'int' +// CHECK: |-TemplateArgument expr +// CHECK: | `-DeclRefExpr {{.*}} 'int' NonTypeTemplateParm {{.*}} 'M2' 'int' +// CHECK: `-TemplateSpecializationType {{.*}} 'Z...>' dependent Z +// CHECK: `-TemplateArgument type 'X...' +// CHECK: `-PackExpansionType {{.*}} 'X...' dependent expansions 2 +// CHECK: `-TemplateSpecializationType {{.*}} 'X' dependent contains_unexpanded_pack X +// CHECK: |-TemplateArgument expr +// CHECK-NOT: Subst +// CHECK: | `-DeclRefExpr {{.*}} 'int' NonTypeTemplateParm [[N]] 'N' 'int' +// CHECK: `-TemplateArgument expr +// CHECK: `-SubstNonTypeTemplateParmPackExpr {{.*}} 'int' +// CHECK: |-NonTypeTemplateParmDecl {{.*}} referenced 'int' depth 1 index 0 ... M +// CHECK: `-TemplateArgument pack +// CHECK: |-TemplateArgument expr +// CHECK-NOT: Subst +// CHECK: | `-DeclRefExpr {{.*}} 'int' NonTypeTemplateParm [[M1]] 'M1' 'int' +// CHECK: `-TemplateArgument expr +// CHECK-NOT: Subst +// CHECK: `-DeclRefExpr {{.*}} 'int' NonTypeTemplateParm [[M2]] 'M2' 'int' diff --git a/clang/test/SemaTemplate/default-arguments-cxx0x.cpp b/clang/test/SemaTemplate/default-arguments-cxx0x.cpp index 2114cc94e6c60..1aa456553599c 100644 --- a/clang/test/SemaTemplate/default-arguments-cxx0x.cpp +++ b/clang/test/SemaTemplate/default-arguments-cxx0x.cpp @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s // RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s // expected-no-diagnostics // Test default template arguments for function templates. @@ -116,6 +117,11 @@ namespace rdar34167492 { }; } +namespace use_of_earlier_param { + template void f(T a, int = decltype(a)()); + void g() { f(0); } +} + #if __cplusplus >= 201402L namespace lambda { // Verify that a default argument in a lambda can refer to the type of a @@ -127,5 +133,32 @@ namespace lambda { void foo() { bar(); } + +#if __cplusplus >= 202002L + // PR46648: ensure we don't reject this by triggering default argument + // instantiation spuriously. + auto x = [](T x = 123) {}; + void y() { x(nullptr); } + + template struct X { + template constexpr int f() { + auto l = [](int n = A + B + C) { return n; }; + return l.template operator()<3>(); + } + }; + static_assert(X<100>().f<20>() == 123); + + template<> template constexpr int X<200>::f() { + auto l = [](int n = 300 + B + C) { return n; }; + return l.template operator()<1>(); + } + static_assert(X<200>().f<20>() == 321); + + template<> template<> constexpr int X<300>::f<20>() { + auto l = [](int n = 450 + C) { return n; }; + return l.template operator()<6>(); + } + static_assert(X<300>().f<20>() == 456); +#endif } // namespace lambda #endif diff --git a/clang/test/SemaTemplate/defaulted.cpp b/clang/test/SemaTemplate/defaulted.cpp new file mode 100644 index 0000000000000..15111f71202df --- /dev/null +++ b/clang/test/SemaTemplate/defaulted.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -std=c++20 -verify %s +// expected-no-diagnostics + +namespace SpaceshipImpliesEq { + template struct A { + int operator<=>(const A&) const = default; + constexpr bool f() { return operator==(*this); } + }; + static_assert(A().f()); +} diff --git a/clang/test/SemaTemplate/dependent-expr.cpp b/clang/test/SemaTemplate/dependent-expr.cpp index 0ce4cb39d3493..abdb8e9c4a9fd 100644 --- a/clang/test/SemaTemplate/dependent-expr.cpp +++ b/clang/test/SemaTemplate/dependent-expr.cpp @@ -144,7 +144,7 @@ namespace PR45083 { void h(auto a, void*) {} // expected-error {{redefinition}} void i(auto a) { - [](auto a, int = ({decltype(a) i; i * 2;})){}(a); // expected-error {{no matching function}} expected-note {{substitution failure}} + [](auto a, int = ({decltype(a) i; i * 2;})){}(a); // expected-error {{invalid operands to binary expression ('decltype(a)' (aka 'void *') and 'int')}} expected-note {{in instantiation of}} } void use_i() { i(0); diff --git a/clang/test/SemaTemplate/nss-recovery.cpp b/clang/test/SemaTemplate/nss-recovery.cpp new file mode 100644 index 0000000000000..08974cbbff113 --- /dev/null +++ b/clang/test/SemaTemplate/nss-recovery.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// There should be no extra errors about missing 'typename' keywords. +void f() { + decltype(undef())::Type T; // expected-error {{use of undeclared identifier}} +} diff --git a/clang/test/SemaTemplate/stack-exhaustion.cpp b/clang/test/SemaTemplate/stack-exhaustion.cpp index 7f76212d2a492..c7bfea4132d5e 100644 --- a/clang/test/SemaTemplate/stack-exhaustion.cpp +++ b/clang/test/SemaTemplate/stack-exhaustion.cpp @@ -1,4 +1,6 @@ -// RUN: %clang_cc1 -verify %s +// RUN: %clang_cc1 -verify %s -DTEST=1 +// RUN: %clang_cc1 -verify %s -DTEST=2 +// RUN: %clang_cc1 -verify %s -DTEST=3 // REQUIRES: thread_support // FIXME: Detection of, or recovery from, stack exhaustion does not work on @@ -6,9 +8,14 @@ // implementation limits, just disable the test. // UNSUPPORTED: system-netbsd +// asan has own stack-overflow check. +// UNSUPPORTED: asan + // expected-warning@* 0-1{{stack nearly exhausted}} // expected-note@* 0+{{}} +#if TEST == 1 + template struct X : X {}; template<> struct X<0> {}; X<1000> x; @@ -21,3 +28,38 @@ int f(X<0>); template auto f(X) -> f(X()); int k = f(X<1000>()); + +#elif TEST == 2 + +namespace template_argument_recursion { + struct ostream; + template T &&declval(); + + namespace mlir { + template() << declval())> + ostream &operator<<(ostream& os, const T& obj); // expected-error {{exceeded maximum depth}} + struct Value; + } + + void printFunctionalType(ostream &os, mlir::Value &v) { os << v; } +} + +#elif TEST == 3 + +namespace template_parameter_type_recursion { + struct ostream; + template T &&declval(); + template struct enable_if { using type = T; }; + + namespace mlir { + template() << declval(), void*>::type = nullptr> + ostream &operator<<(ostream& os, const T& obj); // expected-error {{exceeded maximum depth}} + struct Value; + } + + void printFunctionalType(ostream &os, mlir::Value &v) { os << v; } +} + +#else +#error unknown test +#endif diff --git a/clang/test/Tooling/clang-check-ast-dump.cpp b/clang/test/Tooling/clang-check-ast-dump.cpp index 496d489fd6090..bd9ae5fcc2a59 100644 --- a/clang/test/Tooling/clang-check-ast-dump.cpp +++ b/clang/test/Tooling/clang-check-ast-dump.cpp @@ -33,6 +33,7 @@ // CHECK-ATTR-NEXT: FieldDecl{{.*}}n // CHECK-ATTR-NEXT: AlignedAttr // CHECK-ATTR-NEXT: ConstantExpr +// CHECK-ATTR-NEXT: value: Int 2 // CHECK-ATTR-NEXT: BinaryOperator // // RUN: clang-check -ast-dump -ast-dump-filter test_namespace::AfterNullNode "%s" -- 2>&1 | FileCheck -check-prefix CHECK-AFTER-NULL %s diff --git a/clang/test/lit.cfg.py b/clang/test/lit.cfg.py index 413f811754204..ade32988b9a82 100644 --- a/clang/test/lit.cfg.py +++ b/clang/test/lit.cfg.py @@ -155,6 +155,10 @@ def is_filesystem_case_insensitive(): if not re.match(r'.*-(cygwin)$', config.target_triple): config.available_features.add('clang-driver') +# Tests that are specific to the Apple Silicon macOS. +if re.match(r'^arm64(e)?-apple-(macos|darwin)', config.target_triple): + config.available_features.add('apple-silicon-mac') + # [PR18856] Depends to remove opened file. On win32, a file could be removed # only if all handles were closed. if platform.system() not in ['Windows']: diff --git a/clang/test/utils/update_cc_test_checks/Inputs/mangled_names.c.funcsig.expected b/clang/test/utils/update_cc_test_checks/Inputs/mangled_names.c.funcsig.expected index 005b2f2427473..e76cf074bdb78 100644 --- a/clang/test/utils/update_cc_test_checks/Inputs/mangled_names.c.funcsig.expected +++ b/clang/test/utils/update_cc_test_checks/Inputs/mangled_names.c.funcsig.expected @@ -1,4 +1,4 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature // Example input for update_cc_test_checks // RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/utils/update_cc_test_checks/Inputs/on_the_fly_arg_change.c b/clang/test/utils/update_cc_test_checks/Inputs/on_the_fly_arg_change.c new file mode 100644 index 0000000000000..8956e6b52a210 --- /dev/null +++ b/clang/test/utils/update_cc_test_checks/Inputs/on_the_fly_arg_change.c @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s + +int checks_please() { + return 1; +} + +// UTC_ARGS: --disable + +int no_checks_please() { + // Manual CHECK line should be retained: + // CHECK: manual check line + return -1; +} + +// UTC_ARGS: --enable + + +int checks_again() { + return 2; +} diff --git a/clang/test/utils/update_cc_test_checks/Inputs/on_the_fly_arg_change.c.expected b/clang/test/utils/update_cc_test_checks/Inputs/on_the_fly_arg_change.c.expected new file mode 100644 index 0000000000000..cb7846c7b3d5a --- /dev/null +++ b/clang/test/utils/update_cc_test_checks/Inputs/on_the_fly_arg_change.c.expected @@ -0,0 +1,29 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s + +// CHECK-LABEL: @checks_please( +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 1 +// +int checks_please() { + return 1; +} + +// UTC_ARGS: --disable + +int no_checks_please() { + // Manual CHECK line should be retained: + // CHECK: manual check line + return -1; +} + +// UTC_ARGS: --enable + + +// CHECK-LABEL: @checks_again( +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 2 +// +int checks_again() { + return 2; +} diff --git a/clang/test/utils/update_cc_test_checks/mangled_names.test b/clang/test/utils/update_cc_test_checks/mangled_names.test index 082ed74304f06..bc88c9b5a382f 100644 --- a/clang/test/utils/update_cc_test_checks/mangled_names.test +++ b/clang/test/utils/update_cc_test_checks/mangled_names.test @@ -8,6 +8,11 @@ ## Also try the --function-signature flag # RUN: %update_cc_test_checks %t.c --function-signature # RUN: diff -u %t.c %S/Inputs/mangled_names.c.funcsig.expected -## Verify that running without the --function-signature flag removes the -SAME: lines: +## Running it again should implicitly add the function-signature flag due to UTC_ARGS: # RUN: %update_cc_test_checks %t.c -# RUN: diff -u %t.c %S/Inputs/mangled_names.c.expected +# RUN: diff -u %t.c %S/Inputs/mangled_names.c.funcsig.expected +## Verify that running without the --function-signature flag removes the -SAME: lines: +## We have to remove the UTC_ARGS comment first: +# RUN: grep -v UTC_ARGS %t.c > %t-no-args.c +# RUN: %update_cc_test_checks %t-no-args.c +# RUN: diff -u %t-no-args.c %S/Inputs/mangled_names.c.expected diff --git a/clang/test/utils/update_cc_test_checks/on_the_fly_arg_change.test b/clang/test/utils/update_cc_test_checks/on_the_fly_arg_change.test new file mode 100644 index 0000000000000..629b01f9d0660 --- /dev/null +++ b/clang/test/utils/update_cc_test_checks/on_the_fly_arg_change.test @@ -0,0 +1,6 @@ +# RUN: cp -f %S/Inputs/on_the_fly_arg_change.c %t.c +# RUN: %update_cc_test_checks %t.c +# RUN: diff -u %t.c %S/Inputs/on_the_fly_arg_change.c.expected +## Check that running the script again does not change the result: +# RUN: %update_cc_test_checks %t.c +# RUN: diff -u %t.c %S/Inputs/on_the_fly_arg_change.c.expected diff --git a/clang/tools/clang-check/ClangCheck.cpp b/clang/tools/clang-check/ClangCheck.cpp index 2f59e2b82d343..6565aa2290307 100644 --- a/clang/tools/clang-check/ClangCheck.cpp +++ b/clang/tools/clang-check/ClangCheck.cpp @@ -141,6 +141,7 @@ class ClangCheckActionFactory { /*DumpDecls=*/true, /*Deserialize=*/false, /*DumpLookups=*/false, + /*DumpDeclTypes=*/false, clang::ADOF_Default); if (ASTPrint) return clang::CreateASTPrinter(nullptr, ASTDumpFilter); diff --git a/clang/tools/clang-import-test/CMakeLists.txt b/clang/tools/clang-import-test/CMakeLists.txt index 39a5c41c1512d..4ccc2d752aac4 100644 --- a/clang/tools/clang-import-test/CMakeLists.txt +++ b/clang/tools/clang-import-test/CMakeLists.txt @@ -7,7 +7,7 @@ if(NOT CLANG_BUILT_STANDALONE) set(tablegen_deps intrinsics_gen) endif() -add_clang_tool(clang-import-test +add_clang_executable(clang-import-test clang-import-test.cpp DEPENDS ${tablegen_deps} diff --git a/clang/tools/clang-import-test/clang-import-test.cpp b/clang/tools/clang-import-test/clang-import-test.cpp index 2245c6aff8836..0c9bd237b3ba5 100644 --- a/clang/tools/clang-import-test/clang-import-test.cpp +++ b/clang/tools/clang-import-test/clang-import-test.cpp @@ -320,9 +320,9 @@ llvm::Expected Parse(const std::string &Path, auto &CG = *static_cast(ASTConsumers.back().get()); if (ShouldDumpAST) - ASTConsumers.push_back( - CreateASTDumper(nullptr /*Dump to stdout.*/, "", true, false, false, - clang::ADOF_Default)); + ASTConsumers.push_back(CreateASTDumper(nullptr /*Dump to stdout.*/, "", + true, false, false, false, + clang::ADOF_Default)); CI.getDiagnosticClient().BeginSourceFile( CI.getCompilerInstance().getLangOpts(), diff --git a/clang/tools/clang-shlib/CMakeLists.txt b/clang/tools/clang-shlib/CMakeLists.txt index 07ee0f0a9a929..5949223fc8e34 100644 --- a/clang/tools/clang-shlib/CMakeLists.txt +++ b/clang/tools/clang-shlib/CMakeLists.txt @@ -13,7 +13,12 @@ foreach (lib ${clang_libs}) else() list(APPEND _OBJECTS $) endif() - list(APPEND _DEPS $) + if (BUILD_SHARED_LIBS) + # If we are building static libraries, then we don't need to add the static + # libraries as a depedency, because we are already linking against the + # individual object files. + list(APPEND _DEPS $) + endif() # clang libraries are redundant since we are linking all the individual # object files into libclang-cpp.so, so filter them out from _DEPS. diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp index 5e92fc32e6f6c..f24fd61e61a54 100644 --- a/clang/tools/driver/driver.cpp +++ b/clang/tools/driver/driver.cpp @@ -511,6 +511,11 @@ int main(int argc_, const char **argv_) { for (const auto &J : C->getJobs()) if (const Command *C = dyn_cast(&J)) FailingCommands.push_back(std::make_pair(-1, C)); + + // Print the bug report message that would be printed if we did actually + // crash, but only if we're crashing due to FORCE_CLANG_DIAGNOSTICS_CRASH. + if (::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH")) + llvm::dbgs() << llvm::getBugReportMsg(); } for (const auto &P : FailingCommands) { diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 4a65624268d84..93f9797a965ec 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -3272,7 +3272,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) { } // Visit init captures for (auto InitExpr : E->capture_inits()) { - if (Visit(InitExpr)) + if (InitExpr && Visit(InitExpr)) return true; } @@ -4056,10 +4056,14 @@ static const Expr *evaluateCompoundStmtExpr(const CompoundStmt *CS) { } CXEvalResult clang_Cursor_Evaluate(CXCursor C) { - if (const Expr *E = - clang_getCursorKind(C) == CXCursor_CompoundStmt - ? evaluateCompoundStmtExpr(cast(getCursorStmt(C))) - : evaluateDeclExpr(getCursorDecl(C))) + const Expr *E = nullptr; + if (clang_getCursorKind(C) == CXCursor_CompoundStmt) + E = evaluateCompoundStmtExpr(cast(getCursorStmt(C))); + else if (clang_isDeclaration(C.kind)) + E = evaluateDeclExpr(getCursorDecl(C)); + else if (clang_isExpression(C.kind)) + E = getCursorExpr(C); + if (E) return const_cast( reinterpret_cast(evaluateExpr(const_cast(E), C))); return nullptr; diff --git a/clang/tools/libclang/CIndexInclusionStack.cpp b/clang/tools/libclang/CIndexInclusionStack.cpp index f1c5b53c5ef61..7572512ae5764 100644 --- a/clang/tools/libclang/CIndexInclusionStack.cpp +++ b/clang/tools/libclang/CIndexInclusionStack.cpp @@ -18,10 +18,9 @@ #include "clang/Frontend/ASTUnit.h" using namespace clang; -static void getInclusions(const SrcMgr::SLocEntry &(SourceManager::*Getter)(unsigned, bool*) const, unsigned n, - CXTranslationUnit TU, CXInclusionVisitor CB, - CXClientData clientData) -{ +namespace { +void getInclusions(bool IsLocal, unsigned n, CXTranslationUnit TU, + CXInclusionVisitor CB, CXClientData clientData) { ASTUnit *CXXUnit = cxtu::getASTUnit(TU); SourceManager &SM = CXXUnit->getSourceManager(); ASTContext &Ctx = CXXUnit->getASTContext(); @@ -30,8 +29,8 @@ static void getInclusions(const SrcMgr::SLocEntry &(SourceManager::*Getter)(unsi for (unsigned i = 0 ; i < n ; ++i) { bool Invalid = false; - const SrcMgr::SLocEntry &SL = (SM.*Getter)(i, &Invalid); - + const SrcMgr::SLocEntry &SL = + IsLocal ? SM.getLocalSLocEntry(i) : SM.getLoadedSLocEntry(i, &Invalid); if (!SL.isFile() || Invalid) continue; @@ -61,11 +60,11 @@ static void getInclusions(const SrcMgr::SLocEntry &(SourceManager::*Getter)(unsi // Callback to the client. // FIXME: We should have a function to construct CXFiles. CB(static_cast( - const_cast(FI.getContentCache()->OrigEntry)), + const_cast(FI.getContentCache()->OrigEntry)), InclusionStack.data(), InclusionStack.size(), clientData); } } - +} // namespace void clang_getInclusions(CXTranslationUnit TU, CXInclusionVisitor CB, CXClientData clientData) { @@ -83,14 +82,13 @@ void clang_getInclusions(CXTranslationUnit TU, CXInclusionVisitor CB, // a AST/PCH file, but this file has a pre-compiled preamble, we also need // to look in that file. if (n == 1 || SM.getPreambleFileID().isValid()) { - getInclusions(&SourceManager::getLoadedSLocEntry, - SM.loaded_sloc_entry_size(), TU, CB, clientData); + getInclusions(/*IsLocal=*/false, SM.loaded_sloc_entry_size(), TU, CB, + clientData); } // Not a PCH/AST file. Note, if there is a preamble, it could still be that // there are #includes in this file (e.g. for any include after the first // declaration). if (n != 1) - getInclusions(&SourceManager::getLocalSLocEntry, n, TU, CB, clientData); - + getInclusions(/*IsLocal=*/true, n, TU, CB, clientData); } diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index 172fbb461a7e3..f92ea8de16516 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -3416,6 +3416,26 @@ TEST_P(ASTImporterOptionSpecificTestBase, EXPECT_TRUE(ToCtor->hasBody()); } +TEST_P(ASTImporterOptionSpecificTestBase, ClassTemplateFriendDecl) { + const auto *Code = + R"( + template class X { friend T; }; + struct Y {}; + template class X; + )"; + Decl *ToTU = getToTuDecl(Code, Lang_CXX11); + Decl *FromTU = getTuDecl(Code, Lang_CXX11); + auto *FromSpec = FirstDeclMatcher().match( + FromTU, classTemplateSpecializationDecl()); + auto *ToSpec = FirstDeclMatcher().match( + ToTU, classTemplateSpecializationDecl()); + + auto *ImportedSpec = Import(FromSpec, Lang_CXX11); + EXPECT_EQ(ImportedSpec, ToSpec); + EXPECT_EQ(1u, DeclCounter().match( + ToTU, classTemplateSpecializationDecl())); +} + TEST_P(ASTImporterOptionSpecificTestBase, ClassTemplatePartialSpecializationsShouldNotBeDuplicated) { auto Code = @@ -3954,6 +3974,56 @@ TEST_P(ImportFriendClasses, ImportOfClassDefinitionAndFwdFriendShouldBeLinked) { EXPECT_EQ(ImportedFwd, ImportedDef->getPreviousDecl()); } +TEST_P(ImportFriendClasses, ImportOfRepeatedFriendType) { + const char *Code = + R"( + class Container { + friend class X; + friend class X; + }; + )"; + Decl *ToTu = getToTuDecl(Code, Lang_CXX03); + Decl *FromTu = getTuDecl(Code, Lang_CXX03, "from.cc"); + + auto *ToFriend1 = FirstDeclMatcher().match(ToTu, friendDecl()); + auto *ToFriend2 = LastDeclMatcher().match(ToTu, friendDecl()); + auto *FromFriend1 = + FirstDeclMatcher().match(FromTu, friendDecl()); + auto *FromFriend2 = LastDeclMatcher().match(FromTu, friendDecl()); + + FriendDecl *ToImportedFriend1 = Import(FromFriend1, Lang_CXX03); + FriendDecl *ToImportedFriend2 = Import(FromFriend2, Lang_CXX03); + + EXPECT_NE(ToImportedFriend1, ToImportedFriend2); + EXPECT_EQ(ToFriend1, ToImportedFriend1); + EXPECT_EQ(ToFriend2, ToImportedFriend2); +} + +TEST_P(ImportFriendClasses, ImportOfRepeatedFriendDecl) { + const char *Code = + R"( + class Container { + friend void f(); + friend void f(); + }; + )"; + Decl *ToTu = getToTuDecl(Code, Lang_CXX03); + Decl *FromTu = getTuDecl(Code, Lang_CXX03, "from.cc"); + + auto *ToFriend1 = FirstDeclMatcher().match(ToTu, friendDecl()); + auto *ToFriend2 = LastDeclMatcher().match(ToTu, friendDecl()); + auto *FromFriend1 = + FirstDeclMatcher().match(FromTu, friendDecl()); + auto *FromFriend2 = LastDeclMatcher().match(FromTu, friendDecl()); + + FriendDecl *ToImportedFriend1 = Import(FromFriend1, Lang_CXX03); + FriendDecl *ToImportedFriend2 = Import(FromFriend2, Lang_CXX03); + + EXPECT_NE(ToImportedFriend1, ToImportedFriend2); + EXPECT_EQ(ToFriend1, ToImportedFriend1); + EXPECT_EQ(ToFriend2, ToImportedFriend2); +} + TEST_P(ASTImporterOptionSpecificTestBase, FriendFunInClassTemplate) { auto *Code = R"( template diff --git a/clang/unittests/AST/ASTTraverserTest.cpp b/clang/unittests/AST/ASTTraverserTest.cpp index 5585238939fea..2f131c3fd04f0 100644 --- a/clang/unittests/AST/ASTTraverserTest.cpp +++ b/clang/unittests/AST/ASTTraverserTest.cpp @@ -244,6 +244,7 @@ FullComment verifyWithDynNode(TA, R"cpp( TemplateArgument +`-BuiltinType )cpp"); Func = getFunctionNode(AST.get(), "parmvardecl_attr"); @@ -430,6 +431,7 @@ VarDecl 'c1' StaticAssertDecl |-ImplicitCastExpr | `-SubstNonTypeTemplateParmExpr +| |-NonTypeTemplateParmDecl 'alignment' | `-IntegerLiteral `-StringLiteral )cpp"); diff --git a/clang/unittests/AST/CommentParser.cpp b/clang/unittests/AST/CommentParser.cpp index 327cabd619bdb..ba8b34ebcd38b 100644 --- a/clang/unittests/AST/CommentParser.cpp +++ b/clang/unittests/AST/CommentParser.cpp @@ -64,7 +64,7 @@ FullComment *CommentParserTest::parseString(const char *Source) { if (MY_DEBUG) { llvm::errs() << "=== Source:\n" << Source << "\n=== AST:\n"; - FC->dump(llvm::errs(), &Traits, &SourceMgr); + FC->dump(); } Token Tok; diff --git a/clang/unittests/AST/DeclPrinterTest.cpp b/clang/unittests/AST/DeclPrinterTest.cpp index 018e99237ae94..939c8b52c12c1 100644 --- a/clang/unittests/AST/DeclPrinterTest.cpp +++ b/clang/unittests/AST/DeclPrinterTest.cpp @@ -76,14 +76,16 @@ ::testing::AssertionResult PrintedDeclMatches(StringRef Code, const std::vector &Args, const DeclarationMatcher &NodeMatch, StringRef ExpectedPrinted, StringRef FileName, - PrintingPolicyModifier PolicyModifier = nullptr) { + PrintingPolicyModifier PolicyModifier = nullptr, + bool AllowError = false) { PrintMatch Printer(PolicyModifier); MatchFinder Finder; Finder.addMatcher(NodeMatch, &Printer); std::unique_ptr Factory( newFrontendActionFactory(&Finder)); - if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, FileName)) + if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, FileName) && + !AllowError) return testing::AssertionFailure() << "Parsing error in \"" << Code.str() << "\""; @@ -170,16 +172,12 @@ PrintedDeclCXX1ZMatches(StringRef Code, const DeclarationMatcher &NodeMatch, "input.cc"); } -::testing::AssertionResult PrintedDeclObjCMatches( - StringRef Code, - const DeclarationMatcher &NodeMatch, - StringRef ExpectedPrinted) { +::testing::AssertionResult +PrintedDeclObjCMatches(StringRef Code, const DeclarationMatcher &NodeMatch, + StringRef ExpectedPrinted, bool AllowError = false) { std::vector Args(1, ""); - return PrintedDeclMatches(Code, - Args, - NodeMatch, - ExpectedPrinted, - "input.m"); + return PrintedDeclMatches(Code, Args, NodeMatch, ExpectedPrinted, "input.m", + /*PolicyModifier=*/nullptr, AllowError); } } // unnamed namespace @@ -1321,3 +1319,17 @@ TEST(DeclPrinter, TestObjCProtocol2) { namedDecl(hasName("P1")).bind("id"), "@protocol P1\n@end")); } + +TEST(DeclPrinter, TestObjCCategoryInvalidInterface) { + ASSERT_TRUE(PrintedDeclObjCMatches( + "@interface I (Extension) @end", + namedDecl(hasName("Extension")).bind("id"), + "@interface <>(Extension)\n@end", /*AllowError=*/true)); +} + +TEST(DeclPrinter, TestObjCCategoryImplInvalidInterface) { + ASSERT_TRUE(PrintedDeclObjCMatches( + "@implementation I (Extension) @end", + namedDecl(hasName("Extension")).bind("id"), + "@implementation <>(Extension)\n@end", /*AllowError=*/true)); +} diff --git a/clang/unittests/AST/MatchVerifier.h b/clang/unittests/AST/MatchVerifier.h index 3fb22ef00f98f..217c1abcff693 100644 --- a/clang/unittests/AST/MatchVerifier.h +++ b/clang/unittests/AST/MatchVerifier.h @@ -271,7 +271,7 @@ class DumpVerifier : public MatchVerifier { const DynTypedNode &Node) override { std::string DumpStr; llvm::raw_string_ostream Dump(DumpStr); - Node.dump(Dump, *Result.SourceManager); + Node.dump(Dump, *Result.Context); if (Dump.str().find(ExpectSubstring) == std::string::npos) { std::string MsgStr; diff --git a/clang/unittests/AST/SourceLocationTest.cpp b/clang/unittests/AST/SourceLocationTest.cpp index cb96afed64d31..32dc382aa05c3 100644 --- a/clang/unittests/AST/SourceLocationTest.cpp +++ b/clang/unittests/AST/SourceLocationTest.cpp @@ -60,6 +60,59 @@ TEST(RangeVerifier, WrongRange) { EXPECT_FALSE(Verifier.match("int i;", varDecl())); } +class WhileParenLocationVerifier : public MatchVerifier { + unsigned ExpectLParenLine = 0, ExpectLParenColumn = 0; + unsigned ExpectRParenLine = 0, ExpectRParenColumn = 0; + +public: + void expectLocations(unsigned LParenLine, unsigned LParenColumn, + unsigned RParenLine, unsigned RParenColumn) { + ExpectLParenLine = LParenLine; + ExpectLParenColumn = LParenColumn; + ExpectRParenLine = RParenLine; + ExpectRParenColumn = RParenColumn; + } + +protected: + void verify(const MatchFinder::MatchResult &Result, + const WhileStmt &Node) override { + SourceLocation LParenLoc = Node.getLParenLoc(); + SourceLocation RParenLoc = Node.getRParenLoc(); + unsigned LParenLine = + Result.SourceManager->getSpellingLineNumber(LParenLoc); + unsigned LParenColumn = + Result.SourceManager->getSpellingColumnNumber(LParenLoc); + unsigned RParenLine = + Result.SourceManager->getSpellingLineNumber(RParenLoc); + unsigned RParenColumn = + Result.SourceManager->getSpellingColumnNumber(RParenLoc); + + if (LParenLine != ExpectLParenLine || LParenColumn != ExpectLParenColumn || + RParenLine != ExpectRParenLine || RParenColumn != ExpectRParenColumn) { + std::string MsgStr; + llvm::raw_string_ostream Msg(MsgStr); + Msg << "Expected LParen Location <" << ExpectLParenLine << ":" + << ExpectLParenColumn << ">, found <"; + LParenLoc.print(Msg, *Result.SourceManager); + Msg << ">\n"; + + Msg << "Expected RParen Location <" << ExpectRParenLine << ":" + << ExpectRParenColumn << ">, found <"; + RParenLoc.print(Msg, *Result.SourceManager); + Msg << ">"; + + this->setFailure(Msg.str()); + } + } +}; + +TEST(LocationVerifier, WhileParenLoc) { + WhileParenLocationVerifier Verifier; + Verifier.expectLocations(1, 17, 1, 38); + EXPECT_TRUE(Verifier.match("void f() { while(true/*some comment*/) {} }", + whileStmt())); +} + class LabelDeclRangeVerifier : public RangeVerifier { protected: SourceRange getRange(const LabelStmt &Node) override { diff --git a/clang/unittests/AST/StructuralEquivalenceTest.cpp b/clang/unittests/AST/StructuralEquivalenceTest.cpp index 08512d6062793..2b5ce0fed51d6 100644 --- a/clang/unittests/AST/StructuralEquivalenceTest.cpp +++ b/clang/unittests/AST/StructuralEquivalenceTest.cpp @@ -759,6 +759,27 @@ TEST_F(StructuralEquivalenceRecordTest, RecordsWithDifferentBody) { EXPECT_FALSE(testStructuralMatch(t)); } +TEST_F(StructuralEquivalenceRecordTest, SameFriendMultipleTimes) { + auto t = makeNamedDecls("struct foo { friend class X; };", + "struct foo { friend class X; friend class X; };", + Lang_CXX11); + EXPECT_FALSE(testStructuralMatch(t)); +} + +TEST_F(StructuralEquivalenceRecordTest, SameFriendsDifferentOrder) { + auto t = makeNamedDecls("struct foo { friend class X; friend class Y; };", + "struct foo { friend class Y; friend class X; };", + Lang_CXX11); + EXPECT_FALSE(testStructuralMatch(t)); +} + +TEST_F(StructuralEquivalenceRecordTest, SameFriendsSameOrder) { + auto t = makeNamedDecls("struct foo { friend class X; friend class Y; };", + "struct foo { friend class X; friend class Y; };", + Lang_CXX11); + EXPECT_TRUE(testStructuralMatch(t)); +} + struct StructuralEquivalenceLambdaTest : StructuralEquivalenceTest {}; TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithDifferentMethods) { diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp index 0070c22164a6b..687908043a8d3 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -103,9 +103,9 @@ TEST(IsExpandedFromMacro, ShouldMatchFromCommandLine) { StringRef input = R"cc( void Test() { FOUR_PLUS_FOUR; } )cc"; - EXPECT_TRUE(matchesConditionally(input, - binaryOperator(isExpandedFromMacro("FOUR_PLUS_FOUR")), - true, {"-std=c++11", "-DFOUR_PLUS_FOUR=4+4"})); + EXPECT_TRUE(matchesConditionally( + input, binaryOperator(isExpandedFromMacro("FOUR_PLUS_FOUR")), true, + {"-std=c++11", "-DFOUR_PLUS_FOUR=4+4"})); } TEST(IsExpandedFromMacro, ShouldNotMatchBeginOnly) { @@ -143,31 +143,31 @@ TEST(IsExpandedFromMacro, ShouldNotMatchDifferentInstances) { } TEST(AllOf, AllOverloadsWork) { - const char Program[] = - "struct T { };" - "int f(int, T*, int, int);" - "void g(int x) { T t; f(x, &t, 3, 4); }"; - EXPECT_TRUE(matches(Program, - callExpr(allOf(callee(functionDecl(hasName("f"))), - hasArgument(0, declRefExpr(to(varDecl()))))))); - EXPECT_TRUE(matches(Program, - callExpr(allOf(callee(functionDecl(hasName("f"))), - hasArgument(0, declRefExpr(to(varDecl()))), - hasArgument(1, hasType(pointsTo( - recordDecl(hasName("T"))))))))); - EXPECT_TRUE(matches(Program, - callExpr(allOf(callee(functionDecl(hasName("f"))), - hasArgument(0, declRefExpr(to(varDecl()))), - hasArgument(1, hasType(pointsTo( - recordDecl(hasName("T"))))), - hasArgument(2, integerLiteral(equals(3))))))); - EXPECT_TRUE(matches(Program, - callExpr(allOf(callee(functionDecl(hasName("f"))), - hasArgument(0, declRefExpr(to(varDecl()))), - hasArgument(1, hasType(pointsTo( - recordDecl(hasName("T"))))), - hasArgument(2, integerLiteral(equals(3))), - hasArgument(3, integerLiteral(equals(4))))))); + const char Program[] = "struct T { };" + "int f(int, T*, int, int);" + "void g(int x) { T t; f(x, &t, 3, 4); }"; + EXPECT_TRUE(matches( + Program, callExpr(allOf(callee(functionDecl(hasName("f"))), + hasArgument(0, declRefExpr(to(varDecl()))))))); + EXPECT_TRUE(matches( + Program, + callExpr( + allOf(callee(functionDecl(hasName("f"))), + hasArgument(0, declRefExpr(to(varDecl()))), + hasArgument(1, hasType(pointsTo(recordDecl(hasName("T"))))))))); + EXPECT_TRUE(matches( + Program, callExpr(allOf( + callee(functionDecl(hasName("f"))), + hasArgument(0, declRefExpr(to(varDecl()))), + hasArgument(1, hasType(pointsTo(recordDecl(hasName("T"))))), + hasArgument(2, integerLiteral(equals(3))))))); + EXPECT_TRUE(matches( + Program, callExpr(allOf( + callee(functionDecl(hasName("f"))), + hasArgument(0, declRefExpr(to(varDecl()))), + hasArgument(1, hasType(pointsTo(recordDecl(hasName("T"))))), + hasArgument(2, integerLiteral(equals(3))), + hasArgument(3, integerLiteral(equals(4))))))); } TEST(DeclarationMatcher, MatchHas) { @@ -176,127 +176,103 @@ TEST(DeclarationMatcher, MatchHas) { EXPECT_TRUE(matches("class X {};", HasClassX)); DeclarationMatcher YHasClassX = - recordDecl(hasName("Y"), has(recordDecl(hasName("X")))); + recordDecl(hasName("Y"), has(recordDecl(hasName("X")))); EXPECT_TRUE(matches("class Y { class X {}; };", YHasClassX)); EXPECT_TRUE(notMatches("class X {};", YHasClassX)); - EXPECT_TRUE( - notMatches("class Y { class Z { class X {}; }; };", YHasClassX)); + EXPECT_TRUE(notMatches("class Y { class Z { class X {}; }; };", YHasClassX)); } TEST(DeclarationMatcher, MatchHasRecursiveAllOf) { DeclarationMatcher Recursive = - recordDecl( - has(recordDecl( - has(recordDecl(hasName("X"))), - has(recordDecl(hasName("Y"))), - hasName("Z"))), - has(recordDecl( - has(recordDecl(hasName("A"))), - has(recordDecl(hasName("B"))), - hasName("C"))), - hasName("F")); - - EXPECT_TRUE(matches( - "class F {" - " class Z {" - " class X {};" - " class Y {};" - " };" - " class C {" - " class A {};" - " class B {};" - " };" - "};", Recursive)); - - EXPECT_TRUE(matches( - "class F {" - " class Z {" - " class A {};" - " class X {};" - " class Y {};" - " };" - " class C {" - " class X {};" - " class A {};" - " class B {};" - " };" - "};", Recursive)); - - EXPECT_TRUE(matches( - "class O1 {" - " class O2 {" - " class F {" - " class Z {" - " class A {};" - " class X {};" - " class Y {};" - " };" - " class C {" - " class X {};" - " class A {};" - " class B {};" - " };" - " };" - " };" - "};", Recursive)); + recordDecl(has(recordDecl(has(recordDecl(hasName("X"))), + has(recordDecl(hasName("Y"))), hasName("Z"))), + has(recordDecl(has(recordDecl(hasName("A"))), + has(recordDecl(hasName("B"))), hasName("C"))), + hasName("F")); + + EXPECT_TRUE(matches("class F {" + " class Z {" + " class X {};" + " class Y {};" + " };" + " class C {" + " class A {};" + " class B {};" + " };" + "};", + Recursive)); + + EXPECT_TRUE(matches("class F {" + " class Z {" + " class A {};" + " class X {};" + " class Y {};" + " };" + " class C {" + " class X {};" + " class A {};" + " class B {};" + " };" + "};", + Recursive)); + + EXPECT_TRUE(matches("class O1 {" + " class O2 {" + " class F {" + " class Z {" + " class A {};" + " class X {};" + " class Y {};" + " };" + " class C {" + " class X {};" + " class A {};" + " class B {};" + " };" + " };" + " };" + "};", + Recursive)); } TEST(DeclarationMatcher, MatchHasRecursiveAnyOf) { - DeclarationMatcher Recursive = - recordDecl( - anyOf( - has(recordDecl( - anyOf( - has(recordDecl( - hasName("X"))), - has(recordDecl( - hasName("Y"))), - hasName("Z")))), - has(recordDecl( - anyOf( - hasName("C"), - has(recordDecl( - hasName("A"))), - has(recordDecl( - hasName("B")))))), - hasName("F"))); + DeclarationMatcher Recursive = recordDecl( + anyOf(has(recordDecl(anyOf(has(recordDecl(hasName("X"))), + has(recordDecl(hasName("Y"))), hasName("Z")))), + has(recordDecl(anyOf(hasName("C"), has(recordDecl(hasName("A"))), + has(recordDecl(hasName("B")))))), + hasName("F"))); EXPECT_TRUE(matches("class F {};", Recursive)); EXPECT_TRUE(matches("class Z {};", Recursive)); EXPECT_TRUE(matches("class C {};", Recursive)); EXPECT_TRUE(matches("class M { class N { class X {}; }; };", Recursive)); EXPECT_TRUE(matches("class M { class N { class B {}; }; };", Recursive)); - EXPECT_TRUE( - matches("class O1 { class O2 {" - " class M { class N { class B {}; }; }; " - "}; };", Recursive)); + EXPECT_TRUE(matches("class O1 { class O2 {" + " class M { class N { class B {}; }; }; " + "}; };", + Recursive)); } TEST(DeclarationMatcher, MatchNot) { DeclarationMatcher NotClassX = - cxxRecordDecl( - isDerivedFrom("Y"), - unless(hasName("X"))); + cxxRecordDecl(isDerivedFrom("Y"), unless(hasName("X"))); EXPECT_TRUE(notMatches("", NotClassX)); EXPECT_TRUE(notMatches("class Y {};", NotClassX)); EXPECT_TRUE(matches("class Y {}; class Z : public Y {};", NotClassX)); EXPECT_TRUE(notMatches("class Y {}; class X : public Y {};", NotClassX)); EXPECT_TRUE( - notMatches("class Y {}; class Z {}; class X : public Y {};", - NotClassX)); + notMatches("class Y {}; class Z {}; class X : public Y {};", NotClassX)); DeclarationMatcher ClassXHasNotClassY = - recordDecl( - hasName("X"), - has(recordDecl(hasName("Z"))), - unless( - has(recordDecl(hasName("Y"))))); + recordDecl(hasName("X"), has(recordDecl(hasName("Z"))), + unless(has(recordDecl(hasName("Y"))))); EXPECT_TRUE(matches("class X { class Z {}; };", ClassXHasNotClassY)); - EXPECT_TRUE(notMatches("class X { class Y {}; class Z {}; };", - ClassXHasNotClassY)); + EXPECT_TRUE( + notMatches("class X { class Y {}; class Z {}; };", ClassXHasNotClassY)); DeclarationMatcher NamedNotRecord = - namedDecl(hasName("Foo"), unless(recordDecl())); + namedDecl(hasName("Foo"), unless(recordDecl())); EXPECT_TRUE(matches("void Foo(){}", NamedNotRecord)); EXPECT_TRUE(notMatches("struct Foo {};", NamedNotRecord)); } @@ -318,67 +294,61 @@ TEST(CastExpression, HasCastKind) { TEST(DeclarationMatcher, HasDescendant) { DeclarationMatcher ZDescendantClassX = - recordDecl( - hasDescendant(recordDecl(hasName("X"))), - hasName("Z")); + recordDecl(hasDescendant(recordDecl(hasName("X"))), hasName("Z")); EXPECT_TRUE(matches("class Z { class X {}; };", ZDescendantClassX)); EXPECT_TRUE( - matches("class Z { class Y { class X {}; }; };", ZDescendantClassX)); + matches("class Z { class Y { class X {}; }; };", ZDescendantClassX)); + EXPECT_TRUE(matches("class Z { class A { class Y { class X {}; }; }; };", + ZDescendantClassX)); EXPECT_TRUE( - matches("class Z { class A { class Y { class X {}; }; }; };", - ZDescendantClassX)); - EXPECT_TRUE( - matches("class Z { class A { class B { class Y { class X {}; }; }; }; };", - ZDescendantClassX)); + matches("class Z { class A { class B { class Y { class X {}; }; }; }; };", + ZDescendantClassX)); EXPECT_TRUE(notMatches("class Z {};", ZDescendantClassX)); - DeclarationMatcher ZDescendantClassXHasClassY = - recordDecl( - hasDescendant(recordDecl(has(recordDecl(hasName("Y"))), - hasName("X"))), + DeclarationMatcher ZDescendantClassXHasClassY = recordDecl( + hasDescendant(recordDecl(has(recordDecl(hasName("Y"))), hasName("X"))), hasName("Z")); EXPECT_TRUE(matches("class Z { class X { class Y {}; }; };", ZDescendantClassXHasClassY)); EXPECT_TRUE( - matches("class Z { class A { class B { class X { class Y {}; }; }; }; };", - ZDescendantClassXHasClassY)); - EXPECT_TRUE(notMatches( - "class Z {" - " class A {" - " class B {" - " class X {" - " class C {" - " class Y {};" - " };" - " };" - " }; " - " };" - "};", ZDescendantClassXHasClassY)); + matches("class Z { class A { class B { class X { class Y {}; }; }; }; };", + ZDescendantClassXHasClassY)); + EXPECT_TRUE(notMatches("class Z {" + " class A {" + " class B {" + " class X {" + " class C {" + " class Y {};" + " };" + " };" + " }; " + " };" + "};", + ZDescendantClassXHasClassY)); DeclarationMatcher ZDescendantClassXDescendantClassY = - recordDecl( - hasDescendant(recordDecl(hasDescendant(recordDecl(hasName("Y"))), - hasName("X"))), - hasName("Z")); - EXPECT_TRUE( - matches("class Z { class A { class X { class B { class Y {}; }; }; }; };", - ZDescendantClassXDescendantClassY)); - EXPECT_TRUE(matches( - "class Z {" - " class A {" - " class X {" - " class B {" - " class Y {};" - " };" - " class Y {};" - " };" - " };" - "};", ZDescendantClassXDescendantClassY)); + recordDecl(hasDescendant(recordDecl( + hasDescendant(recordDecl(hasName("Y"))), hasName("X"))), + hasName("Z")); + EXPECT_TRUE( + matches("class Z { class A { class X { class B { class Y {}; }; }; }; };", + ZDescendantClassXDescendantClassY)); + EXPECT_TRUE(matches("class Z {" + " class A {" + " class X {" + " class B {" + " class Y {};" + " };" + " class Y {};" + " };" + " };" + "};", + ZDescendantClassXDescendantClassY)); } TEST(DeclarationMatcher, HasDescendantMemoization) { DeclarationMatcher CannotMemoize = - decl(hasDescendant(typeLoc().bind("x")), has(decl())); + decl(hasDescendant(typeLoc().bind("x")), has(decl())); EXPECT_TRUE(matches("void f() { int i; }", CannotMemoize)); } @@ -401,39 +371,36 @@ TEST(DeclarationMatcher, HasAncestorMemoization) { // That node can't be memoized so we have to check for it before trying to put // it on the cache. DeclarationMatcher CannotMemoize = classTemplateSpecializationDecl( - hasAnyTemplateArgument(templateArgument().bind("targ")), - forEach(fieldDecl(hasAncestor(forStmt())))); + hasAnyTemplateArgument(templateArgument().bind("targ")), + forEach(fieldDecl(hasAncestor(forStmt())))); EXPECT_TRUE(notMatches("template struct S;" - "template <> struct S{ int i; int j; };", + "template <> struct S{ int i; int j; };", CannotMemoize)); } TEST(DeclarationMatcher, HasAttr) { EXPECT_TRUE(matches("struct __attribute__((warn_unused)) X {};", decl(hasAttr(clang::attr::WarnUnused)))); - EXPECT_FALSE(matches("struct X {};", - decl(hasAttr(clang::attr::WarnUnused)))); + EXPECT_FALSE(matches("struct X {};", decl(hasAttr(clang::attr::WarnUnused)))); } - TEST(DeclarationMatcher, MatchAnyOf) { DeclarationMatcher YOrZDerivedFromX = cxxRecordDecl( - anyOf(hasName("Y"), allOf(isDerivedFrom("X"), hasName("Z")))); + anyOf(hasName("Y"), allOf(isDerivedFrom("X"), hasName("Z")))); EXPECT_TRUE(matches("class X {}; class Z : public X {};", YOrZDerivedFromX)); EXPECT_TRUE(matches("class Y {};", YOrZDerivedFromX)); EXPECT_TRUE( - notMatches("class X {}; class W : public X {};", YOrZDerivedFromX)); + notMatches("class X {}; class W : public X {};", YOrZDerivedFromX)); EXPECT_TRUE(notMatches("class Z {};", YOrZDerivedFromX)); DeclarationMatcher XOrYOrZOrU = - recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U"))); + recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U"))); EXPECT_TRUE(matches("class X {};", XOrYOrZOrU)); EXPECT_TRUE(notMatches("class V {};", XOrYOrZOrU)); - DeclarationMatcher XOrYOrZOrUOrV = - recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U"), - hasName("V"))); + DeclarationMatcher XOrYOrZOrUOrV = recordDecl(anyOf( + hasName("X"), hasName("Y"), hasName("Z"), hasName("U"), hasName("V"))); EXPECT_TRUE(matches("class X {};", XOrYOrZOrUOrV)); EXPECT_TRUE(matches("class Y {};", XOrYOrZOrUOrV)); EXPECT_TRUE(matches("class Z {};", XOrYOrZOrUOrV)); @@ -447,8 +414,8 @@ TEST(DeclarationMatcher, MatchAnyOf) { EXPECT_TRUE(notMatches("int F() { return 1; }", MixedTypes)); EXPECT_TRUE( - matches("void f() try { } catch (int) { } catch (...) { }", - cxxCatchStmt(anyOf(hasDescendant(varDecl()), isCatchAll())))); + matches("void f() try { } catch (int) { } catch (...) { }", + cxxCatchStmt(anyOf(hasDescendant(varDecl()), isCatchAll())))); } TEST(DeclarationMatcher, ClassIsDerived) { @@ -460,19 +427,17 @@ TEST(DeclarationMatcher, ClassIsDerived) { EXPECT_TRUE(notMatches("class Y;", IsDerivedFromX)); EXPECT_TRUE(notMatches("", IsDerivedFromX)); EXPECT_TRUE(matches("class X {}; template class Y : Y, X {};", - IsDerivedFromX)); + IsDerivedFromX)); EXPECT_TRUE(matches("class X {}; template class Y : X, Y {};", - IsDerivedFromX)); + IsDerivedFromX)); - DeclarationMatcher IsZDerivedFromX = cxxRecordDecl(hasName("Z"), - isDerivedFrom("X")); - EXPECT_TRUE( - matches( - "class X {};" - "template class Y : Y {};" - "template<> class Y<0> : X {};" - "class Z : Y<1> {};", - IsZDerivedFromX)); + DeclarationMatcher IsZDerivedFromX = + cxxRecordDecl(hasName("Z"), isDerivedFrom("X")); + EXPECT_TRUE(matches("class X {};" + "template class Y : Y {};" + "template<> class Y<0> : X {};" + "class Z : Y<1> {};", + IsZDerivedFromX)); DeclarationMatcher IsDirectlyDerivedFromX = cxxRecordDecl(isDirectlyDerivedFrom("X")); @@ -493,145 +458,138 @@ TEST(DeclarationMatcher, ClassIsDerived) { EXPECT_TRUE(notMatches("", IsAX)); DeclarationMatcher ZIsDerivedFromX = - cxxRecordDecl(hasName("Z"), isDerivedFrom("X")); + cxxRecordDecl(hasName("Z"), isDerivedFrom("X")); DeclarationMatcher ZIsDirectlyDerivedFromX = cxxRecordDecl(hasName("Z"), isDirectlyDerivedFrom("X")); EXPECT_TRUE( - matches("class X {}; class Y : public X {}; class Z : public Y {};", - ZIsDerivedFromX)); + matches("class X {}; class Y : public X {}; class Z : public Y {};", + ZIsDerivedFromX)); EXPECT_TRUE( notMatches("class X {}; class Y : public X {}; class Z : public Y {};", ZIsDirectlyDerivedFromX)); - EXPECT_TRUE( - matches("class X {};" - "template class Y : public X {};" - "class Z : public Y {};", ZIsDerivedFromX)); + EXPECT_TRUE(matches("class X {};" + "template class Y : public X {};" + "class Z : public Y {};", + ZIsDerivedFromX)); EXPECT_TRUE(notMatches("class X {};" "template class Y : public X {};" "class Z : public Y {};", ZIsDirectlyDerivedFromX)); EXPECT_TRUE(matches("class X {}; template class Z : public X {};", ZIsDerivedFromX)); + EXPECT_TRUE(matches("template class X {}; " + "template class Z : public X {};", + ZIsDerivedFromX)); + EXPECT_TRUE(matches("template class X {}; " + "template class Z : public X {};", + ZIsDerivedFromX)); EXPECT_TRUE( - matches("template class X {}; " - "template class Z : public X {};", - ZIsDerivedFromX)); - EXPECT_TRUE( - matches("template class X {}; " - "template class Z : public X {};", - ZIsDerivedFromX)); - EXPECT_TRUE( - notMatches("template class A { class Z : public X {}; };", - ZIsDerivedFromX)); + notMatches("template class A { class Z : public X {}; };", + ZIsDerivedFromX)); EXPECT_TRUE( - matches("template class A { public: class Z : public X {}; }; " - "class X{}; void y() { A::Z z; }", ZIsDerivedFromX)); + matches("template class A { public: class Z : public X {}; }; " + "class X{}; void y() { A::Z z; }", + ZIsDerivedFromX)); EXPECT_TRUE( - matches("template class X {}; " + matches("template class X {}; " "template class A { class Z : public X {}; };", - ZIsDerivedFromX)); - EXPECT_TRUE( - notMatches("template class X> class A { " - " class Z : public X {}; };", ZIsDerivedFromX)); - EXPECT_TRUE( - matches("template class X> class A { " - " public: class Z : public X {}; }; " - "template class X {}; void y() { A::Z z; }", - ZIsDerivedFromX)); - EXPECT_TRUE( - notMatches("template class A { class Z : public X::D {}; };", - ZIsDerivedFromX)); - EXPECT_TRUE( - matches("template class A { public: " - " class Z : public X::D {}; }; " - "class Y { public: class X {}; typedef X D; }; " - "void y() { A::Z z; }", ZIsDerivedFromX)); - EXPECT_TRUE( - matches("class X {}; typedef X Y; class Z : public Y {};", - ZIsDerivedFromX)); + ZIsDerivedFromX)); + EXPECT_TRUE(notMatches("template class X> class A { " + " class Z : public X {}; };", + ZIsDerivedFromX)); + EXPECT_TRUE(matches("template class X> class A { " + " public: class Z : public X {}; }; " + "template class X {}; void y() { A::Z z; }", + ZIsDerivedFromX)); EXPECT_TRUE( - matches("template class Y { typedef typename T::U X; " - " class Z : public X {}; };", ZIsDerivedFromX)); - EXPECT_TRUE(matches("class X {}; class Z : public ::X {};", + notMatches("template class A { class Z : public X::D {}; };", + ZIsDerivedFromX)); + EXPECT_TRUE(matches("template class A { public: " + " class Z : public X::D {}; }; " + "class Y { public: class X {}; typedef X D; }; " + "void y() { A::Z z; }", + ZIsDerivedFromX)); + EXPECT_TRUE(matches("class X {}; typedef X Y; class Z : public Y {};", ZIsDerivedFromX)); + EXPECT_TRUE(matches("template class Y { typedef typename T::U X; " + " class Z : public X {}; };", + ZIsDerivedFromX)); + EXPECT_TRUE(matches("class X {}; class Z : public ::X {};", ZIsDerivedFromX)); EXPECT_TRUE( - notMatches("template class X {}; " + notMatches("template class X {}; " "template class A { class Z : public X::D {}; };", - ZIsDerivedFromX)); + ZIsDerivedFromX)); EXPECT_TRUE( - matches("template class X { public: typedef X D; }; " + matches("template class X { public: typedef X D; }; " "template class A { public: " " class Z : public X::D {}; }; void y() { A::Z z; }", - ZIsDerivedFromX)); - EXPECT_TRUE( - notMatches("template class A { class Z : public X::D::E {}; };", - ZIsDerivedFromX)); + ZIsDerivedFromX)); EXPECT_TRUE( - matches("class X {}; typedef X V; typedef V W; class Z : public W {};", - ZIsDerivedFromX)); + notMatches("template class A { class Z : public X::D::E {}; };", + ZIsDerivedFromX)); EXPECT_TRUE( - matches("class X {}; class Y : public X {}; " - "typedef Y V; typedef V W; class Z : public W {};", - ZIsDerivedFromX)); + matches("class X {}; typedef X V; typedef V W; class Z : public W {};", + ZIsDerivedFromX)); + EXPECT_TRUE(matches("class X {}; class Y : public X {}; " + "typedef Y V; typedef V W; class Z : public W {};", + ZIsDerivedFromX)); EXPECT_TRUE(notMatches("class X {}; class Y : public X {}; " "typedef Y V; typedef V W; class Z : public W {};", ZIsDirectlyDerivedFromX)); EXPECT_TRUE( - matches("template class X {}; " + matches("template class X {}; " "template class A { class Z : public X {}; };", - ZIsDerivedFromX)); + ZIsDerivedFromX)); EXPECT_TRUE( - notMatches("template class D { typedef X A; typedef A B; " + notMatches("template class D { typedef X A; typedef A B; " " typedef B C; class Z : public C {}; };", - ZIsDerivedFromX)); - EXPECT_TRUE( - matches("class X {}; typedef X A; typedef A B; " - "class Z : public B {};", ZIsDerivedFromX)); - EXPECT_TRUE( - matches("class X {}; typedef X A; typedef A B; typedef B C; " - "class Z : public C {};", ZIsDerivedFromX)); - EXPECT_TRUE( - matches("class U {}; typedef U X; typedef X V; " - "class Z : public V {};", ZIsDerivedFromX)); - EXPECT_TRUE( - matches("class Base {}; typedef Base X; " - "class Z : public Base {};", ZIsDerivedFromX)); - EXPECT_TRUE( - matches("class Base {}; typedef Base Base2; typedef Base2 X; " - "class Z : public Base {};", ZIsDerivedFromX)); - EXPECT_TRUE( - notMatches("class Base {}; class Base2 {}; typedef Base2 X; " - "class Z : public Base {};", ZIsDerivedFromX)); - EXPECT_TRUE( - matches("class A {}; typedef A X; typedef A Y; " - "class Z : public Y {};", ZIsDerivedFromX)); - EXPECT_TRUE( - notMatches("template class Z;" - "template <> class Z {};" - "template class Z : public Z {};", - IsDerivedFromX)); - EXPECT_TRUE( - matches("template class X;" - "template <> class X {};" - "template class X : public X {};", - IsDerivedFromX)); - EXPECT_TRUE(matches( - "class X {};" - "template class Z;" - "template <> class Z {};" - "template class Z : public Z, public X {};", - ZIsDerivedFromX)); - EXPECT_TRUE( - notMatches("template struct X;" + ZIsDerivedFromX)); + EXPECT_TRUE(matches("class X {}; typedef X A; typedef A B; " + "class Z : public B {};", + ZIsDerivedFromX)); + EXPECT_TRUE(matches("class X {}; typedef X A; typedef A B; typedef B C; " + "class Z : public C {};", + ZIsDerivedFromX)); + EXPECT_TRUE(matches("class U {}; typedef U X; typedef X V; " + "class Z : public V {};", + ZIsDerivedFromX)); + EXPECT_TRUE(matches("class Base {}; typedef Base X; " + "class Z : public Base {};", + ZIsDerivedFromX)); + EXPECT_TRUE(matches("class Base {}; typedef Base Base2; typedef Base2 X; " + "class Z : public Base {};", + ZIsDerivedFromX)); + EXPECT_TRUE(notMatches("class Base {}; class Base2 {}; typedef Base2 X; " + "class Z : public Base {};", + ZIsDerivedFromX)); + EXPECT_TRUE(matches("class A {}; typedef A X; typedef A Y; " + "class Z : public Y {};", + ZIsDerivedFromX)); + EXPECT_TRUE(notMatches("template class Z;" + "template <> class Z {};" + "template class Z : public Z {};", + IsDerivedFromX)); + EXPECT_TRUE(matches("template class X;" + "template <> class X {};" + "template class X : public X {};", + IsDerivedFromX)); + EXPECT_TRUE( + matches("class X {};" + "template class Z;" + "template <> class Z {};" + "template class Z : public Z, public X {};", + ZIsDerivedFromX)); + EXPECT_TRUE( + notMatches("template struct X;" "template struct X : public X {};", - cxxRecordDecl(isDerivedFrom(recordDecl(hasName("Some")))))); + cxxRecordDecl(isDerivedFrom(recordDecl(hasName("Some")))))); EXPECT_TRUE(matches( - "struct A {};" + "struct A {};" "template struct X;" "template struct X : public X {};" "template<> struct X<0> : public A {};" "struct B : public X<42> {};", - cxxRecordDecl(hasName("B"), isDerivedFrom(recordDecl(hasName("A")))))); + cxxRecordDecl(hasName("B"), isDerivedFrom(recordDecl(hasName("A")))))); EXPECT_TRUE(notMatches( "struct A {};" "template struct X;" @@ -645,7 +603,7 @@ TEST(DeclarationMatcher, ClassIsDerived) { // get rid of the Variable(...) matching and match the right template // declarations directly. const char *RecursiveTemplateOneParameter = - "class Base1 {}; class Base2 {};" + "class Base1 {}; class Base2 {};" "template class Z;" "template <> class Z : public Base1 {};" "template <> class Z : public Base2 {};" @@ -654,21 +612,21 @@ TEST(DeclarationMatcher, ClassIsDerived) { "template class Z : public Z, public Z {};" "void f() { Z z_float; Z z_double; Z z_char; }"; EXPECT_TRUE(matches( - RecursiveTemplateOneParameter, - varDecl(hasName("z_float"), - hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1"))))))); + RecursiveTemplateOneParameter, + varDecl(hasName("z_float"), + hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1"))))))); EXPECT_TRUE(notMatches( - RecursiveTemplateOneParameter, - varDecl(hasName("z_float"), - hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base2"))))))); - EXPECT_TRUE(matches( - RecursiveTemplateOneParameter, - varDecl(hasName("z_char"), - hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1"), - isDerivedFrom("Base2"))))))); + RecursiveTemplateOneParameter, + varDecl(hasName("z_float"), + hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base2"))))))); + EXPECT_TRUE( + matches(RecursiveTemplateOneParameter, + varDecl(hasName("z_char"), + hasInitializer(hasType(cxxRecordDecl( + isDerivedFrom("Base1"), isDerivedFrom("Base2"))))))); const char *RecursiveTemplateTwoParameters = - "class Base1 {}; class Base2 {};" + "class Base1 {}; class Base2 {};" "template class Z;" "template class Z : public Base1 {};" "template class Z : public Base2 {};" @@ -679,34 +637,31 @@ TEST(DeclarationMatcher, ClassIsDerived) { "void f() { Z z_float; Z z_double; " " Z z_char; }"; EXPECT_TRUE(matches( - RecursiveTemplateTwoParameters, - varDecl(hasName("z_float"), - hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1"))))))); + RecursiveTemplateTwoParameters, + varDecl(hasName("z_float"), + hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1"))))))); EXPECT_TRUE(notMatches( - RecursiveTemplateTwoParameters, - varDecl(hasName("z_float"), - hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base2"))))))); - EXPECT_TRUE(matches( - RecursiveTemplateTwoParameters, - varDecl(hasName("z_char"), - hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1"), - isDerivedFrom("Base2"))))))); - EXPECT_TRUE(matches( - "namespace ns { class X {}; class Y : public X {}; }", - cxxRecordDecl(isDerivedFrom("::ns::X")))); - EXPECT_TRUE(notMatches( - "class X {}; class Y : public X {};", - cxxRecordDecl(isDerivedFrom("::ns::X")))); + RecursiveTemplateTwoParameters, + varDecl(hasName("z_float"), + hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base2"))))))); + EXPECT_TRUE( + matches(RecursiveTemplateTwoParameters, + varDecl(hasName("z_char"), + hasInitializer(hasType(cxxRecordDecl( + isDerivedFrom("Base1"), isDerivedFrom("Base2"))))))); + EXPECT_TRUE(matches("namespace ns { class X {}; class Y : public X {}; }", + cxxRecordDecl(isDerivedFrom("::ns::X")))); + EXPECT_TRUE(notMatches("class X {}; class Y : public X {};", + cxxRecordDecl(isDerivedFrom("::ns::X")))); EXPECT_TRUE(matches( - "class X {}; class Y : public X {};", - cxxRecordDecl(isDerivedFrom(recordDecl(hasName("X")).bind("test"))))); + "class X {}; class Y : public X {};", + cxxRecordDecl(isDerivedFrom(recordDecl(hasName("X")).bind("test"))))); - EXPECT_TRUE(matches( - "template class X {};" - "template using Z = X;" - "template class Y : Z {};", - cxxRecordDecl(isDerivedFrom(namedDecl(hasName("X")))))); + EXPECT_TRUE(matches("template class X {};" + "template using Z = X;" + "template class Y : Z {};", + cxxRecordDecl(isDerivedFrom(namedDecl(hasName("X")))))); } TEST(DeclarationMatcher, IsDerivedFromEmptyName) { @@ -737,24 +692,24 @@ TEST(DeclarationMatcher, ObjCClassIsDerived) { DeclarationMatcher IsDirectlyDerivedFromX = objcInterfaceDecl(isDirectlyDerivedFrom("X")); - EXPECT_TRUE( - matchesObjC("@interface X @end @interface Y : X @end", IsDirectlyDerivedFromX)); + EXPECT_TRUE(matchesObjC("@interface X @end @interface Y : X @end", + IsDirectlyDerivedFromX)); EXPECT_TRUE(matchesObjC( "@interface X @end @interface Y<__covariant ObjectType> : X @end", IsDirectlyDerivedFromX)); EXPECT_TRUE(matchesObjC( "@interface X @end @compatibility_alias Y X; @interface Z : Y @end", IsDirectlyDerivedFromX)); - EXPECT_TRUE(matchesObjC( - "@interface X @end typedef X Y; @interface Z : Y @end", - IsDirectlyDerivedFromX)); + EXPECT_TRUE( + matchesObjC("@interface X @end typedef X Y; @interface Z : Y @end", + IsDirectlyDerivedFromX)); EXPECT_TRUE(notMatchesObjC("@interface X @end", IsDirectlyDerivedFromX)); EXPECT_TRUE(notMatchesObjC("@class X;", IsDirectlyDerivedFromX)); EXPECT_TRUE(notMatchesObjC("@class Y;", IsDirectlyDerivedFromX)); EXPECT_TRUE(notMatchesObjC("@interface X @end @compatibility_alias Y X;", IsDirectlyDerivedFromX)); - EXPECT_TRUE(notMatchesObjC("@interface X @end typedef X Y;", - IsDirectlyDerivedFromX)); + EXPECT_TRUE( + notMatchesObjC("@interface X @end typedef X Y;", IsDirectlyDerivedFromX)); DeclarationMatcher IsAX = objcInterfaceDecl(isSameOrDerivedFrom("X")); EXPECT_TRUE(matchesObjC("@interface X @end @interface Y : X @end", IsAX)); @@ -775,9 +730,9 @@ TEST(DeclarationMatcher, ObjCClassIsDerived) { ZIsDerivedFromX)); EXPECT_TRUE(matchesObjC( "@interface X @end typedef X Y; @interface Z : Y @end", ZIsDerivedFromX)); - EXPECT_TRUE(matchesObjC( - "@interface X @end typedef X Y; @interface Z : Y @end", - ZIsDirectlyDerivedFromX)); + EXPECT_TRUE( + matchesObjC("@interface X @end typedef X Y; @interface Z : Y @end", + ZIsDirectlyDerivedFromX)); EXPECT_TRUE(matchesObjC( "@interface A @end typedef A X; typedef A Y; @interface Z : Y @end", ZIsDerivedFromX)); @@ -798,27 +753,33 @@ TEST(DeclarationMatcher, ObjCClassIsDerived) { ZIsDirectlyDerivedFromX)); EXPECT_TRUE(matchesObjC( "@interface A @end @compatibility_alias X A; @compatibility_alias Y A;" - "@interface Z : Y @end", ZIsDerivedFromX)); + "@interface Z : Y @end", + ZIsDerivedFromX)); EXPECT_TRUE(matchesObjC( "@interface A @end @compatibility_alias X A; @compatibility_alias Y A;" - "@interface Z : Y @end", ZIsDirectlyDerivedFromX)); - EXPECT_TRUE(matchesObjC( - "@interface Y @end typedef Y X; @interface Z : X @end", ZIsDerivedFromX)); - EXPECT_TRUE(matchesObjC( - "@interface Y @end typedef Y X; @interface Z : X @end", + "@interface Z : Y @end", ZIsDirectlyDerivedFromX)); EXPECT_TRUE(matchesObjC( - "@interface A @end @compatibility_alias Y A; typedef Y X;" - "@interface Z : A @end", ZIsDerivedFromX)); - EXPECT_TRUE(matchesObjC( - "@interface A @end @compatibility_alias Y A; typedef Y X;" - "@interface Z : A @end", ZIsDirectlyDerivedFromX)); - EXPECT_TRUE(matchesObjC( - "@interface A @end typedef A Y; @compatibility_alias X Y;" - "@interface Z : A @end", ZIsDerivedFromX)); - EXPECT_TRUE(matchesObjC( - "@interface A @end typedef A Y; @compatibility_alias X Y;" - "@interface Z : A @end", ZIsDirectlyDerivedFromX)); + "@interface Y @end typedef Y X; @interface Z : X @end", ZIsDerivedFromX)); + EXPECT_TRUE( + matchesObjC("@interface Y @end typedef Y X; @interface Z : X @end", + ZIsDirectlyDerivedFromX)); + EXPECT_TRUE( + matchesObjC("@interface A @end @compatibility_alias Y A; typedef Y X;" + "@interface Z : A @end", + ZIsDerivedFromX)); + EXPECT_TRUE( + matchesObjC("@interface A @end @compatibility_alias Y A; typedef Y X;" + "@interface Z : A @end", + ZIsDirectlyDerivedFromX)); + EXPECT_TRUE( + matchesObjC("@interface A @end typedef A Y; @compatibility_alias X Y;" + "@interface Z : A @end", + ZIsDerivedFromX)); + EXPECT_TRUE( + matchesObjC("@interface A @end typedef A Y; @compatibility_alias X Y;" + "@interface Z : A @end", + ZIsDirectlyDerivedFromX)); } TEST(DeclarationMatcher, IsLambda) { @@ -830,42 +791,41 @@ TEST(DeclarationMatcher, IsLambda) { TEST(Matcher, BindMatchedNodes) { DeclarationMatcher ClassX = has(recordDecl(hasName("::X")).bind("x")); - EXPECT_TRUE(matchAndVerifyResultTrue("class X {};", - ClassX, std::make_unique>("x"))); + EXPECT_TRUE(matchAndVerifyResultTrue( + "class X {};", ClassX, + std::make_unique>("x"))); - EXPECT_TRUE(matchAndVerifyResultFalse("class X {};", - ClassX, std::make_unique>("other-id"))); + EXPECT_TRUE(matchAndVerifyResultFalse( + "class X {};", ClassX, + std::make_unique>("other-id"))); TypeMatcher TypeAHasClassB = hasDeclaration( - recordDecl(hasName("A"), has(recordDecl(hasName("B")).bind("b")))); + recordDecl(hasName("A"), has(recordDecl(hasName("B")).bind("b")))); - EXPECT_TRUE(matchAndVerifyResultTrue("class A { public: A *a; class B {}; };", - TypeAHasClassB, - std::make_unique>("b"))); + EXPECT_TRUE(matchAndVerifyResultTrue( + "class A { public: A *a; class B {}; };", TypeAHasClassB, + std::make_unique>("b"))); StatementMatcher MethodX = - callExpr(callee(cxxMethodDecl(hasName("x")))).bind("x"); + callExpr(callee(cxxMethodDecl(hasName("x")))).bind("x"); - EXPECT_TRUE(matchAndVerifyResultTrue("class A { void x() { x(); } };", - MethodX, - std::make_unique>("x"))); + EXPECT_TRUE(matchAndVerifyResultTrue( + "class A { void x() { x(); } };", MethodX, + std::make_unique>("x"))); } TEST(Matcher, BindTheSameNameInAlternatives) { StatementMatcher matcher = anyOf( - binaryOperator(hasOperatorName("+"), - hasLHS(expr().bind("x")), - hasRHS(integerLiteral(equals(0)))), - binaryOperator(hasOperatorName("+"), - hasLHS(integerLiteral(equals(0))), - hasRHS(expr().bind("x")))); + binaryOperator(hasOperatorName("+"), hasLHS(expr().bind("x")), + hasRHS(integerLiteral(equals(0)))), + binaryOperator(hasOperatorName("+"), hasLHS(integerLiteral(equals(0))), + hasRHS(expr().bind("x")))); EXPECT_TRUE(matchAndVerifyResultTrue( - // The first branch of the matcher binds x to 0 but then fails. - // The second branch binds x to f() and succeeds. - "int f() { return 0 + f(); }", - matcher, - std::make_unique>("x"))); + // The first branch of the matcher binds x to 0 but then fails. + // The second branch binds x to f() and succeeds. + "int f() { return 0 + f(); }", matcher, + std::make_unique>("x"))); } TEST(Matcher, BindsIDForMemoizedResults) { @@ -873,48 +833,48 @@ TEST(Matcher, BindsIDForMemoizedResults) { // kick in. DeclarationMatcher ClassX = recordDecl(hasName("X")).bind("x"); EXPECT_TRUE(matchAndVerifyResultTrue( - "class A { class B { class X {}; }; };", - DeclarationMatcher(anyOf( - recordDecl(hasName("A"), hasDescendant(ClassX)), - recordDecl(hasName("B"), hasDescendant(ClassX)))), - std::make_unique>("x", 2))); + "class A { class B { class X {}; }; };", + DeclarationMatcher( + anyOf(recordDecl(hasName("A"), hasDescendant(ClassX)), + recordDecl(hasName("B"), hasDescendant(ClassX)))), + std::make_unique>("x", 2))); } TEST(HasType, MatchesAsString) { EXPECT_TRUE( - matches("class Y { public: void x(); }; void z() {Y* y; y->x(); }", - cxxMemberCallExpr(on(hasType(asString("class Y *")))))); + matches("class Y { public: void x(); }; void z() {Y* y; y->x(); }", + cxxMemberCallExpr(on(hasType(asString("class Y *")))))); EXPECT_TRUE( - matches("class X { void x(int x) {} };", - cxxMethodDecl(hasParameter(0, hasType(asString("int")))))); + matches("class X { void x(int x) {} };", + cxxMethodDecl(hasParameter(0, hasType(asString("int")))))); EXPECT_TRUE(matches("namespace ns { struct A {}; } struct B { ns::A a; };", fieldDecl(hasType(asString("ns::A"))))); - EXPECT_TRUE(matches("namespace { struct A {}; } struct B { A a; };", - fieldDecl(hasType(asString("struct (anonymous namespace)::A"))))); + EXPECT_TRUE( + matches("namespace { struct A {}; } struct B { A a; };", + fieldDecl(hasType(asString("struct (anonymous namespace)::A"))))); } TEST(Matcher, HasOperatorNameForOverloadedOperatorCall) { StatementMatcher OpCallAndAnd = - cxxOperatorCallExpr(hasOverloadedOperatorName("&&")); + cxxOperatorCallExpr(hasOverloadedOperatorName("&&")); EXPECT_TRUE(matches("class Y { }; " - "bool operator&&(Y x, Y y) { return true; }; " - "Y a; Y b; bool c = a && b;", OpCallAndAnd)); + "bool operator&&(Y x, Y y) { return true; }; " + "Y a; Y b; bool c = a && b;", + OpCallAndAnd)); StatementMatcher OpCallLessLess = - cxxOperatorCallExpr(hasOverloadedOperatorName("<<")); + cxxOperatorCallExpr(hasOverloadedOperatorName("<<")); EXPECT_TRUE(notMatches("class Y { }; " - "bool operator&&(Y x, Y y) { return true; }; " - "Y a; Y b; bool c = a && b;", + "bool operator&&(Y x, Y y) { return true; }; " + "Y a; Y b; bool c = a && b;", OpCallLessLess)); StatementMatcher OpStarCall = - cxxOperatorCallExpr(hasOverloadedOperatorName("*")); - EXPECT_TRUE(matches("class Y; int operator*(Y &); void f(Y &y) { *y; }", - OpStarCall)); + cxxOperatorCallExpr(hasOverloadedOperatorName("*")); + EXPECT_TRUE( + matches("class Y; int operator*(Y &); void f(Y &y) { *y; }", OpStarCall)); DeclarationMatcher ClassWithOpStar = - cxxRecordDecl(hasMethod(hasOverloadedOperatorName("*"))); - EXPECT_TRUE(matches("class Y { int operator*(); };", - ClassWithOpStar)); - EXPECT_TRUE(notMatches("class Y { void myOperator(); };", - ClassWithOpStar)) ; + cxxRecordDecl(hasMethod(hasOverloadedOperatorName("*"))); + EXPECT_TRUE(matches("class Y { int operator*(); };", ClassWithOpStar)); + EXPECT_TRUE(notMatches("class Y { void myOperator(); };", ClassWithOpStar)); DeclarationMatcher AnyOpStar = functionDecl(hasOverloadedOperatorName("*")); EXPECT_TRUE(matches("class Y; int operator*(Y &);", AnyOpStar)); EXPECT_TRUE(matches("class Y { int operator*(); };", AnyOpStar)); @@ -926,23 +886,22 @@ TEST(Matcher, HasOperatorNameForOverloadedOperatorCall) { EXPECT_TRUE(matches("class Y { Y operator&&(Y &); };", AnyAndOp)); } - TEST(Matcher, NestedOverloadedOperatorCalls) { EXPECT_TRUE(matchAndVerifyResultTrue( - "class Y { }; " + "class Y { }; " "Y& operator&&(Y& x, Y& y) { return x; }; " "Y a; Y b; Y c; Y d = a && b && c;", - cxxOperatorCallExpr(hasOverloadedOperatorName("&&")).bind("x"), - std::make_unique>("x", 2))); + cxxOperatorCallExpr(hasOverloadedOperatorName("&&")).bind("x"), + std::make_unique>("x", 2))); EXPECT_TRUE(matches("class Y { }; " - "Y& operator&&(Y& x, Y& y) { return x; }; " - "Y a; Y b; Y c; Y d = a && b && c;", + "Y& operator&&(Y& x, Y& y) { return x; }; " + "Y a; Y b; Y c; Y d = a && b && c;", cxxOperatorCallExpr(hasParent(cxxOperatorCallExpr())))); EXPECT_TRUE( - matches("class Y { }; " + matches("class Y { }; " "Y& operator&&(Y& x, Y& y) { return x; }; " "Y a; Y b; Y c; Y d = a && b && c;", - cxxOperatorCallExpr(hasDescendant(cxxOperatorCallExpr())))); + cxxOperatorCallExpr(hasDescendant(cxxOperatorCallExpr())))); } TEST(Matcher, VarDecl_Storage) { @@ -971,9 +930,9 @@ TEST(Matcher, VarDecl_StorageDuration) { EXPECT_TRUE(matches(T, varDecl(hasName("x"), hasAutomaticStorageDuration()))); EXPECT_TRUE( - notMatches(T, varDecl(hasName("y"), hasAutomaticStorageDuration()))); + notMatches(T, varDecl(hasName("y"), hasAutomaticStorageDuration()))); EXPECT_TRUE( - notMatches(T, varDecl(hasName("a"), hasAutomaticStorageDuration()))); + notMatches(T, varDecl(hasName("a"), hasAutomaticStorageDuration()))); EXPECT_TRUE(matches(T, varDecl(hasName("y"), hasStaticStorageDuration()))); EXPECT_TRUE(matches(T, varDecl(hasName("a"), hasStaticStorageDuration()))); @@ -991,48 +950,48 @@ TEST(Matcher, VarDecl_StorageDuration) { } TEST(Matcher, FindsVarDeclInFunctionParameter) { - EXPECT_TRUE(matches( - "void f(int i) {}", - varDecl(hasName("i")))); + EXPECT_TRUE(matches("void f(int i) {}", varDecl(hasName("i")))); } TEST(UnaryExpressionOrTypeTraitExpression, MatchesCorrectType) { - EXPECT_TRUE(matches("void x() { int a = sizeof(a); }", sizeOfExpr( - hasArgumentOfType(asString("int"))))); - EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr( - hasArgumentOfType(asString("float"))))); + EXPECT_TRUE(matches("void x() { int a = sizeof(a); }", + sizeOfExpr(hasArgumentOfType(asString("int"))))); + EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", + sizeOfExpr(hasArgumentOfType(asString("float"))))); EXPECT_TRUE(matches( - "struct A {}; void x() { A a; int b = sizeof(a); }", - sizeOfExpr(hasArgumentOfType(hasDeclaration(recordDecl(hasName("A"))))))); - EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr( - hasArgumentOfType(hasDeclaration(recordDecl(hasName("string"))))))); + "struct A {}; void x() { A a; int b = sizeof(a); }", + sizeOfExpr(hasArgumentOfType(hasDeclaration(recordDecl(hasName("A"))))))); + EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", + sizeOfExpr(hasArgumentOfType( + hasDeclaration(recordDecl(hasName("string"))))))); } TEST(IsInteger, MatchesIntegers) { EXPECT_TRUE(matches("int i = 0;", varDecl(hasType(isInteger())))); - EXPECT_TRUE(matches( - "long long i = 0; void f(long long) { }; void g() {f(i);}", - callExpr(hasArgument(0, declRefExpr( - to(varDecl(hasType(isInteger())))))))); + EXPECT_TRUE( + matches("long long i = 0; void f(long long) { }; void g() {f(i);}", + callExpr(hasArgument( + 0, declRefExpr(to(varDecl(hasType(isInteger())))))))); } TEST(IsInteger, ReportsNoFalsePositives) { EXPECT_TRUE(notMatches("int *i;", varDecl(hasType(isInteger())))); - EXPECT_TRUE(notMatches("struct T {}; T t; void f(T *) { }; void g() {f(&t);}", - callExpr(hasArgument(0, declRefExpr( - to(varDecl(hasType(isInteger())))))))); + EXPECT_TRUE( + notMatches("struct T {}; T t; void f(T *) { }; void g() {f(&t);}", + callExpr(hasArgument( + 0, declRefExpr(to(varDecl(hasType(isInteger())))))))); } TEST(IsSignedInteger, MatchesSignedIntegers) { EXPECT_TRUE(matches("int i = 0;", varDecl(hasType(isSignedInteger())))); - EXPECT_TRUE(notMatches("unsigned i = 0;", - varDecl(hasType(isSignedInteger())))); + EXPECT_TRUE( + notMatches("unsigned i = 0;", varDecl(hasType(isSignedInteger())))); } TEST(IsUnsignedInteger, MatchesUnsignedIntegers) { EXPECT_TRUE(notMatches("int i = 0;", varDecl(hasType(isUnsignedInteger())))); - EXPECT_TRUE(matches("unsigned i = 0;", - varDecl(hasType(isUnsignedInteger())))); + EXPECT_TRUE( + matches("unsigned i = 0;", varDecl(hasType(isUnsignedInteger())))); } TEST(IsAnyPointer, MatchesPointers) { @@ -1059,8 +1018,8 @@ TEST(IsAnyCharacter, ReportsNoFalsePositives) { TEST(IsArrow, MatchesMemberVariablesViaArrow) { EXPECT_TRUE(matches("class Y { void x() { this->y; } int y; };", memberExpr(isArrow()))); - EXPECT_TRUE(matches("class Y { void x() { y; } int y; };", - memberExpr(isArrow()))); + EXPECT_TRUE( + matches("class Y { void x() { y; } int y; };", memberExpr(isArrow()))); EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } int y; };", memberExpr(isArrow()))); EXPECT_TRUE(matches("template class Y { void x() { this->m; } };", @@ -1080,10 +1039,9 @@ TEST(IsArrow, MatchesStaticMemberVariablesViaArrow) { } TEST(IsArrow, MatchesMemberCallsViaArrow) { - EXPECT_TRUE(matches("class Y { void x() { this->x(); } };", - memberExpr(isArrow()))); - EXPECT_TRUE(matches("class Y { void x() { x(); } };", - memberExpr(isArrow()))); + EXPECT_TRUE( + matches("class Y { void x() { this->x(); } };", memberExpr(isArrow()))); + EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpr(isArrow()))); EXPECT_TRUE(notMatches("class Y { void x() { Y y; y.x(); } };", memberExpr(isArrow()))); EXPECT_TRUE( @@ -1128,20 +1086,18 @@ TEST(Matcher, ParameterCount) { } TEST(Matcher, References) { - DeclarationMatcher ReferenceClassX = varDecl( - hasType(references(recordDecl(hasName("X"))))); - EXPECT_TRUE(matches("class X {}; void y(X y) { X &x = y; }", - ReferenceClassX)); + DeclarationMatcher ReferenceClassX = + varDecl(hasType(references(recordDecl(hasName("X"))))); EXPECT_TRUE( - matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX)); + matches("class X {}; void y(X y) { X &x = y; }", ReferenceClassX)); + EXPECT_TRUE( + matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX)); // The match here is on the implicit copy constructor code for // class X, not on code 'X x = y'. + EXPECT_TRUE(matches("class X {}; void y(X y) { X x = y; }", ReferenceClassX)); + EXPECT_TRUE(notMatches("class X {}; extern X x;", ReferenceClassX)); EXPECT_TRUE( - matches("class X {}; void y(X y) { X x = y; }", ReferenceClassX)); - EXPECT_TRUE( - notMatches("class X {}; extern X x;", ReferenceClassX)); - EXPECT_TRUE( - notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX)); + notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX)); } TEST(QualType, hasLocalQualifiers) { @@ -1149,16 +1105,15 @@ TEST(QualType, hasLocalQualifiers) { varDecl(hasType(hasLocalQualifiers())))); EXPECT_TRUE(matches("int *const j = nullptr;", varDecl(hasType(hasLocalQualifiers())))); - EXPECT_TRUE(matches("int *volatile k;", - varDecl(hasType(hasLocalQualifiers())))); - EXPECT_TRUE(notMatches("int m;", - varDecl(hasType(hasLocalQualifiers())))); + EXPECT_TRUE( + matches("int *volatile k;", varDecl(hasType(hasLocalQualifiers())))); + EXPECT_TRUE(notMatches("int m;", varDecl(hasType(hasLocalQualifiers())))); } TEST(IsExternC, MatchesExternCFunctionDeclarations) { EXPECT_TRUE(matches("extern \"C\" void f() {}", functionDecl(isExternC()))); - EXPECT_TRUE(matches("extern \"C\" { void f() {} }", - functionDecl(isExternC()))); + EXPECT_TRUE( + matches("extern \"C\" { void f() {} }", functionDecl(isExternC()))); EXPECT_TRUE(notMatches("void f() {}", functionDecl(isExternC()))); } @@ -1186,7 +1141,7 @@ TEST(IsDefaulted, MatchesDefaultedFunctionDeclarations) { TEST(IsDeleted, MatchesDeletedFunctionDeclarations) { EXPECT_TRUE( - notMatches("void Func();", functionDecl(hasName("Func"), isDeleted()))); + notMatches("void Func();", functionDecl(hasName("Func"), isDeleted()))); EXPECT_TRUE(matches("void Func() = delete;", functionDecl(hasName("Func"), isDeleted()))); } @@ -1195,14 +1150,15 @@ TEST(IsNoThrow, MatchesNoThrowFunctionDeclarations) { EXPECT_TRUE(notMatches("void f();", functionDecl(isNoThrow()))); EXPECT_TRUE(notMatches("void f() throw(int);", functionDecl(isNoThrow()))); EXPECT_TRUE( - notMatches("void f() noexcept(false);", functionDecl(isNoThrow()))); + notMatches("void f() noexcept(false);", functionDecl(isNoThrow()))); EXPECT_TRUE(matches("void f() throw();", functionDecl(isNoThrow()))); EXPECT_TRUE(matches("void f() noexcept;", functionDecl(isNoThrow()))); EXPECT_TRUE(notMatches("void f();", functionProtoType(isNoThrow()))); - EXPECT_TRUE(notMatches("void f() throw(int);", functionProtoType(isNoThrow()))); EXPECT_TRUE( - notMatches("void f() noexcept(false);", functionProtoType(isNoThrow()))); + notMatches("void f() throw(int);", functionProtoType(isNoThrow()))); + EXPECT_TRUE( + notMatches("void f() noexcept(false);", functionProtoType(isNoThrow()))); EXPECT_TRUE(matches("void f() throw();", functionProtoType(isNoThrow()))); EXPECT_TRUE(matches("void f() noexcept;", functionProtoType(isNoThrow()))); } @@ -1249,41 +1205,41 @@ TEST(hasInitStatement, MatchesRangeForInitializers) { TEST(TemplateArgumentCountIs, Matches) { EXPECT_TRUE( - matches("template struct C {}; C c;", - classTemplateSpecializationDecl(templateArgumentCountIs(1)))); + matches("template struct C {}; C c;", + classTemplateSpecializationDecl(templateArgumentCountIs(1)))); EXPECT_TRUE( - notMatches("template struct C {}; C c;", - classTemplateSpecializationDecl(templateArgumentCountIs(2)))); + notMatches("template struct C {}; C c;", + classTemplateSpecializationDecl(templateArgumentCountIs(2)))); EXPECT_TRUE(matches("template struct C {}; C c;", templateSpecializationType(templateArgumentCountIs(1)))); EXPECT_TRUE( - notMatches("template struct C {}; C c;", - templateSpecializationType(templateArgumentCountIs(2)))); + notMatches("template struct C {}; C c;", + templateSpecializationType(templateArgumentCountIs(2)))); } TEST(IsIntegral, Matches) { - EXPECT_TRUE(matches("template struct C {}; C<42> c;", - classTemplateSpecializationDecl( - hasAnyTemplateArgument(isIntegral())))); + EXPECT_TRUE(matches( + "template struct C {}; C<42> c;", + classTemplateSpecializationDecl(hasAnyTemplateArgument(isIntegral())))); EXPECT_TRUE(notMatches("template struct C {}; C c;", classTemplateSpecializationDecl(hasAnyTemplateArgument( - templateArgument(isIntegral()))))); + templateArgument(isIntegral()))))); } TEST(EqualsIntegralValue, Matches) { EXPECT_TRUE(matches("template struct C {}; C<42> c;", classTemplateSpecializationDecl( - hasAnyTemplateArgument(equalsIntegralValue("42"))))); + hasAnyTemplateArgument(equalsIntegralValue("42"))))); EXPECT_TRUE(matches("template struct C {}; C<-42> c;", classTemplateSpecializationDecl( - hasAnyTemplateArgument(equalsIntegralValue("-42"))))); + hasAnyTemplateArgument(equalsIntegralValue("-42"))))); EXPECT_TRUE(matches("template struct C {}; C<-0042> c;", classTemplateSpecializationDecl( - hasAnyTemplateArgument(equalsIntegralValue("-34"))))); + hasAnyTemplateArgument(equalsIntegralValue("-34"))))); EXPECT_TRUE(notMatches("template struct C {}; C<42> c;", classTemplateSpecializationDecl(hasAnyTemplateArgument( - equalsIntegralValue("0042"))))); + equalsIntegralValue("0042"))))); } TEST(Matcher, MatchesAccessSpecDecls) { @@ -1304,7 +1260,7 @@ TEST(Matcher, MatchesFinal) { cxxMethodDecl(isFinal()))); EXPECT_TRUE(notMatches("class X {};", cxxRecordDecl(isFinal()))); EXPECT_TRUE( - notMatches("class X { virtual void f(); };", cxxMethodDecl(isFinal()))); + notMatches("class X { virtual void f(); };", cxxMethodDecl(isFinal()))); } TEST(Matcher, MatchesVirtualMethod) { @@ -1315,12 +1271,12 @@ TEST(Matcher, MatchesVirtualMethod) { TEST(Matcher, MatchesVirtualAsWrittenMethod) { EXPECT_TRUE(matches("class A { virtual int f(); };" - "class B : public A { int f(); };", + "class B : public A { int f(); };", cxxMethodDecl(isVirtualAsWritten(), hasName("::A::f")))); EXPECT_TRUE( - notMatches("class A { virtual int f(); };" + notMatches("class A { virtual int f(); };" "class B : public A { int f(); };", - cxxMethodDecl(isVirtualAsWritten(), hasName("::B::f")))); + cxxMethodDecl(isVirtualAsWritten(), hasName("::B::f")))); } TEST(Matcher, MatchesPureMethod) { @@ -1358,26 +1314,26 @@ TEST(Matcher, MatchesMoveAssignmentOperator) { TEST(Matcher, MatchesConstMethod) { EXPECT_TRUE( - matches("struct A { void foo() const; };", cxxMethodDecl(isConst()))); + matches("struct A { void foo() const; };", cxxMethodDecl(isConst()))); EXPECT_TRUE( - notMatches("struct A { void foo(); };", cxxMethodDecl(isConst()))); + notMatches("struct A { void foo(); };", cxxMethodDecl(isConst()))); } TEST(Matcher, MatchesOverridingMethod) { EXPECT_TRUE(matches("class X { virtual int f(); }; " - "class Y : public X { int f(); };", + "class Y : public X { int f(); };", cxxMethodDecl(isOverride(), hasName("::Y::f")))); EXPECT_TRUE(notMatches("class X { virtual int f(); }; " - "class Y : public X { int f(); };", + "class Y : public X { int f(); };", cxxMethodDecl(isOverride(), hasName("::X::f")))); EXPECT_TRUE(notMatches("class X { int f(); }; " - "class Y : public X { int f(); };", + "class Y : public X { int f(); };", cxxMethodDecl(isOverride()))); EXPECT_TRUE(notMatches("class X { int f(); int f(int); }; ", cxxMethodDecl(isOverride()))); EXPECT_TRUE( - matches("template struct Y : Base { void f() override;};", - cxxMethodDecl(isOverride(), hasName("::Y::f")))); + matches("template struct Y : Base { void f() override;};", + cxxMethodDecl(isOverride(), hasName("::Y::f")))); } TEST(Matcher, ConstructorArgument) { @@ -1385,44 +1341,38 @@ TEST(Matcher, ConstructorArgument) { ast_type_traits::TK_AsIs, cxxConstructExpr(hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))))); + EXPECT_TRUE(matches( + "class X { public: X(int); }; void x() { int y; X x(y); }", Constructor)); EXPECT_TRUE( - matches("class X { public: X(int); }; void x() { int y; X x(y); }", - Constructor)); - EXPECT_TRUE( - matches("class X { public: X(int); }; void x() { int y; X x = X(y); }", - Constructor)); - EXPECT_TRUE( - matches("class X { public: X(int); }; void x() { int y; X x = y; }", - Constructor)); + matches("class X { public: X(int); }; void x() { int y; X x = X(y); }", + Constructor)); EXPECT_TRUE( - notMatches("class X { public: X(int); }; void x() { int z; X x(z); }", - Constructor)); + matches("class X { public: X(int); }; void x() { int y; X x = y; }", + Constructor)); + EXPECT_TRUE(notMatches( + "class X { public: X(int); }; void x() { int z; X x(z); }", Constructor)); StatementMatcher WrongIndex = traverse(ast_type_traits::TK_AsIs, cxxConstructExpr( hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))))); - EXPECT_TRUE( - notMatches("class X { public: X(int); }; void x() { int y; X x(y); }", - WrongIndex)); + EXPECT_TRUE(notMatches( + "class X { public: X(int); }; void x() { int y; X x(y); }", WrongIndex)); } TEST(Matcher, ConstructorArgumentCount) { auto Constructor1Arg = traverse(ast_type_traits::TK_AsIs, cxxConstructExpr(argumentCountIs(1))); + EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x(0); }", + Constructor1Arg)); + EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x = X(0); }", + Constructor1Arg)); + EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x = 0; }", + Constructor1Arg)); EXPECT_TRUE( - matches("class X { public: X(int); }; void x() { X x(0); }", - Constructor1Arg)); - EXPECT_TRUE( - matches("class X { public: X(int); }; void x() { X x = X(0); }", - Constructor1Arg)); - EXPECT_TRUE( - matches("class X { public: X(int); }; void x() { X x = 0; }", - Constructor1Arg)); - EXPECT_TRUE( - notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }", - Constructor1Arg)); + notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }", + Constructor1Arg)); } TEST(Matcher, ConstructorListInitialization) { @@ -1430,19 +1380,16 @@ TEST(Matcher, ConstructorListInitialization) { traverse(ast_type_traits::TK_AsIs, varDecl(has(cxxConstructExpr(isListInitialization())))); - EXPECT_TRUE( - matches("class X { public: X(int); }; void x() { X x{0}; }", - ConstructorListInit)); - EXPECT_FALSE( - matches("class X { public: X(int); }; void x() { X x(0); }", - ConstructorListInit)); + EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x{0}; }", + ConstructorListInit)); + EXPECT_FALSE(matches("class X { public: X(int); }; void x() { X x(0); }", + ConstructorListInit)); } TEST(ConstructorDeclaration, IsImplicit) { // This one doesn't match because the constructor is not added by the // compiler (it is not needed). - EXPECT_TRUE(notMatches("class Foo { };", - cxxConstructorDecl(isImplicit()))); + EXPECT_TRUE(notMatches("class Foo { };", cxxConstructorDecl(isImplicit()))); // The compiler added the implicit default constructor. EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();", cxxConstructorDecl(isImplicit()))); @@ -1456,8 +1403,8 @@ TEST(ConstructorDeclaration, IsImplicit) { TEST(ConstructorDeclaration, IsExplicit) { EXPECT_TRUE(matches("struct S { explicit S(int); };", cxxConstructorDecl(isExplicit()))); - EXPECT_TRUE(notMatches("struct S { S(int); };", - cxxConstructorDecl(isExplicit()))); + EXPECT_TRUE( + notMatches("struct S { S(int); };", cxxConstructorDecl(isExplicit()))); EXPECT_TRUE(notMatches("template struct S { explicit(b) S(int);};", cxxConstructorDecl(isExplicit()), langCxx20OrLater())); EXPECT_TRUE(matches("struct S { explicit(true) S(int);};", @@ -1488,9 +1435,9 @@ TEST(DeductionGuideDeclaration, IsExplicit) { } TEST(ConstructorDeclaration, Kinds) { - EXPECT_TRUE(matches( - "struct S { S(); };", - cxxConstructorDecl(isDefaultConstructor(), unless(isImplicit())))); + EXPECT_TRUE( + matches("struct S { S(); };", cxxConstructorDecl(isDefaultConstructor(), + unless(isImplicit())))); EXPECT_TRUE(notMatches( "struct S { S(); };", cxxConstructorDecl(isCopyConstructor(), unless(isImplicit())))); @@ -1501,9 +1448,9 @@ TEST(ConstructorDeclaration, Kinds) { EXPECT_TRUE(notMatches( "struct S { S(const S&); };", cxxConstructorDecl(isDefaultConstructor(), unless(isImplicit())))); - EXPECT_TRUE(matches( - "struct S { S(const S&); };", - cxxConstructorDecl(isCopyConstructor(), unless(isImplicit())))); + EXPECT_TRUE( + matches("struct S { S(const S&); };", + cxxConstructorDecl(isCopyConstructor(), unless(isImplicit())))); EXPECT_TRUE(notMatches( "struct S { S(const S&); };", cxxConstructorDecl(isMoveConstructor(), unless(isImplicit())))); @@ -1514,9 +1461,9 @@ TEST(ConstructorDeclaration, Kinds) { EXPECT_TRUE(notMatches( "struct S { S(S&&); };", cxxConstructorDecl(isCopyConstructor(), unless(isImplicit())))); - EXPECT_TRUE(matches( - "struct S { S(S&&); };", - cxxConstructorDecl(isMoveConstructor(), unless(isImplicit())))); + EXPECT_TRUE( + matches("struct S { S(S&&); };", + cxxConstructorDecl(isMoveConstructor(), unless(isImplicit())))); } TEST(ConstructorDeclaration, IsUserProvided) { @@ -1527,7 +1474,7 @@ TEST(ConstructorDeclaration, IsUserProvided) { EXPECT_TRUE(notMatches("struct S { S() = delete; };", cxxConstructorDecl(isUserProvided()))); EXPECT_TRUE( - matches("struct S { S(); };", cxxConstructorDecl(isUserProvided()))); + matches("struct S { S(); };", cxxConstructorDecl(isUserProvided()))); EXPECT_TRUE(matches("struct S { S(); }; S::S(){}", cxxConstructorDecl(isUserProvided()))); } @@ -1538,11 +1485,11 @@ TEST(ConstructorDeclaration, IsDelegatingConstructor) { EXPECT_TRUE(notMatches("struct S { S(){} S(int X) : X(X) {} int X; };", cxxConstructorDecl(isDelegatingConstructor()))); EXPECT_TRUE(matches( - "struct S { S() : S(0) {} S(int X) : X(X) {} int X; };", - cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(0)))); + "struct S { S() : S(0) {} S(int X) : X(X) {} int X; };", + cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(0)))); EXPECT_TRUE(matches( - "struct S { S(); S(int X); int X; }; S::S(int X) : S() {}", - cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(1)))); + "struct S { S(); S(int X); int X; }; S::S(int X) : S() {}", + cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(1)))); } TEST(StringLiteral, HasSize) { @@ -1584,38 +1531,28 @@ TEST(Matcher, HasNameSupportsNamespaces) { } TEST(Matcher, HasNameSupportsOuterClasses) { - EXPECT_TRUE( - matches("class A { class B { class C; }; };", - recordDecl(hasName("A::B::C")))); - EXPECT_TRUE( - matches("class A { class B { class C; }; };", - recordDecl(hasName("::A::B::C")))); - EXPECT_TRUE( - matches("class A { class B { class C; }; };", - recordDecl(hasName("B::C")))); - EXPECT_TRUE( - matches("class A { class B { class C; }; };", - recordDecl(hasName("C")))); - EXPECT_TRUE( - notMatches("class A { class B { class C; }; };", - recordDecl(hasName("c::B::C")))); - EXPECT_TRUE( - notMatches("class A { class B { class C; }; };", - recordDecl(hasName("A::c::C")))); - EXPECT_TRUE( - notMatches("class A { class B { class C; }; };", - recordDecl(hasName("A::B::A")))); - EXPECT_TRUE( - notMatches("class A { class B { class C; }; };", - recordDecl(hasName("::C")))); - EXPECT_TRUE( - notMatches("class A { class B { class C; }; };", - recordDecl(hasName("::B::C")))); + EXPECT_TRUE(matches("class A { class B { class C; }; };", + recordDecl(hasName("A::B::C")))); + EXPECT_TRUE(matches("class A { class B { class C; }; };", + recordDecl(hasName("::A::B::C")))); + EXPECT_TRUE(matches("class A { class B { class C; }; };", + recordDecl(hasName("B::C")))); + EXPECT_TRUE( + matches("class A { class B { class C; }; };", recordDecl(hasName("C")))); + EXPECT_TRUE(notMatches("class A { class B { class C; }; };", + recordDecl(hasName("c::B::C")))); + EXPECT_TRUE(notMatches("class A { class B { class C; }; };", + recordDecl(hasName("A::c::C")))); + EXPECT_TRUE(notMatches("class A { class B { class C; }; };", + recordDecl(hasName("A::B::A")))); + EXPECT_TRUE(notMatches("class A { class B { class C; }; };", + recordDecl(hasName("::C")))); + EXPECT_TRUE(notMatches("class A { class B { class C; }; };", + recordDecl(hasName("::B::C")))); EXPECT_TRUE(notMatches("class A { class B { class C; }; };", recordDecl(hasName("z::A::B::C")))); - EXPECT_TRUE( - notMatches("class A { class B { class C; }; };", - recordDecl(hasName("A+B::C")))); + EXPECT_TRUE(notMatches("class A { class B { class C; }; };", + recordDecl(hasName("A+B::C")))); } TEST(Matcher, HasNameSupportsInlinedNamespaces) { @@ -1629,10 +1566,10 @@ TEST(Matcher, HasNameSupportsInlinedNamespaces) { TEST(Matcher, HasNameSupportsAnonymousNamespaces) { StringRef code = "namespace a { namespace { class C; } }"; EXPECT_TRUE( - matches(code, recordDecl(hasName("a::(anonymous namespace)::C")))); + matches(code, recordDecl(hasName("a::(anonymous namespace)::C")))); EXPECT_TRUE(matches(code, recordDecl(hasName("a::C")))); EXPECT_TRUE( - matches(code, recordDecl(hasName("::a::(anonymous namespace)::C")))); + matches(code, recordDecl(hasName("::a::(anonymous namespace)::C")))); EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C")))); } @@ -1689,7 +1626,7 @@ TEST(Matcher, HasAnyName) { EXPECT_TRUE(notMatches(Code, recordDecl(hasAnyName("::C", "::b::C")))); EXPECT_TRUE( - matches(Code, recordDecl(hasAnyName("::C", "::b::C", "::a::b::C")))); + matches(Code, recordDecl(hasAnyName("::C", "::b::C", "::a::b::C")))); std::vector Names = {"::C", "::b::C", "::a::b::C"}; EXPECT_TRUE(matches(Code, recordDecl(hasAnyName(Names)))); @@ -1697,27 +1634,27 @@ TEST(Matcher, HasAnyName) { TEST(Matcher, IsDefinition) { DeclarationMatcher DefinitionOfClassA = - recordDecl(hasName("A"), isDefinition()); + recordDecl(hasName("A"), isDefinition()); EXPECT_TRUE(matches("class A {};", DefinitionOfClassA)); EXPECT_TRUE(notMatches("class A;", DefinitionOfClassA)); DeclarationMatcher DefinitionOfVariableA = - varDecl(hasName("a"), isDefinition()); + varDecl(hasName("a"), isDefinition()); EXPECT_TRUE(matches("int a;", DefinitionOfVariableA)); EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA)); DeclarationMatcher DefinitionOfMethodA = - cxxMethodDecl(hasName("a"), isDefinition()); + cxxMethodDecl(hasName("a"), isDefinition()); EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA)); EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA)); DeclarationMatcher DefinitionOfObjCMethodA = - objcMethodDecl(hasName("a"), isDefinition()); + objcMethodDecl(hasName("a"), isDefinition()); EXPECT_TRUE(matchesObjC("@interface A @end " "@implementation A; -(void)a {} @end", DefinitionOfObjCMethodA)); - EXPECT_TRUE(notMatchesObjC("@interface A; - (void)a; @end", - DefinitionOfObjCMethodA)); + EXPECT_TRUE( + notMatchesObjC("@interface A; - (void)a; @end", DefinitionOfObjCMethodA)); } TEST(Matcher, HandlesNullQualTypes) { @@ -1728,7 +1665,7 @@ TEST(Matcher, HandlesNullQualTypes) { // We don't really care whether this matcher succeeds; we're testing that // it completes without crashing. EXPECT_TRUE(matches( - "struct A { };" + "struct A { };" "template " "void f(T t) {" " T local_t(t /* this becomes a null QualType in the AST */);" @@ -1736,13 +1673,10 @@ TEST(Matcher, HandlesNullQualTypes) { "void g() {" " f(0);" "}", - expr(hasType(TypeMatcher( - anyOf( - TypeMatcher(hasDeclaration(anything())), - pointsTo(AnyType), - references(AnyType) - // Other QualType matchers should go here. - )))))); + expr(hasType(TypeMatcher(anyOf(TypeMatcher(hasDeclaration(anything())), + pointsTo(AnyType), references(AnyType) + // Other QualType matchers should go here. + )))))); } TEST(ObjCIvarRefExprMatcher, IvarExpr) { @@ -1750,10 +1684,10 @@ TEST(ObjCIvarRefExprMatcher, IvarExpr) { "@interface A @end " "@implementation A { A *x; } - (void) func { x = 0; } @end"; EXPECT_TRUE(matchesObjC(ObjCString, objcIvarRefExpr())); - EXPECT_TRUE(matchesObjC(ObjCString, objcIvarRefExpr( - hasDeclaration(namedDecl(hasName("x")))))); - EXPECT_FALSE(matchesObjC(ObjCString, objcIvarRefExpr( - hasDeclaration(namedDecl(hasName("y")))))); + EXPECT_TRUE(matchesObjC( + ObjCString, objcIvarRefExpr(hasDeclaration(namedDecl(hasName("x")))))); + EXPECT_FALSE(matchesObjC( + ObjCString, objcIvarRefExpr(hasDeclaration(namedDecl(hasName("y")))))); } TEST(BlockExprMatcher, BlockExpr) { @@ -1761,24 +1695,19 @@ TEST(BlockExprMatcher, BlockExpr) { } TEST(StatementCountIs, FindsNoStatementsInAnEmptyCompoundStatement) { - EXPECT_TRUE(matches("void f() { }", - compoundStmt(statementCountIs(0)))); - EXPECT_TRUE(notMatches("void f() {}", - compoundStmt(statementCountIs(1)))); + EXPECT_TRUE(matches("void f() { }", compoundStmt(statementCountIs(0)))); + EXPECT_TRUE(notMatches("void f() {}", compoundStmt(statementCountIs(1)))); } TEST(StatementCountIs, AppearsToMatchOnlyOneCount) { - EXPECT_TRUE(matches("void f() { 1; }", - compoundStmt(statementCountIs(1)))); - EXPECT_TRUE(notMatches("void f() { 1; }", - compoundStmt(statementCountIs(0)))); - EXPECT_TRUE(notMatches("void f() { 1; }", - compoundStmt(statementCountIs(2)))); + EXPECT_TRUE(matches("void f() { 1; }", compoundStmt(statementCountIs(1)))); + EXPECT_TRUE(notMatches("void f() { 1; }", compoundStmt(statementCountIs(0)))); + EXPECT_TRUE(notMatches("void f() { 1; }", compoundStmt(statementCountIs(2)))); } TEST(StatementCountIs, WorksWithMultipleStatements) { - EXPECT_TRUE(matches("void f() { 1; 2; 3; }", - compoundStmt(statementCountIs(3)))); + EXPECT_TRUE( + matches("void f() { 1; 2; 3; }", compoundStmt(statementCountIs(3)))); } TEST(StatementCountIs, WorksWithNestedCompoundStatements) { @@ -1806,19 +1735,19 @@ TEST(Member, DoesNotMatchTheBaseExpression) { TEST(Member, MatchesInMemberFunctionCall) { EXPECT_TRUE(matches("void f() {" - " struct { void first() {}; } s;" - " s.first();" - "};", + " struct { void first() {}; } s;" + " s.first();" + "};", memberExpr(member(hasName("first"))))); } TEST(Member, MatchesMember) { - EXPECT_TRUE(matches( - "struct A { int i; }; void f() { A a; a.i = 2; }", - memberExpr(hasDeclaration(fieldDecl(hasType(isInteger())))))); - EXPECT_TRUE(notMatches( - "struct A { float f; }; void f() { A a; a.f = 2.0f; }", - memberExpr(hasDeclaration(fieldDecl(hasType(isInteger())))))); + EXPECT_TRUE( + matches("struct A { int i; }; void f() { A a; a.i = 2; }", + memberExpr(hasDeclaration(fieldDecl(hasType(isInteger())))))); + EXPECT_TRUE( + notMatches("struct A { float f; }; void f() { A a; a.f = 2.0f; }", + memberExpr(hasDeclaration(fieldDecl(hasType(isInteger())))))); } TEST(Member, BitFields) { @@ -1841,26 +1770,26 @@ TEST(Member, InClassInitializer) { } TEST(Member, UnderstandsAccess) { - EXPECT_TRUE(matches( - "struct A { int i; };", fieldDecl(isPublic(), hasName("i")))); - EXPECT_TRUE(notMatches( - "struct A { int i; };", fieldDecl(isProtected(), hasName("i")))); - EXPECT_TRUE(notMatches( - "struct A { int i; };", fieldDecl(isPrivate(), hasName("i")))); + EXPECT_TRUE( + matches("struct A { int i; };", fieldDecl(isPublic(), hasName("i")))); + EXPECT_TRUE(notMatches("struct A { int i; };", + fieldDecl(isProtected(), hasName("i")))); + EXPECT_TRUE( + notMatches("struct A { int i; };", fieldDecl(isPrivate(), hasName("i")))); - EXPECT_TRUE(notMatches( - "class A { int i; };", fieldDecl(isPublic(), hasName("i")))); - EXPECT_TRUE(notMatches( - "class A { int i; };", fieldDecl(isProtected(), hasName("i")))); - EXPECT_TRUE(matches( - "class A { int i; };", fieldDecl(isPrivate(), hasName("i")))); + EXPECT_TRUE( + notMatches("class A { int i; };", fieldDecl(isPublic(), hasName("i")))); + EXPECT_TRUE(notMatches("class A { int i; };", + fieldDecl(isProtected(), hasName("i")))); + EXPECT_TRUE( + matches("class A { int i; };", fieldDecl(isPrivate(), hasName("i")))); - EXPECT_TRUE(notMatches( - "class A { protected: int i; };", fieldDecl(isPublic(), hasName("i")))); + EXPECT_TRUE(notMatches("class A { protected: int i; };", + fieldDecl(isPublic(), hasName("i")))); EXPECT_TRUE(matches("class A { protected: int i; };", fieldDecl(isProtected(), hasName("i")))); - EXPECT_TRUE(notMatches( - "class A { protected: int i; };", fieldDecl(isPrivate(), hasName("i")))); + EXPECT_TRUE(notMatches("class A { protected: int i; };", + fieldDecl(isPrivate(), hasName("i")))); // Non-member decls have the AccessSpecifier AS_none and thus aren't matched. EXPECT_TRUE(notMatches("int i;", varDecl(isPublic(), hasName("i")))); @@ -1883,35 +1812,35 @@ TEST(hasDynamicExceptionSpec, MatchesDynamicExceptionSpecifications) { EXPECT_TRUE( matches("void l() throw(...);", functionDecl(hasDynamicExceptionSpec()))); - EXPECT_TRUE(notMatches("void f();", functionProtoType(hasDynamicExceptionSpec()))); + EXPECT_TRUE( + notMatches("void f();", functionProtoType(hasDynamicExceptionSpec()))); EXPECT_TRUE(notMatches("void g() noexcept;", functionProtoType(hasDynamicExceptionSpec()))); EXPECT_TRUE(notMatches("void h() noexcept(true);", functionProtoType(hasDynamicExceptionSpec()))); EXPECT_TRUE(notMatches("void i() noexcept(false);", functionProtoType(hasDynamicExceptionSpec()))); - EXPECT_TRUE( - matches("void j() throw();", functionProtoType(hasDynamicExceptionSpec()))); - EXPECT_TRUE( - matches("void k() throw(int);", functionProtoType(hasDynamicExceptionSpec()))); - EXPECT_TRUE( - matches("void l() throw(...);", functionProtoType(hasDynamicExceptionSpec()))); + EXPECT_TRUE(matches("void j() throw();", + functionProtoType(hasDynamicExceptionSpec()))); + EXPECT_TRUE(matches("void k() throw(int);", + functionProtoType(hasDynamicExceptionSpec()))); + EXPECT_TRUE(matches("void l() throw(...);", + functionProtoType(hasDynamicExceptionSpec()))); } TEST(HasObjectExpression, DoesNotMatchMember) { EXPECT_TRUE(notMatches( - "class X {}; struct Z { X m; }; void f(Z z) { z.m; }", - memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X"))))))); + "class X {}; struct Z { X m; }; void f(Z z) { z.m; }", + memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X"))))))); } TEST(HasObjectExpression, MatchesBaseOfVariable) { EXPECT_TRUE(matches( - "struct X { int m; }; void f(X x) { x.m; }", - memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X"))))))); - EXPECT_TRUE(matches( - "struct X { int m; }; void f(X* x) { x->m; }", - memberExpr(hasObjectExpression( - hasType(pointsTo(recordDecl(hasName("X")))))))); + "struct X { int m; }; void f(X x) { x.m; }", + memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X"))))))); + EXPECT_TRUE(matches("struct X { int m; }; void f(X* x) { x->m; }", + memberExpr(hasObjectExpression( + hasType(pointsTo(recordDecl(hasName("X")))))))); EXPECT_TRUE(matches("template struct X { void f() { T t; t.m; } };", cxxDependentScopeMemberExpr(hasObjectExpression( declRefExpr(to(namedDecl(hasName("t")))))))); @@ -1936,14 +1865,12 @@ TEST(HasObjectExpression, MatchesBaseOfMemberFunc) { TEST(HasObjectExpression, MatchesObjectExpressionOfImplicitlyFormedMemberExpression) { - EXPECT_TRUE(matches( - "class X {}; struct S { X m; void f() { this->m; } };", - memberExpr(hasObjectExpression( - hasType(pointsTo(recordDecl(hasName("S")))))))); - EXPECT_TRUE(matches( - "class X {}; struct S { X m; void f() { m; } };", - memberExpr(hasObjectExpression( - hasType(pointsTo(recordDecl(hasName("S")))))))); + EXPECT_TRUE(matches("class X {}; struct S { X m; void f() { this->m; } };", + memberExpr(hasObjectExpression( + hasType(pointsTo(recordDecl(hasName("S")))))))); + EXPECT_TRUE(matches("class X {}; struct S { X m; void f() { m; } };", + memberExpr(hasObjectExpression( + hasType(pointsTo(recordDecl(hasName("S")))))))); } TEST(Field, DoesNotMatchNonFieldMembers) { @@ -1958,17 +1885,17 @@ TEST(Field, MatchesField) { } TEST(IsVolatileQualified, QualifiersMatch) { - EXPECT_TRUE(matches("volatile int i = 42;", - varDecl(hasType(isVolatileQualified())))); - EXPECT_TRUE(notMatches("volatile int *i;", - varDecl(hasType(isVolatileQualified())))); + EXPECT_TRUE( + matches("volatile int i = 42;", varDecl(hasType(isVolatileQualified())))); + EXPECT_TRUE( + notMatches("volatile int *i;", varDecl(hasType(isVolatileQualified())))); EXPECT_TRUE(matches("typedef volatile int v_int; v_int i = 42;", varDecl(hasType(isVolatileQualified())))); } TEST(IsConstQualified, MatchesConstInt) { - EXPECT_TRUE(matches("const int i = 42;", - varDecl(hasType(isConstQualified())))); + EXPECT_TRUE( + matches("const int i = 42;", varDecl(hasType(isConstQualified())))); } TEST(IsConstQualified, MatchesConstPointer) { @@ -1986,43 +1913,41 @@ TEST(IsConstQualified, MatchesThroughTypedef) { TEST(IsConstQualified, DoesNotMatchInappropriately) { EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;", varDecl(hasType(isConstQualified())))); - EXPECT_TRUE(notMatches("int const* p;", - varDecl(hasType(isConstQualified())))); + EXPECT_TRUE( + notMatches("int const* p;", varDecl(hasType(isConstQualified())))); } TEST(DeclCount, DeclCountIsCorrect) { - EXPECT_TRUE(matches("void f() {int i,j;}", - declStmt(declCountIs(2)))); - EXPECT_TRUE(notMatches("void f() {int i,j; int k;}", - declStmt(declCountIs(3)))); - EXPECT_TRUE(notMatches("void f() {int i,j, k, l;}", - declStmt(declCountIs(3)))); + EXPECT_TRUE(matches("void f() {int i,j;}", declStmt(declCountIs(2)))); + EXPECT_TRUE( + notMatches("void f() {int i,j; int k;}", declStmt(declCountIs(3)))); + EXPECT_TRUE( + notMatches("void f() {int i,j, k, l;}", declStmt(declCountIs(3)))); } - TEST(EachOf, TriggersForEachMatch) { EXPECT_TRUE(matchAndVerifyResultTrue( - "class A { int a; int b; };", - recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")), - has(fieldDecl(hasName("b")).bind("v")))), - std::make_unique>("v", 2))); + "class A { int a; int b; };", + recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")), + has(fieldDecl(hasName("b")).bind("v")))), + std::make_unique>("v", 2))); } TEST(EachOf, BehavesLikeAnyOfUnlessBothMatch) { EXPECT_TRUE(matchAndVerifyResultTrue( - "class A { int a; int c; };", - recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")), - has(fieldDecl(hasName("b")).bind("v")))), - std::make_unique>("v", 1))); + "class A { int a; int c; };", + recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")), + has(fieldDecl(hasName("b")).bind("v")))), + std::make_unique>("v", 1))); EXPECT_TRUE(matchAndVerifyResultTrue( - "class A { int c; int b; };", - recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")), - has(fieldDecl(hasName("b")).bind("v")))), - std::make_unique>("v", 1))); - EXPECT_TRUE(notMatches( - "class A { int c; int d; };", - recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")), - has(fieldDecl(hasName("b")).bind("v")))))); + "class A { int c; int b; };", + recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")), + has(fieldDecl(hasName("b")).bind("v")))), + std::make_unique>("v", 1))); + EXPECT_TRUE( + notMatches("class A { int c; int d; };", + recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")), + has(fieldDecl(hasName("b")).bind("v")))))); } TEST(Optionally, SubmatchersDoNotMatch) { @@ -2056,29 +1981,30 @@ TEST(IsTemplateInstantiation, MatchesImplicitClassTemplateInstantiation) { // Make sure that we can both match the class by name (::X) and by the type // the template was instantiated with (via a field). - EXPECT_TRUE(matches( - "template class X {}; class A {}; X x;", - cxxRecordDecl(hasName("::X"), isTemplateInstantiation()))); + EXPECT_TRUE( + matches("template class X {}; class A {}; X x;", + cxxRecordDecl(hasName("::X"), isTemplateInstantiation()))); EXPECT_TRUE(matches( - "template class X { T t; }; class A {}; X x;", - cxxRecordDecl(isTemplateInstantiation(), hasDescendant( - fieldDecl(hasType(recordDecl(hasName("A")))))))); + "template class X { T t; }; class A {}; X x;", + cxxRecordDecl( + isTemplateInstantiation(), + hasDescendant(fieldDecl(hasType(recordDecl(hasName("A")))))))); } TEST(IsTemplateInstantiation, MatchesImplicitFunctionTemplateInstantiation) { EXPECT_TRUE(matches( - "template void f(T t) {} class A {}; void g() { f(A()); }", - functionDecl(hasParameter(0, hasType(recordDecl(hasName("A")))), - isTemplateInstantiation()))); + "template void f(T t) {} class A {}; void g() { f(A()); }", + functionDecl(hasParameter(0, hasType(recordDecl(hasName("A")))), + isTemplateInstantiation()))); } TEST(IsTemplateInstantiation, MatchesExplicitClassTemplateInstantiation) { - EXPECT_TRUE(matches( - "template class X { T t; }; class A {};" - "template class X;", - cxxRecordDecl(isTemplateInstantiation(), hasDescendant( - fieldDecl(hasType(recordDecl(hasName("A")))))))); + EXPECT_TRUE(matches("template class X { T t; }; class A {};" + "template class X;", + cxxRecordDecl(isTemplateInstantiation(), + hasDescendant(fieldDecl( + hasType(recordDecl(hasName("A")))))))); // Make sure that we match the instantiation instead of the template // definition by checking whether the member function is present. @@ -2091,21 +2017,21 @@ TEST(IsTemplateInstantiation, MatchesExplicitClassTemplateInstantiation) { TEST(IsTemplateInstantiation, MatchesInstantiationOfPartiallySpecializedClassTemplate) { - EXPECT_TRUE(matches( - "template class X {};" - "template class X {}; class A {}; X x;", - cxxRecordDecl(hasName("::X"), isTemplateInstantiation()))); + EXPECT_TRUE( + matches("template class X {};" + "template class X {}; class A {}; X x;", + cxxRecordDecl(hasName("::X"), isTemplateInstantiation()))); } TEST(IsTemplateInstantiation, MatchesInstantiationOfClassTemplateNestedInNonTemplate) { - EXPECT_TRUE(matches( - "class A {};" - "class X {" - " template class Y { U u; };" - " Y y;" - "};", - cxxRecordDecl(hasName("::X::Y"), isTemplateInstantiation()))); + EXPECT_TRUE( + matches("class A {};" + "class X {" + " template class Y { U u; };" + " Y y;" + "};", + cxxRecordDecl(hasName("::X::Y"), isTemplateInstantiation()))); } TEST(IsTemplateInstantiation, DoesNotMatchInstantiationsInsideOfInstantiation) { @@ -2113,31 +2039,30 @@ TEST(IsTemplateInstantiation, DoesNotMatchInstantiationsInsideOfInstantiation) { // normal use case as long as the uppermost instantiation always is marked // as template instantiation, but it might be confusing as a predicate. EXPECT_TRUE(matches( - "class A {};" + "class A {};" "template class X {" " template class Y { U u; };" " Y y;" "}; X x;", - cxxRecordDecl(hasName("::X::Y"), unless(isTemplateInstantiation())))); + cxxRecordDecl(hasName("::X::Y"), unless(isTemplateInstantiation())))); } TEST(IsTemplateInstantiation, DoesNotMatchExplicitClassTemplateSpecialization) { - EXPECT_TRUE(notMatches( - "template class X {}; class A {};" - "template <> class X {}; X x;", - cxxRecordDecl(hasName("::X"), isTemplateInstantiation()))); + EXPECT_TRUE( + notMatches("template class X {}; class A {};" + "template <> class X {}; X x;", + cxxRecordDecl(hasName("::X"), isTemplateInstantiation()))); } TEST(IsTemplateInstantiation, DoesNotMatchNonTemplate) { - EXPECT_TRUE(notMatches( - "class A {}; class Y { A a; };", - cxxRecordDecl(isTemplateInstantiation()))); + EXPECT_TRUE(notMatches("class A {}; class Y { A a; };", + cxxRecordDecl(isTemplateInstantiation()))); } TEST(IsInstantiated, MatchesInstantiation) { EXPECT_TRUE( - matches("template class A { T i; }; class Y { A a; };", - cxxRecordDecl(isInstantiated()))); + matches("template class A { T i; }; class Y { A a; };", + cxxRecordDecl(isInstantiated()))); } TEST(IsInstantiated, NotMatchesDefinition) { @@ -2147,7 +2072,7 @@ TEST(IsInstantiated, NotMatchesDefinition) { TEST(IsInTemplateInstantiation, MatchesInstantiationStmt) { EXPECT_TRUE(matches("template struct A { A() { T i; } };" - "class Y { A a; }; Y y;", + "class Y { A a; }; Y y;", declStmt(isInTemplateInstantiation()))); } @@ -2158,8 +2083,8 @@ TEST(IsInTemplateInstantiation, NotMatchesDefinitionStmt) { TEST(IsInstantiated, MatchesFunctionInstantiation) { EXPECT_TRUE( - matches("template void A(T t) { T i; } void x() { A(0); }", - functionDecl(isInstantiated()))); + matches("template void A(T t) { T i; } void x() { A(0); }", + functionDecl(isInstantiated()))); } TEST(IsInstantiated, NotMatchesFunctionDefinition) { @@ -2169,8 +2094,8 @@ TEST(IsInstantiated, NotMatchesFunctionDefinition) { TEST(IsInTemplateInstantiation, MatchesFunctionInstantiationStmt) { EXPECT_TRUE( - matches("template void A(T t) { T i; } void x() { A(0); }", - declStmt(isInTemplateInstantiation()))); + matches("template void A(T t) { T i; } void x() { A(0); }", + declStmt(isInTemplateInstantiation()))); } TEST(IsInTemplateInstantiation, NotMatchesFunctionDefinitionStmt) { @@ -2183,11 +2108,11 @@ TEST(IsInTemplateInstantiation, Sharing) { // FIXME: Node sharing is an implementation detail, exposing it is ugly // and makes the matcher behave in non-obvious ways. EXPECT_TRUE(notMatches( - "int j; template void A(T t) { j += 42; } void x() { A(0); }", - Matcher)); + "int j; template void A(T t) { j += 42; } void x() { A(0); }", + Matcher)); EXPECT_TRUE(matches( - "int j; template void A(T t) { j += t; } void x() { A(0); }", - Matcher)); + "int j; template void A(T t) { j += t; } void x() { A(0); }", + Matcher)); } TEST(IsInstantiationDependent, MatchesNonValueTypeDependent) { @@ -2232,48 +2157,41 @@ TEST(IsValueDependent, MatchesInstantiationDependent) { expr(isValueDependent()))); } -TEST(IsExplicitTemplateSpecialization, - DoesNotMatchPrimaryTemplate) { - EXPECT_TRUE(notMatches( - "template class X {};", - cxxRecordDecl(isExplicitTemplateSpecialization()))); - EXPECT_TRUE(notMatches( - "template void f(T t);", - functionDecl(isExplicitTemplateSpecialization()))); +TEST(IsExplicitTemplateSpecialization, DoesNotMatchPrimaryTemplate) { + EXPECT_TRUE(notMatches("template class X {};", + cxxRecordDecl(isExplicitTemplateSpecialization()))); + EXPECT_TRUE(notMatches("template void f(T t);", + functionDecl(isExplicitTemplateSpecialization()))); } TEST(IsExplicitTemplateSpecialization, DoesNotMatchExplicitTemplateInstantiations) { - EXPECT_TRUE(notMatches( - "template class X {};" - "template class X; extern template class X;", - cxxRecordDecl(isExplicitTemplateSpecialization()))); - EXPECT_TRUE(notMatches( - "template void f(T t) {}" - "template void f(int t); extern template void f(long t);", - functionDecl(isExplicitTemplateSpecialization()))); + EXPECT_TRUE( + notMatches("template class X {};" + "template class X; extern template class X;", + cxxRecordDecl(isExplicitTemplateSpecialization()))); + EXPECT_TRUE( + notMatches("template void f(T t) {}" + "template void f(int t); extern template void f(long t);", + functionDecl(isExplicitTemplateSpecialization()))); } TEST(IsExplicitTemplateSpecialization, DoesNotMatchImplicitTemplateInstantiations) { - EXPECT_TRUE(notMatches( - "template class X {}; X x;", - cxxRecordDecl(isExplicitTemplateSpecialization()))); - EXPECT_TRUE(notMatches( - "template void f(T t); void g() { f(10); }", - functionDecl(isExplicitTemplateSpecialization()))); + EXPECT_TRUE(notMatches("template class X {}; X x;", + cxxRecordDecl(isExplicitTemplateSpecialization()))); + EXPECT_TRUE( + notMatches("template void f(T t); void g() { f(10); }", + functionDecl(isExplicitTemplateSpecialization()))); } -TEST(IsExplicitTemplateSpecialization, - MatchesExplicitTemplateSpecializations) { - EXPECT_TRUE(matches( - "template class X {};" - "template<> class X {};", - cxxRecordDecl(isExplicitTemplateSpecialization()))); - EXPECT_TRUE(matches( - "template void f(T t) {}" - "template<> void f(int t) {}", - functionDecl(isExplicitTemplateSpecialization()))); +TEST(IsExplicitTemplateSpecialization, MatchesExplicitTemplateSpecializations) { + EXPECT_TRUE(matches("template class X {};" + "template<> class X {};", + cxxRecordDecl(isExplicitTemplateSpecialization()))); + EXPECT_TRUE(matches("template void f(T t) {}" + "template<> void f(int t) {}", + functionDecl(isExplicitTemplateSpecialization()))); } TEST(TypeMatching, MatchesNoReturn) { @@ -2314,8 +2232,8 @@ TEST(TypeMatching, MatchesNoReturn) { EXPECT_TRUE( matches("struct S { [[noreturn]] S(); };", functionDecl(isNoReturn()))); - EXPECT_TRUE(matches("struct S { [[noreturn]] S() {} };", - functionDecl(isNoReturn()))); + EXPECT_TRUE( + matches("struct S { [[noreturn]] S() {} };", functionDecl(isNoReturn()))); // --- @@ -2344,14 +2262,12 @@ TEST(TypeMatching, MatchesNoReturn) { // --- EXPECT_TRUE(matchesC("__attribute__((noreturn)) void func();", - functionDecl(isNoReturn()))); + functionDecl(isNoReturn()))); EXPECT_TRUE(matchesC("__attribute__((noreturn)) void func() {}", - functionDecl(isNoReturn()))); + functionDecl(isNoReturn()))); - EXPECT_TRUE(matchesC("_Noreturn void func();", - functionDecl(isNoReturn()))); - EXPECT_TRUE(matchesC("_Noreturn void func() {}", - functionDecl(isNoReturn()))); + EXPECT_TRUE(matchesC("_Noreturn void func();", functionDecl(isNoReturn()))); + EXPECT_TRUE(matchesC("_Noreturn void func() {}", functionDecl(isNoReturn()))); } TEST(TypeMatching, MatchesBool) { @@ -2383,45 +2299,42 @@ TEST(TypeMatching, MatchesArrayTypes) { EXPECT_TRUE(notMatches("struct A {}; A a[7];", arrayType(hasElementType(builtinType())))); + EXPECT_TRUE(matches("int const a[] = { 2, 3 };", + qualType(arrayType(hasElementType(builtinType()))))); EXPECT_TRUE(matches( - "int const a[] = { 2, 3 };", - qualType(arrayType(hasElementType(builtinType()))))); - EXPECT_TRUE(matches( - "int const a[] = { 2, 3 };", - qualType(isConstQualified(), arrayType(hasElementType(builtinType()))))); - EXPECT_TRUE(matches( - "typedef const int T; T x[] = { 1, 2 };", - qualType(isConstQualified(), arrayType()))); + "int const a[] = { 2, 3 };", + qualType(isConstQualified(), arrayType(hasElementType(builtinType()))))); + EXPECT_TRUE(matches("typedef const int T; T x[] = { 1, 2 };", + qualType(isConstQualified(), arrayType()))); EXPECT_TRUE(notMatches( - "int a[] = { 2, 3 };", - qualType(isConstQualified(), arrayType(hasElementType(builtinType()))))); - EXPECT_TRUE(notMatches( - "int a[] = { 2, 3 };", - qualType(arrayType(hasElementType(isConstQualified(), builtinType()))))); + "int a[] = { 2, 3 };", + qualType(isConstQualified(), arrayType(hasElementType(builtinType()))))); EXPECT_TRUE(notMatches( - "int const a[] = { 2, 3 };", - qualType(arrayType(hasElementType(builtinType())), - unless(isConstQualified())))); + "int a[] = { 2, 3 };", + qualType(arrayType(hasElementType(isConstQualified(), builtinType()))))); + EXPECT_TRUE(notMatches("int const a[] = { 2, 3 };", + qualType(arrayType(hasElementType(builtinType())), + unless(isConstQualified())))); - EXPECT_TRUE(matches("int a[2];", - constantArrayType(hasElementType(builtinType())))); + EXPECT_TRUE( + matches("int a[2];", constantArrayType(hasElementType(builtinType())))); EXPECT_TRUE(matches("const int a = 0;", qualType(isInteger()))); } TEST(TypeMatching, DecayedType) { - EXPECT_TRUE(matches("void f(int i[]);", valueDecl(hasType(decayedType(hasDecayedType(pointerType())))))); + EXPECT_TRUE( + matches("void f(int i[]);", + valueDecl(hasType(decayedType(hasDecayedType(pointerType())))))); EXPECT_TRUE(notMatches("int i[7];", decayedType())); } TEST(TypeMatching, MatchesComplexTypes) { EXPECT_TRUE(matches("_Complex float f;", complexType())); - EXPECT_TRUE(matches( - "_Complex float f;", - complexType(hasElementType(builtinType())))); - EXPECT_TRUE(notMatches( - "_Complex float f;", - complexType(hasElementType(isInteger())))); + EXPECT_TRUE( + matches("_Complex float f;", complexType(hasElementType(builtinType())))); + EXPECT_TRUE(notMatches("_Complex float f;", + complexType(hasElementType(isInteger())))); } TEST(NS, Anonymous) { @@ -2482,38 +2395,38 @@ TEST(DeclarationMatcher, InStdNamespace) { TEST(EqualsBoundNodeMatcher, QualType) { EXPECT_TRUE(matches( - "int i = 1;", varDecl(hasType(qualType().bind("type")), - hasInitializer(ignoringParenImpCasts( - hasType(qualType(equalsBoundNode("type")))))))); + "int i = 1;", varDecl(hasType(qualType().bind("type")), + hasInitializer(ignoringParenImpCasts( + hasType(qualType(equalsBoundNode("type")))))))); EXPECT_TRUE(notMatches("int i = 1.f;", varDecl(hasType(qualType().bind("type")), hasInitializer(ignoringParenImpCasts(hasType( - qualType(equalsBoundNode("type")))))))); + qualType(equalsBoundNode("type")))))))); } TEST(EqualsBoundNodeMatcher, NonMatchingTypes) { EXPECT_TRUE(notMatches( - "int i = 1;", varDecl(namedDecl(hasName("i")).bind("name"), - hasInitializer(ignoringParenImpCasts( - hasType(qualType(equalsBoundNode("type")))))))); + "int i = 1;", varDecl(namedDecl(hasName("i")).bind("name"), + hasInitializer(ignoringParenImpCasts( + hasType(qualType(equalsBoundNode("type")))))))); } TEST(EqualsBoundNodeMatcher, Stmt) { EXPECT_TRUE( - matches("void f() { if(true) {} }", - stmt(allOf(ifStmt().bind("if"), - hasParent(stmt(has(stmt(equalsBoundNode("if"))))))))); + matches("void f() { if(true) {} }", + stmt(allOf(ifStmt().bind("if"), + hasParent(stmt(has(stmt(equalsBoundNode("if"))))))))); EXPECT_TRUE(notMatches( - "void f() { if(true) { if (true) {} } }", - stmt(allOf(ifStmt().bind("if"), has(stmt(equalsBoundNode("if"))))))); + "void f() { if(true) { if (true) {} } }", + stmt(allOf(ifStmt().bind("if"), has(stmt(equalsBoundNode("if"))))))); } TEST(EqualsBoundNodeMatcher, Decl) { EXPECT_TRUE(matches( - "class X { class Y {}; };", - decl(allOf(recordDecl(hasName("::X::Y")).bind("record"), - hasParent(decl(has(decl(equalsBoundNode("record"))))))))); + "class X { class Y {}; };", + decl(allOf(recordDecl(hasName("::X::Y")).bind("record"), + hasParent(decl(has(decl(equalsBoundNode("record"))))))))); EXPECT_TRUE(notMatches("class X { class Y {}; };", decl(allOf(recordDecl(hasName("::X")).bind("record"), @@ -2522,21 +2435,21 @@ TEST(EqualsBoundNodeMatcher, Decl) { TEST(EqualsBoundNodeMatcher, Type) { EXPECT_TRUE(matches( - "class X { int a; int b; };", - recordDecl( - has(fieldDecl(hasName("a"), hasType(type().bind("t")))), - has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t")))))))); + "class X { int a; int b; };", + recordDecl( + has(fieldDecl(hasName("a"), hasType(type().bind("t")))), + has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t")))))))); EXPECT_TRUE(notMatches( - "class X { int a; double b; };", - recordDecl( - has(fieldDecl(hasName("a"), hasType(type().bind("t")))), - has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t")))))))); + "class X { int a; double b; };", + recordDecl( + has(fieldDecl(hasName("a"), hasType(type().bind("t")))), + has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t")))))))); } TEST(EqualsBoundNodeMatcher, UsingForEachDescendant) { EXPECT_TRUE(matchAndVerifyResultTrue( - "int f() {" + "int f() {" " if (1) {" " int i = 9;" " }" @@ -2546,68 +2459,78 @@ TEST(EqualsBoundNodeMatcher, UsingForEachDescendant) { " }" " return 0;" "}", - // Look for variable declarations within functions whose type is the same - // as the function return type. - functionDecl(returns(qualType().bind("type")), - forEachDescendant(varDecl(hasType( - qualType(equalsBoundNode("type")))).bind("decl"))), - // Only i and j should match, not k. - std::make_unique>("decl", 2))); + // Look for variable declarations within functions whose type is the same + // as the function return type. + functionDecl( + returns(qualType().bind("type")), + forEachDescendant(varDecl(hasType(qualType(equalsBoundNode("type")))) + .bind("decl"))), + // Only i and j should match, not k. + std::make_unique>("decl", 2))); } TEST(EqualsBoundNodeMatcher, FiltersMatchedCombinations) { EXPECT_TRUE(matchAndVerifyResultTrue( - "void f() {" + "void f() {" " int x;" " double d;" " x = d + x - d + x;" "}", - functionDecl( - hasName("f"), forEachDescendant(varDecl().bind("d")), - forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d")))))), - std::make_unique>("d", 5))); + functionDecl( + hasName("f"), forEachDescendant(varDecl().bind("d")), + forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d")))))), + std::make_unique>("d", 5))); } TEST(EqualsBoundNodeMatcher, UnlessDescendantsOfAncestorsMatch) { EXPECT_TRUE(matchAndVerifyResultTrue( - "struct StringRef { int size() const; const char* data() const; };" + "struct StringRef { int size() const; const char* data() const; };" "void f(StringRef v) {" " v.data();" "}", - cxxMemberCallExpr( - callee(cxxMethodDecl(hasName("data"))), - on(declRefExpr(to( - varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))), - unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr( - callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))), - on(declRefExpr(to(varDecl(equalsBoundNode("var"))))))))))) - .bind("data"), - std::make_unique>("data", 1))); + cxxMemberCallExpr( + callee(cxxMethodDecl(hasName("data"))), + on(declRefExpr(to( + varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))), + unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr( + callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))), + on(declRefExpr(to(varDecl(equalsBoundNode("var"))))))))))) + .bind("data"), + std::make_unique>("data", 1))); EXPECT_FALSE(matches( - "struct StringRef { int size() const; const char* data() const; };" + "struct StringRef { int size() const; const char* data() const; };" "void f(StringRef v) {" " v.data();" " v.size();" "}", - cxxMemberCallExpr( - callee(cxxMethodDecl(hasName("data"))), - on(declRefExpr(to( - varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))), - unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr( - callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))), - on(declRefExpr(to(varDecl(equalsBoundNode("var"))))))))))) - .bind("data"))); + cxxMemberCallExpr( + callee(cxxMethodDecl(hasName("data"))), + on(declRefExpr(to( + varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))), + unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr( + callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))), + on(declRefExpr(to(varDecl(equalsBoundNode("var"))))))))))) + .bind("data"))); } TEST(NullPointerConstants, Basic) { EXPECT_TRUE(matches("#define NULL ((void *)0)\n" - "void *v1 = NULL;", expr(nullPointerConstant()))); + "void *v1 = NULL;", + expr(nullPointerConstant()))); EXPECT_TRUE(matches("void *v2 = nullptr;", expr(nullPointerConstant()))); EXPECT_TRUE(matches("void *v3 = __null;", expr(nullPointerConstant()))); EXPECT_TRUE(matches("char *cp = (char *)0;", expr(nullPointerConstant()))); EXPECT_TRUE(matches("int *ip = 0;", expr(nullPointerConstant()))); EXPECT_TRUE(matches("int i = 0;", expr(nullPointerConstant()))); + const char kTest[] = R"( + template + struct MyTemplate { + MyTemplate() : field_(__null) {} + T* field_; + }; + )"; + EXPECT_TRUE(matches(kTest, expr(nullPointerConstant()))); } TEST(HasExternalFormalLinkage, Basic) { @@ -2627,10 +2550,10 @@ TEST(HasExternalFormalLinkage, Basic) { } TEST(HasDefaultArgument, Basic) { - EXPECT_TRUE(matches("void x(int val = 0) {}", - parmVarDecl(hasDefaultArgument()))); - EXPECT_TRUE(notMatches("void x(int val) {}", - parmVarDecl(hasDefaultArgument()))); + EXPECT_TRUE( + matches("void x(int val = 0) {}", parmVarDecl(hasDefaultArgument()))); + EXPECT_TRUE( + notMatches("void x(int val) {}", parmVarDecl(hasDefaultArgument()))); } TEST(IsAtPosition, Basic) { @@ -2683,24 +2606,18 @@ TEST(HasArraySize, Basic) { } TEST(HasDefinition, MatchesStructDefinition) { - EXPECT_TRUE(matches("struct x {};", - cxxRecordDecl(hasDefinition()))); - EXPECT_TRUE(notMatches("struct x;", - cxxRecordDecl(hasDefinition()))); + EXPECT_TRUE(matches("struct x {};", cxxRecordDecl(hasDefinition()))); + EXPECT_TRUE(notMatches("struct x;", cxxRecordDecl(hasDefinition()))); } TEST(HasDefinition, MatchesClassDefinition) { - EXPECT_TRUE(matches("class x {};", - cxxRecordDecl(hasDefinition()))); - EXPECT_TRUE(notMatches("class x;", - cxxRecordDecl(hasDefinition()))); + EXPECT_TRUE(matches("class x {};", cxxRecordDecl(hasDefinition()))); + EXPECT_TRUE(notMatches("class x;", cxxRecordDecl(hasDefinition()))); } TEST(HasDefinition, MatchesUnionDefinition) { - EXPECT_TRUE(matches("union x {};", - cxxRecordDecl(hasDefinition()))); - EXPECT_TRUE(notMatches("union x;", - cxxRecordDecl(hasDefinition()))); + EXPECT_TRUE(matches("union x {};", cxxRecordDecl(hasDefinition()))); + EXPECT_TRUE(notMatches("union x;", cxxRecordDecl(hasDefinition()))); } TEST(IsScopedEnum, MatchesScopedEnum) { @@ -2719,19 +2636,19 @@ TEST(HasTrailingReturn, MatchesTrailingReturn) { EXPECT_TRUE(matches("auto Y() -> int { return 0; }", functionDecl(hasTrailingReturn()))); EXPECT_TRUE(matches("auto X() -> int;", functionDecl(hasTrailingReturn()))); - EXPECT_TRUE(notMatches("int X() { return 0; }", - functionDecl(hasTrailingReturn()))); + EXPECT_TRUE( + notMatches("int X() { return 0; }", functionDecl(hasTrailingReturn()))); EXPECT_TRUE(notMatches("int X();", functionDecl(hasTrailingReturn()))); EXPECT_TRUE(notMatchesC("void X();", functionDecl(hasTrailingReturn()))); } TEST(HasTrailingReturn, MatchesLambdaTrailingReturn) { EXPECT_TRUE(matches( - "auto lambda2 = [](double x, double y) -> double {return x + y;};", - functionDecl(hasTrailingReturn()))); - EXPECT_TRUE(notMatches( - "auto lambda2 = [](double x, double y) {return x + y;};", - functionDecl(hasTrailingReturn()))); + "auto lambda2 = [](double x, double y) -> double {return x + y;};", + functionDecl(hasTrailingReturn()))); + EXPECT_TRUE( + notMatches("auto lambda2 = [](double x, double y) {return x + y;};", + functionDecl(hasTrailingReturn()))); } TEST(IsAssignmentOperator, Basic) { @@ -2764,23 +2681,15 @@ TEST(IsComparisonOperator, Basic) { } TEST(HasInit, Basic) { - EXPECT_TRUE( - matches("int x{0};", - initListExpr(hasInit(0, expr())))); - EXPECT_FALSE( - matches("int x{0};", - initListExpr(hasInit(1, expr())))); - EXPECT_FALSE( - matches("int x;", - initListExpr(hasInit(0, expr())))); + EXPECT_TRUE(matches("int x{0};", initListExpr(hasInit(0, expr())))); + EXPECT_FALSE(matches("int x{0};", initListExpr(hasInit(1, expr())))); + EXPECT_FALSE(matches("int x;", initListExpr(hasInit(0, expr())))); } TEST(Matcher, isMain) { - EXPECT_TRUE( - matches("int main() {}", functionDecl(isMain()))); + EXPECT_TRUE(matches("int main() {}", functionDecl(isMain()))); - EXPECT_TRUE( - notMatches("int main2() {}", functionDecl(isMain()))); + EXPECT_TRUE(notMatches("int main2() {}", functionDecl(isMain()))); } TEST(OMPExecutableDirective, isStandaloneDirective) { @@ -2859,11 +2768,18 @@ void x() { EXPECT_TRUE(matchesWithOpenMP(Source3, Matcher)); StringRef Source4 = R"( +void x() { +#pragma omp parallel default(firstprivate) +; +})"; + EXPECT_TRUE(matchesWithOpenMP51(Source4, Matcher)); + + StringRef Source5 = R"( void x(int x) { #pragma omp parallel num_threads(x) ; })"; - EXPECT_TRUE(matchesWithOpenMP(Source4, Matcher)); + EXPECT_TRUE(matchesWithOpenMP(Source5, Matcher)); } TEST(OMPDefaultClause, isNoneKind) { @@ -2899,10 +2815,17 @@ void x() { StringRef Source4 = R"( void x(int x) { +#pragma omp parallel default(firstprivate) +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP51(Source4, Matcher)); + + const std::string Source5 = R"( +void x(int x) { #pragma omp parallel num_threads(x) ; })"; - EXPECT_TRUE(notMatchesWithOpenMP(Source4, Matcher)); + EXPECT_TRUE(notMatchesWithOpenMP(Source5, Matcher)); } TEST(OMPDefaultClause, isSharedKind) { @@ -2938,10 +2861,63 @@ void x() { StringRef Source4 = R"( void x(int x) { +#pragma omp parallel default(firstprivate) +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP51(Source4, Matcher)); + + const std::string Source5 = R"( +void x(int x) { +#pragma omp parallel num_threads(x) +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source5, Matcher)); +} + +TEST(OMPDefaultClause, isFirstPrivateKind) { + auto Matcher = ompExecutableDirective( + hasAnyClause(ompDefaultClause(isFirstPrivateKind()))); + + const std::string Source0 = R"( +void x() { +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher)); + + const std::string Source1 = R"( +void x() { +#pragma omp parallel +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher)); + + const std::string Source2 = R"( +void x() { +#pragma omp parallel default(shared) +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source2, Matcher)); + + const std::string Source3 = R"( +void x() { +#pragma omp parallel default(none) +; +})"; + EXPECT_TRUE(notMatchesWithOpenMP(Source3, Matcher)); + + const std::string Source4 = R"( +void x(int x) { +#pragma omp parallel default(firstprivate) +; +})"; + EXPECT_TRUE(matchesWithOpenMP51(Source4, Matcher)); + + const std::string Source5 = R"( +void x(int x) { #pragma omp parallel num_threads(x) ; })"; - EXPECT_TRUE(notMatchesWithOpenMP(Source4, Matcher)); + EXPECT_TRUE(notMatchesWithOpenMP(Source5, Matcher)); } TEST(OMPExecutableDirective, isAllowedToContainClauseKind) { @@ -2976,24 +2952,31 @@ void x() { EXPECT_TRUE(matchesWithOpenMP(Source3, Matcher)); StringRef Source4 = R"( +void x() { +#pragma omp parallel default(firstprivate) +; +})"; + EXPECT_TRUE(matchesWithOpenMP51(Source4, Matcher)); + + StringRef Source5 = R"( void x(int x) { #pragma omp parallel num_threads(x) ; })"; - EXPECT_TRUE(matchesWithOpenMP(Source4, Matcher)); + EXPECT_TRUE(matchesWithOpenMP(Source5, Matcher)); - StringRef Source5 = R"( + StringRef Source6 = R"( void x() { #pragma omp taskyield })"; - EXPECT_TRUE(notMatchesWithOpenMP(Source5, Matcher)); + EXPECT_TRUE(notMatchesWithOpenMP(Source6, Matcher)); - StringRef Source6 = R"( + StringRef Source7 = R"( void x() { #pragma omp task ; })"; - EXPECT_TRUE(matchesWithOpenMP(Source6, Matcher)); + EXPECT_TRUE(matchesWithOpenMP(Source7, Matcher)); } TEST(HasAnyBase, DirectBase) { @@ -3117,5 +3100,44 @@ TEST(IsVirtual, NoVirtualBase) { cxxRecordDecl(hasAnyBase(isVirtual())))); } +TEST(BaseSpecifier, hasDirectBase) { + EXPECT_TRUE(matches( + R"cc( + class Base {}; + class Derived : Base{}; + )cc", + cxxRecordDecl(hasName("Derived"), + hasDirectBase(hasType(cxxRecordDecl(hasName("Base"))))))); + + StringRef MultiDerived = R"cc( + class Base {}; + class Base2 {}; + class Derived : Base, Base2{}; + )cc"; + + EXPECT_TRUE(matches( + MultiDerived, + cxxRecordDecl(hasName("Derived"), + hasDirectBase(hasType(cxxRecordDecl(hasName("Base"))))))); + EXPECT_TRUE(matches( + MultiDerived, + cxxRecordDecl(hasName("Derived"), + hasDirectBase(hasType(cxxRecordDecl(hasName("Base2"))))))); + + StringRef Indirect = R"cc( + class Base {}; + class Intermediate : Base {}; + class Derived : Intermediate{}; + )cc"; + + EXPECT_TRUE( + matches(Indirect, cxxRecordDecl(hasName("Derived"), + hasDirectBase(hasType(cxxRecordDecl( + hasName("Intermediate"))))))); + EXPECT_TRUE(notMatches( + Indirect, + cxxRecordDecl(hasName("Derived"), + hasDirectBase(hasType(cxxRecordDecl(hasName("Base"))))))); +} } // namespace ast_matchers } // namespace clang diff --git a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp index 1d262fc1a6558..895c8ae48adc1 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp @@ -18,52 +18,47 @@ namespace clang { namespace ast_matchers { -TEST(Finder, DynamicOnlyAcceptsSomeMatchers) { - MatchFinder Finder; - EXPECT_TRUE(Finder.addDynamicMatcher(decl(), nullptr)); - EXPECT_TRUE(Finder.addDynamicMatcher(callExpr(), nullptr)); - EXPECT_TRUE(Finder.addDynamicMatcher(constantArrayType(hasSize(42)), - nullptr)); - - // Do not accept non-toplevel matchers. - EXPECT_FALSE(Finder.addDynamicMatcher(isMain(), nullptr)); - EXPECT_FALSE(Finder.addDynamicMatcher(hasName("x"), nullptr)); -} - -TEST(Decl, MatchesDeclarations) { +TEST_P(ASTMatchersTest, Decl_CXX) { + if (!GetParam().isCXX()) { + // FIXME: Add a test for `decl()` that does not depend on C++. + return; + } EXPECT_TRUE(notMatches("", decl(usingDecl()))); - EXPECT_TRUE(matches("namespace x { class X {}; } using x::X;", - decl(usingDecl()))); + EXPECT_TRUE( + matches("namespace x { class X {}; } using x::X;", decl(usingDecl()))); } -TEST(NameableDeclaration, MatchesVariousDecls) { +TEST_P(ASTMatchersTest, NameableDeclaration_MatchesVariousDecls) { DeclarationMatcher NamedX = namedDecl(hasName("X")); EXPECT_TRUE(matches("typedef int X;", NamedX)); EXPECT_TRUE(matches("int X;", NamedX)); - EXPECT_TRUE(matches("class foo { virtual void X(); };", NamedX)); - EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", NamedX)); EXPECT_TRUE(matches("void foo() { int X; }", NamedX)); - EXPECT_TRUE(matches("namespace X { }", NamedX)); EXPECT_TRUE(matches("enum X { A, B, C };", NamedX)); EXPECT_TRUE(notMatches("#define X 1", NamedX)); } -TEST(NameableDeclaration, REMatchesVariousDecls) { +TEST_P(ASTMatchersTest, NamedDecl_CXX) { + if (!GetParam().isCXX()) { + return; + } + DeclarationMatcher NamedX = namedDecl(hasName("X")); + EXPECT_TRUE(matches("class foo { virtual void X(); };", NamedX)); + EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", NamedX)); + EXPECT_TRUE(matches("namespace X { }", NamedX)); +} + +TEST_P(ASTMatchersTest, MatchesNameRE) { DeclarationMatcher NamedX = namedDecl(matchesName("::X")); EXPECT_TRUE(matches("typedef int Xa;", NamedX)); EXPECT_TRUE(matches("int Xb;", NamedX)); - EXPECT_TRUE(matches("class foo { virtual void Xc(); };", NamedX)); - EXPECT_TRUE(matches("void foo() try { } catch(int Xdef) { }", NamedX)); EXPECT_TRUE(matches("void foo() { int Xgh; }", NamedX)); - EXPECT_TRUE(matches("namespace Xij { }", NamedX)); EXPECT_TRUE(matches("enum X { A, B, C };", NamedX)); EXPECT_TRUE(notMatches("#define Xkl 1", NamedX)); DeclarationMatcher StartsWithNo = namedDecl(matchesName("::no")); EXPECT_TRUE(matches("int no_foo;", StartsWithNo)); - EXPECT_TRUE(matches("class foo { virtual void nobody(); };", StartsWithNo)); DeclarationMatcher Abc = namedDecl(matchesName("a.*b.*c")); EXPECT_TRUE(matches("int abc;", Abc)); @@ -74,18 +69,36 @@ TEST(NameableDeclaration, REMatchesVariousDecls) { DeclarationMatcher StartsWithK = namedDecl(matchesName(":k[^:]*$")); EXPECT_TRUE(matches("int k;", StartsWithK)); EXPECT_TRUE(matches("int kAbc;", StartsWithK)); +} + +TEST_P(ASTMatchersTest, MatchesNameRE_CXX) { + if (!GetParam().isCXX()) { + return; + } + DeclarationMatcher NamedX = namedDecl(matchesName("::X")); + EXPECT_TRUE(matches("class foo { virtual void Xc(); };", NamedX)); + EXPECT_TRUE(matches("void foo() try { } catch(int Xdef) { }", NamedX)); + EXPECT_TRUE(matches("namespace Xij { }", NamedX)); + + DeclarationMatcher StartsWithNo = namedDecl(matchesName("::no")); + EXPECT_TRUE(matches("class foo { virtual void nobody(); };", StartsWithNo)); + + DeclarationMatcher StartsWithK = namedDecl(matchesName(":k[^:]*$")); EXPECT_TRUE(matches("namespace x { int kTest; }", StartsWithK)); EXPECT_TRUE(matches("class C { int k; };", StartsWithK)); EXPECT_TRUE(notMatches("class C { int ckc; };", StartsWithK)); -} + EXPECT_TRUE(notMatches("int K;", StartsWithK)); -TEST(DeclarationMatcher, MatchClass) { - DeclarationMatcher ClassMatcher(recordDecl()); + DeclarationMatcher StartsWithKIgnoreCase = + namedDecl(matchesName(":k[^:]*$", llvm::Regex::IgnoreCase)); + EXPECT_TRUE(matches("int k;", StartsWithKIgnoreCase)); + EXPECT_TRUE(matches("int K;", StartsWithKIgnoreCase)); +} - // This passes on Windows only because we explicitly pass -target - // i386-unknown-unknown. If we were to compile with the default target - // triple, we'd want to EXPECT_TRUE if it's Win32 or MSVC. - EXPECT_FALSE(matches("", ClassMatcher)); +TEST_P(ASTMatchersTest, DeclarationMatcher_MatchClass) { + if (!GetParam().isCXX()) { + return; + } DeclarationMatcher ClassX = recordDecl(recordDecl(hasName("X"))); EXPECT_TRUE(matches("class X;", ClassX)); @@ -94,72 +107,103 @@ TEST(DeclarationMatcher, MatchClass) { EXPECT_TRUE(notMatches("", ClassX)); } -TEST(DeclarationMatcher, translationUnitDecl) { +TEST_P(ASTMatchersTest, TranslationUnitDecl) { + if (!GetParam().isCXX()) { + // FIXME: Add a test for `translationUnitDecl()` that does not depend on + // C++. + return; + } StringRef Code = "int MyVar1;\n" "namespace NameSpace {\n" "int MyVar2;\n" "} // namespace NameSpace\n"; EXPECT_TRUE(matches( - Code, varDecl(hasName("MyVar1"), hasDeclContext(translationUnitDecl())))); + Code, varDecl(hasName("MyVar1"), hasDeclContext(translationUnitDecl())))); EXPECT_FALSE(matches( - Code, varDecl(hasName("MyVar2"), hasDeclContext(translationUnitDecl())))); + Code, varDecl(hasName("MyVar2"), hasDeclContext(translationUnitDecl())))); EXPECT_TRUE(matches( - Code, - varDecl(hasName("MyVar2"), - hasDeclContext(decl(hasDeclContext(translationUnitDecl())))))); + Code, + varDecl(hasName("MyVar2"), + hasDeclContext(decl(hasDeclContext(translationUnitDecl())))))); } -TEST(DeclarationMatcher, LinkageSpecification) { +TEST_P(ASTMatchersTest, LinkageSpecDecl) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(matches("extern \"C\" { void foo() {}; }", linkageSpecDecl())); EXPECT_TRUE(notMatches("void foo() {};", linkageSpecDecl())); } -TEST(ClassTemplate, DoesNotMatchClass) { +TEST_P(ASTMatchersTest, ClassTemplateDecl_DoesNotMatchClass) { + if (!GetParam().isCXX()) { + return; + } DeclarationMatcher ClassX = classTemplateDecl(hasName("X")); EXPECT_TRUE(notMatches("class X;", ClassX)); EXPECT_TRUE(notMatches("class X {};", ClassX)); } -TEST(ClassTemplate, MatchesClassTemplate) { +TEST_P(ASTMatchersTest, ClassTemplateDecl_MatchesClassTemplate) { + if (!GetParam().isCXX()) { + return; + } DeclarationMatcher ClassX = classTemplateDecl(hasName("X")); EXPECT_TRUE(matches("template class X {};", ClassX)); EXPECT_TRUE(matches("class Z { template class X {}; };", ClassX)); } -TEST(ClassTemplate, DoesNotMatchClassTemplateExplicitSpecialization) { - EXPECT_TRUE(notMatches("template class X { };" - "template<> class X { int a; };", - classTemplateDecl(hasName("X"), - hasDescendant(fieldDecl(hasName("a")))))); +TEST_P(ASTMatchersTest, + ClassTemplateDecl_DoesNotMatchClassTemplateExplicitSpecialization) { + if (!GetParam().isCXX()) { + return; + } + EXPECT_TRUE(notMatches( + "template class X { };" + "template<> class X { int a; };", + classTemplateDecl(hasName("X"), hasDescendant(fieldDecl(hasName("a")))))); } -TEST(ClassTemplate, DoesNotMatchClassTemplatePartialSpecialization) { - EXPECT_TRUE(notMatches("template class X { };" - "template class X { int a; };", - classTemplateDecl(hasName("X"), - hasDescendant(fieldDecl(hasName("a")))))); +TEST_P(ASTMatchersTest, + ClassTemplateDecl_DoesNotMatchClassTemplatePartialSpecialization) { + if (!GetParam().isCXX()) { + return; + } + EXPECT_TRUE(notMatches( + "template class X { };" + "template class X { int a; };", + classTemplateDecl(hasName("X"), hasDescendant(fieldDecl(hasName("a")))))); } -TEST(DeclarationMatcher, MatchCudaDecl) { +TEST(ASTMatchersTestCUDA, CUDAKernelCallExpr) { EXPECT_TRUE(matchesWithCuda("__global__ void f() { }" - "void g() { f<<<1, 2>>>(); }", + "void g() { f<<<1, 2>>>(); }", cudaKernelCallExpr())); + EXPECT_TRUE(notMatchesWithCuda("void f() {}", cudaKernelCallExpr())); +} + +TEST(ASTMatchersTestCUDA, HasAttrCUDA) { EXPECT_TRUE(matchesWithCuda("__attribute__((device)) void f() {}", hasAttr(clang::attr::CUDADevice))); - EXPECT_TRUE(notMatchesWithCuda("void f() {}", - cudaKernelCallExpr())); EXPECT_FALSE(notMatchesWithCuda("__attribute__((global)) void f() {}", hasAttr(clang::attr::CUDAGlobal))); } -TEST(ValueDecl, Matches) { +TEST_P(ASTMatchersTest, ValueDecl) { + if (!GetParam().isCXX()) { + // FIXME: Fix this test in non-C++ language modes. + return; + } EXPECT_TRUE(matches("enum EnumType { EnumValue };", valueDecl(hasType(asString("enum EnumType"))))); EXPECT_TRUE(matches("void FunctionDecl();", valueDecl(hasType(asString("void (void)"))))); } -TEST(FriendDecl, Matches) { +TEST_P(ASTMatchersTest, FriendDecl) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(matches("class Y { friend class X; };", friendDecl(hasType(asString("class X"))))); EXPECT_TRUE(matches("class Y { friend class X; };", @@ -169,43 +213,69 @@ TEST(FriendDecl, Matches) { functionDecl(hasName("f"), hasParent(friendDecl())))); } -TEST(Enum, DoesNotMatchClasses) { +TEST_P(ASTMatchersTest, EnumDecl_DoesNotMatchClasses) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(notMatches("class X {};", enumDecl(hasName("X")))); } -TEST(Enum, MatchesEnums) { +TEST_P(ASTMatchersTest, EnumDecl_MatchesEnums) { + if (!GetParam().isCXX()) { + // FIXME: Fix this test in non-C++ language modes. + return; + } EXPECT_TRUE(matches("enum X {};", enumDecl(hasName("X")))); } -TEST(EnumConstant, Matches) { +TEST_P(ASTMatchersTest, EnumConstantDecl) { + if (!GetParam().isCXX()) { + // FIXME: Fix this test in non-C++ language modes. + return; + } DeclarationMatcher Matcher = enumConstantDecl(hasName("A")); EXPECT_TRUE(matches("enum X{ A };", Matcher)); EXPECT_TRUE(notMatches("enum X{ B };", Matcher)); EXPECT_TRUE(notMatches("enum X {};", Matcher)); } -TEST(TagDecl, MatchesTagDecls) { +TEST_P(ASTMatchersTest, TagDecl) { + if (!GetParam().isCXX()) { + // FIXME: Fix this test in non-C++ language modes. + return; + } EXPECT_TRUE(matches("struct X {};", tagDecl(hasName("X")))); - EXPECT_TRUE(matches("class C {};", tagDecl(hasName("C")))); EXPECT_TRUE(matches("union U {};", tagDecl(hasName("U")))); EXPECT_TRUE(matches("enum E {};", tagDecl(hasName("E")))); } -TEST(Matcher, UnresolvedLookupExpr) { - // FIXME: The test is known to be broken on Windows with delayed template - // parsing. - EXPECT_TRUE(matchesConditionally("template" - "T foo() { T a; return a; }" - "template" - "void bar() {" - " foo();" - "}", - unresolvedLookupExpr(), - /*ExpectMatch=*/true, - {"-fno-delayed-template-parsing"})); +TEST_P(ASTMatchersTest, TagDecl_CXX) { + if (!GetParam().isCXX()) { + return; + } + EXPECT_TRUE(matches("class C {};", tagDecl(hasName("C")))); } -TEST(Matcher, ADLCall) { +TEST_P(ASTMatchersTest, UnresolvedLookupExpr) { + if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) { + // FIXME: Fix this test to work with delayed template parsing. + return; + } + + EXPECT_TRUE(matches("template" + "T foo() { T a; return a; }" + "template" + "void bar() {" + " foo();" + "}", + unresolvedLookupExpr())); +} + +TEST_P(ASTMatchersTest, UsesADL) { + if (!GetParam().isCXX()) { + return; + } + StatementMatcher ADLMatch = callExpr(usesADL()); StatementMatcher ADLMatchOper = cxxOperatorCallExpr(usesADL()); StringRef NS_Str = R"cpp( @@ -237,121 +307,140 @@ TEST(Matcher, ADLCall) { EXPECT_TRUE(notMatches(MkStr("NS::X x; NS::operator+(x, x);"), ADLMatch)); } -TEST(Matcher, Call) { +TEST_P(ASTMatchersTest, CallExpr_CXX) { + if (!GetParam().isCXX()) { + // FIXME: Add a test for `callExpr()` that does not depend on C++. + return; + } // FIXME: Do we want to overload Call() to directly take // Matcher, too? StatementMatcher MethodX = - callExpr(hasDeclaration(cxxMethodDecl(hasName("x")))); + callExpr(hasDeclaration(cxxMethodDecl(hasName("x")))); EXPECT_TRUE(matches("class Y { void x() { x(); } };", MethodX)); EXPECT_TRUE(notMatches("class Y { void x() {} };", MethodX)); StatementMatcher MethodOnY = - cxxMemberCallExpr(on(hasType(recordDecl(hasName("Y"))))); + cxxMemberCallExpr(on(hasType(recordDecl(hasName("Y"))))); - EXPECT_TRUE( - matches("class Y { public: void x(); }; void z() { Y y; y.x(); }", - MethodOnY)); - EXPECT_TRUE( - matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }", - MethodOnY)); - EXPECT_TRUE( - notMatches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }", - MethodOnY)); - EXPECT_TRUE( - notMatches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }", - MethodOnY)); - EXPECT_TRUE( - notMatches("class Y { public: void x(); }; void z() { Y *y; y->x(); }", - MethodOnY)); + EXPECT_TRUE(matches("class Y { public: void x(); }; void z() { Y y; y.x(); }", + MethodOnY)); + EXPECT_TRUE(matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }", + MethodOnY)); + EXPECT_TRUE(notMatches( + "class Y { public: void x(); }; void z(Y *&y) { y->x(); }", MethodOnY)); + EXPECT_TRUE(notMatches( + "class Y { public: void x(); }; void z(Y y[]) { y->x(); }", MethodOnY)); + EXPECT_TRUE(notMatches( + "class Y { public: void x(); }; void z() { Y *y; y->x(); }", MethodOnY)); StatementMatcher MethodOnYPointer = - cxxMemberCallExpr(on(hasType(pointsTo(recordDecl(hasName("Y")))))); + cxxMemberCallExpr(on(hasType(pointsTo(recordDecl(hasName("Y")))))); EXPECT_TRUE( - matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }", - MethodOnYPointer)); + matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }", + MethodOnYPointer)); EXPECT_TRUE( - matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }", - MethodOnYPointer)); + matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }", + MethodOnYPointer)); EXPECT_TRUE( - matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }", - MethodOnYPointer)); + matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }", + MethodOnYPointer)); EXPECT_TRUE( - notMatches("class Y { public: void x(); }; void z() { Y y; y.x(); }", - MethodOnYPointer)); + notMatches("class Y { public: void x(); }; void z() { Y y; y.x(); }", + MethodOnYPointer)); EXPECT_TRUE( - notMatches("class Y { public: void x(); }; void z(Y &y) { y.x(); }", - MethodOnYPointer)); + notMatches("class Y { public: void x(); }; void z(Y &y) { y.x(); }", + MethodOnYPointer)); } -TEST(Matcher, Lambda) { - EXPECT_TRUE(matches("auto f = [] (int i) { return i; };", - lambdaExpr())); + +TEST_P(ASTMatchersTest, LambdaExpr) { + if (!GetParam().isCXX11OrLater()) { + return; + } + EXPECT_TRUE(matches("auto f = [] (int i) { return i; };", lambdaExpr())); +} + +TEST_P(ASTMatchersTest, CXXForRangeStmt) { + EXPECT_TRUE( + notMatches("void f() { for (int i; i<5; ++i); }", cxxForRangeStmt())); } -TEST(Matcher, ForRange) { +TEST_P(ASTMatchersTest, CXXForRangeStmt_CXX11) { + if (!GetParam().isCXX11OrLater()) { + return; + } EXPECT_TRUE(matches("int as[] = { 1, 2, 3 };" - "void f() { for (auto &a : as); }", + "void f() { for (auto &a : as); }", cxxForRangeStmt())); - EXPECT_TRUE(notMatches("void f() { for (int i; i<5; ++i); }", - cxxForRangeStmt())); } -TEST(Matcher, SubstNonTypeTemplateParm) { +TEST_P(ASTMatchersTest, SubstNonTypeTemplateParmExpr) { + if (!GetParam().isCXX()) { + return; + } EXPECT_FALSE(matches("template\n" - "struct A { static const int n = 0; };\n" - "struct B : public A<42> {};", - traverse(TK_AsIs, - substNonTypeTemplateParmExpr()))); + "struct A { static const int n = 0; };\n" + "struct B : public A<42> {};", + traverse(TK_AsIs, substNonTypeTemplateParmExpr()))); EXPECT_TRUE(matches("template\n" - "struct A { static const int n = N; };\n" - "struct B : public A<42> {};", - traverse(TK_AsIs, - substNonTypeTemplateParmExpr()))); + "struct A { static const int n = N; };\n" + "struct B : public A<42> {};", + traverse(TK_AsIs, substNonTypeTemplateParmExpr()))); } -TEST(Matcher, NonTypeTemplateParmDecl) { +TEST_P(ASTMatchersTest, NonTypeTemplateParmDecl) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(matches("template void f();", nonTypeTemplateParmDecl(hasName("N")))); EXPECT_TRUE( - notMatches("template void f();", nonTypeTemplateParmDecl())); + notMatches("template void f();", nonTypeTemplateParmDecl())); } -TEST(Matcher, templateTypeParmDecl) { +TEST_P(ASTMatchersTest, TemplateTypeParmDecl) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(matches("template void f();", templateTypeParmDecl(hasName("T")))); - EXPECT_TRUE( - notMatches("template void f();", templateTypeParmDecl())); + EXPECT_TRUE(notMatches("template void f();", templateTypeParmDecl())); } -TEST(Matcher, UserDefinedLiteral) { +TEST_P(ASTMatchersTest, UserDefinedLiteral) { + if (!GetParam().isCXX11OrLater()) { + return; + } EXPECT_TRUE(matches("constexpr char operator \"\" _inc (const char i) {" - " return i + 1;" - "}" - "char c = 'a'_inc;", + " return i + 1;" + "}" + "char c = 'a'_inc;", userDefinedLiteral())); } -TEST(Matcher, FlowControl) { - EXPECT_TRUE(matches("void f() { while(true) { break; } }", breakStmt())); - EXPECT_TRUE(matches("void f() { while(true) { continue; } }", - continueStmt())); +TEST_P(ASTMatchersTest, FlowControl) { + EXPECT_TRUE(matches("void f() { while(1) { break; } }", breakStmt())); + EXPECT_TRUE(matches("void f() { while(1) { continue; } }", continueStmt())); EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}", gotoStmt())); EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}", - labelStmt( - hasDeclaration( - labelDecl(hasName("FOO")))))); + labelStmt(hasDeclaration(labelDecl(hasName("FOO")))))); EXPECT_TRUE(matches("void f() { FOO: ; void *ptr = &&FOO; goto *ptr; }", addrLabelExpr())); EXPECT_TRUE(matches("void f() { return; }", returnStmt())); } -TEST(Matcher, OverloadedOperatorCall) { +TEST_P(ASTMatchersTest, CXXOperatorCallExpr) { + if (!GetParam().isCXX()) { + return; + } + StatementMatcher OpCall = cxxOperatorCallExpr(); // Unary operator EXPECT_TRUE(matches("class Y { }; " - "bool operator!(Y x) { return false; }; " - "Y y; bool c = !y;", OpCall)); + "bool operator!(Y x) { return false; }; " + "Y y; bool c = !y;", + OpCall)); // No match -- special operators like "new", "delete" // FIXME: operator new takes size_t, for which we need stddef.h, for which // we need to figure out include paths in the test. @@ -360,100 +449,108 @@ TEST(Matcher, OverloadedOperatorCall) { // "void *operator new(size_t size) { return 0; } " // "Y *y = new Y;", OpCall)); EXPECT_TRUE(notMatches("class Y { }; " - "void operator delete(void *p) { } " - "void a() {Y *y = new Y; delete y;}", OpCall)); + "void operator delete(void *p) { } " + "void a() {Y *y = new Y; delete y;}", + OpCall)); // Binary operator EXPECT_TRUE(matches("class Y { }; " - "bool operator&&(Y x, Y y) { return true; }; " - "Y a; Y b; bool c = a && b;", + "bool operator&&(Y x, Y y) { return true; }; " + "Y a; Y b; bool c = a && b;", OpCall)); // No match -- normal operator, not an overloaded one. EXPECT_TRUE(notMatches("bool x = true, y = true; bool t = x && y;", OpCall)); EXPECT_TRUE(notMatches("int t = 5 << 2;", OpCall)); } -TEST(Matcher, ThisPointerType) { +TEST_P(ASTMatchersTest, ThisPointerType) { + if (!GetParam().isCXX()) { + return; + } + StatementMatcher MethodOnY = traverse(ast_type_traits::TK_AsIs, cxxMemberCallExpr(thisPointerType(recordDecl(hasName("Y"))))); - EXPECT_TRUE( - matches("class Y { public: void x(); }; void z() { Y y; y.x(); }", - MethodOnY)); - EXPECT_TRUE( - matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }", - MethodOnY)); - EXPECT_TRUE( - matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }", - MethodOnY)); - EXPECT_TRUE( - matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }", - MethodOnY)); - EXPECT_TRUE( - matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }", - MethodOnY)); - - EXPECT_TRUE(matches( - "class Y {" - " public: virtual void x();" - "};" - "class X : public Y {" - " public: virtual void x();" - "};" - "void z() { X *x; x->Y::x(); }", MethodOnY)); -} - -TEST(Matcher, VariableUsage) { - StatementMatcher Reference = - declRefExpr(to( - varDecl(hasInitializer( - cxxMemberCallExpr(thisPointerType(recordDecl(hasName("Y")))))))); - - EXPECT_TRUE(matches( - "class Y {" - " public:" - " bool x() const;" - "};" - "void z(const Y &y) {" - " bool b = y.x();" - " if (b) {}" - "}", Reference)); - - EXPECT_TRUE(notMatches( - "class Y {" - " public:" - " bool x() const;" - "};" - "void z(const Y &y) {" - " bool b = y.x();" - "}", Reference)); -} - -TEST(Matcher, CalledVariable) { - StatementMatcher CallOnVariableY = - cxxMemberCallExpr(on(declRefExpr(to(varDecl(hasName("y")))))); - - EXPECT_TRUE(matches( - "class Y { public: void x() { Y y; y.x(); } };", CallOnVariableY)); + EXPECT_TRUE(matches("class Y { public: void x(); }; void z() { Y y; y.x(); }", + MethodOnY)); + EXPECT_TRUE(matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }", + MethodOnY)); EXPECT_TRUE(matches( - "class Y { public: void x() const { Y y; y.x(); } };", CallOnVariableY)); + "class Y { public: void x(); }; void z(Y *&y) { y->x(); }", MethodOnY)); EXPECT_TRUE(matches( - "class Y { public: void x(); };" - "class X : public Y { void z() { X y; y.x(); } };", CallOnVariableY)); + "class Y { public: void x(); }; void z(Y y[]) { y->x(); }", MethodOnY)); EXPECT_TRUE(matches( - "class Y { public: void x(); };" - "class X : public Y { void z() { X *y; y->x(); } };", CallOnVariableY)); + "class Y { public: void x(); }; void z() { Y *y; y->x(); }", MethodOnY)); + + EXPECT_TRUE(matches("class Y {" + " public: virtual void x();" + "};" + "class X : public Y {" + " public: virtual void x();" + "};" + "void z() { X *x; x->Y::x(); }", + MethodOnY)); +} + +TEST_P(ASTMatchersTest, DeclRefExpr) { + if (!GetParam().isCXX()) { + // FIXME: Add a test for `declRefExpr()` that does not depend on C++. + return; + } + StatementMatcher Reference = declRefExpr(to(varDecl(hasInitializer( + cxxMemberCallExpr(thisPointerType(recordDecl(hasName("Y")))))))); + + EXPECT_TRUE(matches("class Y {" + " public:" + " bool x() const;" + "};" + "void z(const Y &y) {" + " bool b = y.x();" + " if (b) {}" + "}", + Reference)); + + EXPECT_TRUE(notMatches("class Y {" + " public:" + " bool x() const;" + "};" + "void z(const Y &y) {" + " bool b = y.x();" + "}", + Reference)); +} + +TEST_P(ASTMatchersTest, CXXMemberCallExpr) { + if (!GetParam().isCXX()) { + return; + } + StatementMatcher CallOnVariableY = + cxxMemberCallExpr(on(declRefExpr(to(varDecl(hasName("y")))))); + + EXPECT_TRUE(matches("class Y { public: void x() { Y y; y.x(); } };", + CallOnVariableY)); + EXPECT_TRUE(matches("class Y { public: void x() const { Y y; y.x(); } };", + CallOnVariableY)); + EXPECT_TRUE(matches("class Y { public: void x(); };" + "class X : public Y { void z() { X y; y.x(); } };", + CallOnVariableY)); + EXPECT_TRUE(matches("class Y { public: void x(); };" + "class X : public Y { void z() { X *y; y->x(); } };", + CallOnVariableY)); EXPECT_TRUE(notMatches( - "class Y { public: void x(); };" + "class Y { public: void x(); };" "class X : public Y { void z() { unsigned long y; ((X*)y)->x(); } };", - CallOnVariableY)); + CallOnVariableY)); +} + +TEST_P(ASTMatchersTest, UnaryExprOrTypeTraitExpr) { + EXPECT_TRUE( + matches("void x() { int a = sizeof(a); }", unaryExprOrTypeTraitExpr())); } -TEST(UnaryExprOrTypeTraitExpr, MatchesSizeOfAndAlignOf) { - EXPECT_TRUE(matches("void x() { int a = sizeof(a); }", - unaryExprOrTypeTraitExpr())); - EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", - alignOfExpr(anything()))); +TEST_P(ASTMatchersTest, AlignOfExpr) { + EXPECT_TRUE( + notMatches("void x() { int a = sizeof(a); }", alignOfExpr(anything()))); // FIXME: Uncomment once alignof is enabled. // EXPECT_TRUE(matches("void x() { int a = alignof(a); }", // unaryExprOrTypeTraitExpr())); @@ -461,14 +558,21 @@ TEST(UnaryExprOrTypeTraitExpr, MatchesSizeOfAndAlignOf) { // sizeOfExpr())); } -TEST(MemberExpression, DoesNotMatchClasses) { +TEST_P(ASTMatchersTest, MemberExpr_DoesNotMatchClasses) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(notMatches("class Y { void x() {} };", memberExpr())); EXPECT_TRUE(notMatches("class Y { void x() {} };", unresolvedMemberExpr())); EXPECT_TRUE( notMatches("class Y { void x() {} };", cxxDependentScopeMemberExpr())); } -TEST(MemberExpression, MatchesMemberFunctionCall) { +TEST_P(ASTMatchersTest, MemberExpr_MatchesMemberFunctionCall) { + if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) { + // FIXME: Fix this test to work with delayed template parsing. + return; + } EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpr())); EXPECT_TRUE(matches("class Y { template void x() { x(); } };", unresolvedMemberExpr())); @@ -476,13 +580,16 @@ TEST(MemberExpression, MatchesMemberFunctionCall) { cxxDependentScopeMemberExpr())); } -TEST(MemberExpression, MatchesVariable) { - EXPECT_TRUE( - matches("class Y { void x() { this->y; } int y; };", memberExpr())); +TEST_P(ASTMatchersTest, MemberExpr_MatchesVariable) { + if (!GetParam().isCXX() || GetParam().hasDelayedTemplateParsing()) { + // FIXME: Fix this test to work with delayed template parsing. + return; + } EXPECT_TRUE( - matches("class Y { void x() { y; } int y; };", memberExpr())); + matches("class Y { void x() { this->y; } int y; };", memberExpr())); + EXPECT_TRUE(matches("class Y { void x() { y; } int y; };", memberExpr())); EXPECT_TRUE( - matches("class Y { void x() { Y y; y.y; } int y; };", memberExpr())); + matches("class Y { void x() { Y y; y.y; } int y; };", memberExpr())); EXPECT_TRUE(matches("template " "class X : T { void f() { this->T::v; } };", cxxDependentScopeMemberExpr())); @@ -492,76 +599,110 @@ TEST(MemberExpression, MatchesVariable) { cxxDependentScopeMemberExpr())); } -TEST(MemberExpression, MatchesStaticVariable) { +TEST_P(ASTMatchersTest, MemberExpr_MatchesStaticVariable) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };", memberExpr())); - EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };", - memberExpr())); + EXPECT_TRUE( + notMatches("class Y { void x() { y; } static int y; };", memberExpr())); EXPECT_TRUE(notMatches("class Y { void x() { Y::y; } static int y; };", memberExpr())); } -TEST(Function, MatchesFunctionDeclarations) { +TEST_P(ASTMatchersTest, FunctionDecl) { StatementMatcher CallFunctionF = callExpr(callee(functionDecl(hasName("f")))); EXPECT_TRUE(matches("void f() { f(); }", CallFunctionF)); EXPECT_TRUE(notMatches("void f() { }", CallFunctionF)); - if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getOS() != - llvm::Triple::Win32) { - // FIXME: Make this work for MSVC. + EXPECT_TRUE(notMatches("void f(int);", functionDecl(isVariadic()))); + EXPECT_TRUE(notMatches("void f();", functionDecl(isVariadic()))); + EXPECT_TRUE(matches("void f(int, ...);", functionDecl(parameterCountIs(1)))); +} + +TEST_P(ASTMatchersTest, FunctionDecl_C) { + if (!GetParam().isC()) { + return; + } + EXPECT_TRUE(notMatches("void f();", functionDecl(isVariadic()))); + EXPECT_TRUE(matches("void f();", functionDecl(parameterCountIs(0)))); +} + +TEST_P(ASTMatchersTest, FunctionDecl_CXX) { + if (!GetParam().isCXX()) { + return; + } + + StatementMatcher CallFunctionF = callExpr(callee(functionDecl(hasName("f")))); + + if (!GetParam().hasDelayedTemplateParsing()) { + // FIXME: Fix this test to work with delayed template parsing. // Dependent contexts, but a non-dependent call. - EXPECT_TRUE(matches("void f(); template void g() { f(); }", - CallFunctionF)); EXPECT_TRUE( - matches("void f(); template struct S { void g() { f(); } };", - CallFunctionF)); + matches("void f(); template void g() { f(); }", CallFunctionF)); + EXPECT_TRUE( + matches("void f(); template struct S { void g() { f(); } };", + CallFunctionF)); } // Depedent calls don't match. EXPECT_TRUE( - notMatches("void f(int); template void g(T t) { f(t); }", - CallFunctionF)); + notMatches("void f(int); template void g(T t) { f(t); }", + CallFunctionF)); EXPECT_TRUE( - notMatches("void f(int);" + notMatches("void f(int);" "template struct S { void g(T t) { f(t); } };", - CallFunctionF)); + CallFunctionF)); EXPECT_TRUE(matches("void f(...);", functionDecl(isVariadic()))); - EXPECT_TRUE(notMatches("void f(int);", functionDecl(isVariadic()))); + EXPECT_TRUE(matches("void f(...);", functionDecl(parameterCountIs(0)))); +} + +TEST_P(ASTMatchersTest, FunctionDecl_CXX11) { + if (!GetParam().isCXX11OrLater()) { + return; + } + EXPECT_TRUE(notMatches("template void f(Ts...);", functionDecl(isVariadic()))); - EXPECT_TRUE(notMatches("void f();", functionDecl(isVariadic()))); - EXPECT_TRUE(notMatchesC("void f();", functionDecl(isVariadic()))); - EXPECT_TRUE(matches("void f(...);", functionDecl(parameterCountIs(0)))); - EXPECT_TRUE(matchesC("void f();", functionDecl(parameterCountIs(0)))); - EXPECT_TRUE(matches("void f(int, ...);", functionDecl(parameterCountIs(1)))); } -TEST(FunctionTemplate, MatchesFunctionTemplateDeclarations) { - EXPECT_TRUE( - matches("template void f(T t) {}", - functionTemplateDecl(hasName("f")))); +TEST_P(ASTMatchersTest, + FunctionTemplateDecl_MatchesFunctionTemplateDeclarations) { + if (!GetParam().isCXX()) { + return; + } + EXPECT_TRUE(matches("template void f(T t) {}", + functionTemplateDecl(hasName("f")))); } -TEST(FunctionTemplate, DoesNotMatchFunctionDeclarations) { +TEST_P(ASTMatchersTest, FunctionTemplate_DoesNotMatchFunctionDeclarations) { EXPECT_TRUE( - notMatches("void f(double d); void f(int t) {}", - functionTemplateDecl(hasName("f")))); + notMatches("void f(double d);", functionTemplateDecl(hasName("f")))); + EXPECT_TRUE( + notMatches("void f(int t) {}", functionTemplateDecl(hasName("f")))); } -TEST(FunctionTemplate, DoesNotMatchFunctionTemplateSpecializations) { - EXPECT_TRUE( - notMatches("void g(); template void f(T t) {}" - "template <> void f(int t) { g(); }", - functionTemplateDecl(hasName("f"), - hasDescendant(declRefExpr(to( - functionDecl(hasName("g")))))))); +TEST_P(ASTMatchersTest, + FunctionTemplateDecl_DoesNotMatchFunctionTemplateSpecializations) { + if (!GetParam().isCXX()) { + return; + } + EXPECT_TRUE(notMatches( + "void g(); template void f(T t) {}" + "template <> void f(int t) { g(); }", + functionTemplateDecl(hasName("f"), hasDescendant(declRefExpr(to( + functionDecl(hasName("g")))))))); } -TEST(Matcher, MatchesClassTemplateSpecialization) { +TEST_P(ASTMatchersTest, ClassTemplateSpecializationDecl) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(matches("template struct A {};" - "template<> struct A {};", + "template<> struct A {};", classTemplateSpecializationDecl())); EXPECT_TRUE(matches("template struct A {}; A a;", classTemplateSpecializationDecl())); @@ -569,85 +710,114 @@ TEST(Matcher, MatchesClassTemplateSpecialization) { classTemplateSpecializationDecl())); } -TEST(DeclaratorDecl, MatchesDeclaratorDecls) { +TEST_P(ASTMatchersTest, DeclaratorDecl) { EXPECT_TRUE(matches("int x;", declaratorDecl())); + EXPECT_TRUE(notMatches("struct A {};", declaratorDecl())); +} + +TEST_P(ASTMatchersTest, DeclaratorDecl_CXX) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(notMatches("class A {};", declaratorDecl())); } -TEST(ParmVarDecl, MatchesParmVars) { +TEST_P(ASTMatchersTest, ParmVarDecl) { EXPECT_TRUE(matches("void f(int x);", parmVarDecl())); EXPECT_TRUE(notMatches("void f();", parmVarDecl())); } -TEST(Matcher, ConstructorCall) { +TEST_P(ASTMatchersTest, Matcher_ConstructorCall) { + if (!GetParam().isCXX()) { + return; + } + StatementMatcher Constructor = traverse(ast_type_traits::TK_AsIs, cxxConstructExpr()); EXPECT_TRUE( - matches("class X { public: X(); }; void x() { X x; }", Constructor)); - EXPECT_TRUE( - matches("class X { public: X(); }; void x() { X x = X(); }", - Constructor)); - EXPECT_TRUE( - matches("class X { public: X(int); }; void x() { X x = 0; }", - Constructor)); + matches("class X { public: X(); }; void x() { X x; }", Constructor)); + EXPECT_TRUE(matches("class X { public: X(); }; void x() { X x = X(); }", + Constructor)); + EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x = 0; }", + Constructor)); EXPECT_TRUE(matches("class X {}; void x(int) { X x; }", Constructor)); } -TEST(Match, ConstructorInitializers) { +TEST_P(ASTMatchersTest, Match_ConstructorInitializers) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(matches("class C { int i; public: C(int ii) : i(ii) {} };", cxxCtorInitializer(forField(hasName("i"))))); } -TEST(Matcher, ThisExpr) { +TEST_P(ASTMatchersTest, Matcher_ThisExpr) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE( - matches("struct X { int a; int f () { return a; } };", cxxThisExpr())); + matches("struct X { int a; int f () { return a; } };", cxxThisExpr())); EXPECT_TRUE( - notMatches("struct X { int f () { int a; return a; } };", cxxThisExpr())); + notMatches("struct X { int f () { int a; return a; } };", cxxThisExpr())); } -TEST(Matcher, BindTemporaryExpression) { +TEST_P(ASTMatchersTest, Matcher_BindTemporaryExpression) { + if (!GetParam().isCXX()) { + return; + } + StatementMatcher TempExpression = traverse(ast_type_traits::TK_AsIs, cxxBindTemporaryExpr()); StringRef ClassString = "class string { public: string(); ~string(); }; "; - EXPECT_TRUE( - matches(ClassString + - "string GetStringByValue();" - "void FunctionTakesString(string s);" - "void run() { FunctionTakesString(GetStringByValue()); }", - TempExpression)); + EXPECT_TRUE(matches( + ClassString + "string GetStringByValue();" + "void FunctionTakesString(string s);" + "void run() { FunctionTakesString(GetStringByValue()); }", + TempExpression)); - EXPECT_TRUE( - notMatches(ClassString + - "string* GetStringPointer(); " - "void FunctionTakesStringPtr(string* s);" - "void run() {" - " string* s = GetStringPointer();" - " FunctionTakesStringPtr(GetStringPointer());" - " FunctionTakesStringPtr(s);" - "}", - TempExpression)); + EXPECT_TRUE(notMatches(ClassString + + "string* GetStringPointer(); " + "void FunctionTakesStringPtr(string* s);" + "void run() {" + " string* s = GetStringPointer();" + " FunctionTakesStringPtr(GetStringPointer());" + " FunctionTakesStringPtr(s);" + "}", + TempExpression)); - EXPECT_TRUE( - notMatches("class no_dtor {};" - "no_dtor GetObjByValue();" - "void ConsumeObj(no_dtor param);" - "void run() { ConsumeObj(GetObjByValue()); }", - TempExpression)); + EXPECT_TRUE(notMatches("class no_dtor {};" + "no_dtor GetObjByValue();" + "void ConsumeObj(no_dtor param);" + "void run() { ConsumeObj(GetObjByValue()); }", + TempExpression)); } -TEST(MaterializeTemporaryExpr, MatchesTemporary) { - StringRef ClassString = "class string { public: string(); int length(); }; "; +TEST_P(ASTMatchersTest, MaterializeTemporaryExpr_MatchesTemporaryCXX11CXX14) { + if (GetParam().Language != Lang_CXX11 && GetParam().Language != Lang_CXX14) { + return; + } + StatementMatcher TempExpression = traverse(ast_type_traits::TK_AsIs, materializeTemporaryExpr()); - EXPECT_TRUE(matches( - ClassString + "string GetStringByValue();" - "void FunctionTakesString(string s);" - "void run() { FunctionTakesString(GetStringByValue()); }", - TempExpression)); + EXPECT_TRUE(matches("class string { public: string(); }; " + "string GetStringByValue();" + "void FunctionTakesString(string s);" + "void run() { FunctionTakesString(GetStringByValue()); }", + TempExpression)); +} + +TEST_P(ASTMatchersTest, MaterializeTemporaryExpr_MatchesTemporary) { + if (!GetParam().isCXX()) { + return; + } + + StringRef ClassString = "class string { public: string(); int length(); }; "; + StatementMatcher TempExpression = + traverse(ast_type_traits::TK_AsIs, materializeTemporaryExpr()); EXPECT_TRUE(notMatches(ClassString + "string* GetStringPointer(); " @@ -669,23 +839,32 @@ TEST(MaterializeTemporaryExpr, MatchesTemporary) { TempExpression)); } -TEST(Matcher, NewExpression) { +TEST_P(ASTMatchersTest, Matcher_NewExpression) { + if (!GetParam().isCXX()) { + return; + } + StatementMatcher New = cxxNewExpr(); EXPECT_TRUE(matches("class X { public: X(); }; void x() { new X; }", New)); + EXPECT_TRUE(matches("class X { public: X(); }; void x() { new X(); }", New)); EXPECT_TRUE( - matches("class X { public: X(); }; void x() { new X(); }", New)); - EXPECT_TRUE( - matches("class X { public: X(int); }; void x() { new X(0); }", New)); + matches("class X { public: X(int); }; void x() { new X(0); }", New)); EXPECT_TRUE(matches("class X {}; void x(int) { new X; }", New)); } -TEST(Matcher, DeleteExpression) { - EXPECT_TRUE(matches("struct A {}; void f(A* a) { delete a; }", - cxxDeleteExpr())); +TEST_P(ASTMatchersTest, Matcher_DeleteExpression) { + if (!GetParam().isCXX()) { + return; + } + EXPECT_TRUE( + matches("struct A {}; void f(A* a) { delete a; }", cxxDeleteExpr())); } -TEST(Matcher, NoexceptExpression) { +TEST_P(ASTMatchersTest, Matcher_NoexceptExpression) { + if (!GetParam().isCXX11OrLater()) { + return; + } StatementMatcher NoExcept = cxxNoexceptExpr(); EXPECT_TRUE(matches("void foo(); bool bar = noexcept(foo());", NoExcept)); EXPECT_TRUE( @@ -695,37 +874,49 @@ TEST(Matcher, NoexceptExpression) { EXPECT_TRUE(matches("void foo() noexcept(noexcept(1+1));", NoExcept)); } -TEST(Matcher, DefaultArgument) { +TEST_P(ASTMatchersTest, Matcher_DefaultArgument) { + if (!GetParam().isCXX()) { + return; + } StatementMatcher Arg = cxxDefaultArgExpr(); - EXPECT_TRUE(matches("void x(int, int = 0) { int y; x(y); }", Arg)); EXPECT_TRUE( - matches("class X { void x(int, int = 0) { int y; x(y); } };", Arg)); + matches("class X { void x(int, int = 0) { int y; x(y); } };", Arg)); EXPECT_TRUE(notMatches("void x(int, int = 0) { int y; x(y, 0); }", Arg)); } -TEST(Matcher, StringLiterals) { +TEST_P(ASTMatchersTest, StringLiteral) { StatementMatcher Literal = stringLiteral(); EXPECT_TRUE(matches("const char *s = \"string\";", Literal)); - // wide string - EXPECT_TRUE(matches("const wchar_t *s = L\"string\";", Literal)); // with escaped characters EXPECT_TRUE(matches("const char *s = \"\x05five\";", Literal)); // no matching -- though the data type is the same, there is no string literal EXPECT_TRUE(notMatches("const char s[1] = {'a'};", Literal)); } -TEST(Matcher, CharacterLiterals) { - StatementMatcher CharLiteral = characterLiteral(); - EXPECT_TRUE(matches("const char c = 'c';", CharLiteral)); +TEST_P(ASTMatchersTest, StringLiteral_CXX) { + if (!GetParam().isCXX()) { + return; + } + EXPECT_TRUE(matches("const wchar_t *s = L\"string\";", stringLiteral())); +} + +TEST_P(ASTMatchersTest, CharacterLiteral) { + EXPECT_TRUE(matches("const char c = 'c';", characterLiteral())); + EXPECT_TRUE(notMatches("const char c = 0x1;", characterLiteral())); +} + +TEST_P(ASTMatchersTest, CharacterLiteral_CXX) { + if (!GetParam().isCXX()) { + return; + } // wide character - EXPECT_TRUE(matches("const char c = L'c';", CharLiteral)); + EXPECT_TRUE(matches("const char c = L'c';", characterLiteral())); // wide character, Hex encoded, NOT MATCHED! - EXPECT_TRUE(notMatches("const wchar_t c = 0x2126;", CharLiteral)); - EXPECT_TRUE(notMatches("const char c = 0x1;", CharLiteral)); + EXPECT_TRUE(notMatches("const wchar_t c = 0x2126;", characterLiteral())); } -TEST(Matcher, IntegerLiterals) { +TEST_P(ASTMatchersTest, IntegerLiteral) { StatementMatcher HasIntLiteral = integerLiteral(); EXPECT_TRUE(matches("int i = 10;", HasIntLiteral)); EXPECT_TRUE(matches("int i = 0x1AB;", HasIntLiteral)); @@ -734,7 +925,7 @@ TEST(Matcher, IntegerLiterals) { // Non-matching cases (character literals, float and double) EXPECT_TRUE(notMatches("int i = L'a';", - HasIntLiteral)); // this is actually a character + HasIntLiteral)); // this is actually a character // literal cast to int EXPECT_TRUE(notMatches("int i = 'a';", HasIntLiteral)); EXPECT_TRUE(notMatches("int i = 1e10;", HasIntLiteral)); @@ -747,7 +938,7 @@ TEST(Matcher, IntegerLiterals) { hasUnaryOperand(integerLiteral(equals(10)))))); } -TEST(Matcher, FloatLiterals) { +TEST_P(ASTMatchersTest, FloatLiteral) { StatementMatcher HasFloatLiteral = floatLiteral(); EXPECT_TRUE(matches("float i = 10.0;", HasFloatLiteral)); EXPECT_TRUE(matches("float i = 10.0f;", HasFloatLiteral)); @@ -757,51 +948,47 @@ TEST(Matcher, FloatLiterals) { EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0)))); EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0f)))); EXPECT_TRUE( - matches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(5.0))))); + matches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(5.0))))); EXPECT_TRUE(notMatches("float i = 10;", HasFloatLiteral)); EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0)))); EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0f)))); EXPECT_TRUE( - notMatches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(6.0))))); + notMatches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(6.0))))); } -TEST(Matcher, NullPtrLiteral) { +TEST_P(ASTMatchersTest, CXXNullPtrLiteralExpr) { + if (!GetParam().isCXX11OrLater()) { + return; + } EXPECT_TRUE(matches("int* i = nullptr;", cxxNullPtrLiteralExpr())); } -TEST(Matcher, ChooseExpr) { - EXPECT_TRUE(matchesC("void f() { (void)__builtin_choose_expr(1, 2, 3); }", - chooseExpr())); +TEST_P(ASTMatchersTest, ChooseExpr) { + EXPECT_TRUE(matches("void f() { (void)__builtin_choose_expr(1, 2, 3); }", + chooseExpr())); } -TEST(Matcher, GNUNullExpr) { +TEST_P(ASTMatchersTest, GNUNullExpr) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(matches("int* i = __null;", gnuNullExpr())); } -TEST(Matcher, AtomicExpr) { +TEST_P(ASTMatchersTest, AtomicExpr) { EXPECT_TRUE(matches("void foo() { int *ptr; __atomic_load_n(ptr, 1); }", atomicExpr())); } -TEST(Matcher, Initializers) { - const char *ToMatch = "void foo() { struct point { double x; double y; };" - " struct point ptarray[10] = " - " { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; }"; - EXPECT_TRUE(matchesConditionally( - ToMatch, - initListExpr( - has(cxxConstructExpr(requiresZeroInitialization())), - has(initListExpr( - hasType(asString("struct point")), has(floatLiteral(equals(1.0))), - has(implicitValueInitExpr(hasType(asString("double")))))), - has(initListExpr(hasType(asString("struct point")), - has(floatLiteral(equals(2.0))), - has(floatLiteral(equals(1.0)))))), - true, {"-std=gnu++03"})); - - EXPECT_TRUE(matchesC99( - ToMatch, +TEST_P(ASTMatchersTest, Initializers_C99) { + if (!GetParam().isC99OrLater()) { + return; + } + EXPECT_TRUE(matches( + "void foo() { struct point { double x; double y; };" + " struct point ptarray[10] = " + " { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; }", initListExpr(hasSyntacticForm(initListExpr( has(designatedInitExpr(designatorCountIs(2), hasDescendant(floatLiteral(equals(1.0))), @@ -814,33 +1001,59 @@ TEST(Matcher, Initializers) { hasDescendant(integerLiteral(equals(0)))))))))); } -TEST(Matcher, ParenListExpr) { +TEST_P(ASTMatchersTest, Initializers_CXX) { + if (GetParam().Language != Lang_CXX03) { + // FIXME: Make this test pass with other C++ standard versions. + return; + } + EXPECT_TRUE(matches( + "void foo() { struct point { double x; double y; };" + " struct point ptarray[10] = " + " { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; }", + initListExpr( + has(cxxConstructExpr(requiresZeroInitialization())), + has(initListExpr( + hasType(asString("struct point")), has(floatLiteral(equals(1.0))), + has(implicitValueInitExpr(hasType(asString("double")))))), + has(initListExpr(hasType(asString("struct point")), + has(floatLiteral(equals(2.0))), + has(floatLiteral(equals(1.0)))))))); +} + +TEST_P(ASTMatchersTest, ParenListExpr) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE( - matches("template class foo { void bar() { foo X(*this); } };" + matches("template class foo { void bar() { foo X(*this); } };" "template class foo;", - varDecl(hasInitializer(parenListExpr(has(unaryOperator())))))); + varDecl(hasInitializer(parenListExpr(has(unaryOperator())))))); } -TEST(Matcher, StmtExpr) { +TEST_P(ASTMatchersTest, StmtExpr) { EXPECT_TRUE(matches("void declToImport() { int C = ({int X=4; X;}); }", varDecl(hasInitializer(stmtExpr())))); } -TEST(Matcher, ImportPredefinedExpr) { +TEST_P(ASTMatchersTest, PredefinedExpr) { // __func__ expands as StringLiteral("foo") EXPECT_TRUE(matches("void foo() { __func__; }", - predefinedExpr( - hasType(asString("const char [4]")), - has(stringLiteral())))); + predefinedExpr(hasType(asString("const char [4]")), + has(stringLiteral())))); } -TEST(Matcher, AsmStatement) { +TEST_P(ASTMatchersTest, AsmStatement) { EXPECT_TRUE(matches("void foo() { __asm(\"mov al, 2\"); }", asmStmt())); } -TEST(Matcher, Conditions) { +TEST_P(ASTMatchersTest, HasCondition) { + if (!GetParam().isCXX()) { + // FIXME: Add a test for `hasCondition()` that does not depend on C++. + return; + } + StatementMatcher Condition = - ifStmt(hasCondition(cxxBoolLiteral(equals(true)))); + ifStmt(hasCondition(cxxBoolLiteral(equals(true)))); EXPECT_TRUE(matches("void x() { if (true) {} }", Condition)); EXPECT_TRUE(notMatches("void x() { if (false) {} }", Condition)); @@ -849,28 +1062,39 @@ TEST(Matcher, Conditions) { EXPECT_TRUE(notMatches("void x() { if (1) {} }", Condition)); } -TEST(Matcher, ConditionalOperator) { - StatementMatcher Conditional = conditionalOperator( - hasCondition(cxxBoolLiteral(equals(true))), - hasTrueExpression(cxxBoolLiteral(equals(false)))); +TEST_P(ASTMatchersTest, ConditionalOperator) { + if (!GetParam().isCXX()) { + // FIXME: Add a test for `conditionalOperator()` that does not depend on + // C++. + return; + } + + StatementMatcher Conditional = + conditionalOperator(hasCondition(cxxBoolLiteral(equals(true))), + hasTrueExpression(cxxBoolLiteral(equals(false)))); EXPECT_TRUE(matches("void x() { true ? false : true; }", Conditional)); EXPECT_TRUE(notMatches("void x() { false ? false : true; }", Conditional)); EXPECT_TRUE(notMatches("void x() { true ? true : false; }", Conditional)); - StatementMatcher ConditionalFalse = conditionalOperator( - hasFalseExpression(cxxBoolLiteral(equals(false)))); + StatementMatcher ConditionalFalse = + conditionalOperator(hasFalseExpression(cxxBoolLiteral(equals(false)))); EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse)); EXPECT_TRUE( - notMatches("void x() { true ? false : true; }", ConditionalFalse)); + notMatches("void x() { true ? false : true; }", ConditionalFalse)); EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse)); EXPECT_TRUE( - notMatches("void x() { true ? false : true; }", ConditionalFalse)); + notMatches("void x() { true ? false : true; }", ConditionalFalse)); } -TEST(Matcher, BinaryConditionalOperator) { +TEST_P(ASTMatchersTest, BinaryConditionalOperator) { + if (!GetParam().isCXX()) { + // FIXME: This test should work in non-C++ language modes. + return; + } + StatementMatcher AlwaysOne = traverse(ast_type_traits::TK_AsIs, binaryConditionalOperator( @@ -881,144 +1105,192 @@ TEST(Matcher, BinaryConditionalOperator) { EXPECT_TRUE(matches("void x() { 1 ?: 0; }", AlwaysOne)); StatementMatcher FourNotFive = binaryConditionalOperator( - hasTrueExpression(opaqueValueExpr( - hasSourceExpression((integerLiteral(equals(4)))))), - hasFalseExpression(integerLiteral(equals(5)))); + hasTrueExpression( + opaqueValueExpr(hasSourceExpression((integerLiteral(equals(4)))))), + hasFalseExpression(integerLiteral(equals(5)))); EXPECT_TRUE(matches("void x() { 4 ?: 5; }", FourNotFive)); } -TEST(ArraySubscriptMatchers, ArraySubscripts) { - EXPECT_TRUE(matches("int i[2]; void f() { i[1] = 1; }", - arraySubscriptExpr())); - EXPECT_TRUE(notMatches("int i; void f() { i = 1; }", - arraySubscriptExpr())); +TEST_P(ASTMatchersTest, ArraySubscriptExpr) { + EXPECT_TRUE( + matches("int i[2]; void f() { i[1] = 1; }", arraySubscriptExpr())); + EXPECT_TRUE(notMatches("int i; void f() { i = 1; }", arraySubscriptExpr())); } -TEST(For, FindsForLoops) { +TEST_P(ASTMatchersTest, ForStmt) { EXPECT_TRUE(matches("void f() { for(;;); }", forStmt())); - EXPECT_TRUE(matches("void f() { if(true) for(;;); }", forStmt())); + EXPECT_TRUE(matches("void f() { if(1) for(;;); }", forStmt())); +} + +TEST_P(ASTMatchersTest, ForStmt_CXX11) { + if (!GetParam().isCXX11OrLater()) { + return; + } EXPECT_TRUE(notMatches("int as[] = { 1, 2, 3 };" - "void f() { for (auto &a : as); }", + "void f() { for (auto &a : as); }", forStmt())); } -TEST(For, ReportsNoFalsePositives) { +TEST_P(ASTMatchersTest, ForStmt_NoFalsePositives) { EXPECT_TRUE(notMatches("void f() { ; }", forStmt())); - EXPECT_TRUE(notMatches("void f() { if(true); }", forStmt())); + EXPECT_TRUE(notMatches("void f() { if(1); }", forStmt())); } -TEST(CompoundStatement, HandlesSimpleCases) { +TEST_P(ASTMatchersTest, CompoundStatement) { EXPECT_TRUE(notMatches("void f();", compoundStmt())); EXPECT_TRUE(matches("void f() {}", compoundStmt())); EXPECT_TRUE(matches("void f() {{}}", compoundStmt())); } -TEST(CompoundStatement, DoesNotMatchEmptyStruct) { +TEST_P(ASTMatchersTest, CompoundStatement_DoesNotMatchEmptyStruct) { + if (!GetParam().isCXX()) { + // FIXME: Add a similar test that does not depend on C++. + return; + } // It's not a compound statement just because there's "{}" in the source // text. This is an AST search, not grep. - EXPECT_TRUE(notMatches("namespace n { struct S {}; }", - compoundStmt())); - EXPECT_TRUE(matches("namespace n { struct S { void f() {{}} }; }", - compoundStmt())); + EXPECT_TRUE(notMatches("namespace n { struct S {}; }", compoundStmt())); + EXPECT_TRUE( + matches("namespace n { struct S { void f() {{}} }; }", compoundStmt())); } -TEST(CastExpression, MatchesExplicitCasts) { - EXPECT_TRUE(matches("char *p = reinterpret_cast(&p);",castExpr())); +TEST_P(ASTMatchersTest, CastExpr_MatchesExplicitCasts) { EXPECT_TRUE(matches("void *p = (void *)(&p);", castExpr())); +} + +TEST_P(ASTMatchersTest, CastExpr_MatchesExplicitCasts_CXX) { + if (!GetParam().isCXX()) { + return; + } + EXPECT_TRUE(matches("char *p = reinterpret_cast(&p);", castExpr())); EXPECT_TRUE(matches("char q, *p = const_cast(&q);", castExpr())); EXPECT_TRUE(matches("char c = char(0);", castExpr())); } -TEST(CastExpression, MatchesImplicitCasts) { + +TEST_P(ASTMatchersTest, CastExpression_MatchesImplicitCasts) { // This test creates an implicit cast from int to char. EXPECT_TRUE( matches("char c = 0;", traverse(ast_type_traits::TK_AsIs, castExpr()))); // This test creates an implicit cast from lvalue to rvalue. - EXPECT_TRUE(matches("char c = 0, d = c;", + EXPECT_TRUE(matches("void f() { char c = 0, d = c; }", traverse(ast_type_traits::TK_AsIs, castExpr()))); } -TEST(CastExpression, DoesNotMatchNonCasts) { - EXPECT_TRUE(notMatches("char c = '0';", castExpr())); - EXPECT_TRUE(notMatches("char c, &q = c;", castExpr())); +TEST_P(ASTMatchersTest, CastExpr_DoesNotMatchNonCasts) { + if (GetParam().Language == Lang_C89 || GetParam().Language == Lang_C99) { + // This does have a cast in C + EXPECT_TRUE(matches("char c = '0';", implicitCastExpr())); + } else { + EXPECT_TRUE(notMatches("char c = '0';", castExpr())); + } EXPECT_TRUE(notMatches("int i = (0);", castExpr())); EXPECT_TRUE(notMatches("int i = 0;", castExpr())); } -TEST(ReinterpretCast, MatchesSimpleCase) { +TEST_P(ASTMatchersTest, CastExpr_DoesNotMatchNonCasts_CXX) { + if (!GetParam().isCXX()) { + return; + } + EXPECT_TRUE(notMatches("char c, &q = c;", castExpr())); +} + +TEST_P(ASTMatchersTest, CXXReinterpretCastExpr) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(matches("char* p = reinterpret_cast(&p);", cxxReinterpretCastExpr())); } -TEST(ReinterpretCast, DoesNotMatchOtherCasts) { +TEST_P(ASTMatchersTest, CXXReinterpretCastExpr_DoesNotMatchOtherCasts) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(notMatches("char* p = (char*)(&p);", cxxReinterpretCastExpr())); EXPECT_TRUE(notMatches("char q, *p = const_cast(&q);", cxxReinterpretCastExpr())); EXPECT_TRUE(notMatches("void* p = static_cast(&p);", cxxReinterpretCastExpr())); EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};" - "B b;" - "D* p = dynamic_cast(&b);", + "B b;" + "D* p = dynamic_cast(&b);", cxxReinterpretCastExpr())); } -TEST(FunctionalCast, MatchesSimpleCase) { +TEST_P(ASTMatchersTest, CXXFunctionalCastExpr_MatchesSimpleCase) { + if (!GetParam().isCXX()) { + return; + } StringRef foo_class = "class Foo { public: Foo(const char*); };"; EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }", cxxFunctionalCastExpr())); } -TEST(FunctionalCast, DoesNotMatchOtherCasts) { +TEST_P(ASTMatchersTest, CXXFunctionalCastExpr_DoesNotMatchOtherCasts) { + if (!GetParam().isCXX()) { + return; + } StringRef FooClass = "class Foo { public: Foo(const char*); };"; EXPECT_TRUE( - notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }", - cxxFunctionalCastExpr())); - EXPECT_TRUE( - notMatches(FooClass + "void r() { Foo f = \"hello world\"; }", - cxxFunctionalCastExpr())); + notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }", + cxxFunctionalCastExpr())); + EXPECT_TRUE(notMatches(FooClass + "void r() { Foo f = \"hello world\"; }", + cxxFunctionalCastExpr())); } -TEST(DynamicCast, MatchesSimpleCase) { +TEST_P(ASTMatchersTest, CXXDynamicCastExpr) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(matches("struct B { virtual ~B() {} }; struct D : B {};" - "B b;" - "D* p = dynamic_cast(&b);", + "B b;" + "D* p = dynamic_cast(&b);", cxxDynamicCastExpr())); } -TEST(StaticCast, MatchesSimpleCase) { - EXPECT_TRUE(matches("void* p(static_cast(&p));", - cxxStaticCastExpr())); +TEST_P(ASTMatchersTest, CXXStaticCastExpr_MatchesSimpleCase) { + if (!GetParam().isCXX()) { + return; + } + EXPECT_TRUE(matches("void* p(static_cast(&p));", cxxStaticCastExpr())); } -TEST(StaticCast, DoesNotMatchOtherCasts) { +TEST_P(ASTMatchersTest, CXXStaticCastExpr_DoesNotMatchOtherCasts) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(notMatches("char* p = (char*)(&p);", cxxStaticCastExpr())); - EXPECT_TRUE(notMatches("char q, *p = const_cast(&q);", - cxxStaticCastExpr())); + EXPECT_TRUE( + notMatches("char q, *p = const_cast(&q);", cxxStaticCastExpr())); EXPECT_TRUE(notMatches("void* p = reinterpret_cast(&p);", cxxStaticCastExpr())); EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};" - "B b;" - "D* p = dynamic_cast(&b);", + "B b;" + "D* p = dynamic_cast(&b);", cxxStaticCastExpr())); } -TEST(CStyleCast, MatchesSimpleCase) { +TEST_P(ASTMatchersTest, CStyleCastExpr_MatchesSimpleCase) { EXPECT_TRUE(matches("int i = (int) 2.2f;", cStyleCastExpr())); } -TEST(CStyleCast, DoesNotMatchOtherCasts) { +TEST_P(ASTMatchersTest, CStyleCastExpr_DoesNotMatchOtherCasts) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(notMatches("char* p = static_cast(0);" - "char q, *r = const_cast(&q);" - "void* s = reinterpret_cast(&s);" - "struct B { virtual ~B() {} }; struct D : B {};" - "B b;" - "D* t = dynamic_cast(&b);", + "char q, *r = const_cast(&q);" + "void* s = reinterpret_cast(&s);" + "struct B { virtual ~B() {} }; struct D : B {};" + "B b;" + "D* t = dynamic_cast(&b);", cStyleCastExpr())); } -TEST(ImplicitCast, MatchesSimpleCase) { +TEST_P(ASTMatchersTest, ImplicitCastExpr_MatchesSimpleCase) { // This test creates an implicit const cast. - EXPECT_TRUE(matches("int x = 0; const int y = x;", + EXPECT_TRUE(matches("void f() { int x = 0; const int y = x; }", traverse(ast_type_traits::TK_AsIs, varDecl(hasInitializer(implicitCastExpr()))))); // This test creates an implicit cast from int to char. @@ -1031,42 +1303,49 @@ TEST(ImplicitCast, MatchesSimpleCase) { varDecl(hasInitializer(implicitCastExpr()))))); } -TEST(ImplicitCast, DoesNotMatchIncorrectly) { - // This test verifies that implicitCastExpr() matches exactly when implicit casts - // are present, and that it ignores explicit and paren casts. +TEST_P(ASTMatchersTest, ImplicitCastExpr_DoesNotMatchIncorrectly) { + // This test verifies that implicitCastExpr() matches exactly when implicit + // casts are present, and that it ignores explicit and paren casts. // These two test cases have no casts. - EXPECT_TRUE(notMatches("int x = 0;", - varDecl(hasInitializer(implicitCastExpr())))); - EXPECT_TRUE(notMatches("int x = 0, &y = x;", + EXPECT_TRUE( + notMatches("int x = 0;", varDecl(hasInitializer(implicitCastExpr())))); + EXPECT_TRUE( + notMatches("int x = (0);", varDecl(hasInitializer(implicitCastExpr())))); + EXPECT_TRUE(notMatches("void f() { int x = 0; double d = (double) x; }", varDecl(hasInitializer(implicitCastExpr())))); +} - EXPECT_TRUE(notMatches("int x = 0; double d = (double) x;", +TEST_P(ASTMatchersTest, ImplicitCastExpr_DoesNotMatchIncorrectly_CXX) { + if (!GetParam().isCXX()) { + return; + } + EXPECT_TRUE(notMatches("int x = 0, &y = x;", varDecl(hasInitializer(implicitCastExpr())))); EXPECT_TRUE(notMatches("const int *p; int *q = const_cast(p);", varDecl(hasInitializer(implicitCastExpr())))); - - EXPECT_TRUE(notMatches("int x = (0);", - varDecl(hasInitializer(implicitCastExpr())))); } -TEST(Statement, DoesNotMatchDeclarations) { - EXPECT_TRUE(notMatches("class X {};", stmt())); +TEST_P(ASTMatchersTest, Stmt_DoesNotMatchDeclarations) { + EXPECT_TRUE(notMatches("struct X {};", stmt())); } -TEST(Statement, MatchesCompoundStatments) { +TEST_P(ASTMatchersTest, Stmt_MatchesCompoundStatments) { EXPECT_TRUE(matches("void x() {}", stmt())); } -TEST(DeclarationStatement, DoesNotMatchCompoundStatements) { +TEST_P(ASTMatchersTest, DeclStmt_DoesNotMatchCompoundStatements) { EXPECT_TRUE(notMatches("void x() {}", declStmt())); } -TEST(DeclarationStatement, MatchesVariableDeclarationStatements) { +TEST_P(ASTMatchersTest, DeclStmt_MatchesVariableDeclarationStatements) { EXPECT_TRUE(matches("void x() { int a; }", declStmt())); } -TEST(ExprWithCleanups, MatchesExprWithCleanups) { +TEST_P(ASTMatchersTest, ExprWithCleanups_MatchesExprWithCleanups) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(matches("struct Foo { ~Foo(); };" "const Foo f = Foo();", traverse(ast_type_traits::TK_AsIs, @@ -1077,20 +1356,30 @@ TEST(ExprWithCleanups, MatchesExprWithCleanups) { varDecl(hasInitializer(exprWithCleanups()))))); } -TEST(InitListExpression, MatchesInitListExpression) { +TEST_P(ASTMatchersTest, InitListExpr) { EXPECT_TRUE(matches("int a[] = { 1, 2 };", initListExpr(hasType(asString("int [2]"))))); - EXPECT_TRUE(matches("struct B { int x, y; }; B b = { 5, 6 };", + EXPECT_TRUE(matches("struct B { int x, y; }; struct B b = { 5, 6 };", initListExpr(hasType(recordDecl(hasName("B")))))); + EXPECT_TRUE( + matches("int i[1] = {42, [0] = 43};", integerLiteral(equals(42)))); +} + +TEST_P(ASTMatchersTest, InitListExpr_CXX) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(matches("struct S { S(void (*a)()); };" - "void f();" - "S s[1] = { &f };", + "void f();" + "S s[1] = { &f };", declRefExpr(to(functionDecl(hasName("f")))))); - EXPECT_TRUE( - matches("int i[1] = {42, [0] = 43};", integerLiteral(equals(42)))); } -TEST(CXXStdInitializerListExpression, MatchesCXXStdInitializerListExpression) { +TEST_P(ASTMatchersTest, + CXXStdInitializerListExpression_MatchesCXXStdInitializerListExpression) { + if (!GetParam().isCXX11OrLater()) { + return; + } StringRef code = "namespace std {" "template class initializer_list {" " public: initializer_list() noexcept {}" @@ -1117,62 +1406,72 @@ TEST(CXXStdInitializerListExpression, MatchesCXXStdInitializerListExpression) { cxxStdInitializerListExpr())); } -TEST(UsingDeclaration, MatchesUsingDeclarations) { - EXPECT_TRUE(matches("namespace X { int x; } using X::x;", - usingDecl())); +TEST_P(ASTMatchersTest, UsingDecl_MatchesUsingDeclarations) { + if (!GetParam().isCXX()) { + return; + } + EXPECT_TRUE(matches("namespace X { int x; } using X::x;", usingDecl())); } -TEST(UsingDeclaration, MatchesShadowUsingDelcarations) { +TEST_P(ASTMatchersTest, UsingDecl_MatchesShadowUsingDelcarations) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(matches("namespace f { int a; } using f::a;", usingDecl(hasAnyUsingShadowDecl(hasName("a"))))); } -TEST(UsingDirectiveDeclaration, MatchesUsingNamespace) { +TEST_P(ASTMatchersTest, UsingDirectiveDecl_MatchesUsingNamespace) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(matches("namespace X { int x; } using namespace X;", usingDirectiveDecl())); EXPECT_FALSE( - matches("namespace X { int x; } using X::x;", usingDirectiveDecl())); + matches("namespace X { int x; } using X::x;", usingDirectiveDecl())); } - -TEST(While, MatchesWhileLoops) { +TEST_P(ASTMatchersTest, WhileStmt) { EXPECT_TRUE(notMatches("void x() {}", whileStmt())); - EXPECT_TRUE(matches("void x() { while(true); }", whileStmt())); - EXPECT_TRUE(notMatches("void x() { do {} while(true); }", whileStmt())); + EXPECT_TRUE(matches("void x() { while(1); }", whileStmt())); + EXPECT_TRUE(notMatches("void x() { do {} while(1); }", whileStmt())); } -TEST(Do, MatchesDoLoops) { - EXPECT_TRUE(matches("void x() { do {} while(true); }", doStmt())); - EXPECT_TRUE(matches("void x() { do ; while(false); }", doStmt())); +TEST_P(ASTMatchersTest, DoStmt_MatchesDoLoops) { + EXPECT_TRUE(matches("void x() { do {} while(1); }", doStmt())); + EXPECT_TRUE(matches("void x() { do ; while(0); }", doStmt())); } -TEST(Do, DoesNotMatchWhileLoops) { - EXPECT_TRUE(notMatches("void x() { while(true) {} }", doStmt())); +TEST_P(ASTMatchersTest, DoStmt_DoesNotMatchWhileLoops) { + EXPECT_TRUE(notMatches("void x() { while(1) {} }", doStmt())); } -TEST(SwitchCase, MatchesCase) { +TEST_P(ASTMatchersTest, SwitchCase_MatchesCase) { EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchCase())); EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchCase())); EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchCase())); EXPECT_TRUE(notMatches("void x() { switch(42) {} }", switchCase())); } -TEST(SwitchCase, MatchesSwitch) { +TEST_P(ASTMatchersTest, SwitchCase_MatchesSwitch) { EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchStmt())); EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchStmt())); EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchStmt())); EXPECT_TRUE(notMatches("void x() {}", switchStmt())); } -TEST(ExceptionHandling, SimpleCases) { +TEST_P(ASTMatchersTest, CxxExceptionHandling_SimpleCases) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", cxxCatchStmt())); EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", cxxTryStmt())); EXPECT_TRUE( - notMatches("void foo() try { } catch(int X) { }", cxxThrowExpr())); - EXPECT_TRUE(matches("void foo() try { throw; } catch(int X) { }", - cxxThrowExpr())); - EXPECT_TRUE(matches("void foo() try { throw 5;} catch(int X) { }", - cxxThrowExpr())); + notMatches("void foo() try { } catch(int X) { }", cxxThrowExpr())); + EXPECT_TRUE( + matches("void foo() try { throw; } catch(int X) { }", cxxThrowExpr())); + EXPECT_TRUE( + matches("void foo() try { throw 5;} catch(int X) { }", cxxThrowExpr())); EXPECT_TRUE(matches("void foo() try { throw; } catch(...) { }", cxxCatchStmt(isCatchAll()))); EXPECT_TRUE(notMatches("void foo() try { throw; } catch(int) { }", @@ -1183,18 +1482,18 @@ TEST(ExceptionHandling, SimpleCases) { varDecl(isExceptionVariable()))); } -TEST(ParenExpression, SimpleCases) { +TEST_P(ASTMatchersTest, ParenExpr_SimpleCases) { EXPECT_TRUE( matches("int i = (3);", traverse(ast_type_traits::TK_AsIs, parenExpr()))); EXPECT_TRUE(matches("int i = (3 + 7);", traverse(ast_type_traits::TK_AsIs, parenExpr()))); EXPECT_TRUE(notMatches("int i = 3;", traverse(ast_type_traits::TK_AsIs, parenExpr()))); - EXPECT_TRUE(notMatches("int foo() { return 1; }; int a = foo();", + EXPECT_TRUE(notMatches("int f() { return 1; }; void g() { int a = f(); }", traverse(ast_type_traits::TK_AsIs, parenExpr()))); } -TEST(ParenExpression, IgnoringParens) { +TEST_P(ASTMatchersTest, IgnoringParens) { EXPECT_FALSE(matches( "const char* str = (\"my-string\");", traverse(ast_type_traits::TK_AsIs, @@ -1205,31 +1504,33 @@ TEST(ParenExpression, IgnoringParens) { ignoringParens(stringLiteral())))))); } -TEST(TypeMatching, MatchesTypes) { +TEST_P(ASTMatchersTest, QualType) { EXPECT_TRUE(matches("struct S {};", qualType().bind("loc"))); } -TEST(TypeMatching, MatchesConstantArrayTypes) { +TEST_P(ASTMatchersTest, ConstantArrayType) { EXPECT_TRUE(matches("int a[2];", constantArrayType())); - EXPECT_TRUE(notMatches( - "void f() { int a[] = { 2, 3 }; int b[a[0]]; }", - constantArrayType(hasElementType(builtinType())))); + EXPECT_TRUE(notMatches("void f() { int a[] = { 2, 3 }; int b[a[0]]; }", + constantArrayType(hasElementType(builtinType())))); EXPECT_TRUE(matches("int a[42];", constantArrayType(hasSize(42)))); EXPECT_TRUE(matches("int b[2*21];", constantArrayType(hasSize(42)))); EXPECT_TRUE(notMatches("int c[41], d[43];", constantArrayType(hasSize(42)))); } -TEST(TypeMatching, MatchesDependentSizedArrayTypes) { - EXPECT_TRUE(matches( - "template class array { T data[Size]; };", - dependentSizedArrayType())); - EXPECT_TRUE(notMatches( - "int a[42]; int b[] = { 2, 3 }; void f() { int c[b[0]]; }", - dependentSizedArrayType())); +TEST_P(ASTMatchersTest, DependentSizedArrayType) { + if (!GetParam().isCXX()) { + return; + } + EXPECT_TRUE( + matches("template class array { T data[Size]; };", + dependentSizedArrayType())); + EXPECT_TRUE( + notMatches("int a[42]; int b[] = { 2, 3 }; void f() { int c[b[0]]; }", + dependentSizedArrayType())); } -TEST(TypeMatching, MatchesIncompleteArrayType) { +TEST_P(ASTMatchersTest, IncompleteArrayType) { EXPECT_TRUE(matches("int a[] = { 2, 3 };", incompleteArrayType())); EXPECT_TRUE(matches("void f(int a[]) {}", incompleteArrayType())); @@ -1237,31 +1538,32 @@ TEST(TypeMatching, MatchesIncompleteArrayType) { incompleteArrayType())); } -TEST(TypeMatching, MatchesVariableArrayType) { +TEST_P(ASTMatchersTest, VariableArrayType) { EXPECT_TRUE(matches("void f(int b) { int a[b]; }", variableArrayType())); EXPECT_TRUE(notMatches("int a[] = {2, 3}; int b[42];", variableArrayType())); - EXPECT_TRUE(matches( - "void f(int b) { int a[b]; }", - variableArrayType(hasSizeExpr(ignoringImpCasts(declRefExpr(to( - varDecl(hasName("b"))))))))); + EXPECT_TRUE(matches("void f(int b) { int a[b]; }", + variableArrayType(hasSizeExpr(ignoringImpCasts( + declRefExpr(to(varDecl(hasName("b"))))))))); } - -TEST(TypeMatching, MatchesAtomicTypes) { +TEST_P(ASTMatchersTest, AtomicType) { if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getOS() != - llvm::Triple::Win32) { + llvm::Triple::Win32) { // FIXME: Make this work for MSVC. EXPECT_TRUE(matches("_Atomic(int) i;", atomicType())); - EXPECT_TRUE(matches("_Atomic(int) i;", - atomicType(hasValueType(isInteger())))); - EXPECT_TRUE(notMatches("_Atomic(float) f;", - atomicType(hasValueType(isInteger())))); + EXPECT_TRUE( + matches("_Atomic(int) i;", atomicType(hasValueType(isInteger())))); + EXPECT_TRUE( + notMatches("_Atomic(float) f;", atomicType(hasValueType(isInteger())))); } } -TEST(TypeMatching, MatchesAutoTypes) { +TEST_P(ASTMatchersTest, AutoType) { + if (!GetParam().isCXX11OrLater()) { + return; + } EXPECT_TRUE(matches("auto i = 2;", autoType())); EXPECT_TRUE(matches("int v[] = { 2, 3 }; void f() { for (int i : v) {} }", autoType())); @@ -1272,285 +1574,351 @@ TEST(TypeMatching, MatchesAutoTypes) { // FIXME: Matching against the type-as-written can't work here, because the // type as written was not deduced. - //EXPECT_TRUE(matches("auto a = 1;", + // EXPECT_TRUE(matches("auto a = 1;", // autoType(hasDeducedType(isInteger())))); - //EXPECT_TRUE(notMatches("auto b = 2.0;", + // EXPECT_TRUE(notMatches("auto b = 2.0;", // autoType(hasDeducedType(isInteger())))); } -TEST(TypeMatching, MatchesDeclTypes) { +TEST_P(ASTMatchersTest, DecltypeType) { + if (!GetParam().isCXX11OrLater()) { + return; + } EXPECT_TRUE(matches("decltype(1 + 1) sum = 1 + 1;", decltypeType())); EXPECT_TRUE(matches("decltype(1 + 1) sum = 1 + 1;", decltypeType(hasUnderlyingType(isInteger())))); } -TEST(TypeMatching, MatchesFunctionTypes) { +TEST_P(ASTMatchersTest, FunctionType) { EXPECT_TRUE(matches("int (*f)(int);", functionType())); EXPECT_TRUE(matches("void f(int i) {}", functionType())); } -TEST(TypeMatching, IgnoringParens) { +TEST_P(ASTMatchersTest, IgnoringParens_Type) { EXPECT_TRUE( notMatches("void (*fp)(void);", pointerType(pointee(functionType())))); EXPECT_TRUE(matches("void (*fp)(void);", pointerType(pointee(ignoringParens(functionType()))))); } -TEST(TypeMatching, MatchesFunctionProtoTypes) { +TEST_P(ASTMatchersTest, FunctionProtoType) { EXPECT_TRUE(matches("int (*f)(int);", functionProtoType())); EXPECT_TRUE(matches("void f(int i);", functionProtoType())); + EXPECT_TRUE(matches("void f(void);", functionProtoType(parameterCountIs(0)))); +} + +TEST_P(ASTMatchersTest, FunctionProtoType_C) { + if (!GetParam().isC()) { + return; + } + EXPECT_TRUE(notMatches("void f();", functionProtoType())); +} + +TEST_P(ASTMatchersTest, FunctionProtoType_CXX) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(matches("void f();", functionProtoType(parameterCountIs(0)))); - EXPECT_TRUE(notMatchesC("void f();", functionProtoType())); - EXPECT_TRUE( - matchesC("void f(void);", functionProtoType(parameterCountIs(0)))); } -TEST(TypeMatching, MatchesParenType) { +TEST_P(ASTMatchersTest, ParenType) { EXPECT_TRUE( - matches("int (*array)[4];", varDecl(hasType(pointsTo(parenType()))))); + matches("int (*array)[4];", varDecl(hasType(pointsTo(parenType()))))); EXPECT_TRUE(notMatches("int *array[4];", varDecl(hasType(parenType())))); EXPECT_TRUE(matches( - "int (*ptr_to_func)(int);", - varDecl(hasType(pointsTo(parenType(innerType(functionType()))))))); + "int (*ptr_to_func)(int);", + varDecl(hasType(pointsTo(parenType(innerType(functionType()))))))); EXPECT_TRUE(notMatches( - "int (*ptr_to_array)[4];", - varDecl(hasType(pointsTo(parenType(innerType(functionType()))))))); + "int (*ptr_to_array)[4];", + varDecl(hasType(pointsTo(parenType(innerType(functionType()))))))); } -TEST(TypeMatching, PointerTypes) { +TEST_P(ASTMatchersTest, PointerType) { // FIXME: Reactive when these tests can be more specific (not matching // implicit code on certain platforms), likely when we have hasDescendant for // Types/TypeLocs. - //EXPECT_TRUE(matchAndVerifyResultTrue( + // EXPECT_TRUE(matchAndVerifyResultTrue( // "int* a;", // pointerTypeLoc(pointeeLoc(typeLoc().bind("loc"))), // std::make_unique>("loc", 1))); - //EXPECT_TRUE(matchAndVerifyResultTrue( + // EXPECT_TRUE(matchAndVerifyResultTrue( // "int* a;", // pointerTypeLoc().bind("loc"), // std::make_unique>("loc", 1))); - EXPECT_TRUE(matches( - "int** a;", - loc(pointerType(pointee(qualType()))))); - EXPECT_TRUE(matches( - "int** a;", - loc(pointerType(pointee(pointerType()))))); - EXPECT_TRUE(matches( - "int* b; int* * const a = &b;", - loc(qualType(isConstQualified(), pointerType())))); + EXPECT_TRUE(matches("int** a;", loc(pointerType(pointee(qualType()))))); + EXPECT_TRUE(matches("int** a;", loc(pointerType(pointee(pointerType()))))); + EXPECT_TRUE(matches("int* b; int* * const a = &b;", + loc(qualType(isConstQualified(), pointerType())))); + + StringRef Fragment = "int *ptr;"; + EXPECT_TRUE(notMatches(Fragment, + varDecl(hasName("ptr"), hasType(blockPointerType())))); + EXPECT_TRUE(notMatches( + Fragment, varDecl(hasName("ptr"), hasType(memberPointerType())))); + EXPECT_TRUE( + matches(Fragment, varDecl(hasName("ptr"), hasType(pointerType())))); + EXPECT_TRUE( + notMatches(Fragment, varDecl(hasName("ptr"), hasType(referenceType())))); +} +TEST_P(ASTMatchersTest, PointerType_CXX) { + if (!GetParam().isCXX()) { + return; + } StringRef Fragment = "struct A { int i; }; int A::* ptr = &A::i;"; - EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"), - hasType(blockPointerType())))); - EXPECT_TRUE(matches(Fragment, varDecl(hasName("ptr"), - hasType(memberPointerType())))); - EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"), - hasType(pointerType())))); - EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"), - hasType(referenceType())))); - EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"), - hasType(lValueReferenceType())))); - EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"), - hasType(rValueReferenceType())))); - - Fragment = "int *ptr;"; - EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"), - hasType(blockPointerType())))); - EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"), - hasType(memberPointerType())))); - EXPECT_TRUE(matches(Fragment, varDecl(hasName("ptr"), - hasType(pointerType())))); - EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"), - hasType(referenceType())))); + EXPECT_TRUE(notMatches(Fragment, + varDecl(hasName("ptr"), hasType(blockPointerType())))); + EXPECT_TRUE( + matches(Fragment, varDecl(hasName("ptr"), hasType(memberPointerType())))); + EXPECT_TRUE( + notMatches(Fragment, varDecl(hasName("ptr"), hasType(pointerType())))); + EXPECT_TRUE( + notMatches(Fragment, varDecl(hasName("ptr"), hasType(referenceType())))); + EXPECT_TRUE(notMatches( + Fragment, varDecl(hasName("ptr"), hasType(lValueReferenceType())))); + EXPECT_TRUE(notMatches( + Fragment, varDecl(hasName("ptr"), hasType(rValueReferenceType())))); Fragment = "int a; int &ref = a;"; - EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"), - hasType(blockPointerType())))); - EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"), - hasType(memberPointerType())))); - EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"), - hasType(pointerType())))); - EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"), - hasType(referenceType())))); - EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"), - hasType(lValueReferenceType())))); - EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"), - hasType(rValueReferenceType())))); - - Fragment = "int &&ref = 2;"; - EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"), - hasType(blockPointerType())))); - EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"), - hasType(memberPointerType())))); - EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"), - hasType(pointerType())))); - EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"), - hasType(referenceType())))); - EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"), - hasType(lValueReferenceType())))); - EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"), - hasType(rValueReferenceType())))); -} - -TEST(TypeMatching, AutoRefTypes) { + EXPECT_TRUE(notMatches(Fragment, + varDecl(hasName("ref"), hasType(blockPointerType())))); + EXPECT_TRUE(notMatches( + Fragment, varDecl(hasName("ref"), hasType(memberPointerType())))); + EXPECT_TRUE( + notMatches(Fragment, varDecl(hasName("ref"), hasType(pointerType())))); + EXPECT_TRUE( + matches(Fragment, varDecl(hasName("ref"), hasType(referenceType())))); + EXPECT_TRUE(matches(Fragment, + varDecl(hasName("ref"), hasType(lValueReferenceType())))); + EXPECT_TRUE(notMatches( + Fragment, varDecl(hasName("ref"), hasType(rValueReferenceType())))); +} + +TEST_P(ASTMatchersTest, PointerType_CXX11) { + if (!GetParam().isCXX11OrLater()) { + return; + } + StringRef Fragment = "int &&ref = 2;"; + EXPECT_TRUE(notMatches(Fragment, + varDecl(hasName("ref"), hasType(blockPointerType())))); + EXPECT_TRUE(notMatches( + Fragment, varDecl(hasName("ref"), hasType(memberPointerType())))); + EXPECT_TRUE( + notMatches(Fragment, varDecl(hasName("ref"), hasType(pointerType())))); + EXPECT_TRUE( + matches(Fragment, varDecl(hasName("ref"), hasType(referenceType())))); + EXPECT_TRUE(notMatches( + Fragment, varDecl(hasName("ref"), hasType(lValueReferenceType())))); + EXPECT_TRUE(matches(Fragment, + varDecl(hasName("ref"), hasType(rValueReferenceType())))); +} + +TEST_P(ASTMatchersTest, AutoRefTypes) { + if (!GetParam().isCXX11OrLater()) { + return; + } + StringRef Fragment = "auto a = 1;" "auto b = a;" "auto &c = a;" "auto &&d = c;" "auto &&e = 2;"; - EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("a"), - hasType(referenceType())))); - EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("b"), - hasType(referenceType())))); - EXPECT_TRUE(matches(Fragment, varDecl(hasName("c"), - hasType(referenceType())))); - EXPECT_TRUE(matches(Fragment, varDecl(hasName("c"), - hasType(lValueReferenceType())))); - EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("c"), - hasType(rValueReferenceType())))); - EXPECT_TRUE(matches(Fragment, varDecl(hasName("d"), - hasType(referenceType())))); - EXPECT_TRUE(matches(Fragment, varDecl(hasName("d"), - hasType(lValueReferenceType())))); - EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("d"), - hasType(rValueReferenceType())))); - EXPECT_TRUE(matches(Fragment, varDecl(hasName("e"), - hasType(referenceType())))); - EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("e"), - hasType(lValueReferenceType())))); - EXPECT_TRUE(matches(Fragment, varDecl(hasName("e"), - hasType(rValueReferenceType())))); -} - -TEST(TypeMatching, MatchesEnumTypes) { - EXPECT_TRUE(matches("enum Color { Green }; Color color;", - loc(enumType()))); - EXPECT_TRUE(matches("enum class Color { Green }; Color color;", - loc(enumType()))); -} - -TEST(TypeMatching, MatchesPointersToConstTypes) { - EXPECT_TRUE(matches("int b; int * const a = &b;", - loc(pointerType()))); - EXPECT_TRUE(matches("int b; int * const a = &b;", - loc(pointerType()))); - EXPECT_TRUE(matches( - "int b; const int * a = &b;", - loc(pointerType(pointee(builtinType()))))); - EXPECT_TRUE(matches( - "int b; const int * a = &b;", - pointerType(pointee(builtinType())))); + EXPECT_TRUE( + notMatches(Fragment, varDecl(hasName("a"), hasType(referenceType())))); + EXPECT_TRUE( + notMatches(Fragment, varDecl(hasName("b"), hasType(referenceType())))); + EXPECT_TRUE( + matches(Fragment, varDecl(hasName("c"), hasType(referenceType())))); + EXPECT_TRUE( + matches(Fragment, varDecl(hasName("c"), hasType(lValueReferenceType())))); + EXPECT_TRUE(notMatches( + Fragment, varDecl(hasName("c"), hasType(rValueReferenceType())))); + EXPECT_TRUE( + matches(Fragment, varDecl(hasName("d"), hasType(referenceType())))); + EXPECT_TRUE( + matches(Fragment, varDecl(hasName("d"), hasType(lValueReferenceType())))); + EXPECT_TRUE(notMatches( + Fragment, varDecl(hasName("d"), hasType(rValueReferenceType())))); + EXPECT_TRUE( + matches(Fragment, varDecl(hasName("e"), hasType(referenceType())))); + EXPECT_TRUE(notMatches( + Fragment, varDecl(hasName("e"), hasType(lValueReferenceType())))); + EXPECT_TRUE( + matches(Fragment, varDecl(hasName("e"), hasType(rValueReferenceType())))); +} + +TEST_P(ASTMatchersTest, EnumType) { + EXPECT_TRUE( + matches("enum Color { Green }; enum Color color;", loc(enumType()))); +} + +TEST_P(ASTMatchersTest, EnumType_CXX) { + if (!GetParam().isCXX()) { + return; + } + EXPECT_TRUE(matches("enum Color { Green }; Color color;", loc(enumType()))); } -TEST(TypeMatching, MatchesTypedefTypes) { - EXPECT_TRUE(matches("typedef int X; X a;", varDecl(hasName("a"), - hasType(typedefType())))); +TEST_P(ASTMatchersTest, EnumType_CXX11) { + if (!GetParam().isCXX11OrLater()) { + return; + } + EXPECT_TRUE( + matches("enum class Color { Green }; Color color;", loc(enumType()))); +} + +TEST_P(ASTMatchersTest, PointerType_MatchesPointersToConstTypes) { + EXPECT_TRUE(matches("int b; int * const a = &b;", loc(pointerType()))); + EXPECT_TRUE(matches("int b; int * const a = &b;", loc(pointerType()))); + EXPECT_TRUE(matches("int b; const int * a = &b;", + loc(pointerType(pointee(builtinType()))))); + EXPECT_TRUE(matches("int b; const int * a = &b;", + pointerType(pointee(builtinType())))); } -TEST(TypeMatching, MatchesTemplateSpecializationType) { +TEST_P(ASTMatchersTest, TypedefType) { + EXPECT_TRUE(matches("typedef int X; X a;", + varDecl(hasName("a"), hasType(typedefType())))); +} + +TEST_P(ASTMatchersTest, TemplateSpecializationType) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(matches("template class A{}; A a;", templateSpecializationType())); } -TEST(TypeMatching, MatchesDeucedTemplateSpecializationType) { +TEST_P(ASTMatchersTest, DeducedTemplateSpecializationType) { + if (!GetParam().isCXX17OrLater()) { + return; + } EXPECT_TRUE( matches("template class A{ public: A(T) {} }; A a(1);", - deducedTemplateSpecializationType(), langCxx17OrLater())); + deducedTemplateSpecializationType())); } -TEST(TypeMatching, MatchesRecordType) { - EXPECT_TRUE(matches("class C{}; C c;", recordType())); - EXPECT_TRUE(matches("struct S{}; S s;", +TEST_P(ASTMatchersTest, RecordType) { + EXPECT_TRUE(matches("struct S {}; struct S s;", recordType(hasDeclaration(recordDecl(hasName("S")))))); EXPECT_TRUE(notMatches("int i;", recordType(hasDeclaration(recordDecl(hasName("S")))))); } -TEST(TypeMatching, MatchesElaboratedType) { - EXPECT_TRUE(matches( - "namespace N {" - " namespace M {" - " class D {};" - " }" - "}" - "N::M::D d;", elaboratedType())); +TEST_P(ASTMatchersTest, RecordType_CXX) { + if (!GetParam().isCXX()) { + return; + } + EXPECT_TRUE(matches("class C {}; C c;", recordType())); + EXPECT_TRUE(matches("struct S {}; S s;", + recordType(hasDeclaration(recordDecl(hasName("S")))))); +} + +TEST_P(ASTMatchersTest, ElaboratedType) { + if (!GetParam().isCXX()) { + // FIXME: Add a test for `elaboratedType()` that does not depend on C++. + return; + } + EXPECT_TRUE(matches("namespace N {" + " namespace M {" + " class D {};" + " }" + "}" + "N::M::D d;", + elaboratedType())); EXPECT_TRUE(matches("class C {} c;", elaboratedType())); EXPECT_TRUE(notMatches("class C {}; C c;", elaboratedType())); } -TEST(TypeMatching, MatchesSubstTemplateTypeParmType) { +TEST_P(ASTMatchersTest, SubstTemplateTypeParmType) { + if (!GetParam().isCXX()) { + return; + } StringRef code = "template " "int F() {" " return 1 + T();" "}" "int i = F();"; EXPECT_FALSE(matches(code, binaryOperator(hasLHS( - expr(hasType(substTemplateTypeParmType())))))); + expr(hasType(substTemplateTypeParmType())))))); EXPECT_TRUE(matches(code, binaryOperator(hasRHS( - expr(hasType(substTemplateTypeParmType())))))); + expr(hasType(substTemplateTypeParmType())))))); } -TEST(NNS, MatchesNestedNameSpecifiers) { - EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;", - nestedNameSpecifier())); +TEST_P(ASTMatchersTest, NestedNameSpecifier) { + if (!GetParam().isCXX()) { + return; + } + EXPECT_TRUE( + matches("namespace ns { struct A {}; } ns::A a;", nestedNameSpecifier())); EXPECT_TRUE(matches("template class A { typename T::B b; };", nestedNameSpecifier())); - EXPECT_TRUE(matches("struct A { void f(); }; void A::f() {}", - nestedNameSpecifier())); + EXPECT_TRUE( + matches("struct A { void f(); }; void A::f() {}", nestedNameSpecifier())); EXPECT_TRUE(matches("namespace a { namespace b {} } namespace ab = a::b;", nestedNameSpecifier())); - EXPECT_TRUE(matches( - "struct A { static void f() {} }; void g() { A::f(); }", - nestedNameSpecifier())); - EXPECT_TRUE(notMatches( - "struct A { static void f() {} }; void g(A* a) { a->f(); }", - nestedNameSpecifier())); + EXPECT_TRUE(matches("struct A { static void f() {} }; void g() { A::f(); }", + nestedNameSpecifier())); + EXPECT_TRUE( + notMatches("struct A { static void f() {} }; void g(A* a) { a->f(); }", + nestedNameSpecifier())); } -TEST(NullStatement, SimpleCases) { +TEST_P(ASTMatchersTest, NullStmt) { EXPECT_TRUE(matches("void f() {int i;;}", nullStmt())); EXPECT_TRUE(notMatches("void f() {int i;}", nullStmt())); } -TEST(NS, Alias) { +TEST_P(ASTMatchersTest, NamespaceAliasDecl) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(matches("namespace test {} namespace alias = ::test;", namespaceAliasDecl(hasName("alias")))); } -TEST(NNS, MatchesTypes) { +TEST_P(ASTMatchersTest, NestedNameSpecifier_MatchesTypes) { + if (!GetParam().isCXX()) { + return; + } NestedNameSpecifierMatcher Matcher = nestedNameSpecifier( - specifiesType(hasDeclaration(recordDecl(hasName("A"))))); + specifiesType(hasDeclaration(recordDecl(hasName("A"))))); EXPECT_TRUE(matches("struct A { struct B {}; }; A::B b;", Matcher)); - EXPECT_TRUE(matches("struct A { struct B { struct C {}; }; }; A::B::C c;", - Matcher)); + EXPECT_TRUE( + matches("struct A { struct B { struct C {}; }; }; A::B::C c;", Matcher)); EXPECT_TRUE(notMatches("namespace A { struct B {}; } A::B b;", Matcher)); } -TEST(NNS, MatchesNamespaceDecls) { - NestedNameSpecifierMatcher Matcher = nestedNameSpecifier( - specifiesNamespace(hasName("ns"))); +TEST_P(ASTMatchersTest, NestedNameSpecifier_MatchesNamespaceDecls) { + if (!GetParam().isCXX()) { + return; + } + NestedNameSpecifierMatcher Matcher = + nestedNameSpecifier(specifiesNamespace(hasName("ns"))); EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;", Matcher)); EXPECT_TRUE(notMatches("namespace xx { struct A {}; } xx::A a;", Matcher)); EXPECT_TRUE(notMatches("struct ns { struct A {}; }; ns::A a;", Matcher)); } -TEST(NNS, MatchesNestedNameSpecifierPrefixes) { - EXPECT_TRUE(matches( - "struct A { struct B { struct C {}; }; }; A::B::C c;", - nestedNameSpecifier(hasPrefix(specifiesType(asString("struct A")))))); +TEST_P(ASTMatchersTest, + NestedNameSpecifier_MatchesNestedNameSpecifierPrefixes) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(matches( - "struct A { struct B { struct C {}; }; }; A::B::C c;", - nestedNameSpecifierLoc(hasPrefix( - specifiesTypeLoc(loc(qualType(asString("struct A")))))))); + "struct A { struct B { struct C {}; }; }; A::B::C c;", + nestedNameSpecifier(hasPrefix(specifiesType(asString("struct A")))))); + EXPECT_TRUE(matches("struct A { struct B { struct C {}; }; }; A::B::C c;", + nestedNameSpecifierLoc(hasPrefix(specifiesTypeLoc( + loc(qualType(asString("struct A")))))))); EXPECT_TRUE(matches( - "namespace N { struct A { struct B { struct C {}; }; }; } N::A::B::C c;", - nestedNameSpecifierLoc(hasPrefix( - specifiesTypeLoc(loc(qualType(asString("struct N::A")))))))); + "namespace N { struct A { struct B { struct C {}; }; }; } N::A::B::C c;", + nestedNameSpecifierLoc(hasPrefix( + specifiesTypeLoc(loc(qualType(asString("struct N::A")))))))); } - template class VerifyAncestorHasChildIsEqual : public BoundNodesCallback { public: @@ -1566,18 +1934,18 @@ class VerifyAncestorHasChildIsEqual : public BoundNodesCallback { // to equalsNode. const T *TypedNode = cast(Node); return selectFirst( - "", match(stmt(hasParent( - stmt(has(stmt(equalsNode(TypedNode)))).bind(""))), - *Node, Context)) != nullptr; + "", match(stmt(hasParent( + stmt(has(stmt(equalsNode(TypedNode)))).bind(""))), + *Node, Context)) != nullptr; } bool verify(const BoundNodes &Nodes, ASTContext &Context, const Decl *Node) { // Use the original typed pointer to verify we can pass pointers to subtypes // to equalsNode. const T *TypedNode = cast(Node); return selectFirst( - "", match(decl(hasParent( - decl(has(decl(equalsNode(TypedNode)))).bind(""))), - *Node, Context)) != nullptr; + "", match(decl(hasParent( + decl(has(decl(equalsNode(TypedNode)))).bind(""))), + *Node, Context)) != nullptr; } bool verify(const BoundNodes &Nodes, ASTContext &Context, const Type *Node) { // Use the original typed pointer to verify we can pass pointers to subtypes @@ -1585,47 +1953,74 @@ class VerifyAncestorHasChildIsEqual : public BoundNodesCallback { const T *TypedNode = cast(Node); const auto *Dec = Nodes.getNodeAs("decl"); return selectFirst( - "", match(fieldDecl(hasParent(decl(has(fieldDecl( - hasType(type(equalsNode(TypedNode)).bind(""))))))), - *Dec, Context)) != nullptr; + "", match(fieldDecl(hasParent(decl(has(fieldDecl( + hasType(type(equalsNode(TypedNode)).bind(""))))))), + *Dec, Context)) != nullptr; } }; -TEST(IsEqualTo, MatchesNodesByIdentity) { +TEST_P(ASTMatchersTest, IsEqualTo_MatchesNodesByIdentity) { EXPECT_TRUE(matchAndVerifyResultTrue( - "class X { class Y {}; };", recordDecl(hasName("::X::Y")).bind(""), - std::make_unique>())); + "void f() { if (1) if(1) {} }", ifStmt().bind(""), + std::make_unique>())); +} + +TEST_P(ASTMatchersTest, IsEqualTo_MatchesNodesByIdentity_Cxx) { + if (!GetParam().isCXX()) { + return; + } EXPECT_TRUE(matchAndVerifyResultTrue( - "void f() { if (true) if(true) {} }", ifStmt().bind(""), - std::make_unique>())); + "class X { class Y {}; };", recordDecl(hasName("::X::Y")).bind(""), + std::make_unique>())); EXPECT_TRUE(matchAndVerifyResultTrue( - "class X { class Y {} y; };", - fieldDecl(hasName("y"), hasType(type().bind(""))).bind("decl"), - std::make_unique>())); + "class X { class Y {} y; };", + fieldDecl(hasName("y"), hasType(type().bind(""))).bind("decl"), + std::make_unique>())); } -TEST(TypedefDeclMatcher, Match) { +TEST_P(ASTMatchersTest, TypedefDecl) { EXPECT_TRUE(matches("typedef int typedefDeclTest;", typedefDecl(hasName("typedefDeclTest")))); - EXPECT_TRUE(notMatches("using typedefDeclTest2 = int;", - typedefDecl(hasName("typedefDeclTest2")))); } -TEST(TypeAliasDeclMatcher, Match) { - EXPECT_TRUE(matches("using typeAliasTest2 = int;", - typeAliasDecl(hasName("typeAliasTest2")))); +TEST_P(ASTMatchersTest, TypedefDecl_Cxx) { + if (!GetParam().isCXX11OrLater()) { + return; + } + EXPECT_TRUE(notMatches("using typedefDeclTest = int;", + typedefDecl(hasName("typedefDeclTest")))); +} + +TEST_P(ASTMatchersTest, TypeAliasDecl) { EXPECT_TRUE(notMatches("typedef int typeAliasTest;", typeAliasDecl(hasName("typeAliasTest")))); } -TEST(TypedefNameDeclMatcher, Match) { +TEST_P(ASTMatchersTest, TypeAliasDecl_CXX) { + if (!GetParam().isCXX11OrLater()) { + return; + } + EXPECT_TRUE(matches("using typeAliasTest = int;", + typeAliasDecl(hasName("typeAliasTest")))); +} + +TEST_P(ASTMatchersTest, TypedefNameDecl) { EXPECT_TRUE(matches("typedef int typedefNameDeclTest1;", typedefNameDecl(hasName("typedefNameDeclTest1")))); - EXPECT_TRUE(matches("using typedefNameDeclTest2 = int;", - typedefNameDecl(hasName("typedefNameDeclTest2")))); } -TEST(TypeAliasTemplateDeclMatcher, Match) { +TEST_P(ASTMatchersTest, TypedefNameDecl_CXX) { + if (!GetParam().isCXX11OrLater()) { + return; + } + EXPECT_TRUE(matches("using typedefNameDeclTest = int;", + typedefNameDecl(hasName("typedefNameDeclTest")))); +} + +TEST_P(ASTMatchersTest, TypeAliasTemplateDecl) { + if (!GetParam().isCXX11OrLater()) { + return; + } StringRef Code = R"( template class X { T t; }; @@ -1641,8 +2036,8 @@ TEST(TypeAliasTemplateDeclMatcher, Match) { notMatches(Code, typeAliasTemplateDecl(hasName("typeAliasDecl")))); } -TEST(ObjCMessageExprMatcher, SimpleExprs) { - // don't find ObjCMessageExpr where none are present +TEST(ASTMatchersTestObjC, ObjCMessageExpr) { + // Don't find ObjCMessageExpr where none are present. EXPECT_TRUE(notMatchesObjC("", objcMessageExpr(anything()))); StringRef Objc1String = "@interface Str " @@ -1659,46 +2054,34 @@ TEST(ObjCMessageExprMatcher, SimpleExprs) { " Str *up = [text uppercaseString];" "} " "@end "; - EXPECT_TRUE(matchesObjC( - Objc1String, - objcMessageExpr(anything()))); + EXPECT_TRUE(matchesObjC(Objc1String, objcMessageExpr(anything()))); EXPECT_TRUE(matchesObjC(Objc1String, - objcMessageExpr(hasAnySelector({ - "contents", "meth:"})) + objcMessageExpr(hasAnySelector({"contents", "meth:"})) - )); - EXPECT_TRUE(matchesObjC( - Objc1String, - objcMessageExpr(hasSelector("contents")))); - EXPECT_TRUE(matchesObjC( - Objc1String, - objcMessageExpr(hasAnySelector("contents", "contentsA")))); - EXPECT_FALSE(matchesObjC( - Objc1String, - objcMessageExpr(hasAnySelector("contentsB", "contentsC")))); + )); + EXPECT_TRUE( + matchesObjC(Objc1String, objcMessageExpr(hasSelector("contents")))); EXPECT_TRUE(matchesObjC( - Objc1String, - objcMessageExpr(matchesSelector("cont*")))); + Objc1String, objcMessageExpr(hasAnySelector("contents", "contentsA")))); EXPECT_FALSE(matchesObjC( - Objc1String, - objcMessageExpr(matchesSelector("?cont*")))); - EXPECT_TRUE(notMatchesObjC( - Objc1String, - objcMessageExpr(hasSelector("contents"), hasNullSelector()))); - EXPECT_TRUE(matchesObjC( - Objc1String, - objcMessageExpr(hasSelector("contents"), hasUnarySelector()))); - EXPECT_TRUE(matchesObjC( - Objc1String, - objcMessageExpr(hasSelector("contents"), numSelectorArgs(0)))); - EXPECT_TRUE(matchesObjC( - Objc1String, - objcMessageExpr(matchesSelector("uppercase*"), - argumentCountIs(0) - ))); + Objc1String, objcMessageExpr(hasAnySelector("contentsB", "contentsC")))); + EXPECT_TRUE( + matchesObjC(Objc1String, objcMessageExpr(matchesSelector("cont*")))); + EXPECT_FALSE( + matchesObjC(Objc1String, objcMessageExpr(matchesSelector("?cont*")))); + EXPECT_TRUE( + notMatchesObjC(Objc1String, objcMessageExpr(hasSelector("contents"), + hasNullSelector()))); + EXPECT_TRUE(matchesObjC(Objc1String, objcMessageExpr(hasSelector("contents"), + hasUnarySelector()))); + EXPECT_TRUE(matchesObjC(Objc1String, objcMessageExpr(hasSelector("contents"), + numSelectorArgs(0)))); + EXPECT_TRUE( + matchesObjC(Objc1String, objcMessageExpr(matchesSelector("uppercase*"), + argumentCountIs(0)))); } -TEST(ObjCDeclMatcher, CoreDecls) { +TEST(ASTMatchersTestObjC, ObjCDecls) { StringRef ObjCString = "@protocol Proto " "- (void)protoDidThing; " "@end " @@ -1716,36 +2099,20 @@ TEST(ObjCDeclMatcher, CoreDecls) { "- (void)abc_doThing {} " "@end "; - EXPECT_TRUE(matchesObjC( - ObjCString, - objcProtocolDecl(hasName("Proto")))); - EXPECT_TRUE(matchesObjC( - ObjCString, - objcImplementationDecl(hasName("Thing")))); - EXPECT_TRUE(matchesObjC( - ObjCString, - objcCategoryDecl(hasName("ABC")))); - EXPECT_TRUE(matchesObjC( - ObjCString, - objcCategoryImplDecl(hasName("ABC")))); - EXPECT_TRUE(matchesObjC( - ObjCString, - objcMethodDecl(hasName("protoDidThing")))); - EXPECT_TRUE(matchesObjC( - ObjCString, - objcMethodDecl(hasName("abc_doThing")))); - EXPECT_TRUE(matchesObjC( - ObjCString, - objcMethodDecl(hasName("anything")))); - EXPECT_TRUE(matchesObjC( - ObjCString, - objcIvarDecl(hasName("_ivar")))); - EXPECT_TRUE(matchesObjC( - ObjCString, - objcPropertyDecl(hasName("enabled")))); + EXPECT_TRUE(matchesObjC(ObjCString, objcProtocolDecl(hasName("Proto")))); + EXPECT_TRUE( + matchesObjC(ObjCString, objcImplementationDecl(hasName("Thing")))); + EXPECT_TRUE(matchesObjC(ObjCString, objcCategoryDecl(hasName("ABC")))); + EXPECT_TRUE(matchesObjC(ObjCString, objcCategoryImplDecl(hasName("ABC")))); + EXPECT_TRUE( + matchesObjC(ObjCString, objcMethodDecl(hasName("protoDidThing")))); + EXPECT_TRUE(matchesObjC(ObjCString, objcMethodDecl(hasName("abc_doThing")))); + EXPECT_TRUE(matchesObjC(ObjCString, objcMethodDecl(hasName("anything")))); + EXPECT_TRUE(matchesObjC(ObjCString, objcIvarDecl(hasName("_ivar")))); + EXPECT_TRUE(matchesObjC(ObjCString, objcPropertyDecl(hasName("enabled")))); } -TEST(ObjCStmtMatcher, ExceptionStmts) { +TEST(ASTMatchersTestObjC, ObjCExceptionStmts) { StringRef ObjCString = "void f(id obj) {" " @try {" " @throw obj;" @@ -1753,21 +2120,13 @@ TEST(ObjCStmtMatcher, ExceptionStmts) { " } @finally {}" "}"; - EXPECT_TRUE(matchesObjC( - ObjCString, - objcTryStmt())); - EXPECT_TRUE(matchesObjC( - ObjCString, - objcThrowStmt())); - EXPECT_TRUE(matchesObjC( - ObjCString, - objcCatchStmt())); - EXPECT_TRUE(matchesObjC( - ObjCString, - objcFinallyStmt())); + EXPECT_TRUE(matchesObjC(ObjCString, objcTryStmt())); + EXPECT_TRUE(matchesObjC(ObjCString, objcThrowStmt())); + EXPECT_TRUE(matchesObjC(ObjCString, objcCatchStmt())); + EXPECT_TRUE(matchesObjC(ObjCString, objcFinallyStmt())); } -TEST(ObjCAutoreleaseMatcher, AutoreleasePool) { +TEST(ASTMatchersTestObjC, ObjCAutoreleasePoolStmt) { StringRef ObjCString = "void f() {" "@autoreleasepool {" " int x = 1;" @@ -1778,7 +2137,7 @@ TEST(ObjCAutoreleaseMatcher, AutoreleasePool) { EXPECT_FALSE(matchesObjC(ObjCStringNoPool, autoreleasePoolStmt())); } -TEST(OMPExecutableDirective, Matches) { +TEST(ASTMatchersTestOpenMP, OMPExecutableDirective) { auto Matcher = stmt(ompExecutableDirective()); StringRef Source0 = R"( @@ -1802,7 +2161,7 @@ void x() { EXPECT_TRUE(notMatchesWithOpenMP(Source2, Matcher)); } -TEST(OMPDefaultClause, Matches) { +TEST(ASTMatchersTestOpenMP, OMPDefaultClause) { auto Matcher = ompExecutableDirective(hasAnyClause(ompDefaultClause())); StringRef Source0 = R"( @@ -1833,15 +2192,33 @@ void x() { EXPECT_TRUE(matchesWithOpenMP(Source3, Matcher)); StringRef Source4 = R"( +void x() { +#pragma omp parallel default(firstprivate) +; +})"; + EXPECT_TRUE(matchesWithOpenMP51(Source4, Matcher)); + + StringRef Source5 = R"( void x(int x) { #pragma omp parallel num_threads(x) ; })"; - EXPECT_TRUE(notMatchesWithOpenMP(Source4, Matcher)); + EXPECT_TRUE(notMatchesWithOpenMP(Source5, Matcher)); } -TEST(MatchFinderAPI, matchesDynamic) { +TEST(ASTMatchersTest, Finder_DynamicOnlyAcceptsSomeMatchers) { + MatchFinder Finder; + EXPECT_TRUE(Finder.addDynamicMatcher(decl(), nullptr)); + EXPECT_TRUE(Finder.addDynamicMatcher(callExpr(), nullptr)); + EXPECT_TRUE( + Finder.addDynamicMatcher(constantArrayType(hasSize(42)), nullptr)); + + // Do not accept non-toplevel matchers. + EXPECT_FALSE(Finder.addDynamicMatcher(isMain(), nullptr)); + EXPECT_FALSE(Finder.addDynamicMatcher(hasName("x"), nullptr)); +} +TEST(MatchFinderAPI, MatchesDynamic) { StringRef SourceCode = "struct A { void f() {} };"; auto Matcher = functionDecl(isDefinition()).bind("method"); @@ -1864,5 +2241,35 @@ TEST(MatchFinderAPI, matchesDynamic) { EXPECT_EQ(MethodNode, GlobalMethodNode); } +static std::vector allTestClangConfigs() { + std::vector all_configs; + for (TestLanguage lang : {Lang_C89, Lang_C99, Lang_CXX03, Lang_CXX11, + Lang_CXX14, Lang_CXX17, Lang_CXX20}) { + TestClangConfig config; + config.Language = lang; + + // Use an unknown-unknown triple so we don't instantiate the full system + // toolchain. On Linux, instantiating the toolchain involves stat'ing + // large portions of /usr/lib, and this slows down not only this test, but + // all other tests, via contention in the kernel. + // + // FIXME: This is a hack to work around the fact that there's no way to do + // the equivalent of runToolOnCodeWithArgs without instantiating a full + // Driver. We should consider having a function, at least for tests, that + // invokes cc1. + config.Target = "i386-unknown-unknown"; + all_configs.push_back(config); + + // Windows target is interesting to test because it enables + // `-fdelayed-template-parsing`. + config.Target = "x86_64-pc-win32-msvc"; + all_configs.push_back(config); + } + return all_configs; +} + +INSTANTIATE_TEST_CASE_P(ASTMatchersTests, ASTMatchersTest, + testing::ValuesIn(allTestClangConfigs()), ); + } // namespace ast_matchers } // namespace clang diff --git a/clang/unittests/ASTMatchers/ASTMatchersTest.h b/clang/unittests/ASTMatchers/ASTMatchersTest.h index fec033c4d72e6..bde6297f82ddc 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTest.h +++ b/clang/unittests/ASTMatchers/ASTMatchersTest.h @@ -12,6 +12,7 @@ #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Testing/CommandLineArgs.h" +#include "clang/Testing/TestClangConfig.h" #include "clang/Tooling/Tooling.h" #include "gtest/gtest.h" @@ -19,10 +20,10 @@ namespace clang { namespace ast_matchers { using clang::tooling::buildASTFromCodeWithArgs; +using clang::tooling::FileContentMappings; +using clang::tooling::FrontendActionFactory; using clang::tooling::newFrontendActionFactory; using clang::tooling::runToolOnCodeWithArgs; -using clang::tooling::FrontendActionFactory; -using clang::tooling::FileContentMappings; class BoundNodesCallback { public: @@ -37,7 +38,8 @@ class BoundNodesCallback { // If 'FindResultVerifier' is NULL, sets *Verified to true when Run is called. class VerifyMatch : public MatchFinder::MatchCallback { public: - VerifyMatch(std::unique_ptr FindResultVerifier, bool *Verified) + VerifyMatch(std::unique_ptr FindResultVerifier, + bool *Verified) : Verified(Verified), FindResultReviewer(std::move(FindResultVerifier)) {} void run(const MatchFinder::MatchResult &Result) override { @@ -94,34 +96,45 @@ testing::AssertionResult matchesConditionally( return testing::AssertionFailure() << "Could not add dynamic matcher"; std::unique_ptr Factory( newFrontendActionFactory(&Finder)); - // Some tests need rtti/exceptions on. Use an unknown-unknown triple so we - // don't instantiate the full system toolchain. On Linux, instantiating the - // toolchain involves stat'ing large portions of /usr/lib, and this slows down - // not only this test, but all other tests, via contention in the kernel. - // - // FIXME: This is a hack to work around the fact that there's no way to do the - // equivalent of runToolOnCodeWithArgs without instantiating a full Driver. - // We should consider having a function, at least for tests, that invokes cc1. - std::vector Args(CompileArgs.begin(), CompileArgs.end()); - Args.insert(Args.end(), {"-frtti", "-fexceptions", - "-target", "i386-unknown-unknown"}); + std::vector Args = { + // Some tests need rtti/exceptions on. + "-frtti", "-fexceptions", + // Ensure that tests specify the C++ standard version that they need. + "-Werror=c++14-extensions", "-Werror=c++17-extensions", + "-Werror=c++20-extensions"}; + // Append additional arguments at the end to allow overriding the default + // choices that we made above. + llvm::copy(CompileArgs, std::back_inserter(Args)); + if (llvm::find(Args, "-target") == Args.end()) { + // Use an unknown-unknown triple so we don't instantiate the full system + // toolchain. On Linux, instantiating the toolchain involves stat'ing + // large portions of /usr/lib, and this slows down not only this test, but + // all other tests, via contention in the kernel. + // + // FIXME: This is a hack to work around the fact that there's no way to do + // the equivalent of runToolOnCodeWithArgs without instantiating a full + // Driver. We should consider having a function, at least for tests, that + // invokes cc1. + Args.push_back("-target"); + Args.push_back("i386-unknown-unknown"); + } + if (!runToolOnCodeWithArgs( Factory->create(), Code, Args, Filename, "clang-tool", std::make_shared(), VirtualMappedFiles)) { return testing::AssertionFailure() << "Parsing error in \"" << Code << "\""; } if (Found != DynamicFound) { - return testing::AssertionFailure() << "Dynamic match result (" - << DynamicFound - << ") does not match static result (" - << Found << ")"; + return testing::AssertionFailure() + << "Dynamic match result (" << DynamicFound + << ") does not match static result (" << Found << ")"; } if (!Found && ExpectMatch) { return testing::AssertionFailure() - << "Could not find match in \"" << Code << "\""; + << "Could not find match in \"" << Code << "\""; } else if (Found && !ExpectMatch) { return testing::AssertionFailure() - << "Found unexpected match in \"" << Code << "\""; + << "Found unexpected match in \"" << Code << "\""; } return testing::AssertionSuccess(); } @@ -131,13 +144,9 @@ testing::AssertionResult matchesConditionally(const Twine &Code, const T &AMatcher, bool ExpectMatch, ArrayRef TestLanguages) { for (auto Lang : TestLanguages) { - std::vector Args = getCommandLineArgsForTesting(Lang); - Args.insert(Args.end(), - {"-Werror=c++14-extensions", "-Werror=c++17-extensions", - "-Werror=c++20-extensions"}); - auto Result = matchesConditionally(Code, AMatcher, ExpectMatch, Args, - FileContentMappings(), - getFilenameForTesting(Lang)); + auto Result = matchesConditionally( + Code, AMatcher, ExpectMatch, getCommandLineArgsForTesting(Lang), + FileContentMappings(), getFilenameForTesting(Lang)); if (!Result) return Result; } @@ -174,11 +183,6 @@ testing::AssertionResult matchesC(const Twine &Code, const T &AMatcher) { "input.c"); } -template -testing::AssertionResult matchesC99(const Twine &Code, const T &AMatcher) { - return matchesConditionally(Code, AMatcher, true, {Lang_C99}); -} - template testing::AssertionResult notMatchesC(const Twine &Code, const T &AMatcher) { return matchesConditionally(Code, AMatcher, false, {Lang_C89}); @@ -212,7 +216,8 @@ matchesConditionallyWithCuda(const Twine &Code, const T &AMatcher, " size_t sharedSize = 0," " cudaStream_t stream = 0);" "extern \"C\" unsigned __cudaPushCallConfiguration(" - " dim3 gridDim, dim3 blockDim, size_t sharedMem = 0, void *stream = 0);"; + " dim3 gridDim, dim3 blockDim, size_t sharedMem = 0, void *stream = " + "0);"; bool Found = false, DynamicFound = false; MatchFinder Finder; @@ -229,22 +234,20 @@ matchesConditionallyWithCuda(const Twine &Code, const T &AMatcher, std::vector Args = { "-xcuda", "-fno-ms-extensions", "--cuda-host-only", "-nocudainc", "-target", "x86_64-unknown-unknown", std::string(CompileArg)}; - if (!runToolOnCodeWithArgs(Factory->create(), - CudaHeader + Code, Args)) { + if (!runToolOnCodeWithArgs(Factory->create(), CudaHeader + Code, Args)) { return testing::AssertionFailure() << "Parsing error in \"" << Code << "\""; } if (Found != DynamicFound) { - return testing::AssertionFailure() << "Dynamic match result (" - << DynamicFound - << ") does not match static result (" - << Found << ")"; + return testing::AssertionFailure() + << "Dynamic match result (" << DynamicFound + << ") does not match static result (" << Found << ")"; } if (!Found && ExpectMatch) { return testing::AssertionFailure() - << "Could not find match in \"" << Code << "\""; + << "Could not find match in \"" << Code << "\""; } else if (Found && !ExpectMatch) { return testing::AssertionFailure() - << "Found unexpected match in \"" << Code << "\""; + << "Found unexpected match in \"" << Code << "\""; } return testing::AssertionSuccess(); } @@ -272,13 +275,28 @@ testing::AssertionResult notMatchesWithOpenMP(const Twine &Code, return matchesConditionally(Code, AMatcher, false, {"-fopenmp=libomp"}); } +template +testing::AssertionResult matchesWithOpenMP51(const Twine &Code, + const T &AMatcher) { + return matchesConditionally(Code, AMatcher, true, + {"-fopenmp=libomp", "-fopenmp-version=51"}); +} + +template +testing::AssertionResult notMatchesWithOpenMP51(const Twine &Code, + const T &AMatcher) { + return matchesConditionally(Code, AMatcher, false, + {"-fopenmp=libomp", "-fopenmp-version=51"}); +} + template testing::AssertionResult matchAndVerifyResultConditionally( const Twine &Code, const T &AMatcher, std::unique_ptr FindResultVerifier, bool ExpectResult) { bool VerifiedResult = false; MatchFinder Finder; - VerifyMatch VerifyVerifiedResult(std::move(FindResultVerifier), &VerifiedResult); + VerifyMatch VerifyVerifiedResult(std::move(FindResultVerifier), + &VerifiedResult); Finder.addMatcher(AMatcher, &VerifyVerifiedResult); std::unique_ptr Factory( newFrontendActionFactory(&Finder)); @@ -292,10 +310,10 @@ testing::AssertionResult matchAndVerifyResultConditionally( } if (!VerifiedResult && ExpectResult) { return testing::AssertionFailure() - << "Could not verify result in \"" << Code << "\""; + << "Could not verify result in \"" << Code << "\""; } else if (VerifiedResult && !ExpectResult) { return testing::AssertionFailure() - << "Verified unexpected result in \"" << Code << "\""; + << "Verified unexpected result in \"" << Code << "\""; } VerifiedResult = false; @@ -303,15 +321,15 @@ testing::AssertionResult matchAndVerifyResultConditionally( std::unique_ptr AST( buildASTFromCodeWithArgs(Code.toStringRef(Buffer), Args)); if (!AST.get()) - return testing::AssertionFailure() << "Parsing error in \"" << Code - << "\" while building AST"; + return testing::AssertionFailure() + << "Parsing error in \"" << Code << "\" while building AST"; Finder.matchAST(AST->getASTContext()); if (!VerifiedResult && ExpectResult) { return testing::AssertionFailure() - << "Could not verify result in \"" << Code << "\" with AST"; + << "Could not verify result in \"" << Code << "\" with AST"; } else if (VerifiedResult && !ExpectResult) { return testing::AssertionFailure() - << "Verified unexpected result in \"" << Code << "\" with AST"; + << "Verified unexpected result in \"" << Code << "\" with AST"; } return testing::AssertionSuccess(); @@ -323,8 +341,8 @@ template testing::AssertionResult matchAndVerifyResultTrue( const Twine &Code, const T &AMatcher, std::unique_ptr FindResultVerifier) { - return matchAndVerifyResultConditionally( - Code, AMatcher, std::move(FindResultVerifier), true); + return matchAndVerifyResultConditionally(Code, AMatcher, + std::move(FindResultVerifier), true); } template @@ -338,8 +356,7 @@ testing::AssertionResult matchAndVerifyResultFalse( // Implements a run method that returns whether BoundNodes contains a // Decl bound to Id that can be dynamically cast to T. // Optionally checks that the check succeeded a specific number of times. -template -class VerifyIdIsBoundTo : public BoundNodesCallback { +template class VerifyIdIsBoundTo : public BoundNodesCallback { public: // Create an object that checks that a node of type \c T was bound to \c Id. // Does not check for a certain number of matches. @@ -382,7 +399,7 @@ class VerifyIdIsBoundTo : public BoundNodesCallback { if (const NamedDecl *Named = Nodes->getNodeAs(Id)) { Name = Named->getNameAsString(); } else if (const NestedNameSpecifier *NNS = - Nodes->getNodeAs(Id)) { + Nodes->getNodeAs(Id)) { llvm::raw_string_ostream OS(Name); NNS->print(OS, PrintingPolicy(LangOptions())); } @@ -394,7 +411,7 @@ class VerifyIdIsBoundTo : public BoundNodesCallback { return true; } EXPECT_TRUE(M.count(Id) == 0 || - M.find(Id)->second.template get() == nullptr); + M.find(Id)->second.template get() == nullptr); return false; } @@ -410,7 +427,27 @@ class VerifyIdIsBoundTo : public BoundNodesCallback { std::string Name; }; +class ASTMatchersTest : public ::testing::Test, + public ::testing::WithParamInterface { +protected: + template + testing::AssertionResult matches(const Twine &Code, const T &AMatcher) { + const TestClangConfig &TestConfig = GetParam(); + return clang::ast_matchers::matchesConditionally( + Code, AMatcher, /*ExpectMatch=*/true, TestConfig.getCommandLineArgs(), + FileContentMappings(), getFilenameForTesting(TestConfig.Language)); + } + + template + testing::AssertionResult notMatches(const Twine &Code, const T &AMatcher) { + const TestClangConfig &TestConfig = GetParam(); + return clang::ast_matchers::matchesConditionally( + Code, AMatcher, /*ExpectMatch=*/false, TestConfig.getCommandLineArgs(), + FileContentMappings(), getFilenameForTesting(TestConfig.Language)); + } +}; + } // namespace ast_matchers } // namespace clang -#endif // LLVM_CLANG_UNITTESTS_AST_MATCHERS_AST_MATCHERS_TEST_H +#endif // LLVM_CLANG_UNITTESTS_AST_MATCHERS_AST_MATCHERS_TEST_H diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp index 50d101167ff20..380538697f461 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -2864,6 +2864,34 @@ TEST(HasParent, MatchesOnlyParent) { compoundStmt(hasParent(ifStmt())))); } +TEST(MatcherMemoize, HasParentDiffersFromHas) { + // Test introduced after detecting a bug in memoization + constexpr auto code = "void f() { throw 1; }"; + EXPECT_TRUE(notMatches( + code, + cxxThrowExpr(hasParent(expr())))); + EXPECT_TRUE(matches( + code, + cxxThrowExpr(has(expr())))); + EXPECT_TRUE(matches( + code, + cxxThrowExpr(anyOf(hasParent(expr()), has(expr()))))); +} + +TEST(MatcherMemoize, HasDiffersFromHasDescendant) { + // Test introduced after detecting a bug in memoization + constexpr auto code = "void f() { throw 1+1; }"; + EXPECT_TRUE(notMatches( + code, + cxxThrowExpr(has(integerLiteral())))); + EXPECT_TRUE(matches( + code, + cxxThrowExpr(hasDescendant(integerLiteral())))); + EXPECT_TRUE(notMatches(code, + cxxThrowExpr(allOf( + hasDescendant(integerLiteral()), + has(integerLiteral()))))); +} TEST(HasAncestor, MatchesAllAncestors) { EXPECT_TRUE(matches( "template struct C { static void f() { 42; } };" diff --git a/clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp b/clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp index f5e324a3b158d..3af5574216f19 100644 --- a/clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp +++ b/clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp @@ -259,6 +259,15 @@ TEST(ParserTest, FullParserTest) { EXPECT_TRUE(matches("unsigned X = sizeof(int);", MStmt)); EXPECT_FALSE(matches("unsigned X = alignof(int);", MStmt)); + Code = + R"query(namedDecl(matchesName("^::[ABC]*$", "IgnoreCase | BasicRegex")))query"; + llvm::Optional MatchesName( + Parser::parseMatcherExpression(Code, nullptr, nullptr, &Error)); + EXPECT_EQ("", Error.toStringFull()); + M = MatchesName->unconditionalConvertTo(); + EXPECT_TRUE(matches("unsigned AAACCBB;", M)); + EXPECT_TRUE(matches("unsigned aaaccbb;", M)); + Code = "hasInitializer(\n binaryOperator(hasLHS(\"A\")))"; EXPECT_TRUE(!Parser::parseMatcherExpression(Code, &Error).hasValue()); EXPECT_EQ("1:1: Error parsing argument 1 for matcher hasInitializer.\n" @@ -348,6 +357,26 @@ TEST(ParserTest, Errors) { "1:14: Incorrect type for arg 1. (Expected = string) != (Actual = " "String)", ParseMatcherWithError(R"query(decl(hasAttr("unrelated")))query")); + EXPECT_EQ( + "1:1: Error parsing argument 1 for matcher namedDecl.\n" + "1:11: Error building matcher matchesName.\n" + "1:33: Unknown value 'Ignorecase' for arg 2; did you mean 'IgnoreCase'", + ParseMatcherWithError( + R"query(namedDecl(matchesName("[ABC]*", "Ignorecase")))query")); + EXPECT_EQ( + "1:1: Error parsing argument 1 for matcher namedDecl.\n" + "1:11: Error building matcher matchesName.\n" + "1:33: Incorrect type for arg 2. (Expected = string) != (Actual = " + "String)", + ParseMatcherWithError( + R"query(namedDecl(matchesName("[ABC]*", "IgnoreCase & BasicRegex")))query")); + EXPECT_EQ( + "1:1: Error parsing argument 1 for matcher namedDecl.\n" + "1:11: Error building matcher matchesName.\n" + "1:33: Unknown value 'IgnoreCase | Basicregex' for arg 2; did you mean " + "'IgnoreCase | BasicRegex'", + ParseMatcherWithError( + R"query(namedDecl(matchesName("[ABC]*", "IgnoreCase | Basicregex")))query")); } TEST(ParserTest, OverloadErrors) { diff --git a/clang/unittests/CrossTU/CrossTranslationUnitTest.cpp b/clang/unittests/CrossTU/CrossTranslationUnitTest.cpp index 36a697d54c8a0..5495f27f5b32a 100644 --- a/clang/unittests/CrossTU/CrossTranslationUnitTest.cpp +++ b/clang/unittests/CrossTU/CrossTranslationUnitTest.cpp @@ -8,6 +8,7 @@ #include "clang/CrossTU/CrossTranslationUnit.h" #include "clang/AST/ASTConsumer.h" +#include "clang/AST/ParentMapContext.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendAction.h" #include "clang/Tooling/Tooling.h" @@ -44,6 +45,10 @@ class CTUASTConsumer : public clang::ASTConsumer { assert(FD && FD->getName() == "f"); bool OrigFDHasBody = FD->hasBody(); + const DynTypedNodeList ParentsBeforeImport = + Ctx.getParentMapContext().getParents(*FD); + ASSERT_FALSE(ParentsBeforeImport.empty()); + // Prepare the index file and the AST file. int ASTFD; llvm::SmallString<256> ASTFileName; @@ -105,10 +110,29 @@ class CTUASTConsumer : public clang::ASTConsumer { EXPECT_EQ(OrigSLoc, FDWithDefinition->getLocation()); } } + + // Check parent map. + const DynTypedNodeList ParentsAfterImport = + Ctx.getParentMapContext().getParents(*FD); + const DynTypedNodeList ParentsOfImported = + Ctx.getParentMapContext().getParents(*NewFD); + EXPECT_TRUE( + checkParentListsEq(ParentsBeforeImport, ParentsAfterImport)); + EXPECT_FALSE(ParentsOfImported.empty()); } } } + static bool checkParentListsEq(const DynTypedNodeList &L1, + const DynTypedNodeList &L2) { + if (L1.size() != L2.size()) + return false; + for (unsigned int I = 0; I < L1.size(); ++I) + if (L1[I] != L2[I]) + return false; + return true; + } + private: CrossTranslationUnitContext CTU; bool *Success; @@ -123,6 +147,7 @@ class CTUAction : public clang::ASTFrontendAction { std::unique_ptr CreateASTConsumer(clang::CompilerInstance &CI, StringRef) override { CI.getAnalyzerOpts()->CTUImportThreshold = OverrideLimit; + CI.getAnalyzerOpts()->CTUImportCppThreshold = OverrideLimit; return std::make_unique(CI, Success); } diff --git a/clang/unittests/Driver/ModuleCacheTest.cpp b/clang/unittests/Driver/ModuleCacheTest.cpp index db3395f4abb2b..6a0f68f26a676 100644 --- a/clang/unittests/Driver/ModuleCacheTest.cpp +++ b/clang/unittests/Driver/ModuleCacheTest.cpp @@ -21,7 +21,7 @@ TEST(ModuleCacheTest, GetTargetAndMode) { SmallString<128> Buf; Driver::getDefaultModuleCachePath(Buf); StringRef Path = Buf; - EXPECT_TRUE(Path.find("org.llvm.clang") != Path.npos); + EXPECT_TRUE(Path.find("clang") != Path.npos); EXPECT_TRUE(Path.endswith("ModuleCache")); } } // end anonymous namespace. diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index dce71b0f06923..6ac3ffbffd1c8 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -5325,7 +5325,7 @@ TEST_F(FormatTest, DeductionGuides) { verifyFormat("template S(Ts...) -> S;"); verifyFormat( "template \n" - "array(T &&... t) -> array, sizeof...(T)>;"); + "array(T &&...t) -> array, sizeof...(T)>;"); verifyFormat("template A() -> Afoo<3>())>;"); verifyFormat("template A() -> A>)>;"); verifyFormat("template A() -> Afoo<1>)>;"); @@ -6281,6 +6281,17 @@ TEST_F(FormatTest, BreaksConditionalExpressions) { " : bbbbbbbbbbbbbbbbbbbbbbb ? 2222222222222222\n" " : 3333333333333333;", Style); + + Style.AlignOperands = FormatStyle::OAS_DontAlign; + Style.BreakBeforeTernaryOperators = false; + // FIXME: Aligning the question marks is weird given DontAlign. + // Consider disabling this alignment in this case. Also check whether this + // will render the adjustment from https://reviews.llvm.org/D82199 + // unnecessary. + verifyFormat("int x = aaaaaaaaaaaaaaa ? aaaaaaaaaaaaaaaaaa :\n" + " bbbb ? cccccccccccccccccc :\n" + " ddddd;\n", + Style); } TEST_F(FormatTest, BreaksConditionalExpressionsAfterOperator) { @@ -8168,13 +8179,20 @@ TEST_F(FormatTest, AttributePenaltyBreaking) { } TEST_F(FormatTest, UnderstandsEllipsis) { + FormatStyle Style = getLLVMStyle(); verifyFormat("int printf(const char *fmt, ...);"); verifyFormat("template void Foo(Ts... ts) { Foo(ts...); }"); - verifyFormat("template void Foo(Ts *... ts) {}"); + verifyFormat("template void Foo(Ts *...ts) {}"); + + verifyFormat("template a;", Style); - FormatStyle PointersLeft = getLLVMStyle(); - PointersLeft.PointerAlignment = FormatStyle::PAS_Left; - verifyFormat("template void Foo(Ts*... ts) {}", PointersLeft); + Style.PointerAlignment = FormatStyle::PAS_Left; + verifyFormat("template void Foo(Ts*... ts) {}", Style); + + verifyFormat("template a;", Style); + + Style.PointerAlignment = FormatStyle::PAS_Middle; + verifyFormat("template a;", Style); } TEST_F(FormatTest, AdaptivelyFormatsPointersAndReferences) { @@ -12968,9 +12986,7 @@ TEST_F(FormatTest, WhitesmithsBraceBreaking) { " }\n", WhitesmithsBraceStyle); - // FIXME: the block and the break under case 2 in this test don't get indented - // correctly - /* + WhitesmithsBraceStyle.IndentCaseBlocks = true; verifyFormat("void switchTest1(int a)\n" " {\n" " switch (a)\n" @@ -12978,35 +12994,101 @@ TEST_F(FormatTest, WhitesmithsBraceBreaking) { " case 2:\n" " {\n" " }\n" - " break;\n" + " break;\n" " }\n" " }\n", WhitesmithsBraceStyle); - */ - // FIXME: the block and the break under case 2 in this test don't get indented - // correctly - /* verifyFormat("void switchTest2(int a)\n" " {\n" " switch (a)\n" " {\n" - " case 0:\n" + " case 0:\n" " break;\n" - " case 1:\n" + " case 1:\n" + " {\n" + " break;\n" + " }\n" + " case 2:\n" + " {\n" + " }\n" + " break;\n" + " default:\n" + " break;\n" + " }\n" + " }\n", + WhitesmithsBraceStyle); + + verifyFormat("void switchTest3(int a)\n" + " {\n" + " switch (a)\n" " {\n" + " case 0:\n" + " {\n" + " foo(x);\n" + " }\n" + " break;\n" + " default:\n" + " {\n" + " foo(1);\n" + " }\n" " break;\n" " }\n" - " case 2:\n" + " }\n", + WhitesmithsBraceStyle); + + WhitesmithsBraceStyle.IndentCaseBlocks = false; + + verifyFormat("void switchTest4(int a)\n" + " {\n" + " switch (a)\n" + " {\n" + " case 2:\n" " {\n" " }\n" " break;\n" - " default:\n" + " }\n" + " }\n", + WhitesmithsBraceStyle); + + verifyFormat("void switchTest5(int a)\n" + " {\n" + " switch (a)\n" + " {\n" + " case 0:\n" + " break;\n" + " case 1:\n" + " {\n" + " foo();\n" + " break;\n" + " }\n" + " case 2:\n" + " {\n" + " }\n" + " break;\n" + " default:\n" + " break;\n" + " }\n" + " }\n", + WhitesmithsBraceStyle); + + verifyFormat("void switchTest6(int a)\n" + " {\n" + " switch (a)\n" + " {\n" + " case 0:\n" + " {\n" + " foo(x);\n" + " }\n" + " break;\n" + " default:\n" + " {\n" + " foo(1);\n" + " }\n" " break;\n" " }\n" " }\n", WhitesmithsBraceStyle); - */ verifyFormat("enum X\n" " {\n" @@ -13946,6 +14028,19 @@ TEST_F(FormatTest, ParsesConfiguration) { CHECK_PARSE("NamespaceMacros: [TESTSUITE, SUITE]", NamespaceMacros, std::vector({"TESTSUITE", "SUITE"})); + Style.WhitespaceSensitiveMacros.clear(); + CHECK_PARSE("WhitespaceSensitiveMacros: [STRINGIZE]", + WhitespaceSensitiveMacros, std::vector{"STRINGIZE"}); + CHECK_PARSE("WhitespaceSensitiveMacros: [STRINGIZE, ASSERT]", + WhitespaceSensitiveMacros, + std::vector({"STRINGIZE", "ASSERT"})); + Style.WhitespaceSensitiveMacros.clear(); + CHECK_PARSE("WhitespaceSensitiveMacros: ['STRINGIZE']", + WhitespaceSensitiveMacros, std::vector{"STRINGIZE"}); + CHECK_PARSE("WhitespaceSensitiveMacros: ['STRINGIZE', 'ASSERT']", + WhitespaceSensitiveMacros, + std::vector({"STRINGIZE", "ASSERT"})); + Style.IncludeStyle.IncludeCategories.clear(); std::vector ExpectedCategories = { {"abc/.*", 2, 0}, {".*", 1, 0}}; @@ -16455,6 +16550,36 @@ TEST_F(FormatTest, OperatorPassedAsAFunctionPtr) { verifyFormat("foo(operator, , -42);", Style); } +TEST_F(FormatTest, WhitespaceSensitiveMacros) { + FormatStyle Style = getLLVMStyle(); + Style.WhitespaceSensitiveMacros.push_back("FOO"); + + // Don't use the helpers here, since 'mess up' will change the whitespace + // and these are all whitespace sensitive by definition + EXPECT_EQ("FOO(String-ized&Messy+But(: :Still)=Intentional);", + format("FOO(String-ized&Messy+But(: :Still)=Intentional);", Style)); + EXPECT_EQ( + "FOO(String-ized&Messy+But\\(: :Still)=Intentional);", + format("FOO(String-ized&Messy+But\\(: :Still)=Intentional);", Style)); + EXPECT_EQ("FOO(String-ized&Messy+But,: :Still=Intentional);", + format("FOO(String-ized&Messy+But,: :Still=Intentional);", Style)); + EXPECT_EQ("FOO(String-ized&Messy+But,: :\n" + " Still=Intentional);", + format("FOO(String-ized&Messy+But,: :\n" + " Still=Intentional);", + Style)); + Style.AlignConsecutiveAssignments = true; + EXPECT_EQ("FOO(String-ized=&Messy+But,: :\n" + " Still=Intentional);", + format("FOO(String-ized=&Messy+But,: :\n" + " Still=Intentional);", + Style)); + + Style.ColumnLimit = 21; + EXPECT_EQ("FOO(String-ized&Messy+But: :Still=Intentional);", + format("FOO(String-ized&Messy+But: :Still=Intentional);", Style)); +} + TEST_F(FormatTest, VeryLongNamespaceCommentSplit) { // These tests are not in NamespaceFixer because that doesn't // test its interaction with line wrapping diff --git a/clang/unittests/Frontend/CMakeLists.txt b/clang/unittests/Frontend/CMakeLists.txt index cde19e9106142..d247089e92955 100644 --- a/clang/unittests/Frontend/CMakeLists.txt +++ b/clang/unittests/Frontend/CMakeLists.txt @@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS add_clang_unittest(FrontendTests ASTUnitTest.cpp + CompilerInvocationTest.cpp CompilerInstanceTest.cpp FixedPointString.cpp FrontendActionTest.cpp diff --git a/clang/unittests/Frontend/CompilerInvocationTest.cpp b/clang/unittests/Frontend/CompilerInvocationTest.cpp new file mode 100644 index 0000000000000..ed82d678462fc --- /dev/null +++ b/clang/unittests/Frontend/CompilerInvocationTest.cpp @@ -0,0 +1,118 @@ +//===- unittests/Frontend/CompilerInvocationTest.cpp - CI tests //---------===// +// +// 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/Frontend/CompilerInvocation.h" +#include "clang/Frontend/CompilerInstance.h" +#include "llvm/Support/Host.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +using namespace llvm; +using namespace clang; + +using ::testing::Contains; +using ::testing::Each; +using ::testing::StrEq; +using ::testing::StrNe; + +namespace { + +class CC1CommandLineGenerationTest : public ::testing::Test { +public: + IntrusiveRefCntPtr Diags; + SmallVector GeneratedArgs; + SmallVector GeneratedArgsStorage; + + const char *operator()(const Twine &Arg) { + return GeneratedArgsStorage.emplace_back(Arg.str()).c_str(); + } + + CC1CommandLineGenerationTest() + : Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions())) {} +}; + +TEST_F(CC1CommandLineGenerationTest, CanGenerateCC1CommandLineFlag) { + const char *Args[] = {"clang", "-xc++", "-fmodules-strict-context-hash", "-"}; + + CompilerInvocation CInvok; + CompilerInvocation::CreateFromArgs(CInvok, Args, *Diags); + + CInvok.generateCC1CommandLine(GeneratedArgs, *this); + + ASSERT_THAT(GeneratedArgs, Contains(StrEq("-fmodules-strict-context-hash"))); +} + +TEST_F(CC1CommandLineGenerationTest, CanGenerateCC1CommandLineSeparate) { + const char *TripleCStr = "i686-apple-darwin9"; + const char *Args[] = {"clang", "-xc++", "-triple", TripleCStr, "-"}; + + CompilerInvocation CInvok; + CompilerInvocation::CreateFromArgs(CInvok, Args, *Diags); + + CInvok.generateCC1CommandLine(GeneratedArgs, *this); + + ASSERT_THAT(GeneratedArgs, Contains(StrEq(TripleCStr))); +} + +TEST_F(CC1CommandLineGenerationTest, + CanGenerateCC1CommandLineSeparateRequiredPresent) { + const std::string DefaultTriple = + llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple()); + const char *Args[] = {"clang", "-xc++", "-triple", DefaultTriple.c_str(), + "-"}; + + CompilerInvocation CInvok; + CompilerInvocation::CreateFromArgs(CInvok, Args, *Diags); + + CInvok.generateCC1CommandLine(GeneratedArgs, *this); + + // Triple should always be emitted even if it is the default + ASSERT_THAT(GeneratedArgs, Contains(StrEq(DefaultTriple.c_str()))); +} + +TEST_F(CC1CommandLineGenerationTest, + CanGenerateCC1CommandLineSeparateRequiredAbsent) { + const std::string DefaultTriple = + llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple()); + const char *Args[] = {"clang", "-xc++", "-"}; + + CompilerInvocation CInvok; + CompilerInvocation::CreateFromArgs(CInvok, Args, *Diags); + + CInvok.generateCC1CommandLine(GeneratedArgs, *this); + + // Triple should always be emitted even if it is the default + ASSERT_THAT(GeneratedArgs, Contains(StrEq(DefaultTriple.c_str()))); +} + +TEST_F(CC1CommandLineGenerationTest, CanGenerateCC1CommandLineSeparateEnum) { + const char *RelocationModelCStr = "static"; + const char *Args[] = {"clang", "-xc++", "-mrelocation-model", + RelocationModelCStr, "-"}; + + CompilerInvocation CInvok; + CompilerInvocation::CreateFromArgs(CInvok, Args, *Diags); + + CInvok.generateCC1CommandLine(GeneratedArgs, *this); + + // Non default relocation model + ASSERT_THAT(GeneratedArgs, Contains(StrEq(RelocationModelCStr))); + GeneratedArgs.clear(); + + RelocationModelCStr = "pic"; + Args[3] = RelocationModelCStr; + + CompilerInvocation CInvok1; + CompilerInvocation::CreateFromArgs(CInvok1, Args, *Diags); + + CInvok1.generateCC1CommandLine(GeneratedArgs, *this); + ASSERT_THAT(GeneratedArgs, Each(StrNe(RelocationModelCStr))); +} + +} // anonymous namespace diff --git a/clang/unittests/StaticAnalyzer/CMakeLists.txt b/clang/unittests/StaticAnalyzer/CMakeLists.txt index 564eba879f245..0e6d8763d96d2 100644 --- a/clang/unittests/StaticAnalyzer/CMakeLists.txt +++ b/clang/unittests/StaticAnalyzer/CMakeLists.txt @@ -7,6 +7,7 @@ add_clang_unittest(StaticAnalysisTests AnalyzerOptionsTest.cpp CallDescriptionTest.cpp CallEventTest.cpp + FalsePositiveRefutationBRVisitorTest.cpp ParamRegionTest.cpp RangeSetTest.cpp RegisterCustomCheckersTest.cpp diff --git a/clang/unittests/StaticAnalyzer/CheckerRegistration.h b/clang/unittests/StaticAnalyzer/CheckerRegistration.h index 0bbed9b7784ff..e02b856e0e9c4 100644 --- a/clang/unittests/StaticAnalyzer/CheckerRegistration.h +++ b/clang/unittests/StaticAnalyzer/CheckerRegistration.h @@ -14,6 +14,7 @@ #include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h" #include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h" #include "clang/Tooling/Tooling.h" +#include "gtest/gtest.h" namespace clang { namespace ento { @@ -65,10 +66,21 @@ class TestAction : public ASTFrontendAction { } }; +inline SmallString<80> getCurrentTestNameAsFileName() { + const ::testing::TestInfo *Info = + ::testing::UnitTest::GetInstance()->current_test_info(); + + SmallString<80> FileName; + (Twine{Info->name()} + ".cc").toVector(FileName); + return FileName; +} + template bool runCheckerOnCode(const std::string &Code, std::string &Diags) { + const SmallVectorImpl &FileName = getCurrentTestNameAsFileName(); llvm::raw_string_ostream OS(Diags); - return tooling::runToolOnCode(std::make_unique>(OS), Code); + return tooling::runToolOnCode(std::make_unique>(OS), Code, + FileName); } template @@ -77,5 +89,22 @@ bool runCheckerOnCode(const std::string &Code) { return runCheckerOnCode(Code, Diags); } +template +bool runCheckerOnCodeWithArgs(const std::string &Code, + const std::vector &Args, + std::string &Diags) { + const SmallVectorImpl &FileName = getCurrentTestNameAsFileName(); + llvm::raw_string_ostream OS(Diags); + return tooling::runToolOnCodeWithArgs( + std::make_unique>(OS), Code, Args, FileName); +} + +template +bool runCheckerOnCodeWithArgs(const std::string &Code, + const std::vector &Args) { + std::string Diags; + return runCheckerOnCodeWithArgs(Code, Args, Diags); +} + } // namespace ento } // namespace clang diff --git a/clang/unittests/StaticAnalyzer/FalsePositiveRefutationBRVisitorTest.cpp b/clang/unittests/StaticAnalyzer/FalsePositiveRefutationBRVisitorTest.cpp new file mode 100644 index 0000000000000..7c151c1821133 --- /dev/null +++ b/clang/unittests/StaticAnalyzer/FalsePositiveRefutationBRVisitorTest.cpp @@ -0,0 +1,223 @@ +//===- unittests/StaticAnalyzer/FalsePositiveRefutationBRVisitorTest.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 "CheckerRegistration.h" +#include "Reusables.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" +#include "clang/StaticAnalyzer/Core/Checker.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" +#include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h" +#include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h" +#include "llvm/Config/config.h" +#include "gtest/gtest.h" + +// FIXME: Use GTEST_SKIP() instead if GTest is updated to version 1.10.0 +#ifdef LLVM_WITH_Z3 +#define SKIP_WITHOUT_Z3 +#else +#define SKIP_WITHOUT_Z3 return +#endif + +namespace clang { +namespace ento { +namespace { + +class FalsePositiveGenerator : public Checker { + using Self = FalsePositiveGenerator; + const BuiltinBug FalsePositiveGeneratorBug{this, "FalsePositiveGenerator"}; + using HandlerFn = bool (Self::*)(const CallEvent &Call, + CheckerContext &) const; + CallDescriptionMap Callbacks = { + {{"reachedWithContradiction", 0}, &Self::reachedWithContradiction}, + {{"reachedWithNoContradiction", 0}, &Self::reachedWithNoContradiction}, + {{"reportIfCanBeTrue", 1}, &Self::reportIfCanBeTrue}, + }; + + bool report(CheckerContext &C, ProgramStateRef State, + StringRef Description) const { + ExplodedNode *Node = C.generateNonFatalErrorNode(State); + if (!Node) + return false; + + auto Report = std::make_unique( + FalsePositiveGeneratorBug, Description, Node); + C.emitReport(std::move(Report)); + return true; + } + + bool reachedWithNoContradiction(const CallEvent &, CheckerContext &C) const { + return report(C, C.getState(), "REACHED_WITH_NO_CONTRADICTION"); + } + + bool reachedWithContradiction(const CallEvent &, CheckerContext &C) const { + return report(C, C.getState(), "REACHED_WITH_CONTRADICTION"); + } + + // Similar to ExprInspectionChecker::analyzerEval except it emits warning only + // if the argument can be true. The report emits the report in the state where + // the assertion true. + bool reportIfCanBeTrue(const CallEvent &Call, CheckerContext &C) const { + // A specific instantiation of an inlined function may have more constrained + // values than can generally be assumed. Skip the check. + if (C.getPredecessor()->getLocationContext()->getStackFrame()->getParent()) + return false; + + SVal AssertionVal = Call.getArgSVal(0); + if (AssertionVal.isUndef()) + return false; + + ProgramStateRef State = C.getPredecessor()->getState(); + ProgramStateRef StTrue; + std::tie(StTrue, std::ignore) = + State->assume(AssertionVal.castAs()); + if (StTrue) + return report(C, StTrue, "CAN_BE_TRUE"); + return false; + } + +public: + bool evalCall(const CallEvent &Call, CheckerContext &C) const { + if (const HandlerFn *Callback = Callbacks.lookup(Call)) + return (this->*(*Callback))(Call, C); + return false; + } +}; + +void addFalsePositiveGenerator(AnalysisASTConsumer &AnalysisConsumer, + AnalyzerOptions &AnOpts) { + AnOpts.CheckersAndPackages = {{"test.FalsePositiveGenerator", true}, + {"debug.ViewExplodedGraph", false}}; + AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) { + Registry.addChecker( + "test.FalsePositiveGenerator", "EmptyDescription", "EmptyDocsUri"); + }); +} + +// C++20 use constexpr below. +const std::vector LazyAssumeArgs{ + "-Xclang", "-analyzer-config", "-Xclang", "eagerly-assume=false"}; +const std::vector LazyAssumeAndCrossCheckArgs{ + "-Xclang", "-analyzer-config", "-Xclang", "eagerly-assume=false", + "-Xclang", "-analyzer-config", "-Xclang", "crosscheck-with-z3=true"}; + +TEST(FalsePositiveRefutationBRVisitor, UnSatInTheMiddleNoReport) { + SKIP_WITHOUT_Z3; + constexpr auto Code = R"( + void reachedWithContradiction(); + void reachedWithNoContradiction(); + void test(int x, int y) { + if (x * y == 0) + return; + reachedWithNoContradiction(); + if (x == 0) { + reachedWithContradiction(); + // x * y != 0 => x != 0 && y != 0 => contradict with x == 0 + } + })"; + + std::string Diags; + EXPECT_TRUE(runCheckerOnCodeWithArgs( + Code, LazyAssumeAndCrossCheckArgs, Diags)); + EXPECT_EQ(Diags, + "test.FalsePositiveGenerator:REACHED_WITH_NO_CONTRADICTION\n"); + // Single warning. The second report was invalidated by the visitor. + + // Without enabling the crosscheck-with-z3 both reports are displayed. + std::string Diags2; + EXPECT_TRUE(runCheckerOnCodeWithArgs( + Code, LazyAssumeArgs, Diags2)); + EXPECT_EQ(Diags2, + "test.FalsePositiveGenerator:REACHED_WITH_NO_CONTRADICTION\n" + "test.FalsePositiveGenerator:REACHED_WITH_CONTRADICTION\n"); +} + +TEST(FalsePositiveRefutationBRVisitor, UnSatAtErrorNodeWithNewSymbolNoReport) { + SKIP_WITHOUT_Z3; + constexpr auto Code = R"( + void reportIfCanBeTrue(bool); + void reachedWithNoContradiction(); + void test(int x, int y) { + if (x * y == 0) + return; + // We know that 'x * y': {[MIN,-1], [1,MAX]} + reachedWithNoContradiction(); + reportIfCanBeTrue(x == 0); // contradiction + // The function introduces the 'x == 0' constraint in the ErrorNode which + // leads to contradiction with the constraint of 'x * y'. + // Note that the new constraint was bound to a new symbol 'x'. + })"; + std::string Diags; + EXPECT_TRUE(runCheckerOnCodeWithArgs( + Code, LazyAssumeAndCrossCheckArgs, Diags)); + EXPECT_EQ(Diags, + "test.FalsePositiveGenerator:REACHED_WITH_NO_CONTRADICTION\n"); + // Single warning. The second report was invalidated by the visitor. + + // Without enabling the crosscheck-with-z3 both reports are displayed. + std::string Diags2; + EXPECT_TRUE(runCheckerOnCodeWithArgs( + Code, LazyAssumeArgs, Diags2)); + EXPECT_EQ(Diags2, + "test.FalsePositiveGenerator:REACHED_WITH_NO_CONTRADICTION\n" + "test.FalsePositiveGenerator:CAN_BE_TRUE\n"); +} + +TEST(FalsePositiveRefutationBRVisitor, + UnSatAtErrorNodeDueToRefinedConstraintNoReport) { + SKIP_WITHOUT_Z3; + constexpr auto Code = R"( + void reportIfCanBeTrue(bool); + void reachedWithNoContradiction(); + void test(unsigned x, unsigned n) { + if (n >= 1 && n <= 2) { + if (x >= 3) + return; + // x: [0,2] and n: [1,2] + int y = x + n; // y: '(x+n)' Which is in approximately between 1 and 4. + + // Registers the symbol 'y' with the constraint [1, MAX] in the true + // branch. + if (y > 0) { + // Since the x: [0,2] and n: [1,2], the 'y' is indeed greater than + // zero. If we emit a warning here, the constraints on the BugPath is + // SAT. Therefore that report is NOT invalidated. + reachedWithNoContradiction(); // 'y' can be greater than zero. OK + + // If we ask the analyzer whether the 'y' can be 5. It won't know, + // therefore, the state will be created where the 'y' expression is 5. + // Although, this assumption is false! + // 'y' can not be 5 if the maximal value of both x and n is 2. + // The BugPath which become UnSAT in the ErrorNode with a refined + // constraint, should be invalidated. + reportIfCanBeTrue(y == 5); + } + } + })"; + + std::string Diags; + EXPECT_TRUE(runCheckerOnCodeWithArgs( + Code, LazyAssumeAndCrossCheckArgs, Diags)); + EXPECT_EQ(Diags, + "test.FalsePositiveGenerator:REACHED_WITH_NO_CONTRADICTION\n"); + // Single warning. The second report was invalidated by the visitor. + + // Without enabling the crosscheck-with-z3 both reports are displayed. + std::string Diags2; + EXPECT_TRUE(runCheckerOnCodeWithArgs( + Code, LazyAssumeArgs, Diags2)); + EXPECT_EQ(Diags2, + "test.FalsePositiveGenerator:REACHED_WITH_NO_CONTRADICTION\n" + "test.FalsePositiveGenerator:CAN_BE_TRUE\n"); +} + +} // namespace +} // namespace ento +} // namespace clang diff --git a/clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp b/clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp index 30a4efc06a4a0..60b8aafa0d84e 100644 --- a/clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp +++ b/clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp @@ -11,6 +11,7 @@ #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" +#include "clang/StaticAnalyzer/Core/CheckerRegistryData.h" #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h" @@ -41,17 +42,16 @@ class CustomChecker : public Checker { void addCustomChecker(AnalysisASTConsumer &AnalysisConsumer, AnalyzerOptions &AnOpts) { - AnOpts.CheckersAndPackages = {{"custom.CustomChecker", true}}; + AnOpts.CheckersAndPackages = {{"test.CustomChecker", true}}; AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) { - Registry.addChecker("custom.CustomChecker", "Description", - ""); + Registry.addChecker("test.CustomChecker", "Description", ""); }); } TEST(RegisterCustomCheckers, RegisterChecker) { std::string Diags; EXPECT_TRUE(runCheckerOnCode("void f() {;}", Diags)); - EXPECT_EQ(Diags, "custom.CustomChecker:Custom diagnostic description\n"); + EXPECT_EQ(Diags, "test.CustomChecker:Custom diagnostic description\n"); } //===----------------------------------------------------------------------===// @@ -100,7 +100,7 @@ class CheckerRegistrationOrderPrinter llvm::raw_svector_ostream OS(Buf); C.getAnalysisManager() .getCheckerManager() - ->getCheckerRegistry() + ->getCheckerRegistryData() .printEnabledCheckerList(OS); // Strip a newline off. auto R = @@ -120,7 +120,7 @@ bool shouldRegisterCheckerRegistrationOrderPrinter(const CheckerManager &mgr) { void addCheckerRegistrationOrderPrinter(CheckerRegistry &Registry) { Registry.addChecker(registerCheckerRegistrationOrderPrinter, shouldRegisterCheckerRegistrationOrderPrinter, - "custom.RegistrationOrder", "Description", "", false); + "test.RegistrationOrder", "Description", "", false); } #define UNITTEST_CHECKER(CHECKER_NAME, DIAG_MSG) \ @@ -141,7 +141,7 @@ void addCheckerRegistrationOrderPrinter(CheckerRegistry &Registry) { } \ void add##CHECKER_NAME(CheckerRegistry &Registry) { \ Registry.addChecker(register##CHECKER_NAME, shouldRegister##CHECKER_NAME, \ - "custom." #CHECKER_NAME, "Description", "", false); \ + "test." #CHECKER_NAME, "Description", "", false); \ } UNITTEST_CHECKER(StrongDep, "Strong") @@ -154,22 +154,22 @@ bool shouldRegisterStrongFALSE(const CheckerManager &mgr) { void addDep(AnalysisASTConsumer &AnalysisConsumer, AnalyzerOptions &AnOpts) { - AnOpts.CheckersAndPackages = {{"custom.Dep", true}, - {"custom.RegistrationOrder", true}}; + AnOpts.CheckersAndPackages = {{"test.Dep", true}, + {"test.RegistrationOrder", true}}; AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) { Registry.addChecker(registerStrongDep, shouldRegisterStrongFALSE, - "custom.Strong", "Description", "", false); + "test.Strong", "Description", "", false); addStrongDep(Registry); addDep(Registry); addCheckerRegistrationOrderPrinter(Registry); - Registry.addDependency("custom.Dep", "custom.Strong"); + Registry.addDependency("test.Dep", "test.Strong"); }); } TEST(RegisterDeps, UnsatisfiedDependency) { std::string Diags; EXPECT_TRUE(runCheckerOnCode("void f() {int i;}", Diags)); - EXPECT_EQ(Diags, "custom.RegistrationOrder:custom.RegistrationOrder\n"); + EXPECT_EQ(Diags, "test.RegistrationOrder:test.RegistrationOrder\n"); } //===----------------------------------------------------------------------===// @@ -180,52 +180,52 @@ UNITTEST_CHECKER(WeakDep, "Weak") void addWeakDepCheckerBothEnabled(AnalysisASTConsumer &AnalysisConsumer, AnalyzerOptions &AnOpts) { - AnOpts.CheckersAndPackages = {{"custom.Dep", true}, - {"custom.WeakDep", true}, - {"custom.RegistrationOrder", true}}; + AnOpts.CheckersAndPackages = {{"test.Dep", true}, + {"test.WeakDep", true}, + {"test.RegistrationOrder", true}}; AnalysisConsumer.AddCheckerRegistrationFn([=](CheckerRegistry &Registry) { addWeakDep(Registry); addDep(Registry); addCheckerRegistrationOrderPrinter(Registry); - Registry.addWeakDependency("custom.Dep", "custom.WeakDep"); + Registry.addWeakDependency("test.Dep", "test.WeakDep"); }); } void addWeakDepCheckerBothEnabledSwitched(AnalysisASTConsumer &AnalysisConsumer, AnalyzerOptions &AnOpts) { - AnOpts.CheckersAndPackages = {{"custom.Dep", true}, - {"custom.WeakDep", true}, - {"custom.RegistrationOrder", true}}; + AnOpts.CheckersAndPackages = {{"test.Dep", true}, + {"test.WeakDep", true}, + {"test.RegistrationOrder", true}}; AnalysisConsumer.AddCheckerRegistrationFn([=](CheckerRegistry &Registry) { addWeakDep(Registry); addDep(Registry); addCheckerRegistrationOrderPrinter(Registry); - Registry.addWeakDependency("custom.WeakDep", "custom.Dep"); + Registry.addWeakDependency("test.WeakDep", "test.Dep"); }); } void addWeakDepCheckerDepDisabled(AnalysisASTConsumer &AnalysisConsumer, AnalyzerOptions &AnOpts) { - AnOpts.CheckersAndPackages = {{"custom.Dep", true}, - {"custom.WeakDep", false}, - {"custom.RegistrationOrder", true}}; + AnOpts.CheckersAndPackages = {{"test.Dep", true}, + {"test.WeakDep", false}, + {"test.RegistrationOrder", true}}; AnalysisConsumer.AddCheckerRegistrationFn([=](CheckerRegistry &Registry) { addWeakDep(Registry); addDep(Registry); addCheckerRegistrationOrderPrinter(Registry); - Registry.addWeakDependency("custom.Dep", "custom.WeakDep"); + Registry.addWeakDependency("test.Dep", "test.WeakDep"); }); } void addWeakDepCheckerDepUnspecified(AnalysisASTConsumer &AnalysisConsumer, AnalyzerOptions &AnOpts) { - AnOpts.CheckersAndPackages = {{"custom.Dep", true}, - {"custom.RegistrationOrder", true}}; + AnOpts.CheckersAndPackages = {{"test.Dep", true}, + {"test.RegistrationOrder", true}}; AnalysisConsumer.AddCheckerRegistrationFn([=](CheckerRegistry &Registry) { addWeakDep(Registry); addDep(Registry); addCheckerRegistrationOrderPrinter(Registry); - Registry.addWeakDependency("custom.Dep", "custom.WeakDep"); + Registry.addWeakDependency("test.Dep", "test.WeakDep"); }); } @@ -234,10 +234,10 @@ UNITTEST_CHECKER(Dep2, "Dep2") void addWeakDepHasWeakDep(AnalysisASTConsumer &AnalysisConsumer, AnalyzerOptions &AnOpts) { - AnOpts.CheckersAndPackages = {{"custom.Dep", true}, - {"custom.WeakDep", true}, - {"custom.WeakDep2", true}, - {"custom.RegistrationOrder", true}}; + AnOpts.CheckersAndPackages = {{"test.Dep", true}, + {"test.WeakDep", true}, + {"test.WeakDep2", true}, + {"test.RegistrationOrder", true}}; AnalysisConsumer.AddCheckerRegistrationFn([=](CheckerRegistry &Registry) { addStrongDep(Registry); addWeakDep(Registry); @@ -245,17 +245,17 @@ void addWeakDepHasWeakDep(AnalysisASTConsumer &AnalysisConsumer, addDep(Registry); addDep2(Registry); addCheckerRegistrationOrderPrinter(Registry); - Registry.addWeakDependency("custom.Dep", "custom.WeakDep"); - Registry.addWeakDependency("custom.WeakDep", "custom.WeakDep2"); + Registry.addWeakDependency("test.Dep", "test.WeakDep"); + Registry.addWeakDependency("test.WeakDep", "test.WeakDep2"); }); } void addWeakDepTransitivity(AnalysisASTConsumer &AnalysisConsumer, AnalyzerOptions &AnOpts) { - AnOpts.CheckersAndPackages = {{"custom.Dep", true}, - {"custom.WeakDep", false}, - {"custom.WeakDep2", true}, - {"custom.RegistrationOrder", true}}; + AnOpts.CheckersAndPackages = {{"test.Dep", true}, + {"test.WeakDep", false}, + {"test.WeakDep2", true}, + {"test.RegistrationOrder", true}}; AnalysisConsumer.AddCheckerRegistrationFn([=](CheckerRegistry &Registry) { addStrongDep(Registry); addWeakDep(Registry); @@ -263,8 +263,8 @@ void addWeakDepTransitivity(AnalysisASTConsumer &AnalysisConsumer, addDep(Registry); addDep2(Registry); addCheckerRegistrationOrderPrinter(Registry); - Registry.addWeakDependency("custom.Dep", "custom.WeakDep"); - Registry.addWeakDependency("custom.WeakDep", "custom.WeakDep2"); + Registry.addWeakDependency("test.Dep", "test.WeakDep"); + Registry.addWeakDependency("test.WeakDep", "test.WeakDep2"); }); } @@ -272,42 +272,40 @@ TEST(RegisterDeps, SimpleWeakDependency) { std::string Diags; EXPECT_TRUE(runCheckerOnCode( "void f() {int i;}", Diags)); - EXPECT_EQ(Diags, "custom.RegistrationOrder:custom.WeakDep\ncustom." - "Dep\ncustom.RegistrationOrder\n"); + EXPECT_EQ(Diags, "test.RegistrationOrder:test.WeakDep\ntest." + "Dep\ntest.RegistrationOrder\n"); Diags.clear(); // Mind that AnalyzerOption listed the enabled checker list in the same order, // but the dependencies are switched. EXPECT_TRUE(runCheckerOnCode( "void f() {int i;}", Diags)); - EXPECT_EQ(Diags, "custom.RegistrationOrder:custom.Dep\ncustom." - "RegistrationOrder\ncustom.WeakDep\n"); + EXPECT_EQ(Diags, "test.RegistrationOrder:test.Dep\ntest." + "RegistrationOrder\ntest.WeakDep\n"); Diags.clear(); // Weak dependencies dont prevent dependent checkers from being enabled. EXPECT_TRUE(runCheckerOnCode( "void f() {int i;}", Diags)); - EXPECT_EQ(Diags, - "custom.RegistrationOrder:custom.Dep\ncustom.RegistrationOrder\n"); + EXPECT_EQ(Diags, "test.RegistrationOrder:test.Dep\ntest.RegistrationOrder\n"); Diags.clear(); // Nor will they be enabled just because a dependent checker is. EXPECT_TRUE(runCheckerOnCode( "void f() {int i;}", Diags)); - EXPECT_EQ(Diags, - "custom.RegistrationOrder:custom.Dep\ncustom.RegistrationOrder\n"); + EXPECT_EQ(Diags, "test.RegistrationOrder:test.Dep\ntest.RegistrationOrder\n"); Diags.clear(); EXPECT_TRUE( runCheckerOnCode("void f() {int i;}", Diags)); - EXPECT_EQ(Diags, "custom.RegistrationOrder:custom.WeakDep2\ncustom." - "Dep\ncustom.RegistrationOrder\n"); + EXPECT_EQ(Diags, "test.RegistrationOrder:test.WeakDep2\ntest." + "Dep\ntest.RegistrationOrder\n"); Diags.clear(); EXPECT_TRUE( runCheckerOnCode("void f() {int i;}", Diags)); - EXPECT_EQ(Diags, "custom.RegistrationOrder:custom.WeakDep2\ncustom." - "WeakDep\ncustom.Dep\ncustom.RegistrationOrder\n"); + EXPECT_EQ(Diags, "test.RegistrationOrder:test.WeakDep2\ntest." + "WeakDep\ntest.Dep\ntest.RegistrationOrder\n"); Diags.clear(); } @@ -317,98 +315,98 @@ TEST(RegisterDeps, SimpleWeakDependency) { void addWeakDepHasStrongDep(AnalysisASTConsumer &AnalysisConsumer, AnalyzerOptions &AnOpts) { - AnOpts.CheckersAndPackages = {{"custom.Dep", true}, - {"custom.StrongDep", true}, - {"custom.WeakDep", true}, - {"custom.RegistrationOrder", true}}; + AnOpts.CheckersAndPackages = {{"test.Dep", true}, + {"test.StrongDep", true}, + {"test.WeakDep", true}, + {"test.RegistrationOrder", true}}; AnalysisConsumer.AddCheckerRegistrationFn([=](CheckerRegistry &Registry) { addStrongDep(Registry); addWeakDep(Registry); addDep(Registry); addCheckerRegistrationOrderPrinter(Registry); - Registry.addDependency("custom.WeakDep", "custom.StrongDep"); - Registry.addWeakDependency("custom.Dep", "custom.WeakDep"); + Registry.addDependency("test.WeakDep", "test.StrongDep"); + Registry.addWeakDependency("test.Dep", "test.WeakDep"); }); } void addWeakDepAndStrongDep(AnalysisASTConsumer &AnalysisConsumer, AnalyzerOptions &AnOpts) { - AnOpts.CheckersAndPackages = {{"custom.Dep", true}, - {"custom.StrongDep", true}, - {"custom.WeakDep", true}, - {"custom.RegistrationOrder", true}}; + AnOpts.CheckersAndPackages = {{"test.Dep", true}, + {"test.StrongDep", true}, + {"test.WeakDep", true}, + {"test.RegistrationOrder", true}}; AnalysisConsumer.AddCheckerRegistrationFn([=](CheckerRegistry &Registry) { addStrongDep(Registry); addWeakDep(Registry); addDep(Registry); addCheckerRegistrationOrderPrinter(Registry); - Registry.addDependency("custom.Dep", "custom.StrongDep"); - Registry.addWeakDependency("custom.Dep", "custom.WeakDep"); + Registry.addDependency("test.Dep", "test.StrongDep"); + Registry.addWeakDependency("test.Dep", "test.WeakDep"); }); } void addDisabledWeakDepHasStrongDep(AnalysisASTConsumer &AnalysisConsumer, AnalyzerOptions &AnOpts) { - AnOpts.CheckersAndPackages = {{"custom.Dep", true}, - {"custom.StrongDep", true}, - {"custom.WeakDep", false}, - {"custom.RegistrationOrder", true}}; + AnOpts.CheckersAndPackages = {{"test.Dep", true}, + {"test.StrongDep", true}, + {"test.WeakDep", false}, + {"test.RegistrationOrder", true}}; AnalysisConsumer.AddCheckerRegistrationFn([=](CheckerRegistry &Registry) { addStrongDep(Registry); addWeakDep(Registry); addDep(Registry); addCheckerRegistrationOrderPrinter(Registry); - Registry.addDependency("custom.WeakDep", "custom.StrongDep"); - Registry.addWeakDependency("custom.Dep", "custom.WeakDep"); + Registry.addDependency("test.WeakDep", "test.StrongDep"); + Registry.addWeakDependency("test.Dep", "test.WeakDep"); }); } void addDisabledWeakDepHasUnspecifiedStrongDep( AnalysisASTConsumer &AnalysisConsumer, AnalyzerOptions &AnOpts) { - AnOpts.CheckersAndPackages = {{"custom.Dep", true}, - {"custom.WeakDep", false}, - {"custom.RegistrationOrder", true}}; + AnOpts.CheckersAndPackages = {{"test.Dep", true}, + {"test.WeakDep", false}, + {"test.RegistrationOrder", true}}; AnalysisConsumer.AddCheckerRegistrationFn([=](CheckerRegistry &Registry) { addStrongDep(Registry); addWeakDep(Registry); addDep(Registry); addCheckerRegistrationOrderPrinter(Registry); - Registry.addDependency("custom.WeakDep", "custom.StrongDep"); - Registry.addWeakDependency("custom.Dep", "custom.WeakDep"); + Registry.addDependency("test.WeakDep", "test.StrongDep"); + Registry.addWeakDependency("test.Dep", "test.WeakDep"); }); } void addWeakDepHasDisabledStrongDep(AnalysisASTConsumer &AnalysisConsumer, AnalyzerOptions &AnOpts) { - AnOpts.CheckersAndPackages = {{"custom.Dep", true}, - {"custom.StrongDep", false}, - {"custom.WeakDep", true}, - {"custom.RegistrationOrder", true}}; + AnOpts.CheckersAndPackages = {{"test.Dep", true}, + {"test.StrongDep", false}, + {"test.WeakDep", true}, + {"test.RegistrationOrder", true}}; AnalysisConsumer.AddCheckerRegistrationFn([=](CheckerRegistry &Registry) { addStrongDep(Registry); addWeakDep(Registry); addDep(Registry); addCheckerRegistrationOrderPrinter(Registry); - Registry.addDependency("custom.WeakDep", "custom.StrongDep"); - Registry.addWeakDependency("custom.Dep", "custom.WeakDep"); + Registry.addDependency("test.WeakDep", "test.StrongDep"); + Registry.addWeakDependency("test.Dep", "test.WeakDep"); }); } void addWeakDepHasUnspecifiedButLaterEnabledStrongDep( AnalysisASTConsumer &AnalysisConsumer, AnalyzerOptions &AnOpts) { - AnOpts.CheckersAndPackages = {{"custom.Dep", true}, - {"custom.Dep2", true}, - {"custom.WeakDep", true}, - {"custom.RegistrationOrder", true}}; + AnOpts.CheckersAndPackages = {{"test.Dep", true}, + {"test.Dep2", true}, + {"test.WeakDep", true}, + {"test.RegistrationOrder", true}}; AnalysisConsumer.AddCheckerRegistrationFn([=](CheckerRegistry &Registry) { addStrongDep(Registry); addWeakDep(Registry); addDep(Registry); addDep2(Registry); addCheckerRegistrationOrderPrinter(Registry); - Registry.addDependency("custom.WeakDep", "custom.StrongDep"); - Registry.addDependency("custom.Dep2", "custom.StrongDep"); - Registry.addWeakDependency("custom.Dep", "custom.WeakDep"); + Registry.addDependency("test.WeakDep", "test.StrongDep"); + Registry.addDependency("test.Dep2", "test.StrongDep"); + Registry.addWeakDependency("test.Dep", "test.WeakDep"); }); } @@ -416,8 +414,8 @@ TEST(RegisterDeps, DependencyInteraction) { std::string Diags; EXPECT_TRUE( runCheckerOnCode("void f() {int i;}", Diags)); - EXPECT_EQ(Diags, "custom.RegistrationOrder:custom.StrongDep\ncustom." - "WeakDep\ncustom.Dep\ncustom.RegistrationOrder\n"); + EXPECT_EQ(Diags, "test.RegistrationOrder:test.StrongDep\ntest." + "WeakDep\ntest.Dep\ntest.RegistrationOrder\n"); Diags.clear(); // Weak dependencies are registered before strong dependencies. This is most @@ -426,39 +424,36 @@ TEST(RegisterDeps, DependencyInteraction) { // established in between the modeling portion and the weak dependency. EXPECT_TRUE( runCheckerOnCode("void f() {int i;}", Diags)); - EXPECT_EQ(Diags, "custom.RegistrationOrder:custom.WeakDep\ncustom." - "StrongDep\ncustom.Dep\ncustom.RegistrationOrder\n"); + EXPECT_EQ(Diags, "test.RegistrationOrder:test.WeakDep\ntest." + "StrongDep\ntest.Dep\ntest.RegistrationOrder\n"); Diags.clear(); // If a weak dependency is disabled, the checker itself can still be enabled. EXPECT_TRUE(runCheckerOnCode( "void f() {int i;}", Diags)); - EXPECT_EQ(Diags, "custom.RegistrationOrder:custom.Dep\ncustom." - "RegistrationOrder\ncustom.StrongDep\n"); + EXPECT_EQ(Diags, "test.RegistrationOrder:test.Dep\ntest." + "RegistrationOrder\ntest.StrongDep\n"); Diags.clear(); // If a weak dependency is disabled, the checker itself can still be enabled, // but it shouldn't enable a strong unspecified dependency. EXPECT_TRUE(runCheckerOnCode( "void f() {int i;}", Diags)); - EXPECT_EQ(Diags, - "custom.RegistrationOrder:custom.Dep\ncustom.RegistrationOrder\n"); + EXPECT_EQ(Diags, "test.RegistrationOrder:test.Dep\ntest.RegistrationOrder\n"); Diags.clear(); // A strong dependency of a weak dependency is disabled, so neither of them // should be enabled. EXPECT_TRUE(runCheckerOnCode( "void f() {int i;}", Diags)); - EXPECT_EQ(Diags, - "custom.RegistrationOrder:custom.Dep\ncustom.RegistrationOrder\n"); + EXPECT_EQ(Diags, "test.RegistrationOrder:test.Dep\ntest.RegistrationOrder\n"); Diags.clear(); EXPECT_TRUE( runCheckerOnCode( "void f() {int i;}", Diags)); - EXPECT_EQ(Diags, - "custom.RegistrationOrder:custom.StrongDep\ncustom.WeakDep\ncustom." - "Dep\ncustom.Dep2\ncustom.RegistrationOrder\n"); + EXPECT_EQ(Diags, "test.RegistrationOrder:test.StrongDep\ntest.WeakDep\ntest." + "Dep\ntest.Dep2\ntest.RegistrationOrder\n"); Diags.clear(); } } // namespace diff --git a/clang/unittests/Tooling/CMakeLists.txt b/clang/unittests/Tooling/CMakeLists.txt index 67ab6bea20160..c439f5a786375 100644 --- a/clang/unittests/Tooling/CMakeLists.txt +++ b/clang/unittests/Tooling/CMakeLists.txt @@ -9,6 +9,7 @@ set(LLVM_LINK_COMPONENTS if (MSVC) set_source_files_properties(RecursiveASTVisitorTest.cpp PROPERTIES COMPILE_FLAGS /bigobj) set_source_files_properties(RecursiveASTVisitorTestExprVisitor.cpp PROPERTIES COMPILE_FLAGS /bigobj) + set_source_files_properties(RecursiveASTVisitorTests/Callbacks.cpp PROPERTIES COMPILE_FLAGS /bigobj) set_source_files_properties(SourceCodeTest.cpp PROPERTIES COMPILE_FLAGS /bigobj) endif() @@ -27,6 +28,7 @@ add_clang_unittest(ToolingTests QualTypeNamesTest.cpp RangeSelectorTest.cpp RecursiveASTVisitorTests/Attr.cpp + RecursiveASTVisitorTests/Callbacks.cpp RecursiveASTVisitorTests/Class.cpp RecursiveASTVisitorTests/ConstructExpr.cpp RecursiveASTVisitorTests/CXXBoolLiteralExpr.cpp diff --git a/clang/unittests/Tooling/RangeSelectorTest.cpp b/clang/unittests/Tooling/RangeSelectorTest.cpp index da5b3c524e4b0..e2d7723eab116 100644 --- a/clang/unittests/Tooling/RangeSelectorTest.cpp +++ b/clang/unittests/Tooling/RangeSelectorTest.cpp @@ -201,7 +201,7 @@ TEST(RangeSelectorTest, RangeOpNodes) { )cc"; auto Matcher = callExpr(hasArgument(0, expr().bind("a0")), hasArgument(1, expr().bind("a1"))); - RangeSelector R = range("a0", "a1"); + RangeSelector R = encloseNodes("a0", "a1"); TestMatch Match = matchCode(Code, Matcher); EXPECT_THAT_EXPECTED(select(R, Match), HasValue("3, 7")); } @@ -213,7 +213,7 @@ TEST(RangeSelectorTest, RangeOpGeneral) { )cc"; auto Matcher = callExpr(hasArgument(0, expr().bind("a0")), hasArgument(1, expr().bind("a1"))); - RangeSelector R = range(node("a0"), node("a1")); + RangeSelector R = enclose(node("a0"), node("a1")); TestMatch Match = matchCode(Code, Matcher); EXPECT_THAT_EXPECTED(select(R, Match), HasValue("3, 7")); } diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/Callbacks.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/Callbacks.cpp new file mode 100644 index 0000000000000..71f2bf6be599f --- /dev/null +++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/Callbacks.cpp @@ -0,0 +1,1209 @@ +//===--- clang/unittests/Tooling/RecursiveASTVisitorTests/Callbacks.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 "TestVisitor.h" + +using namespace clang; + +namespace { + +enum class ShouldTraversePostOrder : bool { + No = false, + Yes = true, +}; + +/// Base class for tests for RecursiveASTVisitor tests that validate the +/// sequence of calls to user-defined callbacks like Traverse*(), WalkUp*(), +/// Visit*(). +template +class RecordingVisitorBase : public TestVisitor { + ShouldTraversePostOrder ShouldTraversePostOrderValue; + +public: + RecordingVisitorBase(ShouldTraversePostOrder ShouldTraversePostOrderValue) + : ShouldTraversePostOrderValue(ShouldTraversePostOrderValue) {} + + bool shouldTraversePostOrder() const { + return static_cast(ShouldTraversePostOrderValue); + } + + // Callbacks received during traversal. + std::string CallbackLog; + unsigned CallbackLogIndent = 0; + + std::string stmtToString(Stmt *S) { + StringRef ClassName = S->getStmtClassName(); + if (IntegerLiteral *IL = dyn_cast(S)) { + return (ClassName + "(" + IL->getValue().toString(10, false) + ")").str(); + } + if (UnaryOperator *UO = dyn_cast(S)) { + return (ClassName + "(" + UnaryOperator::getOpcodeStr(UO->getOpcode()) + + ")") + .str(); + } + if (BinaryOperator *BO = dyn_cast(S)) { + return (ClassName + "(" + BinaryOperator::getOpcodeStr(BO->getOpcode()) + + ")") + .str(); + } + if (CallExpr *CE = dyn_cast(S)) { + if (FunctionDecl *Callee = CE->getDirectCallee()) { + if (Callee->getIdentifier()) { + return (ClassName + "(" + Callee->getName() + ")").str(); + } + } + } + if (DeclRefExpr *DRE = dyn_cast(S)) { + if (NamedDecl *ND = DRE->getFoundDecl()) { + if (ND->getIdentifier()) { + return (ClassName + "(" + ND->getName() + ")").str(); + } + } + } + return ClassName.str(); + } + + /// Record the fact that the user-defined callback member function + /// \p CallbackName was called with the argument \p S. Then, record the + /// effects of calling the default implementation \p CallDefaultFn. + template + void recordCallback(StringRef CallbackName, Stmt *S, + CallDefault CallDefaultFn) { + for (unsigned i = 0; i != CallbackLogIndent; ++i) { + CallbackLog += " "; + } + CallbackLog += (CallbackName + " " + stmtToString(S) + "\n").str(); + ++CallbackLogIndent; + CallDefaultFn(); + --CallbackLogIndent; + } +}; + +template +::testing::AssertionResult visitorCallbackLogEqual(VisitorTy Visitor, + StringRef Code, + StringRef ExpectedLog) { + Visitor.runOver(Code); + // EXPECT_EQ shows the diff between the two strings if they are different. + EXPECT_EQ(ExpectedLog.trim().str(), + StringRef(Visitor.CallbackLog).trim().str()); + if (ExpectedLog.trim() != StringRef(Visitor.CallbackLog).trim()) { + return ::testing::AssertionFailure(); + } + return ::testing::AssertionSuccess(); +} + +} // namespace + +TEST(RecursiveASTVisitor, StmtCallbacks_TraverseLeaf) { + class RecordingVisitor : public RecordingVisitorBase { + public: + RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue) + : RecordingVisitorBase(ShouldTraversePostOrderValue) {} + + bool TraverseIntegerLiteral(IntegerLiteral *IL) { + recordCallback(__func__, IL, [&]() { + RecordingVisitorBase::TraverseIntegerLiteral(IL); + }); + return true; + } + + bool WalkUpFromStmt(Stmt *S) { + recordCallback(__func__, S, + [&]() { RecordingVisitorBase::WalkUpFromStmt(S); }); + return true; + } + }; + + StringRef Code = R"cpp( +void add(int, int); +void test() { + 1; + 2 + 3; + add(4, 5); +} +)cpp"; + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::No), Code, + R"txt( +WalkUpFromStmt CompoundStmt +TraverseIntegerLiteral IntegerLiteral(1) + WalkUpFromStmt IntegerLiteral(1) +WalkUpFromStmt BinaryOperator(+) +TraverseIntegerLiteral IntegerLiteral(2) + WalkUpFromStmt IntegerLiteral(2) +TraverseIntegerLiteral IntegerLiteral(3) + WalkUpFromStmt IntegerLiteral(3) +WalkUpFromStmt CallExpr(add) +WalkUpFromStmt ImplicitCastExpr +WalkUpFromStmt DeclRefExpr(add) +TraverseIntegerLiteral IntegerLiteral(4) + WalkUpFromStmt IntegerLiteral(4) +TraverseIntegerLiteral IntegerLiteral(5) + WalkUpFromStmt IntegerLiteral(5) +)txt")); + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::Yes), Code, + R"txt( +TraverseIntegerLiteral IntegerLiteral(1) + WalkUpFromStmt IntegerLiteral(1) +TraverseIntegerLiteral IntegerLiteral(2) + WalkUpFromStmt IntegerLiteral(2) +TraverseIntegerLiteral IntegerLiteral(3) + WalkUpFromStmt IntegerLiteral(3) +WalkUpFromStmt BinaryOperator(+) +WalkUpFromStmt DeclRefExpr(add) +WalkUpFromStmt ImplicitCastExpr +TraverseIntegerLiteral IntegerLiteral(4) + WalkUpFromStmt IntegerLiteral(4) +TraverseIntegerLiteral IntegerLiteral(5) + WalkUpFromStmt IntegerLiteral(5) +WalkUpFromStmt CallExpr(add) +WalkUpFromStmt CompoundStmt +)txt")); +} + +TEST(RecursiveASTVisitor, StmtCallbacks_TraverseLeaf_WalkUpFromLeaf) { + class RecordingVisitor : public RecordingVisitorBase { + public: + RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue) + : RecordingVisitorBase(ShouldTraversePostOrderValue) {} + + bool TraverseIntegerLiteral(IntegerLiteral *IL) { + recordCallback(__func__, IL, [&]() { + RecordingVisitorBase::TraverseIntegerLiteral(IL); + }); + return true; + } + + bool WalkUpFromStmt(Stmt *S) { + recordCallback(__func__, S, + [&]() { RecordingVisitorBase::WalkUpFromStmt(S); }); + return true; + } + + bool WalkUpFromExpr(Expr *E) { + recordCallback(__func__, E, + [&]() { RecordingVisitorBase::WalkUpFromExpr(E); }); + return true; + } + + bool WalkUpFromIntegerLiteral(IntegerLiteral *IL) { + recordCallback(__func__, IL, [&]() { + RecordingVisitorBase::WalkUpFromIntegerLiteral(IL); + }); + return true; + } + }; + + StringRef Code = R"cpp( +void add(int, int); +void test() { + 1; + 2 + 3; + add(4, 5); +} +)cpp"; + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::No), Code, + R"txt( +WalkUpFromStmt CompoundStmt +TraverseIntegerLiteral IntegerLiteral(1) + WalkUpFromIntegerLiteral IntegerLiteral(1) + WalkUpFromExpr IntegerLiteral(1) + WalkUpFromStmt IntegerLiteral(1) +WalkUpFromExpr BinaryOperator(+) + WalkUpFromStmt BinaryOperator(+) +TraverseIntegerLiteral IntegerLiteral(2) + WalkUpFromIntegerLiteral IntegerLiteral(2) + WalkUpFromExpr IntegerLiteral(2) + WalkUpFromStmt IntegerLiteral(2) +TraverseIntegerLiteral IntegerLiteral(3) + WalkUpFromIntegerLiteral IntegerLiteral(3) + WalkUpFromExpr IntegerLiteral(3) + WalkUpFromStmt IntegerLiteral(3) +WalkUpFromExpr CallExpr(add) + WalkUpFromStmt CallExpr(add) +WalkUpFromExpr ImplicitCastExpr + WalkUpFromStmt ImplicitCastExpr +WalkUpFromExpr DeclRefExpr(add) + WalkUpFromStmt DeclRefExpr(add) +TraverseIntegerLiteral IntegerLiteral(4) + WalkUpFromIntegerLiteral IntegerLiteral(4) + WalkUpFromExpr IntegerLiteral(4) + WalkUpFromStmt IntegerLiteral(4) +TraverseIntegerLiteral IntegerLiteral(5) + WalkUpFromIntegerLiteral IntegerLiteral(5) + WalkUpFromExpr IntegerLiteral(5) + WalkUpFromStmt IntegerLiteral(5) +)txt")); + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::Yes), Code, + R"txt( +TraverseIntegerLiteral IntegerLiteral(1) + WalkUpFromIntegerLiteral IntegerLiteral(1) + WalkUpFromExpr IntegerLiteral(1) + WalkUpFromStmt IntegerLiteral(1) +TraverseIntegerLiteral IntegerLiteral(2) + WalkUpFromIntegerLiteral IntegerLiteral(2) + WalkUpFromExpr IntegerLiteral(2) + WalkUpFromStmt IntegerLiteral(2) +TraverseIntegerLiteral IntegerLiteral(3) + WalkUpFromIntegerLiteral IntegerLiteral(3) + WalkUpFromExpr IntegerLiteral(3) + WalkUpFromStmt IntegerLiteral(3) +WalkUpFromExpr BinaryOperator(+) + WalkUpFromStmt BinaryOperator(+) +WalkUpFromExpr DeclRefExpr(add) + WalkUpFromStmt DeclRefExpr(add) +WalkUpFromExpr ImplicitCastExpr + WalkUpFromStmt ImplicitCastExpr +TraverseIntegerLiteral IntegerLiteral(4) + WalkUpFromIntegerLiteral IntegerLiteral(4) + WalkUpFromExpr IntegerLiteral(4) + WalkUpFromStmt IntegerLiteral(4) +TraverseIntegerLiteral IntegerLiteral(5) + WalkUpFromIntegerLiteral IntegerLiteral(5) + WalkUpFromExpr IntegerLiteral(5) + WalkUpFromStmt IntegerLiteral(5) +WalkUpFromExpr CallExpr(add) + WalkUpFromStmt CallExpr(add) +WalkUpFromStmt CompoundStmt +)txt")); +} + +TEST(RecursiveASTVisitor, StmtCallbacks_WalkUpFromLeaf) { + class RecordingVisitor : public RecordingVisitorBase { + public: + RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue) + : RecordingVisitorBase(ShouldTraversePostOrderValue) {} + + bool WalkUpFromStmt(Stmt *S) { + recordCallback(__func__, S, + [&]() { RecordingVisitorBase::WalkUpFromStmt(S); }); + return true; + } + + bool WalkUpFromExpr(Expr *E) { + recordCallback(__func__, E, + [&]() { RecordingVisitorBase::WalkUpFromExpr(E); }); + return true; + } + + bool WalkUpFromIntegerLiteral(IntegerLiteral *IL) { + recordCallback(__func__, IL, [&]() { + RecordingVisitorBase::WalkUpFromIntegerLiteral(IL); + }); + return true; + } + }; + + StringRef Code = R"cpp( +void add(int, int); +void test() { + 1; + 2 + 3; + add(4, 5); +} +)cpp"; + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::No), Code, + R"txt( +WalkUpFromStmt CompoundStmt +WalkUpFromIntegerLiteral IntegerLiteral(1) + WalkUpFromExpr IntegerLiteral(1) + WalkUpFromStmt IntegerLiteral(1) +WalkUpFromExpr BinaryOperator(+) + WalkUpFromStmt BinaryOperator(+) +WalkUpFromIntegerLiteral IntegerLiteral(2) + WalkUpFromExpr IntegerLiteral(2) + WalkUpFromStmt IntegerLiteral(2) +WalkUpFromIntegerLiteral IntegerLiteral(3) + WalkUpFromExpr IntegerLiteral(3) + WalkUpFromStmt IntegerLiteral(3) +WalkUpFromExpr CallExpr(add) + WalkUpFromStmt CallExpr(add) +WalkUpFromExpr ImplicitCastExpr + WalkUpFromStmt ImplicitCastExpr +WalkUpFromExpr DeclRefExpr(add) + WalkUpFromStmt DeclRefExpr(add) +WalkUpFromIntegerLiteral IntegerLiteral(4) + WalkUpFromExpr IntegerLiteral(4) + WalkUpFromStmt IntegerLiteral(4) +WalkUpFromIntegerLiteral IntegerLiteral(5) + WalkUpFromExpr IntegerLiteral(5) + WalkUpFromStmt IntegerLiteral(5) +)txt")); + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::Yes), Code, + R"txt( +WalkUpFromIntegerLiteral IntegerLiteral(1) + WalkUpFromExpr IntegerLiteral(1) + WalkUpFromStmt IntegerLiteral(1) +WalkUpFromIntegerLiteral IntegerLiteral(2) + WalkUpFromExpr IntegerLiteral(2) + WalkUpFromStmt IntegerLiteral(2) +WalkUpFromIntegerLiteral IntegerLiteral(3) + WalkUpFromExpr IntegerLiteral(3) + WalkUpFromStmt IntegerLiteral(3) +WalkUpFromExpr BinaryOperator(+) + WalkUpFromStmt BinaryOperator(+) +WalkUpFromExpr DeclRefExpr(add) + WalkUpFromStmt DeclRefExpr(add) +WalkUpFromExpr ImplicitCastExpr + WalkUpFromStmt ImplicitCastExpr +WalkUpFromIntegerLiteral IntegerLiteral(4) + WalkUpFromExpr IntegerLiteral(4) + WalkUpFromStmt IntegerLiteral(4) +WalkUpFromIntegerLiteral IntegerLiteral(5) + WalkUpFromExpr IntegerLiteral(5) + WalkUpFromStmt IntegerLiteral(5) +WalkUpFromExpr CallExpr(add) + WalkUpFromStmt CallExpr(add) +WalkUpFromStmt CompoundStmt +)txt")); +} + +TEST(RecursiveASTVisitor, StmtCallbacks_TraverseUnaryOperator) { + class RecordingVisitor : public RecordingVisitorBase { + public: + RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue) + : RecordingVisitorBase(ShouldTraversePostOrderValue) {} + + bool TraverseUnaryOperator(UnaryOperator *UO) { + recordCallback(__func__, UO, [&]() { + RecordingVisitorBase::TraverseUnaryOperator(UO); + }); + return true; + } + + bool WalkUpFromStmt(Stmt *S) { + recordCallback(__func__, S, + [&]() { RecordingVisitorBase::WalkUpFromStmt(S); }); + return true; + } + }; + + StringRef Code = R"cpp( +void test() { + 1; + -2; + 3; +} +)cpp"; + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::No), Code, + R"txt( +WalkUpFromStmt CompoundStmt +WalkUpFromStmt IntegerLiteral(1) +TraverseUnaryOperator UnaryOperator(-) + WalkUpFromStmt UnaryOperator(-) + WalkUpFromStmt IntegerLiteral(2) +WalkUpFromStmt IntegerLiteral(3) +)txt")); + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::Yes), Code, + R"txt( +WalkUpFromStmt IntegerLiteral(1) +TraverseUnaryOperator UnaryOperator(-) + WalkUpFromStmt IntegerLiteral(2) + WalkUpFromStmt UnaryOperator(-) +WalkUpFromStmt IntegerLiteral(3) +WalkUpFromStmt CompoundStmt +)txt")); +} + +TEST(RecursiveASTVisitor, + StmtCallbacks_TraverseUnaryOperator_WalkUpFromUnaryOperator) { + class RecordingVisitor : public RecordingVisitorBase { + public: + RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue) + : RecordingVisitorBase(ShouldTraversePostOrderValue) {} + + bool TraverseUnaryOperator(UnaryOperator *UO) { + recordCallback(__func__, UO, [&]() { + RecordingVisitorBase::TraverseUnaryOperator(UO); + }); + return true; + } + + bool WalkUpFromStmt(Stmt *S) { + recordCallback(__func__, S, + [&]() { RecordingVisitorBase::WalkUpFromStmt(S); }); + return true; + } + + bool WalkUpFromExpr(Expr *E) { + recordCallback(__func__, E, + [&]() { RecordingVisitorBase::WalkUpFromExpr(E); }); + return true; + } + + bool WalkUpFromUnaryOperator(UnaryOperator *UO) { + recordCallback(__func__, UO, [&]() { + RecordingVisitorBase::WalkUpFromUnaryOperator(UO); + }); + return true; + } + }; + + StringRef Code = R"cpp( +void test() { + 1; + -2; + 3; +} +)cpp"; + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::No), Code, + R"txt( +WalkUpFromStmt CompoundStmt +WalkUpFromExpr IntegerLiteral(1) + WalkUpFromStmt IntegerLiteral(1) +TraverseUnaryOperator UnaryOperator(-) + WalkUpFromUnaryOperator UnaryOperator(-) + WalkUpFromExpr UnaryOperator(-) + WalkUpFromStmt UnaryOperator(-) + WalkUpFromExpr IntegerLiteral(2) + WalkUpFromStmt IntegerLiteral(2) +WalkUpFromExpr IntegerLiteral(3) + WalkUpFromStmt IntegerLiteral(3) +)txt")); + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::Yes), Code, + R"txt( +WalkUpFromExpr IntegerLiteral(1) + WalkUpFromStmt IntegerLiteral(1) +TraverseUnaryOperator UnaryOperator(-) + WalkUpFromExpr IntegerLiteral(2) + WalkUpFromStmt IntegerLiteral(2) + WalkUpFromUnaryOperator UnaryOperator(-) + WalkUpFromExpr UnaryOperator(-) + WalkUpFromStmt UnaryOperator(-) +WalkUpFromExpr IntegerLiteral(3) + WalkUpFromStmt IntegerLiteral(3) +WalkUpFromStmt CompoundStmt +)txt")); +} + +TEST(RecursiveASTVisitor, StmtCallbacks_WalkUpFromUnaryOperator) { + class RecordingVisitor : public RecordingVisitorBase { + public: + RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue) + : RecordingVisitorBase(ShouldTraversePostOrderValue) {} + + bool WalkUpFromStmt(Stmt *S) { + recordCallback(__func__, S, + [&]() { RecordingVisitorBase::WalkUpFromStmt(S); }); + return true; + } + + bool WalkUpFromExpr(Expr *E) { + recordCallback(__func__, E, + [&]() { RecordingVisitorBase::WalkUpFromExpr(E); }); + return true; + } + + bool WalkUpFromUnaryOperator(UnaryOperator *UO) { + recordCallback(__func__, UO, [&]() { + RecordingVisitorBase::WalkUpFromUnaryOperator(UO); + }); + return true; + } + }; + + StringRef Code = R"cpp( +void test() { + 1; + -2; + 3; +} +)cpp"; + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::No), Code, + R"txt( +WalkUpFromStmt CompoundStmt +WalkUpFromExpr IntegerLiteral(1) + WalkUpFromStmt IntegerLiteral(1) +WalkUpFromUnaryOperator UnaryOperator(-) + WalkUpFromExpr UnaryOperator(-) + WalkUpFromStmt UnaryOperator(-) +WalkUpFromExpr IntegerLiteral(2) + WalkUpFromStmt IntegerLiteral(2) +WalkUpFromExpr IntegerLiteral(3) + WalkUpFromStmt IntegerLiteral(3) +)txt")); + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::Yes), Code, + R"txt( +WalkUpFromExpr IntegerLiteral(1) + WalkUpFromStmt IntegerLiteral(1) +WalkUpFromExpr IntegerLiteral(2) + WalkUpFromStmt IntegerLiteral(2) +WalkUpFromUnaryOperator UnaryOperator(-) + WalkUpFromExpr UnaryOperator(-) + WalkUpFromStmt UnaryOperator(-) +WalkUpFromExpr IntegerLiteral(3) + WalkUpFromStmt IntegerLiteral(3) +WalkUpFromStmt CompoundStmt +)txt")); +} + +TEST(RecursiveASTVisitor, StmtCallbacks_TraverseBinaryOperator) { + class RecordingVisitor : public RecordingVisitorBase { + public: + RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue) + : RecordingVisitorBase(ShouldTraversePostOrderValue) {} + + bool TraverseBinaryOperator(BinaryOperator *BO) { + recordCallback(__func__, BO, [&]() { + RecordingVisitorBase::TraverseBinaryOperator(BO); + }); + return true; + } + + bool WalkUpFromStmt(Stmt *S) { + recordCallback(__func__, S, + [&]() { RecordingVisitorBase::WalkUpFromStmt(S); }); + return true; + } + }; + + StringRef Code = R"cpp( +void test() { + 1; + 2 + 3; + 4; +} +)cpp"; + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::No), Code, + R"txt( +WalkUpFromStmt CompoundStmt +WalkUpFromStmt IntegerLiteral(1) +TraverseBinaryOperator BinaryOperator(+) + WalkUpFromStmt BinaryOperator(+) + WalkUpFromStmt IntegerLiteral(2) + WalkUpFromStmt IntegerLiteral(3) +WalkUpFromStmt IntegerLiteral(4) +)txt")); + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::Yes), Code, + R"txt( +WalkUpFromStmt IntegerLiteral(1) +TraverseBinaryOperator BinaryOperator(+) + WalkUpFromStmt IntegerLiteral(2) + WalkUpFromStmt IntegerLiteral(3) + WalkUpFromStmt BinaryOperator(+) +WalkUpFromStmt IntegerLiteral(4) +WalkUpFromStmt CompoundStmt +)txt")); +} + +TEST(RecursiveASTVisitor, + StmtCallbacks_TraverseBinaryOperator_WalkUpFromBinaryOperator) { + class RecordingVisitor : public RecordingVisitorBase { + public: + RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue) + : RecordingVisitorBase(ShouldTraversePostOrderValue) {} + + bool TraverseBinaryOperator(BinaryOperator *BO) { + recordCallback(__func__, BO, [&]() { + RecordingVisitorBase::TraverseBinaryOperator(BO); + }); + return true; + } + + bool WalkUpFromStmt(Stmt *S) { + recordCallback(__func__, S, + [&]() { RecordingVisitorBase::WalkUpFromStmt(S); }); + return true; + } + + bool WalkUpFromExpr(Expr *E) { + recordCallback(__func__, E, + [&]() { RecordingVisitorBase::WalkUpFromExpr(E); }); + return true; + } + + bool WalkUpFromBinaryOperator(BinaryOperator *BO) { + recordCallback(__func__, BO, [&]() { + RecordingVisitorBase::WalkUpFromBinaryOperator(BO); + }); + return true; + } + }; + + StringRef Code = R"cpp( +void test() { + 1; + 2 + 3; + 4; +} +)cpp"; + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::No), Code, + R"txt( +WalkUpFromStmt CompoundStmt +WalkUpFromExpr IntegerLiteral(1) + WalkUpFromStmt IntegerLiteral(1) +TraverseBinaryOperator BinaryOperator(+) + WalkUpFromBinaryOperator BinaryOperator(+) + WalkUpFromExpr BinaryOperator(+) + WalkUpFromStmt BinaryOperator(+) + WalkUpFromExpr IntegerLiteral(2) + WalkUpFromStmt IntegerLiteral(2) + WalkUpFromExpr IntegerLiteral(3) + WalkUpFromStmt IntegerLiteral(3) +WalkUpFromExpr IntegerLiteral(4) + WalkUpFromStmt IntegerLiteral(4) +)txt")); + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::Yes), Code, + R"txt( +WalkUpFromExpr IntegerLiteral(1) + WalkUpFromStmt IntegerLiteral(1) +TraverseBinaryOperator BinaryOperator(+) + WalkUpFromExpr IntegerLiteral(2) + WalkUpFromStmt IntegerLiteral(2) + WalkUpFromExpr IntegerLiteral(3) + WalkUpFromStmt IntegerLiteral(3) + WalkUpFromBinaryOperator BinaryOperator(+) + WalkUpFromExpr BinaryOperator(+) + WalkUpFromStmt BinaryOperator(+) +WalkUpFromExpr IntegerLiteral(4) + WalkUpFromStmt IntegerLiteral(4) +WalkUpFromStmt CompoundStmt +)txt")); +} + +TEST(RecursiveASTVisitor, StmtCallbacks_WalkUpFromBinaryOperator) { + class RecordingVisitor : public RecordingVisitorBase { + public: + RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue) + : RecordingVisitorBase(ShouldTraversePostOrderValue) {} + + bool WalkUpFromStmt(Stmt *S) { + recordCallback(__func__, S, + [&]() { RecordingVisitorBase::WalkUpFromStmt(S); }); + return true; + } + + bool WalkUpFromExpr(Expr *E) { + recordCallback(__func__, E, + [&]() { RecordingVisitorBase::WalkUpFromExpr(E); }); + return true; + } + + bool WalkUpFromBinaryOperator(BinaryOperator *BO) { + recordCallback(__func__, BO, [&]() { + RecordingVisitorBase::WalkUpFromBinaryOperator(BO); + }); + return true; + } + }; + + StringRef Code = R"cpp( +void test() { + 1; + 2 + 3; + 4; +} +)cpp"; + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::No), Code, + R"txt( +WalkUpFromStmt CompoundStmt +WalkUpFromExpr IntegerLiteral(1) + WalkUpFromStmt IntegerLiteral(1) +WalkUpFromBinaryOperator BinaryOperator(+) + WalkUpFromExpr BinaryOperator(+) + WalkUpFromStmt BinaryOperator(+) +WalkUpFromExpr IntegerLiteral(2) + WalkUpFromStmt IntegerLiteral(2) +WalkUpFromExpr IntegerLiteral(3) + WalkUpFromStmt IntegerLiteral(3) +WalkUpFromExpr IntegerLiteral(4) + WalkUpFromStmt IntegerLiteral(4) +)txt")); + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::Yes), Code, + R"txt( +WalkUpFromExpr IntegerLiteral(1) + WalkUpFromStmt IntegerLiteral(1) +WalkUpFromExpr IntegerLiteral(2) + WalkUpFromStmt IntegerLiteral(2) +WalkUpFromExpr IntegerLiteral(3) + WalkUpFromStmt IntegerLiteral(3) +WalkUpFromBinaryOperator BinaryOperator(+) + WalkUpFromExpr BinaryOperator(+) + WalkUpFromStmt BinaryOperator(+) +WalkUpFromExpr IntegerLiteral(4) + WalkUpFromStmt IntegerLiteral(4) +WalkUpFromStmt CompoundStmt +)txt")); +} + +TEST(RecursiveASTVisitor, StmtCallbacks_TraverseCompoundAssignOperator) { + class RecordingVisitor : public RecordingVisitorBase { + public: + RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue) + : RecordingVisitorBase(ShouldTraversePostOrderValue) {} + + bool TraverseCompoundAssignOperator(CompoundAssignOperator *CAO) { + recordCallback(__func__, CAO, [&]() { + RecordingVisitorBase::TraverseCompoundAssignOperator(CAO); + }); + return true; + } + + bool WalkUpFromStmt(Stmt *S) { + recordCallback(__func__, S, + [&]() { RecordingVisitorBase::WalkUpFromStmt(S); }); + return true; + } + }; + + StringRef Code = R"cpp( +void test(int a) { + 1; + a += 2; + 3; +} +)cpp"; + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::No), Code, + R"txt( +WalkUpFromStmt CompoundStmt +WalkUpFromStmt IntegerLiteral(1) +TraverseCompoundAssignOperator CompoundAssignOperator(+=) + WalkUpFromStmt CompoundAssignOperator(+=) + WalkUpFromStmt DeclRefExpr(a) + WalkUpFromStmt IntegerLiteral(2) +WalkUpFromStmt IntegerLiteral(3) +)txt")); + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::Yes), Code, + R"txt( +WalkUpFromStmt IntegerLiteral(1) +TraverseCompoundAssignOperator CompoundAssignOperator(+=) + WalkUpFromStmt DeclRefExpr(a) + WalkUpFromStmt IntegerLiteral(2) + WalkUpFromStmt CompoundAssignOperator(+=) +WalkUpFromStmt IntegerLiteral(3) +WalkUpFromStmt CompoundStmt +)txt")); +} + +TEST( + RecursiveASTVisitor, + StmtCallbacks_TraverseCompoundAssignOperator_WalkUpFromCompoundAssignOperator) { + class RecordingVisitor : public RecordingVisitorBase { + public: + RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue) + : RecordingVisitorBase(ShouldTraversePostOrderValue) {} + + bool TraverseCompoundAssignOperator(CompoundAssignOperator *CAO) { + recordCallback(__func__, CAO, [&]() { + RecordingVisitorBase::TraverseCompoundAssignOperator(CAO); + }); + return true; + } + + bool WalkUpFromStmt(Stmt *S) { + recordCallback(__func__, S, + [&]() { RecordingVisitorBase::WalkUpFromStmt(S); }); + return true; + } + + bool WalkUpFromExpr(Expr *E) { + recordCallback(__func__, E, + [&]() { RecordingVisitorBase::WalkUpFromExpr(E); }); + return true; + } + + bool WalkUpFromCompoundAssignOperator(CompoundAssignOperator *CAO) { + recordCallback(__func__, CAO, [&]() { + RecordingVisitorBase::WalkUpFromCompoundAssignOperator(CAO); + }); + return true; + } + }; + + StringRef Code = R"cpp( +void test(int a) { + 1; + a += 2; + 3; +} +)cpp"; + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::No), Code, + R"txt( +WalkUpFromStmt CompoundStmt +WalkUpFromExpr IntegerLiteral(1) + WalkUpFromStmt IntegerLiteral(1) +TraverseCompoundAssignOperator CompoundAssignOperator(+=) + WalkUpFromCompoundAssignOperator CompoundAssignOperator(+=) + WalkUpFromExpr CompoundAssignOperator(+=) + WalkUpFromStmt CompoundAssignOperator(+=) + WalkUpFromExpr DeclRefExpr(a) + WalkUpFromStmt DeclRefExpr(a) + WalkUpFromExpr IntegerLiteral(2) + WalkUpFromStmt IntegerLiteral(2) +WalkUpFromExpr IntegerLiteral(3) + WalkUpFromStmt IntegerLiteral(3) +)txt")); + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::Yes), Code, + R"txt( +WalkUpFromExpr IntegerLiteral(1) + WalkUpFromStmt IntegerLiteral(1) +TraverseCompoundAssignOperator CompoundAssignOperator(+=) + WalkUpFromExpr DeclRefExpr(a) + WalkUpFromStmt DeclRefExpr(a) + WalkUpFromExpr IntegerLiteral(2) + WalkUpFromStmt IntegerLiteral(2) + WalkUpFromCompoundAssignOperator CompoundAssignOperator(+=) + WalkUpFromExpr CompoundAssignOperator(+=) + WalkUpFromStmt CompoundAssignOperator(+=) +WalkUpFromExpr IntegerLiteral(3) + WalkUpFromStmt IntegerLiteral(3) +WalkUpFromStmt CompoundStmt +)txt")); +} + +TEST(RecursiveASTVisitor, StmtCallbacks_WalkUpFromCompoundAssignOperator) { + class RecordingVisitor : public RecordingVisitorBase { + public: + RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue) + : RecordingVisitorBase(ShouldTraversePostOrderValue) {} + + bool WalkUpFromStmt(Stmt *S) { + recordCallback(__func__, S, + [&]() { RecordingVisitorBase::WalkUpFromStmt(S); }); + return true; + } + + bool WalkUpFromExpr(Expr *E) { + recordCallback(__func__, E, + [&]() { RecordingVisitorBase::WalkUpFromExpr(E); }); + return true; + } + + bool WalkUpFromCompoundAssignOperator(CompoundAssignOperator *CAO) { + recordCallback(__func__, CAO, [&]() { + RecordingVisitorBase::WalkUpFromCompoundAssignOperator(CAO); + }); + return true; + } + }; + + StringRef Code = R"cpp( +void test(int a) { + 1; + a += 2; + 3; +} +)cpp"; + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::No), Code, + R"txt( +WalkUpFromStmt CompoundStmt +WalkUpFromExpr IntegerLiteral(1) + WalkUpFromStmt IntegerLiteral(1) +WalkUpFromCompoundAssignOperator CompoundAssignOperator(+=) + WalkUpFromExpr CompoundAssignOperator(+=) + WalkUpFromStmt CompoundAssignOperator(+=) +WalkUpFromExpr DeclRefExpr(a) + WalkUpFromStmt DeclRefExpr(a) +WalkUpFromExpr IntegerLiteral(2) + WalkUpFromStmt IntegerLiteral(2) +WalkUpFromExpr IntegerLiteral(3) + WalkUpFromStmt IntegerLiteral(3) +)txt")); + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::Yes), Code, + R"txt( +WalkUpFromExpr IntegerLiteral(1) + WalkUpFromStmt IntegerLiteral(1) +WalkUpFromExpr DeclRefExpr(a) + WalkUpFromStmt DeclRefExpr(a) +WalkUpFromExpr IntegerLiteral(2) + WalkUpFromStmt IntegerLiteral(2) +WalkUpFromCompoundAssignOperator CompoundAssignOperator(+=) + WalkUpFromExpr CompoundAssignOperator(+=) + WalkUpFromStmt CompoundAssignOperator(+=) +WalkUpFromExpr IntegerLiteral(3) + WalkUpFromStmt IntegerLiteral(3) +WalkUpFromStmt CompoundStmt +)txt")); +} + +TEST(RecursiveASTVisitor, StmtCallbacks_TraverseCallExpr) { + class RecordingVisitor : public RecordingVisitorBase { + public: + RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue) + : RecordingVisitorBase(ShouldTraversePostOrderValue) {} + + bool TraverseCallExpr(CallExpr *CE) { + recordCallback(__func__, CE, + [&]() { RecordingVisitorBase::TraverseCallExpr(CE); }); + return true; + } + + bool WalkUpFromStmt(Stmt *S) { + recordCallback(__func__, S, + [&]() { RecordingVisitorBase::WalkUpFromStmt(S); }); + return true; + } + }; + + StringRef Code = R"cpp( +void add(int, int); +void test() { + 1; + 2 + 3; + add(4, 5); +} +)cpp"; + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::No), Code, + R"txt( +WalkUpFromStmt CompoundStmt +WalkUpFromStmt IntegerLiteral(1) +WalkUpFromStmt BinaryOperator(+) +WalkUpFromStmt IntegerLiteral(2) +WalkUpFromStmt IntegerLiteral(3) +TraverseCallExpr CallExpr(add) + WalkUpFromStmt CallExpr(add) + WalkUpFromStmt ImplicitCastExpr + WalkUpFromStmt DeclRefExpr(add) + WalkUpFromStmt IntegerLiteral(4) + WalkUpFromStmt IntegerLiteral(5) +)txt")); + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::Yes), Code, + R"txt( +WalkUpFromStmt IntegerLiteral(1) +WalkUpFromStmt IntegerLiteral(2) +WalkUpFromStmt IntegerLiteral(3) +WalkUpFromStmt BinaryOperator(+) +TraverseCallExpr CallExpr(add) + WalkUpFromStmt DeclRefExpr(add) + WalkUpFromStmt ImplicitCastExpr + WalkUpFromStmt IntegerLiteral(4) + WalkUpFromStmt IntegerLiteral(5) + WalkUpFromStmt CallExpr(add) +WalkUpFromStmt CompoundStmt +)txt")); +} + +TEST(RecursiveASTVisitor, StmtCallbacks_TraverseCallExpr_WalkUpFromCallExpr) { + class RecordingVisitor : public RecordingVisitorBase { + public: + RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue) + : RecordingVisitorBase(ShouldTraversePostOrderValue) {} + + bool TraverseCallExpr(CallExpr *CE) { + recordCallback(__func__, CE, + [&]() { RecordingVisitorBase::TraverseCallExpr(CE); }); + return true; + } + + bool WalkUpFromStmt(Stmt *S) { + recordCallback(__func__, S, + [&]() { RecordingVisitorBase::WalkUpFromStmt(S); }); + return true; + } + + bool WalkUpFromExpr(Expr *E) { + recordCallback(__func__, E, + [&]() { RecordingVisitorBase::WalkUpFromExpr(E); }); + return true; + } + + bool WalkUpFromCallExpr(CallExpr *CE) { + recordCallback(__func__, CE, + [&]() { RecordingVisitorBase::WalkUpFromCallExpr(CE); }); + return true; + } + }; + + StringRef Code = R"cpp( +void add(int, int); +void test() { + 1; + 2 + 3; + add(4, 5); +} +)cpp"; + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::No), Code, + R"txt( +WalkUpFromStmt CompoundStmt +WalkUpFromExpr IntegerLiteral(1) + WalkUpFromStmt IntegerLiteral(1) +WalkUpFromExpr BinaryOperator(+) + WalkUpFromStmt BinaryOperator(+) +WalkUpFromExpr IntegerLiteral(2) + WalkUpFromStmt IntegerLiteral(2) +WalkUpFromExpr IntegerLiteral(3) + WalkUpFromStmt IntegerLiteral(3) +TraverseCallExpr CallExpr(add) + WalkUpFromCallExpr CallExpr(add) + WalkUpFromExpr CallExpr(add) + WalkUpFromStmt CallExpr(add) + WalkUpFromExpr ImplicitCastExpr + WalkUpFromStmt ImplicitCastExpr + WalkUpFromExpr DeclRefExpr(add) + WalkUpFromStmt DeclRefExpr(add) + WalkUpFromExpr IntegerLiteral(4) + WalkUpFromStmt IntegerLiteral(4) + WalkUpFromExpr IntegerLiteral(5) + WalkUpFromStmt IntegerLiteral(5) +)txt")); + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::Yes), Code, + R"txt( +WalkUpFromExpr IntegerLiteral(1) + WalkUpFromStmt IntegerLiteral(1) +WalkUpFromExpr IntegerLiteral(2) + WalkUpFromStmt IntegerLiteral(2) +WalkUpFromExpr IntegerLiteral(3) + WalkUpFromStmt IntegerLiteral(3) +WalkUpFromExpr BinaryOperator(+) + WalkUpFromStmt BinaryOperator(+) +TraverseCallExpr CallExpr(add) + WalkUpFromExpr DeclRefExpr(add) + WalkUpFromStmt DeclRefExpr(add) + WalkUpFromExpr ImplicitCastExpr + WalkUpFromStmt ImplicitCastExpr + WalkUpFromExpr IntegerLiteral(4) + WalkUpFromStmt IntegerLiteral(4) + WalkUpFromExpr IntegerLiteral(5) + WalkUpFromStmt IntegerLiteral(5) + WalkUpFromCallExpr CallExpr(add) + WalkUpFromExpr CallExpr(add) + WalkUpFromStmt CallExpr(add) +WalkUpFromStmt CompoundStmt +)txt")); +} + +TEST(RecursiveASTVisitor, StmtCallbacks_WalkUpFromCallExpr) { + class RecordingVisitor : public RecordingVisitorBase { + public: + RecordingVisitor(ShouldTraversePostOrder ShouldTraversePostOrderValue) + : RecordingVisitorBase(ShouldTraversePostOrderValue) {} + + bool WalkUpFromStmt(Stmt *S) { + recordCallback(__func__, S, + [&]() { RecordingVisitorBase::WalkUpFromStmt(S); }); + return true; + } + + bool WalkUpFromExpr(Expr *E) { + recordCallback(__func__, E, + [&]() { RecordingVisitorBase::WalkUpFromExpr(E); }); + return true; + } + + bool WalkUpFromCallExpr(CallExpr *CE) { + recordCallback(__func__, CE, + [&]() { RecordingVisitorBase::WalkUpFromCallExpr(CE); }); + return true; + } + }; + + StringRef Code = R"cpp( +void add(int, int); +void test() { + 1; + 2 + 3; + add(4, 5); +} +)cpp"; + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::No), Code, + R"txt( +WalkUpFromStmt CompoundStmt +WalkUpFromExpr IntegerLiteral(1) + WalkUpFromStmt IntegerLiteral(1) +WalkUpFromExpr BinaryOperator(+) + WalkUpFromStmt BinaryOperator(+) +WalkUpFromExpr IntegerLiteral(2) + WalkUpFromStmt IntegerLiteral(2) +WalkUpFromExpr IntegerLiteral(3) + WalkUpFromStmt IntegerLiteral(3) +WalkUpFromCallExpr CallExpr(add) + WalkUpFromExpr CallExpr(add) + WalkUpFromStmt CallExpr(add) +WalkUpFromExpr ImplicitCastExpr + WalkUpFromStmt ImplicitCastExpr +WalkUpFromExpr DeclRefExpr(add) + WalkUpFromStmt DeclRefExpr(add) +WalkUpFromExpr IntegerLiteral(4) + WalkUpFromStmt IntegerLiteral(4) +WalkUpFromExpr IntegerLiteral(5) + WalkUpFromStmt IntegerLiteral(5) +)txt")); + + EXPECT_TRUE(visitorCallbackLogEqual( + RecordingVisitor(ShouldTraversePostOrder::Yes), Code, + R"txt( +WalkUpFromExpr IntegerLiteral(1) + WalkUpFromStmt IntegerLiteral(1) +WalkUpFromExpr IntegerLiteral(2) + WalkUpFromStmt IntegerLiteral(2) +WalkUpFromExpr IntegerLiteral(3) + WalkUpFromStmt IntegerLiteral(3) +WalkUpFromExpr BinaryOperator(+) + WalkUpFromStmt BinaryOperator(+) +WalkUpFromExpr DeclRefExpr(add) + WalkUpFromStmt DeclRefExpr(add) +WalkUpFromExpr ImplicitCastExpr + WalkUpFromStmt ImplicitCastExpr +WalkUpFromExpr IntegerLiteral(4) + WalkUpFromStmt IntegerLiteral(4) +WalkUpFromExpr IntegerLiteral(5) + WalkUpFromStmt IntegerLiteral(5) +WalkUpFromCallExpr CallExpr(add) + WalkUpFromExpr CallExpr(add) + WalkUpFromStmt CallExpr(add) +WalkUpFromStmt CompoundStmt +)txt")); +} diff --git a/clang/unittests/Tooling/RefactoringTest.cpp b/clang/unittests/Tooling/RefactoringTest.cpp index d65c6dba77b24..97a26a71deec7 100644 --- a/clang/unittests/Tooling/RefactoringTest.cpp +++ b/clang/unittests/Tooling/RefactoringTest.cpp @@ -1296,6 +1296,18 @@ TEST_F(AtomicChangeTest, InsertAfterWithInvalidLocation) { Replacement(Context.Sources, SourceLocation(), 0, "b"))); } +TEST_F(AtomicChangeTest, Metadata) { + AtomicChange Change(Context.Sources, DefaultLoc, 17); + const llvm::Any &Metadata = Change.getMetadata(); + ASSERT_TRUE(llvm::any_isa(Metadata)); + EXPECT_EQ(llvm::any_cast(Metadata), 17); +} + +TEST_F(AtomicChangeTest, NoMetadata) { + AtomicChange Change(Context.Sources, DefaultLoc); + EXPECT_FALSE(Change.getMetadata().hasValue()); +} + class ApplyAtomicChangesTest : public ::testing::Test { protected: ApplyAtomicChangesTest() : FilePath("file.cc") { diff --git a/clang/unittests/Tooling/ReplacementsYamlTest.cpp b/clang/unittests/Tooling/ReplacementsYamlTest.cpp index c8fe9c4db412b..3328d9bad55c7 100644 --- a/clang/unittests/Tooling/ReplacementsYamlTest.cpp +++ b/clang/unittests/Tooling/ReplacementsYamlTest.cpp @@ -65,7 +65,7 @@ TEST(ReplacementsYamlTest, serializesNewLines) { " - FilePath: '/path/to/file1.h'\n" " Offset: 0\n" " Length: 0\n" - " ReplacementText: '#include \n\n'\n" + " ReplacementText: \"#include \\n\"\n" "...\n", YamlContentStream.str().c_str()); } diff --git a/clang/unittests/Tooling/SourceCodeTest.cpp b/clang/unittests/Tooling/SourceCodeTest.cpp index aeb0ca36582bc..eb652cf030644 100644 --- a/clang/unittests/Tooling/SourceCodeTest.cpp +++ b/clang/unittests/Tooling/SourceCodeTest.cpp @@ -9,6 +9,8 @@ #include "clang/Tooling/Transformer/SourceCode.h" #include "TestVisitor.h" #include "clang/Basic/Diagnostic.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Lex/Lexer.h" #include "llvm/Testing/Support/Annotations.h" #include "llvm/Testing/Support/Error.h" #include "llvm/Testing/Support/SupportHelpers.h" @@ -21,9 +23,11 @@ using llvm::Failed; using llvm::Succeeded; using llvm::ValueIs; using tooling::getAssociatedRange; +using tooling::getExtendedRange; using tooling::getExtendedText; using tooling::getRangeForEdit; using tooling::getText; +using tooling::maybeExtendRange; using tooling::validateEditRange; namespace { @@ -52,7 +56,7 @@ MATCHER_P(EqualsRange, R, "") { arg.getBegin() == R.getBegin() && arg.getEnd() == R.getEnd(); } -MATCHER_P2(EqualsAnnotatedRange, SM, R, "") { +MATCHER_P2(EqualsAnnotatedRange, Context, R, "") { if (arg.getBegin().isMacroID()) { *result_listener << "which starts in a macro"; return false; @@ -62,15 +66,13 @@ MATCHER_P2(EqualsAnnotatedRange, SM, R, "") { return false; } - unsigned Begin = SM->getFileOffset(arg.getBegin()); - unsigned End = SM->getFileOffset(arg.getEnd()); + CharSourceRange Range = Lexer::getAsCharRange( + arg, Context->getSourceManager(), Context->getLangOpts()); + unsigned Begin = Context->getSourceManager().getFileOffset(Range.getBegin()); + unsigned End = Context->getSourceManager().getFileOffset(Range.getEnd()); - *result_listener << "which is [" << Begin << ","; - if (arg.isTokenRange()) { - *result_listener << End << "]"; - return Begin == R.Begin && End + 1 == R.End; - } - *result_listener << End << ")"; + *result_listener << "which is a " << (arg.isTokenRange() ? "Token" : "Char") + << " range [" << Begin << "," << End << ")"; return Begin == R.Begin && End == R.End; } @@ -84,11 +86,13 @@ static ::testing::Matcher AsRange(const SourceManager &SM, // Base class for visitors that expect a single match corresponding to a // specific annotated range. template class AnnotatedCodeVisitor : public TestVisitor { - llvm::Annotations Code; +protected: int MatchCount = 0; + llvm::Annotations Code; public: AnnotatedCodeVisitor() : Code("$r[[]]") {} + // Helper for tests of `getAssociatedRange`. bool VisitDeclHelper(Decl *Decl) { // Only consider explicit declarations. if (Decl->isImplicit()) @@ -96,8 +100,7 @@ template class AnnotatedCodeVisitor : public TestVisitor { ++MatchCount; EXPECT_THAT(getAssociatedRange(*Decl, *this->Context), - EqualsAnnotatedRange(&this->Context->getSourceManager(), - Code.range("r"))) + EqualsAnnotatedRange(this->Context, Code.range("r"))) << Code.code(); return true; } @@ -183,6 +186,45 @@ TEST(SourceCodeTest, getExtendedText) { Visitor.runOver("int foo() { return foo() + 3; }"); } +TEST(SourceCodeTest, maybeExtendRange_TokenRange) { + struct ExtendTokenRangeVisitor + : AnnotatedCodeVisitor { + bool VisitCallExpr(CallExpr *CE) { + ++MatchCount; + EXPECT_THAT(getExtendedRange(*CE, tok::TokenKind::semi, *Context), + EqualsAnnotatedRange(Context, Code.range("r"))); + return true; + } + }; + + ExtendTokenRangeVisitor Visitor; + // Extends to include semicolon. + Visitor.runOverAnnotated("void f(int x, int y) { $r[[f(x, y);]] }"); + // Does not extend to include semicolon. + Visitor.runOverAnnotated( + "int f(int x, int y) { if (0) return $r[[f(x, y)]] + 3; }"); +} + +TEST(SourceCodeTest, maybeExtendRange_CharRange) { + struct ExtendCharRangeVisitor : AnnotatedCodeVisitor { + bool VisitCallExpr(CallExpr *CE) { + ++MatchCount; + CharSourceRange Call = Lexer::getAsCharRange(CE->getSourceRange(), + Context->getSourceManager(), + Context->getLangOpts()); + EXPECT_THAT(maybeExtendRange(Call, tok::TokenKind::semi, *Context), + EqualsAnnotatedRange(Context, Code.range("r"))); + return true; + } + }; + ExtendCharRangeVisitor Visitor; + // Extends to include semicolon. + Visitor.runOverAnnotated("void f(int x, int y) { $r[[f(x, y);]] }"); + // Does not extend to include semicolon. + Visitor.runOverAnnotated( + "int f(int x, int y) { if (0) return $r[[f(x, y)]] + 3; }"); +} + TEST(SourceCodeTest, getAssociatedRange) { struct VarDeclsVisitor : AnnotatedCodeVisitor { bool VisitVarDecl(VarDecl *Decl) { return VisitDeclHelper(Decl); } diff --git a/clang/unittests/Tooling/StencilTest.cpp b/clang/unittests/Tooling/StencilTest.cpp index 9408a1e62dfa3..c843e33dd0daa 100644 --- a/clang/unittests/Tooling/StencilTest.cpp +++ b/clang/unittests/Tooling/StencilTest.cpp @@ -180,12 +180,12 @@ TEST_F(StencilTest, SelectionOp) { TEST_F(StencilTest, IfBoundOpBound) { StringRef Id = "id"; - testExpr(Id, "3;", ifBound(Id, text("5"), text("7")), "5"); + testExpr(Id, "3;", ifBound(Id, cat("5"), cat("7")), "5"); } TEST_F(StencilTest, IfBoundOpUnbound) { StringRef Id = "id"; - testExpr(Id, "3;", ifBound("other", text("5"), text("7")), "7"); + testExpr(Id, "3;", ifBound("other", cat("5"), cat("7")), "7"); } TEST_F(StencilTest, ExpressionOpNoParens) { @@ -293,7 +293,7 @@ TEST_F(StencilTest, AccessOpValueExplicitText) { x; )cc"; StringRef Id = "id"; - testExpr(Id, Snippet, access(Id, text("field")), "x.field"); + testExpr(Id, Snippet, access(Id, cat("field")), "x.field"); } TEST_F(StencilTest, AccessOpValueAddress) { @@ -428,7 +428,12 @@ TEST_F(StencilTest, CatOfInvalidRangeFails) { hasArgument(0, expr().bind("arg")))); ASSERT_TRUE(StmtMatch); Stencil S = cat(node("arg")); - EXPECT_THAT_EXPECTED(S->eval(StmtMatch->Result), Failed()); + Expected Result = S->eval(StmtMatch->Result); + ASSERT_THAT_EXPECTED(Result, Failed()); + llvm::handleAllErrors(Result.takeError(), [](const llvm::StringError &E) { + EXPECT_THAT(E.getMessage(), AllOf(HasSubstr("selected range"), + HasSubstr("macro expansion"))); + }); } TEST(StencilToStringTest, RawTextOp) { @@ -479,7 +484,7 @@ TEST(StencilToStringTest, AccessOpText) { } TEST(StencilToStringTest, AccessOpSelector) { - auto S = access("Id", selection(name("otherId"))); + auto S = access("Id", cat(name("otherId"))); StringRef Expected = R"repr(access("Id", selection(...)))repr"; EXPECT_EQ(S->toString(), Expected); } @@ -491,7 +496,7 @@ TEST(StencilToStringTest, AccessOpStencil) { } TEST(StencilToStringTest, IfBoundOp) { - auto S = ifBound("Id", text("trueText"), access("exprId", "memberData")); + auto S = ifBound("Id", cat("trueText"), access("exprId", "memberData")); StringRef Expected = R"repr(ifBound("Id", "trueText", access("exprId", "memberData")))repr"; EXPECT_EQ(S->toString(), Expected); @@ -505,7 +510,7 @@ TEST(StencilToStringTest, RunOp) { TEST(StencilToStringTest, Sequence) { auto S = cat("foo", access("x", "m()"), "bar", - ifBound("x", text("t"), access("e", "f"))); + ifBound("x", cat("t"), access("e", "f"))); StringRef Expected = R"repr(seq("foo", access("x", "m()"), "bar", )repr" R"repr(ifBound("x", "t", access("e", "f"))))repr"; EXPECT_EQ(S->toString(), Expected); @@ -524,8 +529,8 @@ TEST(StencilToStringTest, SequenceSingle) { } TEST(StencilToStringTest, SequenceFromVector) { - auto S = catVector({text("foo"), access("x", "m()"), text("bar"), - ifBound("x", text("t"), access("e", "f"))}); + auto S = catVector({cat("foo"), access("x", "m()"), cat("bar"), + ifBound("x", cat("t"), access("e", "f"))}); StringRef Expected = R"repr(seq("foo", access("x", "m()"), "bar", )repr" R"repr(ifBound("x", "t", access("e", "f"))))repr"; EXPECT_EQ(S->toString(), Expected); diff --git a/clang/unittests/Tooling/Syntax/TreeTest.cpp b/clang/unittests/Tooling/Syntax/TreeTest.cpp index 5f48ef1299885..bd639aa581661 100644 --- a/clang/unittests/Tooling/Syntax/TreeTest.cpp +++ b/clang/unittests/Tooling/Syntax/TreeTest.cpp @@ -18,6 +18,7 @@ #include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/Lex/PreprocessorOptions.h" #include "clang/Testing/CommandLineArgs.h" +#include "clang/Testing/TestClangConfig.h" #include "clang/Tooling/Core/Replacement.h" #include "clang/Tooling/Syntax/BuildTree.h" #include "clang/Tooling/Syntax/Mutations.h" @@ -47,77 +48,6 @@ static llvm::ArrayRef tokens(syntax::Node *N) { T->lastLeaf()->token() + 1); } -struct TestClangConfig { - TestLanguage Language; - std::string Target; - - bool isC99OrLater() const { return Language == Lang_C99; } - - bool isCXX() const { - return Language == Lang_CXX03 || Language == Lang_CXX11 || - Language == Lang_CXX14 || Language == Lang_CXX17 || - Language == Lang_CXX20; - } - - bool isCXX11OrLater() const { - return Language == Lang_CXX11 || Language == Lang_CXX14 || - Language == Lang_CXX17 || Language == Lang_CXX20; - } - - bool isCXX14OrLater() const { - return Language == Lang_CXX14 || Language == Lang_CXX17 || - Language == Lang_CXX20; - } - - bool supportsCXXDynamicExceptionSpecification() const { - return Language == Lang_CXX03 || Language == Lang_CXX11 || - Language == Lang_CXX14; - } - - bool hasDelayedTemplateParsing() const { - return Target == "x86_64-pc-win32-msvc"; - } - - std::vector getCommandLineArgs() const { - std::vector Result = getCommandLineArgsForTesting(Language); - Result.push_back("-target"); - Result.push_back(Target); - return Result; - } - - std::string toString() const { - std::string Result; - llvm::raw_string_ostream OS(Result); - OS << "{ Language=" << Language << ", Target=" << Target << " }"; - return OS.str(); - } - - friend std::ostream &operator<<(std::ostream &OS, - const TestClangConfig &ClangConfig) { - return OS << ClangConfig.toString(); - } - - static std::vector &allConfigs() { - static std::vector all_configs = []() { - std::vector all_configs; - for (TestLanguage lang : {Lang_C89, Lang_C99, Lang_CXX03, Lang_CXX11, - Lang_CXX14, Lang_CXX17, Lang_CXX20}) { - TestClangConfig config; - config.Language = lang; - config.Target = "x86_64-pc-linux-gnu"; - all_configs.push_back(config); - - // Windows target is interesting to test because it enables - // `-fdelayed-template-parsing`. - config.Target = "x86_64-pc-win32-msvc"; - all_configs.push_back(config); - } - return all_configs; - }(); - return all_configs; - } -}; - class SyntaxTreeTest : public ::testing::Test, public ::testing::WithParamInterface { protected: @@ -1199,14 +1129,512 @@ void test(S s) { )txt")); } -TEST_P(SyntaxTreeTest, CxxNullPtrLiteral) { - if (!GetParam().isCXX11OrLater()) { +TEST_P(SyntaxTreeTest, ParenExpr) { + EXPECT_TRUE(treeDumpEqual( + R"cpp( +void test() { + (1); + ((1)); + (1 + (2)); +} +)cpp", + R"txt( +*: TranslationUnit +`-SimpleDeclaration + |-void + |-SimpleDeclarator + | |-test + | `-ParametersAndQualifiers + | |-( + | `-) + `-CompoundStatement + |-{ + |-ExpressionStatement + | |-ParenExpression + | | |-( + | | |-IntegerLiteralExpression + | | | `-1 + | | `-) + | `-; + |-ExpressionStatement + | |-ParenExpression + | | |-( + | | |-ParenExpression + | | | |-( + | | | |-IntegerLiteralExpression + | | | | `-1 + | | | `-) + | | `-) + | `-; + |-ExpressionStatement + | |-ParenExpression + | | |-( + | | |-BinaryOperatorExpression + | | | |-IntegerLiteralExpression + | | | | `-1 + | | | |-+ + | | | `-ParenExpression + | | | |-( + | | | |-IntegerLiteralExpression + | | | | `-2 + | | | `-) + | | `-) + | `-; + `-} +)txt")); +} + +TEST_P(SyntaxTreeTest, UserDefinedLiteral) { + if (!GetParam().isCXX11OrLater()) { + return; + } + EXPECT_TRUE(treeDumpEqual( + R"cpp( +typedef decltype(sizeof(void *)) size_t; + +unsigned operator "" _i(unsigned long long); +unsigned operator "" _f(long double); +unsigned operator "" _c(char); +unsigned operator "" _s(const char*, size_t); +unsigned operator "" _r(const char*); +template +unsigned operator "" _t(); + +void test() { + 12_i; // call: operator "" _i(12uLL) | kind: integer + 1.2_f; // call: operator "" _f(1.2L) | kind: float + '2'_c; // call: operator "" _c('2') | kind: char + "12"_s; // call: operator "" _s("12") | kind: string + + 12_r; // call: operator "" _r("12") | kind: integer + 1.2_r; // call: operator "" _i("1.2") | kind: float + 12_t; // call: operator<'1', '2'> "" _x() | kind: integer + 1.2_t; // call: operator<'1', '2'> "" _x() | kind: float +} + )cpp", + R"txt( +*: TranslationUnit +|-SimpleDeclaration +| |-typedef +| |-decltype +| |-( +| |-UnknownExpression +| | |-sizeof +| | |-( +| | |-void +| | |-* +| | `-) +| |-) +| |-SimpleDeclarator +| | `-size_t +| `-; +|-SimpleDeclaration +| |-unsigned +| |-SimpleDeclarator +| | |-operator +| | |-"" +| | |-_i +| | `-ParametersAndQualifiers +| | |-( +| | |-SimpleDeclaration +| | | |-unsigned +| | | |-long +| | | `-long +| | `-) +| `-; +|-SimpleDeclaration +| |-unsigned +| |-SimpleDeclarator +| | |-operator +| | |-"" +| | |-_f +| | `-ParametersAndQualifiers +| | |-( +| | |-SimpleDeclaration +| | | |-long +| | | `-double +| | `-) +| `-; +|-SimpleDeclaration +| |-unsigned +| |-SimpleDeclarator +| | |-operator +| | |-"" +| | |-_c +| | `-ParametersAndQualifiers +| | |-( +| | |-SimpleDeclaration +| | | `-char +| | `-) +| `-; +|-SimpleDeclaration +| |-unsigned +| |-SimpleDeclarator +| | |-operator +| | |-"" +| | |-_s +| | `-ParametersAndQualifiers +| | |-( +| | |-SimpleDeclaration +| | | |-const +| | | |-char +| | | `-SimpleDeclarator +| | | `-* +| | |-, +| | |-SimpleDeclaration +| | | `-size_t +| | `-) +| `-; +|-SimpleDeclaration +| |-unsigned +| |-SimpleDeclarator +| | |-operator +| | |-"" +| | |-_r +| | `-ParametersAndQualifiers +| | |-( +| | |-SimpleDeclaration +| | | |-const +| | | |-char +| | | `-SimpleDeclarator +| | | `-* +| | `-) +| `-; +|-TemplateDeclaration +| |-template +| |-< +| |-SimpleDeclaration +| | `-char +| |-... +| |-> +| `-SimpleDeclaration +| |-unsigned +| |-SimpleDeclarator +| | |-operator +| | |-"" +| | |-_t +| | `-ParametersAndQualifiers +| | |-( +| | `-) +| `-; +`-SimpleDeclaration + |-void + |-SimpleDeclarator + | |-test + | `-ParametersAndQualifiers + | |-( + | `-) + `-CompoundStatement + |-{ + |-ExpressionStatement + | |-IntegerUserDefinedLiteralExpression + | | `-12_i + | `-; + |-ExpressionStatement + | |-FloatUserDefinedLiteralExpression + | | `-1.2_f + | `-; + |-ExpressionStatement + | |-CharUserDefinedLiteralExpression + | | `-'2'_c + | `-; + |-ExpressionStatement + | |-StringUserDefinedLiteralExpression + | | `-"12"_s + | `-; + |-ExpressionStatement + | |-IntegerUserDefinedLiteralExpression + | | `-12_r + | `-; + |-ExpressionStatement + | |-FloatUserDefinedLiteralExpression + | | `-1.2_r + | `-; + |-ExpressionStatement + | |-IntegerUserDefinedLiteralExpression + | | `-12_t + | `-; + |-ExpressionStatement + | |-FloatUserDefinedLiteralExpression + | | `-1.2_t + | `-; + `-} +)txt")); +} + +TEST_P(SyntaxTreeTest, IntegerLiteralLongLong) { + if (!GetParam().isCXX11OrLater()) { + return; + } + EXPECT_TRUE(treeDumpEqual( + R"cpp( +void test() { + 12ll; + 12ull; +} +)cpp", + R"txt( +*: TranslationUnit +`-SimpleDeclaration + |-void + |-SimpleDeclarator + | |-test + | `-ParametersAndQualifiers + | |-( + | `-) + `-CompoundStatement + |-{ + |-ExpressionStatement + | |-IntegerLiteralExpression + | | `-12ll + | `-; + |-ExpressionStatement + | |-IntegerLiteralExpression + | | `-12ull + | `-; + `-} +)txt")); +} + +TEST_P(SyntaxTreeTest, IntegerLiteralBinary) { + if (!GetParam().isCXX14OrLater()) { + return; + } + EXPECT_TRUE(treeDumpEqual( + R"cpp( +void test() { + 0b1100; +} +)cpp", + R"txt( +*: TranslationUnit +`-SimpleDeclaration + |-void + |-SimpleDeclarator + | |-test + | `-ParametersAndQualifiers + | |-( + | `-) + `-CompoundStatement + |-{ + |-ExpressionStatement + | |-IntegerLiteralExpression + | | `-0b1100 + | `-; + `-} +)txt")); +} + +TEST_P(SyntaxTreeTest, IntegerLiteralWithDigitSeparators) { + if (!GetParam().isCXX14OrLater()) { + return; + } + EXPECT_TRUE(treeDumpEqual( + R"cpp( +void test() { + 1'2'0ull; +} +)cpp", + R"txt( +*: TranslationUnit +`-SimpleDeclaration + |-void + |-SimpleDeclarator + | |-test + | `-ParametersAndQualifiers + | |-( + | `-) + `-CompoundStatement + |-{ + |-ExpressionStatement + | |-IntegerLiteralExpression + | | `-1'2'0ull + | `-; + `-} +)txt")); +} + +TEST_P(SyntaxTreeTest, CharacterLiteral) { + EXPECT_TRUE(treeDumpEqual( + R"cpp( +void test() { + 'a'; + '\n'; + '\x20'; + '\0'; + L'a'; + L'α'; +} +)cpp", + R"txt( +*: TranslationUnit +`-SimpleDeclaration + |-void + |-SimpleDeclarator + | |-test + | `-ParametersAndQualifiers + | |-( + | `-) + `-CompoundStatement + |-{ + |-ExpressionStatement + | |-CharacterLiteralExpression + | | `-'a' + | `-; + |-ExpressionStatement + | |-CharacterLiteralExpression + | | `-'\n' + | `-; + |-ExpressionStatement + | |-CharacterLiteralExpression + | | `-'\x20' + | `-; + |-ExpressionStatement + | |-CharacterLiteralExpression + | | `-'\0' + | `-; + |-ExpressionStatement + | |-CharacterLiteralExpression + | | `-L'a' + | `-; + |-ExpressionStatement + | |-CharacterLiteralExpression + | | `-L'α' + | `-; + `-} +)txt")); +} + +TEST_P(SyntaxTreeTest, CharacterLiteralUtf) { + if (!GetParam().isCXX11OrLater()) { + return; + } + EXPECT_TRUE(treeDumpEqual( + R"cpp( +void test() { + u'a'; + u'構'; + U'a'; + U'🌲'; +} +)cpp", + R"txt( +*: TranslationUnit +`-SimpleDeclaration + |-void + |-SimpleDeclarator + | |-test + | `-ParametersAndQualifiers + | |-( + | `-) + `-CompoundStatement + |-{ + |-ExpressionStatement + | |-CharacterLiteralExpression + | | `-u'a' + | `-; + |-ExpressionStatement + | |-CharacterLiteralExpression + | | `-u'構' + | `-; + |-ExpressionStatement + | |-CharacterLiteralExpression + | | `-U'a' + | `-; + |-ExpressionStatement + | |-CharacterLiteralExpression + | | `-U'🌲' + | `-; + `-} +)txt")); +} + +TEST_P(SyntaxTreeTest, CharacterLiteralUtf8) { + if (!GetParam().isCXX17OrLater()) { + return; + } + EXPECT_TRUE(treeDumpEqual( + R"cpp( +void test() { + u8'a'; + u8'\x7f'; +} +)cpp", + R"txt( +*: TranslationUnit +`-SimpleDeclaration + |-void + |-SimpleDeclarator + | |-test + | `-ParametersAndQualifiers + | |-( + | `-) + `-CompoundStatement + |-{ + |-ExpressionStatement + | |-CharacterLiteralExpression + | | `-u8'a' + | `-; + |-ExpressionStatement + | |-CharacterLiteralExpression + | | `-u8'\x7f' + | `-; + `-} +)txt")); +} + +TEST_P(SyntaxTreeTest, FloatingLiteral) { + EXPECT_TRUE(treeDumpEqual( + R"cpp( +void test() { + 1e-2; + 2.; + .2; + 2.f; +} +)cpp", + R"txt( +*: TranslationUnit +`-SimpleDeclaration + |-void + |-SimpleDeclarator + | |-test + | `-ParametersAndQualifiers + | |-( + | `-) + `-CompoundStatement + |-{ + |-ExpressionStatement + | |-FloatingLiteralExpression + | | `-1e-2 + | `-; + |-ExpressionStatement + | |-FloatingLiteralExpression + | | `-2. + | `-; + |-ExpressionStatement + | |-FloatingLiteralExpression + | | `-.2 + | `-; + |-ExpressionStatement + | |-FloatingLiteralExpression + | | `-2.f + | `-; + `-} +)txt")); +} + +TEST_P(SyntaxTreeTest, FloatingLiteralHexadecimal) { + if (!GetParam().isCXX17OrLater()) { return; } EXPECT_TRUE(treeDumpEqual( R"cpp( void test() { - nullptr; + 0xfp1; + 0xf.p1; + 0x.fp1; + 0xf.fp1f; } )cpp", R"txt( @@ -1221,23 +1649,31 @@ void test() { `-CompoundStatement |-{ |-ExpressionStatement - | |-CxxNullPtrExpression - | | `-nullptr + | |-FloatingLiteralExpression + | | `-0xfp1 + | `-; + |-ExpressionStatement + | |-FloatingLiteralExpression + | | `-0xf.p1 + | `-; + |-ExpressionStatement + | |-FloatingLiteralExpression + | | `-0x.fp1 + | `-; + |-ExpressionStatement + | |-FloatingLiteralExpression + | | `-0xf.fp1f | `-; `-} )txt")); } -TEST_P(SyntaxTreeTest, IntegerLiteral) { +TEST_P(SyntaxTreeTest, StringLiteral) { EXPECT_TRUE(treeDumpEqual( R"cpp( void test() { - 12; - 12u; - 12l; - 12ul; - 014; - 0XC; + "a\n\0\x20"; + L"αβ"; } )cpp", R"txt( @@ -1252,42 +1688,27 @@ void test() { `-CompoundStatement |-{ |-ExpressionStatement - | |-IntegerLiteralExpression - | | `-12 - | `-; - |-ExpressionStatement - | |-IntegerLiteralExpression - | | `-12u - | `-; - |-ExpressionStatement - | |-IntegerLiteralExpression - | | `-12l - | `-; - |-ExpressionStatement - | |-IntegerLiteralExpression - | | `-12ul - | `-; - |-ExpressionStatement - | |-IntegerLiteralExpression - | | `-014 + | |-StringLiteralExpression + | | `-"a\n\0\x20" | `-; |-ExpressionStatement - | |-IntegerLiteralExpression - | | `-0XC + | |-StringLiteralExpression + | | `-L"αβ" | `-; `-} )txt")); } -TEST_P(SyntaxTreeTest, IntegerLiteralLongLong) { +TEST_P(SyntaxTreeTest, StringLiteralUtf) { if (!GetParam().isCXX11OrLater()) { return; } EXPECT_TRUE(treeDumpEqual( R"cpp( void test() { - 12ll; - 12ull; + u8"a\x1f\x05"; + u"C++抽象構文木"; + U"📖🌲\n"; } )cpp", R"txt( @@ -1302,25 +1723,63 @@ void test() { `-CompoundStatement |-{ |-ExpressionStatement - | |-IntegerLiteralExpression - | | `-12ll + | |-StringLiteralExpression + | | `-u8"a\x1f\x05" | `-; |-ExpressionStatement - | |-IntegerLiteralExpression - | | `-12ull + | |-StringLiteralExpression + | | `-u"C++抽象構文木" + | `-; + |-ExpressionStatement + | |-StringLiteralExpression + | | `-U"📖🌲\n" | `-; `-} )txt")); } -TEST_P(SyntaxTreeTest, IntegerLiteralBinary) { - if (!GetParam().isCXX14OrLater()) { +TEST_P(SyntaxTreeTest, StringLiteralRaw) { + if (!GetParam().isCXX11OrLater()) { + return; + } + // This test uses regular string literals instead of raw string literals to + // hold source code and expected output because of a bug in MSVC up to MSVC + // 2019 16.2: + // https://developercommunity.visualstudio.com/content/problem/67300/stringifying-raw-string-literal.html + EXPECT_TRUE(treeDumpEqual( // + "void test() {\n" + " R\"SyntaxTree(\n" + " Hello \"Syntax\" \\\"\n" + " )SyntaxTree\";\n" + "}\n", + "*: TranslationUnit\n" + "`-SimpleDeclaration\n" + " |-void\n" + " |-SimpleDeclarator\n" + " | |-test\n" + " | `-ParametersAndQualifiers\n" + " | |-(\n" + " | `-)\n" + " `-CompoundStatement\n" + " |-{\n" + " |-ExpressionStatement\n" + " | |-StringLiteralExpression\n" + " | | `-R\"SyntaxTree(\n" + " Hello \"Syntax\" \\\"\n" + " )SyntaxTree\"\n" + " | `-;\n" + " `-}\n")); +} + +TEST_P(SyntaxTreeTest, BoolLiteral) { + if (GetParam().isC()) { return; } EXPECT_TRUE(treeDumpEqual( R"cpp( void test() { - 0b1100; + true; + false; } )cpp", R"txt( @@ -1335,21 +1794,25 @@ void test() { `-CompoundStatement |-{ |-ExpressionStatement - | |-IntegerLiteralExpression - | | `-0b1100 + | |-BoolLiteralExpression + | | `-true + | `-; + |-ExpressionStatement + | |-BoolLiteralExpression + | | `-false | `-; `-} )txt")); } -TEST_P(SyntaxTreeTest, IntegerLiteralWithDigitSeparators) { - if (!GetParam().isCXX14OrLater()) { +TEST_P(SyntaxTreeTest, CxxNullPtrLiteral) { + if (!GetParam().isCXX11OrLater()) { return; } EXPECT_TRUE(treeDumpEqual( R"cpp( void test() { - 1'2'0ull; + nullptr; } )cpp", R"txt( @@ -1364,8 +1827,8 @@ void test() { `-CompoundStatement |-{ |-ExpressionStatement - | |-IntegerLiteralExpression - | | `-1'2'0ull + | |-CxxNullPtrExpression + | | `-nullptr | `-; `-} )txt")); @@ -1691,18 +2154,18 @@ void test(int a) { |-{ |-ExpressionStatement | |-BinaryOperatorExpression - | | |-UnknownExpression + | | |-BoolLiteralExpression | | | `-true | | |-|| - | | `-UnknownExpression + | | `-BoolLiteralExpression | | `-false | `-; |-ExpressionStatement | |-BinaryOperatorExpression - | | |-UnknownExpression + | | |-BoolLiteralExpression | | | `-true | | |-or - | | `-UnknownExpression + | | `-BoolLiteralExpression | | `-false | `-; |-ExpressionStatement @@ -1759,7 +2222,7 @@ void test(int a, int b) { |-{ |-ExpressionStatement | |-BinaryOperatorExpression - | | |-UnknownExpression + | | |-ParenExpression | | | |-( | | | |-BinaryOperatorExpression | | | | |-IntegerLiteralExpression @@ -1769,7 +2232,7 @@ void test(int a, int b) { | | | | `-2 | | | `-) | | |-* - | | `-UnknownExpression + | | `-ParenExpression | | |-( | | |-BinaryOperatorExpression | | | |-IntegerLiteralExpression @@ -1857,11 +2320,18 @@ struct X { X& operator=(const X&); friend X operator+(X, const X&); friend bool operator<(const X&, const X&); + friend X operator<<(X&, const X&); + X operator,(X&); + // TODO: Fix crash on member function pointer and add a test for `->*` + // TODO: Unbox operators in syntax tree. + // Represent operators by `+` instead of `IdExpression-UnqualifiedId-+` }; void test(X x, X y) { x = y; x + y; x < y; + x << y; + x, y; } )cpp", R"txt( @@ -1926,6 +2396,40 @@ void test(X x, X y) { | | | | `-& | | | `-) | | `-; +| |-UnknownDeclaration +| | `-SimpleDeclaration +| | |-friend +| | |-X +| | |-SimpleDeclarator +| | | |-operator +| | | |-<< +| | | `-ParametersAndQualifiers +| | | |-( +| | | |-SimpleDeclaration +| | | | |-X +| | | | `-SimpleDeclarator +| | | | `-& +| | | |-, +| | | |-SimpleDeclaration +| | | | |-const +| | | | |-X +| | | | `-SimpleDeclarator +| | | | `-& +| | | `-) +| | `-; +| |-SimpleDeclaration +| | |-X +| | |-SimpleDeclarator +| | | |-operator +| | | |-, +| | | `-ParametersAndQualifiers +| | | |-( +| | | |-SimpleDeclaration +| | | | |-X +| | | | `-SimpleDeclarator +| | | | `-& +| | | `-) +| | `-; | |-} | `-; `-SimpleDeclaration @@ -1983,6 +2487,185 @@ void test(X x, X y) { | | `-UnqualifiedId | | `-y | `-; + |-ExpressionStatement + | |-BinaryOperatorExpression + | | |-IdExpression + | | | `-UnqualifiedId + | | | `-x + | | |-IdExpression + | | | `-UnqualifiedId + | | | `-<< + | | `-IdExpression + | | `-UnqualifiedId + | | `-y + | `-; + |-ExpressionStatement + | |-BinaryOperatorExpression + | | |-IdExpression + | | | `-UnqualifiedId + | | | `-x + | | |-IdExpression + | | | `-UnqualifiedId + | | | `-, + | | `-IdExpression + | | `-UnqualifiedId + | | `-y + | `-; + `-} +)txt")); +} + +TEST_P(SyntaxTreeTest, UserDefinedUnaryPrefixOperator) { + if (!GetParam().isCXX()) { + return; + } + EXPECT_TRUE(treeDumpEqual( + R"cpp( +struct X { + X operator++(); + bool operator!(); + X* operator&(); +}; +void test(X x) { + ++x; + !x; + &x; +} +)cpp", + R"txt( +*: TranslationUnit +|-SimpleDeclaration +| |-struct +| |-X +| |-{ +| |-SimpleDeclaration +| | |-X +| | |-SimpleDeclarator +| | | |-operator +| | | |-++ +| | | `-ParametersAndQualifiers +| | | |-( +| | | `-) +| | `-; +| |-SimpleDeclaration +| | |-bool +| | |-SimpleDeclarator +| | | |-operator +| | | |-! +| | | `-ParametersAndQualifiers +| | | |-( +| | | `-) +| | `-; +| |-SimpleDeclaration +| | |-X +| | |-SimpleDeclarator +| | | |-* +| | | |-operator +| | | |-& +| | | `-ParametersAndQualifiers +| | | |-( +| | | `-) +| | `-; +| |-} +| `-; +`-SimpleDeclaration + |-void + |-SimpleDeclarator + | |-test + | `-ParametersAndQualifiers + | |-( + | |-SimpleDeclaration + | | |-X + | | `-SimpleDeclarator + | | `-x + | `-) + `-CompoundStatement + |-{ + |-ExpressionStatement + | |-PrefixUnaryOperatorExpression + | | |-IdExpression + | | | `-UnqualifiedId + | | | `-++ + | | `-IdExpression + | | `-UnqualifiedId + | | `-x + | `-; + |-ExpressionStatement + | |-PrefixUnaryOperatorExpression + | | |-IdExpression + | | | `-UnqualifiedId + | | | `-! + | | `-IdExpression + | | `-UnqualifiedId + | | `-x + | `-; + |-ExpressionStatement + | |-PrefixUnaryOperatorExpression + | | |-IdExpression + | | | `-UnqualifiedId + | | | `-& + | | `-IdExpression + | | `-UnqualifiedId + | | `-x + | `-; + `-} +)txt")); +} + +TEST_P(SyntaxTreeTest, UserDefinedUnaryPostfixOperator) { + if (!GetParam().isCXX()) { + return; + } + EXPECT_TRUE(treeDumpEqual( + R"cpp( +struct X { + X operator++(int); +}; +void test(X x) { + x++; +} +)cpp", + R"txt( +*: TranslationUnit +|-SimpleDeclaration +| |-struct +| |-X +| |-{ +| |-SimpleDeclaration +| | |-X +| | |-SimpleDeclarator +| | | |-operator +| | | |-++ +| | | `-ParametersAndQualifiers +| | | |-( +| | | |-SimpleDeclaration +| | | | `-int +| | | `-) +| | `-; +| |-} +| `-; +`-SimpleDeclaration + |-void + |-SimpleDeclarator + | |-test + | `-ParametersAndQualifiers + | |-( + | |-SimpleDeclaration + | | |-X + | | `-SimpleDeclarator + | | `-x + | `-) + `-CompoundStatement + |-{ + |-ExpressionStatement + | |-PostfixUnaryOperatorExpression + | | |-IdExpression + | | | `-UnqualifiedId + | | | `-x + | | `-IdExpression + | | `-UnqualifiedId + | | `-++ + | `-; `-} )txt")); } @@ -2556,17 +3239,17 @@ static_assert(true); |-StaticAssertDeclaration | |-static_assert | |-( -| |-UnknownExpression +| |-BoolLiteralExpression | | `-true | |-, -| |-UnknownExpression +| |-StringLiteralExpression | | `-"message" | |-) | `-; `-StaticAssertDeclaration |-static_assert |-( - |-UnknownExpression + |-BoolLiteralExpression | `-true |-) `-; @@ -3186,7 +3869,7 @@ int b() noexcept(true); | |-) | |-noexcept | |-( - | |-UnknownExpression + | |-BoolLiteralExpression | | `-true | `-) `-; @@ -3536,7 +4219,24 @@ TEST_P(SyntaxTreeTest, SynthesizedNodes) { EXPECT_TRUE(S->isDetached()); } +static std::vector allTestClangConfigs() { + std::vector all_configs; + for (TestLanguage lang : {Lang_C89, Lang_C99, Lang_CXX03, Lang_CXX11, + Lang_CXX14, Lang_CXX17, Lang_CXX20}) { + TestClangConfig config; + config.Language = lang; + config.Target = "x86_64-pc-linux-gnu"; + all_configs.push_back(config); + + // Windows target is interesting to test because it enables + // `-fdelayed-template-parsing`. + config.Target = "x86_64-pc-win32-msvc"; + all_configs.push_back(config); + } + return all_configs; +} + INSTANTIATE_TEST_CASE_P(SyntaxTreeTests, SyntaxTreeTest, - testing::ValuesIn(TestClangConfig::allConfigs()), ); + testing::ValuesIn(allTestClangConfigs()), ); } // namespace diff --git a/clang/unittests/Tooling/TransformerTest.cpp b/clang/unittests/Tooling/TransformerTest.cpp index d19f747a69b57..7d6b632937487 100644 --- a/clang/unittests/Tooling/TransformerTest.cpp +++ b/clang/unittests/Tooling/TransformerTest.cpp @@ -439,6 +439,29 @@ TEST_F(TransformerTest, RemoveEdit) { Input, Expected); } +TEST_F(TransformerTest, WithMetadata) { + std::string Input = R"cc( + int f() { + int x = 5; + return 7; + } + )cc"; + + Transformer T( + makeRule(declStmt().bind("decl"), + withMetadata(remove(statement(std::string("decl"))), 17)), + consumer()); + T.registerMatchers(&MatchFinder); + auto Factory = newFrontendActionFactory(&MatchFinder); + EXPECT_TRUE(runToolOnCodeWithArgs( + Factory->create(), Input, std::vector(), "input.cc", + "clang-tool", std::make_shared(), {})); + ASSERT_EQ(Changes.size(), 1u); + const llvm::Any &Metadata = Changes[0].getMetadata(); + ASSERT_TRUE(llvm::any_isa(Metadata)); + EXPECT_THAT(llvm::any_cast(Metadata), 17); +} + TEST_F(TransformerTest, MultiChange) { std::string Input = R"cc( void foo() { diff --git a/clang/utils/TableGen/NeonEmitter.cpp b/clang/utils/TableGen/NeonEmitter.cpp index 7494f05c85fdc..d5bf59ef04adf 100644 --- a/clang/utils/TableGen/NeonEmitter.cpp +++ b/clang/utils/TableGen/NeonEmitter.cpp @@ -1062,7 +1062,8 @@ std::string Intrinsic::mangleName(std::string Name, ClassKind LocalCK) const { std::string S = Name; if (Name == "vcvt_f16_f32" || Name == "vcvt_f32_f16" || - Name == "vcvt_f32_f64" || Name == "vcvt_f64_f32") + Name == "vcvt_f32_f64" || Name == "vcvt_f64_f32" || + Name == "vcvt_f32_bf16") return Name; if (!typeCode.empty()) { @@ -2311,9 +2312,14 @@ void NeonEmitter::run(raw_ostream &OS) { OS << "#ifndef __ARM_NEON_H\n"; OS << "#define __ARM_NEON_H\n\n"; + OS << "#ifndef __ARM_FP\n"; + OS << "#error \"NEON intrinsics not available with the soft-float ABI. " + "Please use -mfloat-abi=softfp or -mfloat-abi=hard\"\n"; + OS << "#else\n\n"; + OS << "#if !defined(__ARM_NEON)\n"; OS << "#error \"NEON support not enabled\"\n"; - OS << "#endif\n\n"; + OS << "#else\n\n"; OS << "#include \n\n"; @@ -2403,6 +2409,8 @@ void NeonEmitter::run(raw_ostream &OS) { OS << "\n"; OS << "#undef __ai\n\n"; + OS << "#endif /* if !defined(__ARM_NEON) */\n"; + OS << "#endif /* ifndef __ARM_FP */\n"; OS << "#endif /* __ARM_NEON_H */\n"; } diff --git a/clang/utils/TableGen/SveEmitter.cpp b/clang/utils/TableGen/SveEmitter.cpp index c8e16a9283ffe..1d42edd8a94a8 100644 --- a/clang/utils/TableGen/SveEmitter.cpp +++ b/clang/utils/TableGen/SveEmitter.cpp @@ -92,8 +92,8 @@ class SVEType { bool isChar() const { return ElementBitwidth == 8; } bool isVoid() const { return Void & !Pointer; } bool isDefault() const { return DefaultType; } - bool isFloat() const { return Float; } - bool isBFloat() const { return BFloat; } + bool isFloat() const { return Float && !BFloat; } + bool isBFloat() const { return BFloat && !Float; } bool isFloatingPoint() const { return Float || BFloat; } bool isInteger() const { return !isFloatingPoint() && !Predicate; } bool isScalarPredicate() const { @@ -248,13 +248,13 @@ class SVEEmitter { const char *Type; const char *BuiltinType; }; - SmallVector Reinterprets = { + SmallVector Reinterprets = { {"s8", "svint8_t", "q16Sc"}, {"s16", "svint16_t", "q8Ss"}, {"s32", "svint32_t", "q4Si"}, {"s64", "svint64_t", "q2SWi"}, {"u8", "svuint8_t", "q16Uc"}, {"u16", "svuint16_t", "q8Us"}, {"u32", "svuint32_t", "q4Ui"}, {"u64", "svuint64_t", "q2UWi"}, - {"f16", "svfloat16_t", "q8h"}, {"f32", "svfloat32_t", "q4f"}, - {"f64", "svfloat64_t", "q2d"}}; + {"f16", "svfloat16_t", "q8h"}, {"bf16", "svbfloat16_t", "q8y"}, + {"f32", "svfloat32_t", "q4f"}, {"f64", "svfloat64_t", "q2d"}}; RecordKeeper &Records; llvm::StringMap EltTypes; @@ -491,6 +491,7 @@ void SVEType::applyTypespec() { break; case 'b': BFloat = true; + Float = false; ElementBitwidth = 16; break; default: @@ -538,6 +539,7 @@ void SVEType::applyModifier(char Mod) { case 'b': Signed = false; Float = false; + BFloat = false; ElementBitwidth /= 4; break; case 'o': @@ -567,18 +569,21 @@ void SVEType::applyModifier(char Mod) { case '@': Signed = false; Float = false; + BFloat = false; ElementBitwidth /= 4; NumVectors = 0; break; case 'K': Signed = true; Float = false; + BFloat = false; Bitwidth = ElementBitwidth; NumVectors = 0; break; case 'L': Signed = false; Float = false; + BFloat = false; Bitwidth = ElementBitwidth; NumVectors = 0; break; @@ -586,15 +591,18 @@ void SVEType::applyModifier(char Mod) { Predicate = false; Signed = false; Float = false; + BFloat = false; break; case 'x': Predicate = false; Signed = true; Float = false; + BFloat = false; break; case 'i': Predicate = false; Float = false; + BFloat = false; ElementBitwidth = Bitwidth = 64; NumVectors = 0; Signed = false; @@ -603,6 +611,7 @@ void SVEType::applyModifier(char Mod) { case 'I': Predicate = false; Float = false; + BFloat = false; ElementBitwidth = Bitwidth = 32; NumVectors = 0; Signed = true; @@ -612,6 +621,7 @@ void SVEType::applyModifier(char Mod) { case 'J': Predicate = false; Float = false; + BFloat = false; ElementBitwidth = Bitwidth = 32; NumVectors = 0; Signed = true; @@ -622,6 +632,7 @@ void SVEType::applyModifier(char Mod) { Predicate = false; Signed = true; Float = false; + BFloat = false; ElementBitwidth = Bitwidth = 32; NumVectors = 0; break; @@ -629,6 +640,7 @@ void SVEType::applyModifier(char Mod) { Predicate = false; Signed = true; Float = false; + BFloat = false; ElementBitwidth = Bitwidth = 64; NumVectors = 0; break; @@ -636,6 +648,7 @@ void SVEType::applyModifier(char Mod) { Predicate = false; Signed = false; Float = false; + BFloat = false; ElementBitwidth = Bitwidth = 32; NumVectors = 0; break; @@ -643,6 +656,7 @@ void SVEType::applyModifier(char Mod) { Predicate = false; Signed = false; Float = false; + BFloat = false; ElementBitwidth = Bitwidth = 64; NumVectors = 0; break; @@ -661,16 +675,19 @@ void SVEType::applyModifier(char Mod) { case 'g': Signed = false; Float = false; + BFloat = false; ElementBitwidth = 64; break; case 't': Signed = true; Float = false; + BFloat = false; ElementBitwidth = 32; break; case 'z': Signed = false; Float = false; + BFloat = false; ElementBitwidth = 32; break; case 'O': @@ -681,6 +698,7 @@ void SVEType::applyModifier(char Mod) { case 'M': Predicate = false; Float = true; + BFloat = false; ElementBitwidth = 32; break; case 'N': @@ -1085,10 +1103,20 @@ void SVEEmitter::createHeader(raw_ostream &OS) { OS << "typedef __SVUint16_t svuint16_t;\n"; OS << "typedef __SVUint32_t svuint32_t;\n"; OS << "typedef __SVUint64_t svuint64_t;\n"; - OS << "typedef __SVFloat16_t svfloat16_t;\n"; - OS << "typedef __SVBFloat16_t svbfloat16_t;\n\n"; + OS << "typedef __SVFloat16_t svfloat16_t;\n\n"; + + OS << "#if defined(__ARM_FEATURE_SVE_BF16) && " + "!defined(__ARM_FEATURE_BF16_SCALAR_ARITHMETIC)\n"; + OS << "#error \"__ARM_FEATURE_BF16_SCALAR_ARITHMETIC must be defined when " + "__ARM_FEATURE_SVE_BF16 is defined\"\n"; + OS << "#endif\n\n"; + + OS << "#if defined(__ARM_FEATURE_SVE_BF16)\n"; + OS << "typedef __SVBFloat16_t svbfloat16_t;\n"; + OS << "#endif\n\n"; - OS << "#ifdef __ARM_FEATURE_BF16_SCALAR_ARITHMETIC\n"; + OS << "#if defined(__ARM_FEATURE_BF16_SCALAR_ARITHMETIC)\n"; + OS << "#include \n"; OS << "typedef __bf16 bfloat16_t;\n"; OS << "#endif\n\n"; @@ -1129,6 +1157,12 @@ void SVEEmitter::createHeader(raw_ostream &OS) { OS << "typedef __clang_svfloat64x4_t svfloat64x4_t;\n"; OS << "typedef __SVBool_t svbool_t;\n\n"; + OS << "#ifdef __ARM_FEATURE_SVE_BF16\n"; + OS << "typedef __clang_svbfloat16x2_t svbfloat16x2_t;\n"; + OS << "typedef __clang_svbfloat16x3_t svbfloat16x3_t;\n"; + OS << "typedef __clang_svbfloat16x4_t svbfloat16x4_t;\n"; + OS << "#endif\n"; + OS << "typedef enum\n"; OS << "{\n"; OS << " SV_POW2 = 0,\n"; @@ -1174,6 +1208,10 @@ void SVEEmitter::createHeader(raw_ostream &OS) { for (auto ShortForm : { false, true } ) for (const ReinterpretTypeInfo &From : Reinterprets) for (const ReinterpretTypeInfo &To : Reinterprets) { + const bool IsBFloat = StringRef(From.Suffix).equals("bf16") || + StringRef(To.Suffix).equals("bf16"); + if (IsBFloat) + OS << "#if defined(__ARM_FEATURE_SVE_BF16)\n"; if (ShortForm) { OS << "__aio " << From.Type << " svreinterpret_" << From.Suffix; OS << "(" << To.Type << " op) {\n"; @@ -1184,6 +1222,8 @@ void SVEEmitter::createHeader(raw_ostream &OS) { OS << "#define svreinterpret_" << From.Suffix << "_" << To.Suffix << "(...) __builtin_sve_reinterpret_" << From.Suffix << "_" << To.Suffix << "(__VA_ARGS__)\n"; + if (IsBFloat) + OS << "#endif /* #if defined(__ARM_FEATURE_SVE_BF16) */\n"; } SmallVector, 128> Defs; @@ -1222,6 +1262,11 @@ void SVEEmitter::createHeader(raw_ostream &OS) { if (!InGuard.empty()) OS << "#endif //" << InGuard << "\n"; + OS << "#if defined(__ARM_FEATURE_SVE_BF16)\n"; + OS << "#define svcvtnt_bf16_x svcvtnt_bf16_m\n"; + OS << "#define svcvtnt_bf16_f32_x svcvtnt_bf16_f32_m\n"; + OS << "#endif /*__ARM_FEATURE_SVE_BF16 */\n\n"; + OS << "#if defined(__ARM_FEATURE_SVE2)\n"; OS << "#define svcvtnt_f16_x svcvtnt_f16_m\n"; OS << "#define svcvtnt_f16_f32_x svcvtnt_f16_f32_m\n"; diff --git a/clang/utils/analyzer/.dockerignore b/clang/utils/analyzer/.dockerignore new file mode 100644 index 0000000000000..2322248c5da91 --- /dev/null +++ b/clang/utils/analyzer/.dockerignore @@ -0,0 +1 @@ +./projects diff --git a/clang/utils/analyzer/Dockerfile b/clang/utils/analyzer/Dockerfile new file mode 100644 index 0000000000000..21906011c7dc2 --- /dev/null +++ b/clang/utils/analyzer/Dockerfile @@ -0,0 +1,60 @@ +FROM ubuntu:bionic + +RUN apt-get update && apt-get install -y \ + apt-transport-https \ + ca-certificates \ + gnupg \ + software-properties-common \ + wget + +# newer CMake is required by LLVM +RUN wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null +RUN apt-add-repository -y 'deb https://apt.kitware.com/ubuntu/ bionic main' + +# test system dependencies +RUN apt-get update && apt-get install -y \ + git=1:2.17.1-1ubuntu0.7 \ + gettext=0.19.8.1-6ubuntu0.3 \ + python3=3.6.7-1~18.04 \ + python3-pip=9.0.1-2.3~ubuntu1.18.04.1 \ + cmake=3.17.3-0kitware1 \ + ninja-build=1.8.2-1 + +# box2d dependencies +RUN apt-get install -y \ + libx11-dev=2:1.6.4-3ubuntu0.2 \ + libxrandr-dev=2:1.5.1-1 \ + libxinerama-dev=2:1.1.3-1 \ + libxcursor-dev=1:1.1.15-1 \ + libxi-dev=2:1.7.9-1 + +# symengine dependencies +RUN apt-get install -y \ + libgmp10=2:6.1.2+dfsg-2 \ + libgmp-dev=2:6.1.2+dfsg-2 + +# simbody dependencies +RUN apt-get install -y \ + liblapack-dev=3.7.1-4ubuntu1 + +# drogon dependencies +RUN apt-get install -y \ + libjsonrpccpp-dev=0.7.0-1build2 \ + uuid-dev=2.31.1-0.4ubuntu3.6 + +RUN update-alternatives --install /usr/bin/python python /usr/bin/python3 1 + +VOLUME /analyzer +VOLUME /projects +VOLUME /llvm-project +VOLUME /build +VOLUME /scripts + +ENV PATH="/analyzer/bin:${PATH}" + +ADD entrypoint.py /entrypoint.py + +ADD requirements.txt /requirements.txt +RUN pip3 install -r /requirements.txt + +ENTRYPOINT ["python", "/entrypoint.py"] diff --git a/clang/utils/analyzer/SATest.py b/clang/utils/analyzer/SATest.py index f45f593d08ec6..16f1dce0c584e 100755 --- a/clang/utils/analyzer/SATest.py +++ b/clang/utils/analyzer/SATest.py @@ -1,17 +1,23 @@ #!/usr/bin/env python -import SATestAdd -import SATestBuild -import SATestUpdateDiffs -import CmpRuns - -from ProjectMap import ProjectInfo, ProjectMap - import argparse import sys +import os + +from subprocess import call + +SCRIPTS_DIR = os.path.dirname(os.path.realpath(__file__)) +PROJECTS_DIR = os.path.join(SCRIPTS_DIR, "projects") +DEFAULT_LLVM_DIR = os.path.realpath(os.path.join(SCRIPTS_DIR, + os.path.pardir, + os.path.pardir, + os.path.pardir)) def add(parser, args): + import SATestAdd + from ProjectMap import ProjectInfo + if args.source == "git" and (args.origin == "" or args.commit == ""): parser.error( "Please provide both --origin and --commit if source is 'git'") @@ -27,6 +33,9 @@ def add(parser, args): def build(parser, args): + import SATestBuild + from ProjectMap import ProjectMap + SATestBuild.VERBOSE = args.verbose project_map = ProjectMap() @@ -62,6 +71,16 @@ def build(parser, args): def compare(parser, args): + import CmpRuns + + choices = [CmpRuns.HistogramType.RELATIVE.value, + CmpRuns.HistogramType.LOG_RELATIVE.value, + CmpRuns.HistogramType.ABSOLUTE.value] + + if args.histogram is not None and args.histogram not in choices: + parser.error("Incorrect histogram type, available choices are {}" + .format(choices)) + dir_old = CmpRuns.ResultsDirectory(args.old[0], args.root_old) dir_new = CmpRuns.ResultsDirectory(args.new[0], args.root_new) @@ -73,11 +92,77 @@ def compare(parser, args): def update(parser, args): + import SATestUpdateDiffs + from ProjectMap import ProjectMap + project_map = ProjectMap() for project in project_map.projects: SATestUpdateDiffs.update_reference_results(project) +def docker(parser, args): + if len(args.rest) > 0: + if args.rest[0] != "--": + parser.error("REST arguments should start with '--'") + args.rest = args.rest[1:] + + if args.build_image: + docker_build_image() + elif args.shell: + docker_shell(args) + else: + sys.exit(docker_run(args, ' '.join(args.rest))) + + +def docker_build_image(): + sys.exit(call("docker build --tag satest-image {}".format(SCRIPTS_DIR), + shell=True)) + + +def docker_shell(args): + try: + # First we need to start the docker container in a waiting mode, + # so it doesn't do anything, but most importantly keeps working + # while the shell session is in progress. + docker_run(args, "--wait", "--detach") + # Since the docker container is running, we can actually connect to it + call("docker exec -it satest bash", shell=True) + + except KeyboardInterrupt: + pass + + finally: + docker_cleanup() + + +def docker_run(args, command, docker_args=""): + try: + return call("docker run --rm --name satest " + "-v {llvm}:/llvm-project " + "-v {build}:/build " + "-v {clang}:/analyzer " + "-v {scripts}:/scripts " + "-v {projects}:/projects " + "{docker_args} " + "satest-image:latest {command}" + .format(llvm=args.llvm_project_dir, + build=args.build_dir, + clang=args.clang_dir, + scripts=SCRIPTS_DIR, + projects=PROJECTS_DIR, + docker_args=docker_args, + command=command), + shell=True) + + except KeyboardInterrupt: + docker_cleanup() + + +def docker_cleanup(): + print("Please wait for docker to clean up") + call("docker stop satest", shell=True) + + def main(): parser = argparse.ArgumentParser() subparsers = parser.add_subparsers() @@ -101,8 +186,7 @@ def main(): "(please provide --origin and --commit), " "'zip' for unpacking source from a zip file, " "'script' for downloading source by running " - "a custom script {}" - .format(SATestBuild.DOWNLOAD_SCRIPT)) + "a custom script") add_parser.add_argument("--origin", action="store", default="", help="Origin link for a git repository") add_parser.add_argument("--commit", action="store", default="", @@ -163,9 +247,6 @@ def main(): dest="show_stats", default=False, help="Show change in statistics") cmp_parser.add_argument("--histogram", action="store", default=None, - choices=[CmpRuns.HistogramType.RELATIVE.value, - CmpRuns.HistogramType.LOG_RELATIVE.value, - CmpRuns.HistogramType.ABSOLUTE.value], help="Show histogram of paths differences. " "Requires matplotlib") cmp_parser.add_argument("old", nargs=1, help="Directory with old results") @@ -180,6 +261,29 @@ def main(): # TODO: add option to decide whether we should use git upd_parser.set_defaults(func=update) + # docker subcommand + dock_parser = subparsers.add_parser( + "docker", + help="Run regression system in the docker.") + + dock_parser.add_argument("--build-image", action="store_true", + help="Build docker image for running tests.") + dock_parser.add_argument("--shell", action="store_true", + help="Start a shell on docker.") + dock_parser.add_argument("--llvm-project-dir", action="store", + default=DEFAULT_LLVM_DIR, + help="Path to LLVM source code. Defaults " + "to the repo where this script is located. ") + dock_parser.add_argument("--build-dir", action="store", default="", + help="Path to a directory where docker should " + "build LLVM code.") + dock_parser.add_argument("--clang-dir", action="store", default="", + help="Path to find/install LLVM installation.") + dock_parser.add_argument("rest", nargs=argparse.REMAINDER, default=[], + help="Additionall args that will be forwarded " + "to the docker's entrypoint.") + dock_parser.set_defaults(func=docker) + args = parser.parse_args() args.func(parser, args) diff --git a/clang/utils/analyzer/SATestBuild.py b/clang/utils/analyzer/SATestBuild.py index d83ff1e7d0096..eefab869f6ef9 100644 --- a/clang/utils/analyzer/SATestBuild.py +++ b/clang/utils/analyzer/SATestBuild.py @@ -43,7 +43,7 @@ variable. It should contain a comma separated list. """ import CmpRuns -import SATestUtils +import SATestUtils as utils from ProjectMap import DownloadType, ProjectInfo import glob @@ -63,16 +63,34 @@ # and this is we can shush that false positive from plistlib import InvalidFileException # type:ignore from subprocess import CalledProcessError, check_call -from typing import Dict, IO, List, NamedTuple, Optional, TYPE_CHECKING +from typing import Dict, IO, List, NamedTuple, Optional, TYPE_CHECKING, Tuple ############################################################################### # Helper functions. ############################################################################### +class StreamToLogger: + def __init__(self, logger: logging.Logger, + log_level: int = logging.INFO): + self.logger = logger + self.log_level = log_level + + def write(self, message: str): + # Rstrip in order not to write an extra newline. + self.logger.log(self.log_level, message.rstrip()) + + def flush(self): + pass + + def fileno(self) -> int: + return 0 + + +Logger = logging.getLogger("main") LOCAL = threading.local() -LOCAL.stdout = sys.stdout -LOCAL.stderr = sys.stderr +LOCAL.stdout = StreamToLogger(Logger, logging.INFO) +LOCAL.stderr = StreamToLogger(Logger, logging.ERROR) def stderr(message: str): @@ -97,7 +115,7 @@ def stdout(message: str): if 'CC' in os.environ: cc_candidate: Optional[str] = os.environ['CC'] else: - cc_candidate = SATestUtils.which("clang", os.environ['PATH']) + cc_candidate = utils.which("clang", os.environ['PATH']) if not cc_candidate: stderr("Error: cannot find 'clang' in PATH") sys.exit(1) @@ -164,23 +182,6 @@ def stdout(message: str): VERBOSE = 0 -class StreamToLogger: - def __init__(self, logger: logging.Logger, - log_level: int = logging.INFO): - self.logger = logger - self.log_level = log_level - - def write(self, message: str): - # Rstrip in order not to write an extra newline. - self.logger.log(self.log_level, message.rstrip()) - - def flush(self): - pass - - def fileno(self) -> int: - return 0 - - ############################################################################### # Test harness logic. ############################################################################### @@ -193,9 +194,9 @@ def run_cleanup_script(directory: str, build_log_file: IO): cwd = os.path.join(directory, PATCHED_SOURCE_DIR_NAME) script_path = os.path.join(directory, CLEANUP_SCRIPT) - SATestUtils.run_script(script_path, build_log_file, cwd, - out=LOCAL.stdout, err=LOCAL.stderr, - verbose=VERBOSE) + utils.run_script(script_path, build_log_file, cwd, + out=LOCAL.stdout, err=LOCAL.stderr, + verbose=VERBOSE) class TestInfo(NamedTuple): @@ -350,8 +351,6 @@ def get_output_dir(self) -> str: return OUTPUT_DIR_NAME def build(self, directory: str, output_dir: str): - time_start = time.time() - build_log_path = get_build_log_path(output_dir) stdout(f"Log file: {build_log_path}\n") @@ -374,19 +373,23 @@ def build(self, directory: str, output_dir: str): if self.project.mode == 1: self._download_and_patch(directory, build_log_file) run_cleanup_script(directory, build_log_file) - self.scan_build(directory, output_dir, build_log_file) + build_time, memory = self.scan_build(directory, output_dir, + build_log_file) else: - self.analyze_preprocessed(directory, output_dir) + build_time, memory = self.analyze_preprocessed(directory, + output_dir) if self.is_reference_build: run_cleanup_script(directory, build_log_file) normalize_reference_results(directory, output_dir, self.project.mode) - stdout(f"Build complete (time: {time.time() - time_start:.2f}). " + stdout(f"Build complete (time: {utils.time_to_str(build_time)}, " + f"peak memory: {utils.memory_to_str(memory)}). " f"See the log for more details: {build_log_path}\n") - def scan_build(self, directory: str, output_dir: str, build_log_file: IO): + def scan_build(self, directory: str, output_dir: str, + build_log_file: IO) -> Tuple[float, int]: """ Build the project with scan-build by reading in the commands and prefixing them with the scan-build options. @@ -415,6 +418,10 @@ def scan_build(self, directory: str, output_dir: str, build_log_file: IO): options += "--override-compiler " extra_env: Dict[str, str] = {} + + execution_time = 0.0 + peak_memory = 0 + try: command_file = open(build_script_path, "r") command_prefix = "scan-build " + options + " " @@ -450,11 +457,15 @@ def scan_build(self, directory: str, output_dir: str, build_log_file: IO): if VERBOSE >= 1: stdout(f" Executing: {command_to_run}\n") - check_call(command_to_run, cwd=cwd, - stderr=build_log_file, - stdout=build_log_file, - env=dict(os.environ, **extra_env), - shell=True) + time, mem = utils.check_and_measure_call( + command_to_run, cwd=cwd, + stderr=build_log_file, + stdout=build_log_file, + env=dict(os.environ, **extra_env), + shell=True) + + execution_time += time + peak_memory = max(peak_memory, mem) except CalledProcessError: stderr("Error: scan-build failed. Its output was: \n") @@ -462,7 +473,10 @@ def scan_build(self, directory: str, output_dir: str, build_log_file: IO): shutil.copyfileobj(build_log_file, LOCAL.stderr) sys.exit(1) - def analyze_preprocessed(self, directory: str, output_dir: str): + return execution_time, peak_memory + + def analyze_preprocessed(self, directory: str, + output_dir: str) -> Tuple[float, int]: """ Run analysis on a set of preprocessed files. """ @@ -486,14 +500,17 @@ def analyze_preprocessed(self, directory: str, output_dir: str): fail_path = os.path.join(plist_path, "failures") os.makedirs(fail_path) + execution_time = 0.0 + peak_memory = 0 + for full_file_name in glob.glob(directory + "/*"): file_name = os.path.basename(full_file_name) failed = False # Only run the analyzes on supported files. - if SATestUtils.has_no_extension(file_name): + if utils.has_no_extension(file_name): continue - if not SATestUtils.is_valid_single_input_file(file_name): + if not utils.is_valid_single_input_file(file_name): stderr(f"Error: Invalid single input file {full_file_name}.\n") raise Exception() @@ -508,8 +525,12 @@ def analyze_preprocessed(self, directory: str, output_dir: str): if VERBOSE >= 1: stdout(f" Executing: {command}\n") - check_call(command, cwd=directory, stderr=log_file, - stdout=log_file, shell=True) + time, mem = utils.check_and_measure_call( + command, cwd=directory, stderr=log_file, + stdout=log_file, shell=True) + + execution_time += time + peak_memory = max(peak_memory, mem) except CalledProcessError as e: stderr(f"Error: Analyzes of {full_file_name} failed. " @@ -521,6 +542,8 @@ def analyze_preprocessed(self, directory: str, output_dir: str): if not failed: os.remove(log_file.name) + return execution_time, peak_memory + def generate_config(self) -> str: out = "serialize-stats=true,stable-report-filename=true" @@ -570,7 +593,7 @@ def _download(self, directory: str, build_log_file: IO): def _download_from_git(self, directory: str, build_log_file: IO): cached_source = os.path.join(directory, CACHED_SOURCE_DIR_NAME) - check_call(f"git clone {self.project.origin} {cached_source}", + check_call(f"git clone --recursive {self.project.origin} {cached_source}", cwd=directory, stderr=build_log_file, stdout=build_log_file, shell=True) check_call(f"git checkout --quiet {self.project.commit}", @@ -578,7 +601,7 @@ def _download_from_git(self, directory: str, build_log_file: IO): stdout=build_log_file, shell=True) def _unpack_zip(self, directory: str, build_log_file: IO): - zip_files = list(glob.glob(os.path.join(directory, "/*.zip"))) + zip_files = list(glob.glob(directory + "/*.zip")) if len(zip_files) == 0: raise ValueError( @@ -597,9 +620,9 @@ def _unpack_zip(self, directory: str, build_log_file: IO): @staticmethod def _run_download_script(directory: str, build_log_file: IO): script_path = os.path.join(directory, DOWNLOAD_SCRIPT) - SATestUtils.run_script(script_path, build_log_file, directory, - out=LOCAL.stdout, err=LOCAL.stderr, - verbose=VERBOSE) + utils.run_script(script_path, build_log_file, directory, + out=LOCAL.stdout, err=LOCAL.stderr, + verbose=VERBOSE) @staticmethod def _apply_patch(directory: str, build_log_file: IO): diff --git a/clang/utils/analyzer/SATestUtils.py b/clang/utils/analyzer/SATestUtils.py index 4e126e66b869f..3947e183d82f3 100644 --- a/clang/utils/analyzer/SATestUtils.py +++ b/clang/utils/analyzer/SATestUtils.py @@ -1,8 +1,9 @@ import os import sys +import time from subprocess import CalledProcessError, check_call -from typing import List, IO, Optional +from typing import List, IO, Optional, Tuple def which(command: str, paths: Optional[str] = None) -> Optional[str]: @@ -47,6 +48,87 @@ def is_valid_single_input_file(file_name: str) -> bool: return ext in (".i", ".ii", ".c", ".cpp", ".m", "") +def time_to_str(time: float) -> str: + """ + Convert given time in seconds into a human-readable string. + """ + return f"{time:.2f}s" + + +def memory_to_str(memory: int) -> str: + """ + Convert given number of bytes into a human-readable string. + """ + if memory: + try: + import humanize + return humanize.naturalsize(memory, gnu=True) + except ImportError: + # no formatter installed, let's keep it in bytes + return f"{memory}B" + + # If memory is 0, we didn't succeed measuring it. + return "N/A" + + +def check_and_measure_call(*popenargs, **kwargs) -> Tuple[float, int]: + """ + Run command with arguments. Wait for command to complete and measure + execution time and peak memory consumption. + If the exit code was zero then return, otherwise raise + CalledProcessError. The CalledProcessError object will have the + return code in the returncode attribute. + + The arguments are the same as for the call and check_call functions. + + Return a tuple of execution time and peak memory. + """ + peak_mem = 0 + start_time = time.time() + + try: + import psutil as ps + + def get_memory(process: ps.Process) -> int: + mem = 0 + + # we want to gather memory usage from all of the child processes + descendants = list(process.children(recursive=True)) + descendants.append(process) + + for subprocess in descendants: + try: + mem += subprocess.memory_info().rss + except (ps.NoSuchProcess, ps.AccessDenied): + continue + + return mem + + with ps.Popen(*popenargs, **kwargs) as process: + # while the process is running calculate resource utilization. + while (process.is_running() and + process.status() != ps.STATUS_ZOMBIE): + # track the peak utilization of the process + peak_mem = max(peak_mem, get_memory(process)) + time.sleep(.5) + + if process.is_running(): + process.kill() + + if process.returncode != 0: + cmd = kwargs.get("args") + if cmd is None: + cmd = popenargs[0] + raise CalledProcessError(process.returncode, cmd) + + except ImportError: + # back off to subprocess if we don't have psutil installed + peak_mem = 0 + check_call(*popenargs, **kwargs) + + return time.time() - start_time, peak_mem + + def run_script(script_path: str, build_log_file: IO, cwd: str, out=sys.stdout, err=sys.stderr, verbose: int = 0): """ diff --git a/clang/utils/analyzer/entrypoint.py b/clang/utils/analyzer/entrypoint.py new file mode 100644 index 0000000000000..b440e776b57cb --- /dev/null +++ b/clang/utils/analyzer/entrypoint.py @@ -0,0 +1,72 @@ +import argparse +import os +import sys + +from subprocess import call, check_call, CalledProcessError +from time import sleep +from typing import List, Tuple + + +def main(): + settings, rest = parse_arguments() + if settings.wait: + wait() + if settings.build_llvm or settings.build_llvm_only: + build_llvm() + if settings.build_llvm_only: + return + sys.exit(test(rest)) + + +def wait(): + # It is an easy on CPU way of keeping the docker container running + # while the user has a terminal session in that container. + while True: + sleep(3600) + + +def parse_arguments() -> Tuple[argparse.Namespace, List[str]]: + parser = argparse.ArgumentParser() + parser.add_argument('--wait', action='store_true') + parser.add_argument('--build-llvm', action='store_true') + parser.add_argument('--build-llvm-only', action='store_true') + return parser.parse_known_args() + + +def build_llvm(): + os.chdir('/build') + try: + if is_cmake_needed(): + cmake() + ninja() + except CalledProcessError: + print("Build failed!") + sys.exit(1) + + +def is_cmake_needed(): + return "build.ninja" not in os.listdir() + + +CMAKE_COMMAND = "cmake -G Ninja -DCMAKE_BUILD_TYPE=Release " \ + "-DCMAKE_INSTALL_PREFIX=/analyzer -DLLVM_TARGETS_TO_BUILD=X86 " \ + "-DLLVM_ENABLE_PROJECTS=clang -DLLVM_BUILD_RUNTIME=OFF " \ + "-DLLVM_ENABLE_TERMINFO=OFF -DCLANG_ENABLE_ARCMT=OFF " \ + "-DCLANG_ENABLE_STATIC_ANALYZER=ON" + + +def cmake(): + check_call(CMAKE_COMMAND + ' /llvm-project/llvm', shell=True) + + +def ninja(): + check_call("ninja install", shell=True) + + +def test(args: List[str]) -> int: + os.chdir("/projects") + return call("/scripts/SATest.py " + " ".join(args), shell=True) + + +if __name__ == '__main__': + main() diff --git a/clang/utils/analyzer/exploded-graph-rewriter.py b/clang/utils/analyzer/exploded-graph-rewriter.py index bae863cb6d046..54d87addd3da3 100755 --- a/clang/utils/analyzer/exploded-graph-rewriter.py +++ b/clang/utils/analyzer/exploded-graph-rewriter.py @@ -368,8 +368,7 @@ def add_raw_line(self, raw_line): self.root_id = node_id # Note: when writing tests you don't need to escape everything, # even though in a valid dot file everything is escaped. - node_label = result.group(2).replace('\\l', '') \ - .replace(' ', '') \ + node_label = result.group(2).replace(' ', '') \ .replace('\\"', '"') \ .replace('\\{', '{') \ .replace('\\}', '}') \ @@ -378,6 +377,13 @@ def add_raw_line(self, raw_line): .replace('\\<', '\\\\<') \ .replace('\\>', '\\\\>') \ .rstrip(',') + # Handle `\l` separately because a string literal can be in code + # like "string\\literal" with the `\l` inside. + # Also on Windows macros __FILE__ produces specific delimiters `\` + # and a directory or file may starts with the letter `l`. + # Find all `\l` (like `,\l`, `}\l`, `[\l`) except `\\l`, + # because the literal as a rule containes multiple `\` before `\l`. + node_label = re.sub(r'(?', '>') \ - .replace('\\l', '
') \ .replace('|', '\\|') + s = re.sub(r'(?', s) if self._gray_mode: s = re.sub(r'', '', s) s = re.sub(r'', '', s) diff --git a/clang/utils/analyzer/projects/box2d/cleanup_run_static_analyzer.sh b/clang/utils/analyzer/projects/box2d/cleanup_run_static_analyzer.sh new file mode 100755 index 0000000000000..e14c423280ec5 --- /dev/null +++ b/clang/utils/analyzer/projects/box2d/cleanup_run_static_analyzer.sh @@ -0,0 +1 @@ +rm -rf ./build diff --git a/clang/utils/analyzer/projects/box2d/run_static_analyzer.cmd b/clang/utils/analyzer/projects/box2d/run_static_analyzer.cmd new file mode 100644 index 0000000000000..6678fe635db32 --- /dev/null +++ b/clang/utils/analyzer/projects/box2d/run_static_analyzer.cmd @@ -0,0 +1,2 @@ +cmake . -DCMAKE_BUILD_TYPE=Debug -Bbuild -GNinja +cmake --build build diff --git a/clang/utils/analyzer/projects/cxxopts/cleanup_run_static_analyzer.sh b/clang/utils/analyzer/projects/cxxopts/cleanup_run_static_analyzer.sh new file mode 100755 index 0000000000000..e14c423280ec5 --- /dev/null +++ b/clang/utils/analyzer/projects/cxxopts/cleanup_run_static_analyzer.sh @@ -0,0 +1 @@ +rm -rf ./build diff --git a/clang/utils/analyzer/projects/cxxopts/run_static_analyzer.cmd b/clang/utils/analyzer/projects/cxxopts/run_static_analyzer.cmd new file mode 100644 index 0000000000000..6678fe635db32 --- /dev/null +++ b/clang/utils/analyzer/projects/cxxopts/run_static_analyzer.cmd @@ -0,0 +1,2 @@ +cmake . -DCMAKE_BUILD_TYPE=Debug -Bbuild -GNinja +cmake --build build diff --git a/clang/utils/analyzer/projects/drogon/cleanup_run_static_analyzer.sh b/clang/utils/analyzer/projects/drogon/cleanup_run_static_analyzer.sh new file mode 100755 index 0000000000000..e14c423280ec5 --- /dev/null +++ b/clang/utils/analyzer/projects/drogon/cleanup_run_static_analyzer.sh @@ -0,0 +1 @@ +rm -rf ./build diff --git a/clang/utils/analyzer/projects/drogon/run_static_analyzer.cmd b/clang/utils/analyzer/projects/drogon/run_static_analyzer.cmd new file mode 100644 index 0000000000000..6678fe635db32 --- /dev/null +++ b/clang/utils/analyzer/projects/drogon/run_static_analyzer.cmd @@ -0,0 +1,2 @@ +cmake . -DCMAKE_BUILD_TYPE=Debug -Bbuild -GNinja +cmake --build build diff --git a/clang/utils/analyzer/projects/duckdb/cleanup_run_static_analyzer.sh b/clang/utils/analyzer/projects/duckdb/cleanup_run_static_analyzer.sh new file mode 100755 index 0000000000000..e14c423280ec5 --- /dev/null +++ b/clang/utils/analyzer/projects/duckdb/cleanup_run_static_analyzer.sh @@ -0,0 +1 @@ +rm -rf ./build diff --git a/clang/utils/analyzer/projects/duckdb/run_static_analyzer.cmd b/clang/utils/analyzer/projects/duckdb/run_static_analyzer.cmd new file mode 100644 index 0000000000000..6678fe635db32 --- /dev/null +++ b/clang/utils/analyzer/projects/duckdb/run_static_analyzer.cmd @@ -0,0 +1,2 @@ +cmake . -DCMAKE_BUILD_TYPE=Debug -Bbuild -GNinja +cmake --build build diff --git a/clang/utils/analyzer/projects/fmt/cleanup_run_static_analyzer.sh b/clang/utils/analyzer/projects/fmt/cleanup_run_static_analyzer.sh new file mode 100755 index 0000000000000..e14c423280ec5 --- /dev/null +++ b/clang/utils/analyzer/projects/fmt/cleanup_run_static_analyzer.sh @@ -0,0 +1 @@ +rm -rf ./build diff --git a/clang/utils/analyzer/projects/fmt/run_static_analyzer.cmd b/clang/utils/analyzer/projects/fmt/run_static_analyzer.cmd new file mode 100644 index 0000000000000..6678fe635db32 --- /dev/null +++ b/clang/utils/analyzer/projects/fmt/run_static_analyzer.cmd @@ -0,0 +1,2 @@ +cmake . -DCMAKE_BUILD_TYPE=Debug -Bbuild -GNinja +cmake --build build diff --git a/clang/utils/analyzer/projects/libsoundio/cleanup_run_static_analyzer.sh b/clang/utils/analyzer/projects/libsoundio/cleanup_run_static_analyzer.sh new file mode 100755 index 0000000000000..e14c423280ec5 --- /dev/null +++ b/clang/utils/analyzer/projects/libsoundio/cleanup_run_static_analyzer.sh @@ -0,0 +1 @@ +rm -rf ./build diff --git a/clang/utils/analyzer/projects/libsoundio/run_static_analyzer.cmd b/clang/utils/analyzer/projects/libsoundio/run_static_analyzer.cmd new file mode 100644 index 0000000000000..6678fe635db32 --- /dev/null +++ b/clang/utils/analyzer/projects/libsoundio/run_static_analyzer.cmd @@ -0,0 +1,2 @@ +cmake . -DCMAKE_BUILD_TYPE=Debug -Bbuild -GNinja +cmake --build build diff --git a/clang/utils/analyzer/projects/oatpp/cleanup_run_static_analyzer.sh b/clang/utils/analyzer/projects/oatpp/cleanup_run_static_analyzer.sh new file mode 100755 index 0000000000000..e14c423280ec5 --- /dev/null +++ b/clang/utils/analyzer/projects/oatpp/cleanup_run_static_analyzer.sh @@ -0,0 +1 @@ +rm -rf ./build diff --git a/clang/utils/analyzer/projects/oatpp/run_static_analyzer.cmd b/clang/utils/analyzer/projects/oatpp/run_static_analyzer.cmd new file mode 100644 index 0000000000000..6678fe635db32 --- /dev/null +++ b/clang/utils/analyzer/projects/oatpp/run_static_analyzer.cmd @@ -0,0 +1,2 @@ +cmake . -DCMAKE_BUILD_TYPE=Debug -Bbuild -GNinja +cmake --build build diff --git a/clang/utils/analyzer/projects/projects.json b/clang/utils/analyzer/projects/projects.json new file mode 100644 index 0000000000000..e3d853ac6f6a5 --- /dev/null +++ b/clang/utils/analyzer/projects/projects.json @@ -0,0 +1,107 @@ +[ + { + "name": "cxxopts", + "mode": 1, + "source": "git", + "origin": "https://github.com/jarro2783/cxxopts.git", + "commit": "794c975" + }, + { + "name": "box2d", + "mode": 1, + "source": "git", + "origin": "https://github.com/erincatto/box2d.git", + "commit": "1025f9a" + }, + { + "name": "tinyexpr", + "mode": 1, + "source": "git", + "origin": "https://github.com/codeplea/tinyexpr.git", + "commit": "ffb0d41" + }, + { + "name": "symengine", + "mode": 1, + "source": "git", + "origin": "https://github.com/symengine/symengine.git", + "commit": "4f669d59" + }, + { + "name": "termbox", + "mode": 1, + "source": "git", + "origin": "https://github.com/nsf/termbox.git", + "commit": "0df1355" + }, + { + "name": "tinyvm", + "mode": 1, + "source": "git", + "origin": "https://github.com/jakogut/tinyvm.git", + "commit": "10c25d8" + }, + { + "name": "tinyspline", + "mode": 1, + "source": "git", + "origin": "https://github.com/msteinbeck/tinyspline.git", + "commit": "f8b1ab7" + }, + { + "name": "oatpp", + "mode": 1, + "source": "git", + "origin": "https://github.com/oatpp/oatpp.git", + "commit": "d3e60fb" + }, + { + "name": "libsoundio", + "mode": 1, + "source": "git", + "origin": "https://github.com/andrewrk/libsoundio.git", + "commit": "b810bf2" + }, + { + "name": "zstd", + "mode": 1, + "source": "git", + "origin": "https://github.com/facebook/zstd.git", + "commit": "2af4e073" + }, + { + "name": "simbody", + "mode": 1, + "source": "git", + "origin": "https://github.com/simbody/simbody.git", + "commit": "5cf513d" + }, + { + "name": "duckdb", + "mode": 1, + "source": "git", + "origin": "https://github.com/cwida/duckdb.git", + "commit": "d098c9f" + }, + { + "name": "drogon", + "mode": 1, + "source": "git", + "origin": "https://github.com/an-tao/drogon.git", + "commit": "fd2a612" + }, + { + "name": "fmt", + "mode": 1, + "source": "git", + "origin": "https://github.com/fmtlib/fmt.git", + "commit": "5e7c70e" + }, + { + "name": "re2", + "mode": 1, + "source": "git", + "origin": "https://github.com/google/re2.git", + "commit": "2b25567" + } +] diff --git a/clang/utils/analyzer/projects/re2/cleanup_run_static_analyzer.sh b/clang/utils/analyzer/projects/re2/cleanup_run_static_analyzer.sh new file mode 100755 index 0000000000000..e14c423280ec5 --- /dev/null +++ b/clang/utils/analyzer/projects/re2/cleanup_run_static_analyzer.sh @@ -0,0 +1 @@ +rm -rf ./build diff --git a/clang/utils/analyzer/projects/re2/run_static_analyzer.cmd b/clang/utils/analyzer/projects/re2/run_static_analyzer.cmd new file mode 100644 index 0000000000000..6678fe635db32 --- /dev/null +++ b/clang/utils/analyzer/projects/re2/run_static_analyzer.cmd @@ -0,0 +1,2 @@ +cmake . -DCMAKE_BUILD_TYPE=Debug -Bbuild -GNinja +cmake --build build diff --git a/clang/utils/analyzer/projects/simbody/cleanup_run_static_analyzer.sh b/clang/utils/analyzer/projects/simbody/cleanup_run_static_analyzer.sh new file mode 100755 index 0000000000000..e14c423280ec5 --- /dev/null +++ b/clang/utils/analyzer/projects/simbody/cleanup_run_static_analyzer.sh @@ -0,0 +1 @@ +rm -rf ./build diff --git a/clang/utils/analyzer/projects/simbody/run_static_analyzer.cmd b/clang/utils/analyzer/projects/simbody/run_static_analyzer.cmd new file mode 100644 index 0000000000000..6678fe635db32 --- /dev/null +++ b/clang/utils/analyzer/projects/simbody/run_static_analyzer.cmd @@ -0,0 +1,2 @@ +cmake . -DCMAKE_BUILD_TYPE=Debug -Bbuild -GNinja +cmake --build build diff --git a/clang/utils/analyzer/projects/symengine/cleanup_run_static_analyzer.sh b/clang/utils/analyzer/projects/symengine/cleanup_run_static_analyzer.sh new file mode 100755 index 0000000000000..e14c423280ec5 --- /dev/null +++ b/clang/utils/analyzer/projects/symengine/cleanup_run_static_analyzer.sh @@ -0,0 +1 @@ +rm -rf ./build diff --git a/clang/utils/analyzer/projects/symengine/run_static_analyzer.cmd b/clang/utils/analyzer/projects/symengine/run_static_analyzer.cmd new file mode 100644 index 0000000000000..aaf6bca468d47 --- /dev/null +++ b/clang/utils/analyzer/projects/symengine/run_static_analyzer.cmd @@ -0,0 +1,2 @@ +cmake . -DCMAKE_BUILD_TYPE=Debug -DWITH_COTIRE=OFF -Bbuild -GNinja +cmake --build build diff --git a/clang/utils/analyzer/projects/termbox/cleanup_run_static_analyzer.sh b/clang/utils/analyzer/projects/termbox/cleanup_run_static_analyzer.sh new file mode 100755 index 0000000000000..3d0f2153c1c59 --- /dev/null +++ b/clang/utils/analyzer/projects/termbox/cleanup_run_static_analyzer.sh @@ -0,0 +1,2 @@ +./waf clean +exit 0 diff --git a/clang/utils/analyzer/projects/termbox/run_static_analyzer.cmd b/clang/utils/analyzer/projects/termbox/run_static_analyzer.cmd new file mode 100644 index 0000000000000..1b8c416343e5e --- /dev/null +++ b/clang/utils/analyzer/projects/termbox/run_static_analyzer.cmd @@ -0,0 +1,2 @@ +./waf configure +./waf diff --git a/clang/utils/analyzer/projects/tinyexpr/cleanup_run_static_analyzer.sh b/clang/utils/analyzer/projects/tinyexpr/cleanup_run_static_analyzer.sh new file mode 100755 index 0000000000000..efcd16e590a18 --- /dev/null +++ b/clang/utils/analyzer/projects/tinyexpr/cleanup_run_static_analyzer.sh @@ -0,0 +1 @@ +make clean diff --git a/clang/utils/analyzer/projects/tinyexpr/run_static_analyzer.cmd b/clang/utils/analyzer/projects/tinyexpr/run_static_analyzer.cmd new file mode 100644 index 0000000000000..8f58e6df93d2f --- /dev/null +++ b/clang/utils/analyzer/projects/tinyexpr/run_static_analyzer.cmd @@ -0,0 +1 @@ +make diff --git a/clang/utils/analyzer/projects/tinyspline/cleanup_run_static_analyzer.sh b/clang/utils/analyzer/projects/tinyspline/cleanup_run_static_analyzer.sh new file mode 100755 index 0000000000000..e14c423280ec5 --- /dev/null +++ b/clang/utils/analyzer/projects/tinyspline/cleanup_run_static_analyzer.sh @@ -0,0 +1 @@ +rm -rf ./build diff --git a/clang/utils/analyzer/projects/tinyspline/run_static_analyzer.cmd b/clang/utils/analyzer/projects/tinyspline/run_static_analyzer.cmd new file mode 100644 index 0000000000000..6678fe635db32 --- /dev/null +++ b/clang/utils/analyzer/projects/tinyspline/run_static_analyzer.cmd @@ -0,0 +1,2 @@ +cmake . -DCMAKE_BUILD_TYPE=Debug -Bbuild -GNinja +cmake --build build diff --git a/clang/utils/analyzer/projects/tinyvm/cleanup_run_static_analyzer.sh b/clang/utils/analyzer/projects/tinyvm/cleanup_run_static_analyzer.sh new file mode 100755 index 0000000000000..efcd16e590a18 --- /dev/null +++ b/clang/utils/analyzer/projects/tinyvm/cleanup_run_static_analyzer.sh @@ -0,0 +1 @@ +make clean diff --git a/clang/utils/analyzer/projects/tinyvm/run_static_analyzer.cmd b/clang/utils/analyzer/projects/tinyvm/run_static_analyzer.cmd new file mode 100644 index 0000000000000..8f58e6df93d2f --- /dev/null +++ b/clang/utils/analyzer/projects/tinyvm/run_static_analyzer.cmd @@ -0,0 +1 @@ +make diff --git a/clang/utils/analyzer/projects/zstd/cleanup_run_static_analyzer.sh b/clang/utils/analyzer/projects/zstd/cleanup_run_static_analyzer.sh new file mode 100755 index 0000000000000..2f4ec2f3631bf --- /dev/null +++ b/clang/utils/analyzer/projects/zstd/cleanup_run_static_analyzer.sh @@ -0,0 +1 @@ +rm -rf ./build_analyzer diff --git a/clang/utils/analyzer/projects/zstd/run_static_analyzer.cmd b/clang/utils/analyzer/projects/zstd/run_static_analyzer.cmd new file mode 100644 index 0000000000000..5253ac025f051 --- /dev/null +++ b/clang/utils/analyzer/projects/zstd/run_static_analyzer.cmd @@ -0,0 +1,2 @@ +cmake ./build/cmake -DCMAKE_BUILD_TYPE=Debug -Bbuild_analyzer -GNinja +cmake --build build_analyzer diff --git a/clang/utils/analyzer/requirements.txt b/clang/utils/analyzer/requirements.txt new file mode 100644 index 0000000000000..ec4f669299523 --- /dev/null +++ b/clang/utils/analyzer/requirements.txt @@ -0,0 +1,4 @@ +graphviz +humanize +matplotlib +psutil diff --git a/clang/utils/make-ast-dump-check.sh b/clang/utils/make-ast-dump-check.sh index f0c268c883e92..365f227cc1c66 100755 --- a/clang/utils/make-ast-dump-check.sh +++ b/clang/utils/make-ast-dump-check.sh @@ -70,6 +70,10 @@ BEGIN { if ($generate_serialization_test == 1) { gsub(" imported", "{{( imported)?}}", s) gsub(" ", "{{( )?}}", s) + gsub("line:[0-9]+:[0-9]+", "line:{{.*}}", s) + gsub("line:[0-9]+", "line:{{.*}}", s) + gsub("col:[0-9]+", "col:{{.*}}", s) + gsub(":[0-9]+:[0-9]+", "{{.*}}", s) } } diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html index 97879c2e64c79..65f196ad59d0f 100755 --- a/clang/www/cxx_dr_status.html +++ b/clang/www/cxx_dr_status.html @@ -2789,7 +2789,7 @@

C++ defect report implementation status

- + diff --git a/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt index 8619b6e6280ca..fa62814b635d3 100644 --- a/compiler-rt/CMakeLists.txt +++ b/compiler-rt/CMakeLists.txt @@ -535,8 +535,6 @@ else() set(COMPILER_RT_LLD_PATH ${LLVM_MAIN_SRC_DIR}/../lld) if(EXISTS ${COMPILER_RT_LLD_PATH}/ AND LLVM_TOOL_LLD_BUILD) set(COMPILER_RT_HAS_LLD TRUE) - else() - set(COMPILER_RT_HAS_LLD ${COMPILER_RT_HAS_FUSE_LD_LLD_FLAG}) endif() endif() pythonize_bool(COMPILER_RT_HAS_LLD) diff --git a/compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake b/compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake index 657d2c97eac8e..425de8bffdf72 100644 --- a/compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake +++ b/compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake @@ -169,25 +169,46 @@ function(darwin_test_archs os valid_archs) CACHE STRING "List of valid architectures for platform ${os}." FORCE) endfunction() -# This function checks the host cpusubtype to see if it is post-haswell. Haswell -# and later machines can run x86_64h binaries. Haswell is cpusubtype 8. +# This function checks the host cputype/cpusubtype to filter supported +# architecture for the host OS. This is used to determine which tests are +# available for the host. function(darwin_filter_host_archs input output) list_intersect(tmp_var DARWIN_osx_ARCHS ${input}) execute_process( - COMMAND sysctl hw.cpusubtype - OUTPUT_VARIABLE SUBTYPE) - - string(REGEX MATCH "hw.cpusubtype: ([0-9]*)" - SUBTYPE_MATCHED "${SUBTYPE}") - set(HASWELL_SUPPORTED Off) - if(SUBTYPE_MATCHED) - if(${CMAKE_MATCH_1} GREATER 7) - set(HASWELL_SUPPORTED On) + COMMAND sysctl hw.cputype + OUTPUT_VARIABLE CPUTYPE) + string(REGEX MATCH "hw.cputype: ([0-9]*)" + CPUTYPE_MATCHED "${CPUTYPE}") + set(ARM_HOST Off) + if(CPUTYPE_MATCHED) + # ARM cputype is (0x01000000 | 12) and X86(_64) is always 7. + if(${CMAKE_MATCH_1} GREATER 11) + set(ARM_HOST On) endif() endif() - if(NOT HASWELL_SUPPORTED) - list(REMOVE_ITEM tmp_var x86_64h) + + if(ARM_HOST) + list(REMOVE_ITEM tmp_var i386) + else() + list(REMOVE_ITEM tmp_var arm64) + list(REMOVE_ITEM tmp_var arm64e) + execute_process( + COMMAND sysctl hw.cpusubtype + OUTPUT_VARIABLE SUBTYPE) + string(REGEX MATCH "hw.cpusubtype: ([0-9]*)" + SUBTYPE_MATCHED "${SUBTYPE}") + + set(HASWELL_SUPPORTED Off) + if(SUBTYPE_MATCHED) + if(${CMAKE_MATCH_1} GREATER 7) + set(HASWELL_SUPPORTED On) + endif() + endif() + if(NOT HASWELL_SUPPORTED) + list(REMOVE_ITEM tmp_var x86_64h) + endif() endif() + set(${output} ${tmp_var} PARENT_SCOPE) endfunction() diff --git a/compiler-rt/cmake/builtin-config-ix.cmake b/compiler-rt/cmake/builtin-config-ix.cmake index 5f4275ae54d4c..8de901513beb5 100644 --- a/compiler-rt/cmake/builtin-config-ix.cmake +++ b/compiler-rt/cmake/builtin-config-ix.cmake @@ -64,11 +64,34 @@ if(APPLE) find_darwin_sdk_dir(DARWIN_tvossim_SYSROOT appletvsimulator) find_darwin_sdk_dir(DARWIN_tvos_SYSROOT appletvos) + # Get supported architecture from SDKSettings. + function(sdk_has_arch_support sdk_path os arch has_support) + execute_process(COMMAND + /usr/libexec/PlistBuddy -c "Print :SupportedTargets:${os}:Archs" ${sdk_path}/SDKSettings.plist + OUTPUT_VARIABLE SDK_SUPPORTED_ARCHS + RESULT_VARIABLE PLIST_ERROR) + if (PLIST_ERROR EQUAL 0 AND + SDK_SUPPORTED_ARCHS MATCHES " ${arch}\n") + message(STATUS "Found ${arch} support in ${sdk_path}/SDKSettings.plist") + set("${has_support}" On PARENT_SCOPE) + else() + message(STATUS "No ${arch} support in ${sdk_path}/SDKSettings.plist") + set("${has_support}" Off PARENT_SCOPE) + endif() + endfunction() + set(DARWIN_EMBEDDED_PLATFORMS) set(DARWIN_osx_BUILTIN_MIN_VER 10.5) set(DARWIN_osx_BUILTIN_MIN_VER_FLAG -mmacosx-version-min=${DARWIN_osx_BUILTIN_MIN_VER}) set(DARWIN_osx_BUILTIN_ALL_POSSIBLE_ARCHS ${X86} ${X86_64}) + # Add support for arm64 macOS if available in SDK. + foreach(arch ${ARM64}) + sdk_has_arch_support(${DARWIN_osx_SYSROOT} macosx ${arch} MACOS_ARM_SUPPORT) + if (MACOS_ARM_SUPPORT) + list(APPEND DARWIN_osx_BUILTIN_ALL_POSSIBLE_ARCHS ${arch}) + endif() + endforeach(arch) if(COMPILER_RT_ENABLE_IOS) list(APPEND DARWIN_EMBEDDED_PLATFORMS ios) diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index 1f3697ff6f659..2edc1dabd90d3 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -650,7 +650,7 @@ endif() # TODO: Add builtins support. -if (CRT_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux") +if (CRT_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux" AND NOT LLVM_USE_SANITIZER) set(COMPILER_RT_HAS_CRT TRUE) else() set(COMPILER_RT_HAS_CRT FALSE) diff --git a/compiler-rt/lib/asan/tests/asan_test.cpp b/compiler-rt/lib/asan/tests/asan_test.cpp index 83b0b0e8d33e9..edc98ed185202 100644 --- a/compiler-rt/lib/asan/tests/asan_test.cpp +++ b/compiler-rt/lib/asan/tests/asan_test.cpp @@ -588,9 +588,6 @@ NOINLINE void TouchStackFunc() { A[i] = i*i; } -// Disabled due to rdar://problem/62141412 -#if !(defined(__APPLE__) && defined(__i386__)) - // Test that we handle longjmp and do not report false positives on stack. TEST(AddressSanitizer, LongJmpTest) { static jmp_buf buf; @@ -600,7 +597,6 @@ TEST(AddressSanitizer, LongJmpTest) { TouchStackFunc(); } } -#endif #if !defined(_WIN32) // Only basic longjmp is available on Windows. NOINLINE void UnderscopeLongJmpFunc1(jmp_buf buf) { @@ -662,8 +658,6 @@ TEST(AddressSanitizer, UnderscopeLongJmpTest) { } } -// Disabled due to rdar://problem/62141412 -#if !(defined(__APPLE__) && defined(__i386__)) TEST(AddressSanitizer, SigLongJmpTest) { static sigjmp_buf buf; if (!sigsetjmp(buf, 1)) { @@ -674,8 +668,6 @@ TEST(AddressSanitizer, SigLongJmpTest) { } #endif -#endif - // FIXME: Why does clang-cl define __EXCEPTIONS? #if defined(__EXCEPTIONS) && !defined(_WIN32) NOINLINE void ThrowFunc() { diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt index f8431bdcf059f..5e3c901322ec6 100644 --- a/compiler-rt/lib/builtins/CMakeLists.txt +++ b/compiler-rt/lib/builtins/CMakeLists.txt @@ -46,7 +46,6 @@ set(GENERIC_SOURCES absvti2.c adddf3.c addsf3.c - addtf3.c addvdi3.c addvsi3.c addvti3.c @@ -75,9 +74,7 @@ set(GENERIC_SOURCES divsc3.c divsf3.c divsi3.c - divtc3.c divti3.c - divtf3.c extendsfdf2.c extendhfsf2.c ffsdi2.c @@ -123,7 +120,6 @@ set(GENERIC_SOURCES mulsc3.c mulsf3.c multi3.c - multf3.c mulvdi3.c mulvsi3.c mulvti3.c @@ -143,13 +139,11 @@ set(GENERIC_SOURCES popcountti2.c powidf2.c powisf2.c - powitf2.c subdf3.c subsf3.c subvdi3.c subvsi3.c subvti3.c - subtf3.c trampoline_setup.c truncdfhf2.c truncdfsf2.c @@ -168,7 +162,10 @@ set(GENERIC_SOURCES ) set(GENERIC_TF_SOURCES + addtf3.c comparetf2.c + divtc3.c + divtf3.c extenddftf2.c extendsftf2.c fixtfdi.c @@ -184,6 +181,9 @@ set(GENERIC_TF_SOURCES floatunsitf.c floatuntitf.c multc3.c + multf3.c + powitf2.c + subtf3.c trunctfdf2.c trunctfsf2.c ) @@ -505,13 +505,9 @@ set(hexagon_SOURCES hexagon/dfsqrt.S hexagon/divdi3.S hexagon/divsi3.S - hexagon/fabs_opt.S hexagon/fastmath2_dlib_asm.S hexagon/fastmath2_ldlib_asm.S hexagon/fastmath_dlib_asm.S - hexagon/fma_opt.S - hexagon/fmax_opt.S - hexagon/fmin_opt.S hexagon/memcpy_forward_vp4cp4n2.S hexagon/memcpy_likely_aligned.S hexagon/moddi3.S diff --git a/compiler-rt/lib/builtins/README.txt b/compiler-rt/lib/builtins/README.txt index e603dfa053566..f9e1bc805092e 100644 --- a/compiler-rt/lib/builtins/README.txt +++ b/compiler-rt/lib/builtins/README.txt @@ -20,13 +20,18 @@ Here is the specification for this library: http://gcc.gnu.org/onlinedocs/gccint/Libgcc.html#Libgcc +Please note that the libgcc specification explicitly mentions actual types of +arguments and returned values being expressed with machine modes. +In some cases particular types such as "int", "unsigned", "long long", etc. +may be specified just as examples there. + Here is a synopsis of the contents of this library: -typedef int si_int; -typedef unsigned su_int; +typedef int32_t si_int; +typedef uint32_t su_int; -typedef long long di_int; -typedef unsigned long long du_int; +typedef int64_t di_int; +typedef uint64_t du_int; // Integral bit manipulation @@ -38,24 +43,24 @@ ti_int __ashrti3(ti_int a, si_int b); // a >> b arithmetic (sign fill) di_int __lshrdi3(di_int a, si_int b); // a >> b logical (zero fill) ti_int __lshrti3(ti_int a, si_int b); // a >> b logical (zero fill) -si_int __clzsi2(si_int a); // count leading zeros -si_int __clzdi2(di_int a); // count leading zeros -si_int __clzti2(ti_int a); // count leading zeros -si_int __ctzsi2(si_int a); // count trailing zeros -si_int __ctzdi2(di_int a); // count trailing zeros -si_int __ctzti2(ti_int a); // count trailing zeros +int __clzsi2(si_int a); // count leading zeros +int __clzdi2(di_int a); // count leading zeros +int __clzti2(ti_int a); // count leading zeros +int __ctzsi2(si_int a); // count trailing zeros +int __ctzdi2(di_int a); // count trailing zeros +int __ctzti2(ti_int a); // count trailing zeros -si_int __ffssi2(si_int a); // find least significant 1 bit -si_int __ffsdi2(di_int a); // find least significant 1 bit -si_int __ffsti2(ti_int a); // find least significant 1 bit +int __ffssi2(si_int a); // find least significant 1 bit +int __ffsdi2(di_int a); // find least significant 1 bit +int __ffsti2(ti_int a); // find least significant 1 bit -si_int __paritysi2(si_int a); // bit parity -si_int __paritydi2(di_int a); // bit parity -si_int __parityti2(ti_int a); // bit parity +int __paritysi2(si_int a); // bit parity +int __paritydi2(di_int a); // bit parity +int __parityti2(ti_int a); // bit parity -si_int __popcountsi2(si_int a); // bit population -si_int __popcountdi2(di_int a); // bit population -si_int __popcountti2(ti_int a); // bit population +int __popcountsi2(si_int a); // bit population +int __popcountdi2(di_int a); // bit population +int __popcountti2(ti_int a); // bit population uint32_t __bswapsi2(uint32_t a); // a byteswapped uint64_t __bswapdi2(uint64_t a); // a byteswapped @@ -169,10 +174,10 @@ long double __floatuntixf(tu_int a); // Floating point raised to integer power -float __powisf2( float a, si_int b); // a ^ b -double __powidf2( double a, si_int b); // a ^ b -long double __powixf2(long double a, si_int b); // a ^ b -long double __powitf2(long double a, si_int b); // ppc only, a ^ b +float __powisf2( float a, int b); // a ^ b +double __powidf2( double a, int b); // a ^ b +long double __powixf2(long double a, int b); // a ^ b +long double __powitf2(long double a, int b); // ppc only, a ^ b // Complex arithmetic diff --git a/compiler-rt/lib/builtins/clzdi2.c b/compiler-rt/lib/builtins/clzdi2.c index d64e9eda85130..12c17982a5cb1 100644 --- a/compiler-rt/lib/builtins/clzdi2.c +++ b/compiler-rt/lib/builtins/clzdi2.c @@ -21,12 +21,12 @@ // ctz instruction, gcc resolves __builtin_clz to __clzdi2 rather than // __clzsi2, leading to infinite recursion. #define __builtin_clz(a) __clzsi2(a) -extern si_int __clzsi2(si_int); +extern int __clzsi2(si_int); #endif // Precondition: a != 0 -COMPILER_RT_ABI si_int __clzdi2(di_int a) { +COMPILER_RT_ABI int __clzdi2(di_int a) { dwords x; x.all = a; const si_int f = -(x.s.high == 0); diff --git a/compiler-rt/lib/builtins/clzsi2.c b/compiler-rt/lib/builtins/clzsi2.c index 3f9f27f413315..d75f56d937b07 100644 --- a/compiler-rt/lib/builtins/clzsi2.c +++ b/compiler-rt/lib/builtins/clzsi2.c @@ -16,7 +16,7 @@ // Precondition: a != 0 -COMPILER_RT_ABI si_int __clzsi2(si_int a) { +COMPILER_RT_ABI int __clzsi2(si_int a) { su_int x = (su_int)a; si_int t = ((x & 0xFFFF0000) == 0) << 4; // if (x is small) t = 16 else 0 x >>= 16 - t; // x = [0 - 0xFFFF] diff --git a/compiler-rt/lib/builtins/clzti2.c b/compiler-rt/lib/builtins/clzti2.c index 0c787104caa2a..25d30119f271c 100644 --- a/compiler-rt/lib/builtins/clzti2.c +++ b/compiler-rt/lib/builtins/clzti2.c @@ -18,7 +18,7 @@ // Precondition: a != 0 -COMPILER_RT_ABI si_int __clzti2(ti_int a) { +COMPILER_RT_ABI int __clzti2(ti_int a) { twords x; x.all = a; const di_int f = -(x.s.high == 0); diff --git a/compiler-rt/lib/builtins/cpu_model.c b/compiler-rt/lib/builtins/cpu_model.c index 59c6974207c79..8346bb62dcfb4 100644 --- a/compiler-rt/lib/builtins/cpu_model.c +++ b/compiler-rt/lib/builtins/cpu_model.c @@ -125,7 +125,8 @@ enum ProcessorFeatures { FEATURE_AVX512VNNI, FEATURE_AVX512BITALG, FEATURE_AVX512BF16, - FEATURE_AVX512VP2INTERSECT + FEATURE_AVX512VP2INTERSECT, + CPU_FEATURE_MAX }; // The check below for i386 was copied from clang's cpuid.h (__get_cpuid_max). @@ -271,12 +272,17 @@ static void detectX86FamilyModel(unsigned EAX, unsigned *Family, } } -static void getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, - const unsigned *Features, - unsigned *Type, unsigned *Subtype) { +static const char * +getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, + const unsigned *Features, + unsigned *Type, unsigned *Subtype) { #define testFeature(F) \ (Features[F / 32] & (F % 32)) != 0 + // We select CPU strings to match the code in Host.cpp, but we don't use them + // in compiler-rt. + const char *CPU = 0; + switch (Family) { case 6: switch (Model) { @@ -287,13 +293,17 @@ static void getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, // 0Fh. All processors are manufactured using the 65 nm process. case 0x16: // Intel Celeron processor model 16h. All processors are // manufactured using the 65 nm process + CPU = "core2"; + *Type = INTEL_CORE2; + break; case 0x17: // Intel Core 2 Extreme processor, Intel Xeon processor, model // 17h. All processors are manufactured using the 45 nm process. // // 45nm: Penryn , Wolfdale, Yorkfield (XE) case 0x1d: // Intel Xeon processor MP. All processors are manufactured using // the 45 nm process. - *Type = INTEL_CORE2; // "penryn" + CPU = "penryn"; + *Type = INTEL_CORE2; break; case 0x1a: // Intel Core i7 processor and Intel Xeon processor. All // processors are manufactured using the 45 nm process. @@ -301,25 +311,29 @@ static void getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, // As found in a Summer 2010 model iMac. case 0x1f: case 0x2e: // Nehalem EX - *Type = INTEL_COREI7; // "nehalem" + CPU = "nehalem"; + *Type = INTEL_COREI7; *Subtype = INTEL_COREI7_NEHALEM; break; case 0x25: // Intel Core i7, laptop version. case 0x2c: // Intel Core i7 processor and Intel Xeon processor. All // processors are manufactured using the 32 nm process. case 0x2f: // Westmere EX - *Type = INTEL_COREI7; // "westmere" + CPU = "westmere"; + *Type = INTEL_COREI7; *Subtype = INTEL_COREI7_WESTMERE; break; case 0x2a: // Intel Core i7 processor. All processors are manufactured // using the 32 nm process. case 0x2d: - *Type = INTEL_COREI7; //"sandybridge" + CPU = "sandybridge"; + *Type = INTEL_COREI7; *Subtype = INTEL_COREI7_SANDYBRIDGE; break; case 0x3a: case 0x3e: // Ivy Bridge EP - *Type = INTEL_COREI7; // "ivybridge" + CPU = "ivybridge"; + *Type = INTEL_COREI7; *Subtype = INTEL_COREI7_IVYBRIDGE; break; @@ -328,7 +342,8 @@ static void getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, case 0x3f: case 0x45: case 0x46: - *Type = INTEL_COREI7; // "haswell" + CPU = "haswell"; + *Type = INTEL_COREI7; *Subtype = INTEL_COREI7_HASWELL; break; @@ -337,7 +352,8 @@ static void getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, case 0x47: case 0x4f: case 0x56: - *Type = INTEL_COREI7; // "broadwell" + CPU = "broadwell"; + *Type = INTEL_COREI7; *Subtype = INTEL_COREI7_BROADWELL; break; @@ -348,39 +364,47 @@ static void getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, case 0x9e: // Kaby Lake desktop case 0xa5: // Comet Lake-H/S case 0xa6: // Comet Lake-U - *Type = INTEL_COREI7; // "skylake" + CPU = "skylake"; + *Type = INTEL_COREI7; *Subtype = INTEL_COREI7_SKYLAKE; break; // Skylake Xeon: case 0x55: *Type = INTEL_COREI7; - if (testFeature(FEATURE_AVX512BF16)) - *Subtype = INTEL_COREI7_COOPERLAKE; // "cooperlake" - else if (testFeature(FEATURE_AVX512VNNI)) - *Subtype = INTEL_COREI7_CASCADELAKE; // "cascadelake" - else - *Subtype = INTEL_COREI7_SKYLAKE_AVX512; // "skylake-avx512" + if (testFeature(FEATURE_AVX512BF16)) { + CPU = "cooperlake"; + *Subtype = INTEL_COREI7_COOPERLAKE; + } else if (testFeature(FEATURE_AVX512VNNI)) { + CPU = "cascadelake"; + *Subtype = INTEL_COREI7_CASCADELAKE; + } else { + CPU = "skylake-avx512"; + *Subtype = INTEL_COREI7_SKYLAKE_AVX512; + } break; // Cannonlake: case 0x66: + CPU = "cannonlake"; *Type = INTEL_COREI7; - *Subtype = INTEL_COREI7_CANNONLAKE; // "cannonlake" + *Subtype = INTEL_COREI7_CANNONLAKE; break; // Icelake: case 0x7d: case 0x7e: + CPU = "icelake-client"; *Type = INTEL_COREI7; - *Subtype = INTEL_COREI7_ICELAKE_CLIENT; // "icelake-client" + *Subtype = INTEL_COREI7_ICELAKE_CLIENT; break; // Icelake Xeon: case 0x6a: case 0x6c: + CPU = "icelake-server"; *Type = INTEL_COREI7; - *Subtype = INTEL_COREI7_ICELAKE_SERVER; // "icelake-server" + *Subtype = INTEL_COREI7_ICELAKE_SERVER; break; case 0x1c: // Most 45 nm Intel Atom processors @@ -388,8 +412,9 @@ static void getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, case 0x27: // 32 nm Atom Medfield case 0x35: // 32 nm Atom Midview case 0x36: // 32 nm Atom Midview + CPU = "bonnell"; *Type = INTEL_BONNELL; - break; // "bonnell" + break; // Atom Silvermont codes from the Intel software optimization guide. case 0x37: @@ -398,26 +423,32 @@ static void getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, case 0x5a: case 0x5d: case 0x4c: // really airmont + CPU = "silvermont"; *Type = INTEL_SILVERMONT; - break; // "silvermont" + break; // Goldmont: case 0x5c: // Apollo Lake case 0x5f: // Denverton + CPU = "goldmont"; *Type = INTEL_GOLDMONT; break; // "goldmont" case 0x7a: + CPU = "goldmont-plus"; *Type = INTEL_GOLDMONT_PLUS; break; case 0x86: + CPU = "tremont"; *Type = INTEL_TREMONT; break; case 0x57: - *Type = INTEL_KNL; // knl + CPU = "knl"; + *Type = INTEL_KNL; break; case 0x85: - *Type = INTEL_KNM; // knm + CPU = "knm"; + *Type = INTEL_KNM; break; default: // Unknown family 6 CPU. @@ -427,17 +458,22 @@ static void getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, default: break; // Unknown. } + + return CPU; } -static void getAMDProcessorTypeAndSubtype(unsigned Family, unsigned Model, - const unsigned *Features, - unsigned *Type, unsigned *Subtype) { - // FIXME: this poorly matches the generated SubtargetFeatureKV table. There - // appears to be no way to generate the wide variety of AMD-specific targets - // from the information returned from CPUID. +static const char * +getAMDProcessorTypeAndSubtype(unsigned Family, unsigned Model, + const unsigned *Features, + unsigned *Type, unsigned *Subtype) { + // We select CPU strings to match the code in Host.cpp, but we don't use them + // in compiler-rt. + const char *CPU = 0; + switch (Family) { case 16: - *Type = AMDFAM10H; // "amdfam10" + CPU = "amdfam10"; + *Type = AMDFAM10H; switch (Model) { case 2: *Subtype = AMDFAM10H_BARCELONA; @@ -451,50 +487,58 @@ static void getAMDProcessorTypeAndSubtype(unsigned Family, unsigned Model, } break; case 20: + CPU = "btver1"; *Type = AMD_BTVER1; - break; // "btver1"; + break; case 21: + CPU = "bdver1"; *Type = AMDFAM15H; if (Model >= 0x60 && Model <= 0x7f) { + CPU = "bdver4"; *Subtype = AMDFAM15H_BDVER4; - break; // "bdver4"; 60h-7Fh: Excavator + break; // 60h-7Fh: Excavator } if (Model >= 0x30 && Model <= 0x3f) { + CPU = "bdver3"; *Subtype = AMDFAM15H_BDVER3; - break; // "bdver3"; 30h-3Fh: Steamroller + break; // 30h-3Fh: Steamroller } if ((Model >= 0x10 && Model <= 0x1f) || Model == 0x02) { + CPU = "bdver2"; *Subtype = AMDFAM15H_BDVER2; - break; // "bdver2"; 02h, 10h-1Fh: Piledriver + break; // 02h, 10h-1Fh: Piledriver } if (Model <= 0x0f) { *Subtype = AMDFAM15H_BDVER1; - break; // "bdver1"; 00h-0Fh: Bulldozer + break; // 00h-0Fh: Bulldozer } break; case 22: + CPU = "btver2"; *Type = AMD_BTVER2; - break; // "btver2" + break; case 23: + CPU = "znver1"; *Type = AMDFAM17H; if ((Model >= 0x30 && Model <= 0x3f) || Model == 0x71) { + CPU = "znver2"; *Subtype = AMDFAM17H_ZNVER2; - break; // "znver2"; 30h-3fh, 71h: Zen2 + break; // 30h-3fh, 71h: Zen2 } if (Model <= 0x0f) { *Subtype = AMDFAM17H_ZNVER1; - break; // "znver1"; 00h-0Fh: Zen1 + break; // 00h-0Fh: Zen1 } break; default: - break; // "generic" + break; // Unknown AMD CPU. } + + return CPU; } static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf, unsigned *Features) { - Features[0] = 0; - Features[1] = 0; unsigned EAX, EBX; #define setFeature(F) \ @@ -653,7 +697,7 @@ int CONSTRUCTOR_ATTRIBUTE __cpu_indicator_init(void) { unsigned MaxLeaf = 5; unsigned Vendor; unsigned Model, Family; - unsigned Features[2]; + unsigned Features[(CPU_FEATURE_MAX + 31) / 32] = {0}; // This function needs to run just once. if (__cpu_model.__cpu_vendor) @@ -670,6 +714,8 @@ int CONSTRUCTOR_ATTRIBUTE __cpu_indicator_init(void) { // Find available features. getAvailableFeatures(ECX, EDX, MaxLeaf, &Features[0]); + + assert((sizeof(Features)/sizeof(Features[0])) == 2); __cpu_model.__cpu_features[0] = Features[0]; __cpu_features2 = Features[1]; diff --git a/compiler-rt/lib/builtins/ctzdi2.c b/compiler-rt/lib/builtins/ctzdi2.c index 8335f5cbb314e..26c908d876ac4 100644 --- a/compiler-rt/lib/builtins/ctzdi2.c +++ b/compiler-rt/lib/builtins/ctzdi2.c @@ -21,7 +21,7 @@ // ctz instruction, gcc resolves __builtin_ctz to __ctzdi2 rather than // __ctzsi2, leading to infinite recursion. #define __builtin_ctz(a) __ctzsi2(a) -extern si_int __ctzsi2(si_int); +extern int __ctzsi2(si_int); #endif // Precondition: a != 0 diff --git a/compiler-rt/lib/builtins/ctzsi2.c b/compiler-rt/lib/builtins/ctzsi2.c index 09c6863b74e3a..ed95c60579339 100644 --- a/compiler-rt/lib/builtins/ctzsi2.c +++ b/compiler-rt/lib/builtins/ctzsi2.c @@ -16,7 +16,7 @@ // Precondition: a != 0 -COMPILER_RT_ABI si_int __ctzsi2(si_int a) { +COMPILER_RT_ABI int __ctzsi2(si_int a) { su_int x = (su_int)a; si_int t = ((x & 0x0000FFFF) == 0) << 4; // if (x has no small bits) t = 16 else 0 diff --git a/compiler-rt/lib/builtins/ctzti2.c b/compiler-rt/lib/builtins/ctzti2.c index 2a1312c8437de..fb136d0de1c0d 100644 --- a/compiler-rt/lib/builtins/ctzti2.c +++ b/compiler-rt/lib/builtins/ctzti2.c @@ -18,7 +18,7 @@ // Precondition: a != 0 -COMPILER_RT_ABI si_int __ctzti2(ti_int a) { +COMPILER_RT_ABI int __ctzti2(ti_int a) { twords x; x.all = a; const di_int f = -(x.s.low == 0); diff --git a/compiler-rt/lib/builtins/ffsti2.c b/compiler-rt/lib/builtins/ffsti2.c index a2d7ce08ada13..a2177d148a099 100644 --- a/compiler-rt/lib/builtins/ffsti2.c +++ b/compiler-rt/lib/builtins/ffsti2.c @@ -17,7 +17,7 @@ // Returns: the index of the least significant 1-bit in a, or // the value zero if a is zero. The least significant bit is index one. -COMPILER_RT_ABI si_int __ffsti2(ti_int a) { +COMPILER_RT_ABI int __ffsti2(ti_int a) { twords x; x.all = a; if (x.s.low == 0) { diff --git a/compiler-rt/lib/builtins/floatdidf.c b/compiler-rt/lib/builtins/floatdidf.c index 8f887314b9e1b..b2d8f2b44b6d3 100644 --- a/compiler-rt/lib/builtins/floatdidf.c +++ b/compiler-rt/lib/builtins/floatdidf.c @@ -87,7 +87,7 @@ COMPILER_RT_ABI double __floatdidf(di_int a) { } double_bits fb; fb.u.s.high = ((su_int)s & 0x80000000) | // sign - ((e + 1023) << 20) | // exponent + ((su_int)(e + 1023) << 20) | // exponent ((su_int)(a >> 32) & 0x000FFFFF); // mantissa-high fb.u.s.low = (su_int)a; // mantissa-low return fb.f; diff --git a/compiler-rt/lib/builtins/floatundidf.c b/compiler-rt/lib/builtins/floatundidf.c index e7c6aae5ce382..4c445b118080b 100644 --- a/compiler-rt/lib/builtins/floatundidf.c +++ b/compiler-rt/lib/builtins/floatundidf.c @@ -90,7 +90,7 @@ COMPILER_RT_ABI double __floatundidf(du_int a) { // a is now rounded to DBL_MANT_DIG bits } double_bits fb; - fb.u.s.high = ((e + 1023) << 20) | // exponent + fb.u.s.high = ((su_int)(e + 1023) << 20) | // exponent ((su_int)(a >> 32) & 0x000FFFFF); // mantissa-high fb.u.s.low = (su_int)a; // mantissa-low return fb.f; diff --git a/compiler-rt/lib/builtins/fp_lib.h b/compiler-rt/lib/builtins/fp_lib.h index e6ba077d23130..bd1f180f499e8 100644 --- a/compiler-rt/lib/builtins/fp_lib.h +++ b/compiler-rt/lib/builtins/fp_lib.h @@ -46,7 +46,7 @@ typedef float fp_t; #define REP_C UINT32_C #define significandBits 23 -static __inline int rep_clz(rep_t a) { return __builtin_clz(a); } +static __inline int rep_clz(rep_t a) { return clzsi(a); } // 32x32 --> 64 bit multiply static __inline void wideMultiply(rep_t a, rep_t b, rep_t *hi, rep_t *lo) { diff --git a/compiler-rt/lib/builtins/hexagon/dffma.S b/compiler-rt/lib/builtins/hexagon/dffma.S index c201d3d8be5e1..843e88b3cab84 100644 --- a/compiler-rt/lib/builtins/hexagon/dffma.S +++ b/compiler-rt/lib/builtins/hexagon/dffma.S @@ -104,13 +104,11 @@ .type __hexagon_fmadf4,@function .global __hexagon_fmadf5 .type __hexagon_fmadf5,@function - .global fma - .type fma,@function Q6_ALIAS(fmadf5) .p2align 5 __hexagon_fmadf4: __hexagon_fmadf5: -fma: +.Lfma_begin: { P_TMP = dfclass(A,#2) P_TMP = dfclass(B,#2) @@ -561,7 +559,7 @@ fma: B = insert(BTMP,#63,#0) AH -= asl(TMP,#HI_MANTBITS) } - jump fma + jump .Lfma_begin .Lfma_ab_tiny: ATMP = combine(##0x00100000,#0) @@ -569,7 +567,7 @@ fma: A = insert(ATMP,#63,#0) B = insert(ATMP,#63,#0) } - jump fma + jump .Lfma_begin .Lab_inf: { diff --git a/compiler-rt/lib/builtins/hexagon/fabs_opt.S b/compiler-rt/lib/builtins/hexagon/fabs_opt.S deleted file mode 100644 index 6bf9b84b3d209..0000000000000 --- a/compiler-rt/lib/builtins/hexagon/fabs_opt.S +++ /dev/null @@ -1,36 +0,0 @@ -//===----------------------Hexagon builtin routine ------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -.macro FUNCTION_BEGIN name -.text -.p2align 5 -.globl \name -.type \name, @function -\name: -.endm - -.macro FUNCTION_END name -.size \name, . - \name -.endm - -FUNCTION_BEGIN fabs - { - r1 = clrbit(r1, #31) - jumpr r31 - } -FUNCTION_END fabs - -FUNCTION_BEGIN fabsf - { - r0 = clrbit(r0, #31) - jumpr r31 - } -FUNCTION_END fabsf - - .globl fabsl - .set fabsl, fabs diff --git a/compiler-rt/lib/builtins/hexagon/fma_opt.S b/compiler-rt/lib/builtins/hexagon/fma_opt.S deleted file mode 100644 index 7f566adffd6a4..0000000000000 --- a/compiler-rt/lib/builtins/hexagon/fma_opt.S +++ /dev/null @@ -1,30 +0,0 @@ -//===----------------------Hexagon builtin routine ------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -.macro FUNCTION_BEGIN name -.text -.p2align 5 -.globl \name -.type \name, @function -\name: -.endm - -.macro FUNCTION_END name -.size \name, . - \name -.endm - -FUNCTION_BEGIN fmaf - r2 += sfmpy(r0, r1) - { - r0 = r2 - jumpr r31 - } -FUNCTION_END fmaf - - .globl fmal - .set fmal, fma diff --git a/compiler-rt/lib/builtins/hexagon/fmax_opt.S b/compiler-rt/lib/builtins/hexagon/fmax_opt.S deleted file mode 100644 index 81d711dff8d20..0000000000000 --- a/compiler-rt/lib/builtins/hexagon/fmax_opt.S +++ /dev/null @@ -1,29 +0,0 @@ -//===----------------------Hexagon builtin routine ------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -.macro FUNCTION_BEGIN name -.text -.p2align 5 -.globl \name -.type \name, @function -\name: -.endm - -.macro FUNCTION_END name -.size \name, . - \name -.endm - -FUNCTION_BEGIN fmaxf - { - r0 = sfmax(r0, r1) - jumpr r31 - } -FUNCTION_END fmaxf - - .globl fmaxl - .set fmaxl, fmax diff --git a/compiler-rt/lib/builtins/hexagon/fmin_opt.S b/compiler-rt/lib/builtins/hexagon/fmin_opt.S deleted file mode 100644 index d043f1d7a6987..0000000000000 --- a/compiler-rt/lib/builtins/hexagon/fmin_opt.S +++ /dev/null @@ -1,29 +0,0 @@ -//===----------------------Hexagon builtin routine ------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -.macro FUNCTION_BEGIN name -.text -.p2align 5 -.globl \name -.type \name, @function -\name: -.endm - -.macro FUNCTION_END name -.size \name, . - \name -.endm - -FUNCTION_BEGIN fminf - { - r0 = sfmin(r0, r1) - jumpr r31 - } -FUNCTION_END fminf - - .globl fminl - .set fminl, fmin diff --git a/compiler-rt/lib/builtins/int_lib.h b/compiler-rt/lib/builtins/int_lib.h index 7e1dabe29d01a..991c4a99ea6e2 100644 --- a/compiler-rt/lib/builtins/int_lib.h +++ b/compiler-rt/lib/builtins/int_lib.h @@ -92,8 +92,8 @@ // Include internal utility function declarations. #include "int_util.h" -COMPILER_RT_ABI si_int __paritysi2(si_int a); -COMPILER_RT_ABI si_int __paritydi2(di_int a); +COMPILER_RT_ABI int __paritysi2(si_int a); +COMPILER_RT_ABI int __paritydi2(di_int a); COMPILER_RT_ABI di_int __divdi3(di_int a, di_int b); COMPILER_RT_ABI si_int __divsi3(si_int a, si_int b); @@ -102,7 +102,7 @@ COMPILER_RT_ABI su_int __udivsi3(su_int n, su_int d); COMPILER_RT_ABI su_int __udivmodsi4(su_int a, su_int b, su_int *rem); COMPILER_RT_ABI du_int __udivmoddi4(du_int a, du_int b, du_int *rem); #ifdef CRT_HAS_128BIT -COMPILER_RT_ABI si_int __clzti2(ti_int a); +COMPILER_RT_ABI int __clzti2(ti_int a); COMPILER_RT_ABI tu_int __udivmodti4(tu_int a, tu_int b, tu_int *rem); #endif @@ -110,14 +110,14 @@ COMPILER_RT_ABI tu_int __udivmodti4(tu_int a, tu_int b, tu_int *rem); #if defined(_MSC_VER) && !defined(__clang__) #include -uint32_t __inline __builtin_ctz(uint32_t value) { +int __inline __builtin_ctz(uint32_t value) { unsigned long trailing_zero = 0; if (_BitScanForward(&trailing_zero, value)) return trailing_zero; return 32; } -uint32_t __inline __builtin_clz(uint32_t value) { +int __inline __builtin_clz(uint32_t value) { unsigned long leading_zero = 0; if (_BitScanReverse(&leading_zero, value)) return 31 - leading_zero; @@ -125,14 +125,14 @@ uint32_t __inline __builtin_clz(uint32_t value) { } #if defined(_M_ARM) || defined(_M_X64) -uint32_t __inline __builtin_clzll(uint64_t value) { +int __inline __builtin_clzll(uint64_t value) { unsigned long leading_zero = 0; if (_BitScanReverse64(&leading_zero, value)) return 63 - leading_zero; return 64; } #else -uint32_t __inline __builtin_clzll(uint64_t value) { +int __inline __builtin_clzll(uint64_t value) { if (value == 0) return 64; uint32_t msh = (uint32_t)(value >> 32); diff --git a/compiler-rt/lib/builtins/paritydi2.c b/compiler-rt/lib/builtins/paritydi2.c index dd9d45e63ea47..58e85f89e0437 100644 --- a/compiler-rt/lib/builtins/paritydi2.c +++ b/compiler-rt/lib/builtins/paritydi2.c @@ -14,7 +14,7 @@ // Returns: 1 if number of bits is odd else returns 0 -COMPILER_RT_ABI si_int __paritydi2(di_int a) { +COMPILER_RT_ABI int __paritydi2(di_int a) { dwords x; x.all = a; return __paritysi2(x.s.high ^ x.s.low); diff --git a/compiler-rt/lib/builtins/paritysi2.c b/compiler-rt/lib/builtins/paritysi2.c index 3efa961f2f85f..a4b84e0806328 100644 --- a/compiler-rt/lib/builtins/paritysi2.c +++ b/compiler-rt/lib/builtins/paritysi2.c @@ -14,7 +14,7 @@ // Returns: 1 if number of bits is odd else returns 0 -COMPILER_RT_ABI si_int __paritysi2(si_int a) { +COMPILER_RT_ABI int __paritysi2(si_int a) { su_int x = (su_int)a; x ^= x >> 16; x ^= x >> 8; diff --git a/compiler-rt/lib/builtins/parityti2.c b/compiler-rt/lib/builtins/parityti2.c index f3942ba8378c7..79e920d8a02df 100644 --- a/compiler-rt/lib/builtins/parityti2.c +++ b/compiler-rt/lib/builtins/parityti2.c @@ -16,7 +16,7 @@ // Returns: 1 if number of bits is odd else returns 0 -COMPILER_RT_ABI si_int __parityti2(ti_int a) { +COMPILER_RT_ABI int __parityti2(ti_int a) { twords x; x.all = a; return __paritydi2(x.s.high ^ x.s.low); diff --git a/compiler-rt/lib/builtins/popcountsi2.c b/compiler-rt/lib/builtins/popcountsi2.c index 75e592a778d98..4d346c45d9cee 100644 --- a/compiler-rt/lib/builtins/popcountsi2.c +++ b/compiler-rt/lib/builtins/popcountsi2.c @@ -14,7 +14,7 @@ // Returns: count of 1 bits -COMPILER_RT_ABI si_int __popcountsi2(si_int a) { +COMPILER_RT_ABI int __popcountsi2(si_int a) { su_int x = (su_int)a; x = x - ((x >> 1) & 0x55555555); // Every 2 bits holds the sum of every pair of bits diff --git a/compiler-rt/lib/builtins/popcountti2.c b/compiler-rt/lib/builtins/popcountti2.c index 853fd722309ee..79cbb2fb34c00 100644 --- a/compiler-rt/lib/builtins/popcountti2.c +++ b/compiler-rt/lib/builtins/popcountti2.c @@ -17,7 +17,7 @@ // Returns: count of 1 bits -COMPILER_RT_ABI si_int __popcountti2(ti_int a) { +COMPILER_RT_ABI int __popcountti2(ti_int a) { tu_int x3 = (tu_int)a; x3 = x3 - ((x3 >> 1) & (((tu_int)0x5555555555555555uLL << 64) | 0x5555555555555555uLL)); diff --git a/compiler-rt/lib/builtins/powidf2.c b/compiler-rt/lib/builtins/powidf2.c index 9697588484e74..81058af508297 100644 --- a/compiler-rt/lib/builtins/powidf2.c +++ b/compiler-rt/lib/builtins/powidf2.c @@ -14,7 +14,7 @@ // Returns: a ^ b -COMPILER_RT_ABI double __powidf2(double a, si_int b) { +COMPILER_RT_ABI double __powidf2(double a, int b) { const int recip = b < 0; double r = 1; while (1) { diff --git a/compiler-rt/lib/builtins/powisf2.c b/compiler-rt/lib/builtins/powisf2.c index 469402348825c..d0ab26167bbd2 100644 --- a/compiler-rt/lib/builtins/powisf2.c +++ b/compiler-rt/lib/builtins/powisf2.c @@ -14,7 +14,7 @@ // Returns: a ^ b -COMPILER_RT_ABI float __powisf2(float a, si_int b) { +COMPILER_RT_ABI float __powisf2(float a, int b) { const int recip = b < 0; float r = 1; while (1) { diff --git a/compiler-rt/lib/builtins/powitf2.c b/compiler-rt/lib/builtins/powitf2.c index 141a3a0ea727f..8e639a03a3c4b 100644 --- a/compiler-rt/lib/builtins/powitf2.c +++ b/compiler-rt/lib/builtins/powitf2.c @@ -17,7 +17,7 @@ // Returns: a ^ b -COMPILER_RT_ABI long double __powitf2(long double a, si_int b) { +COMPILER_RT_ABI long double __powitf2(long double a, int b) { const int recip = b < 0; long double r = 1; while (1) { diff --git a/compiler-rt/lib/builtins/powixf2.c b/compiler-rt/lib/builtins/powixf2.c index b7b52095afa17..3edfe9fd7af59 100644 --- a/compiler-rt/lib/builtins/powixf2.c +++ b/compiler-rt/lib/builtins/powixf2.c @@ -16,7 +16,7 @@ // Returns: a ^ b -COMPILER_RT_ABI long double __powixf2(long double a, si_int b) { +COMPILER_RT_ABI long double __powixf2(long double a, int b) { const int recip = b < 0; long double r = 1; while (1) { diff --git a/compiler-rt/lib/builtins/udivmodti4.c b/compiler-rt/lib/builtins/udivmodti4.c index dd14a8b579ca5..55def37c9e1fe 100644 --- a/compiler-rt/lib/builtins/udivmodti4.c +++ b/compiler-rt/lib/builtins/udivmodti4.c @@ -14,182 +14,145 @@ #ifdef CRT_HAS_128BIT +// Returns the 128 bit division result by 64 bit. Result must fit in 64 bits. +// Remainder stored in r. +// Taken and adjusted from libdivide libdivide_128_div_64_to_64 division +// fallback. For a correctness proof see the reference for this algorithm +// in Knuth, Volume 2, section 4.3.1, Algorithm D. +UNUSED +static inline du_int udiv128by64to64default(du_int u1, du_int u0, du_int v, + du_int *r) { + const unsigned n_udword_bits = sizeof(du_int) * CHAR_BIT; + const du_int b = (1ULL << (n_udword_bits / 2)); // Number base (32 bits) + du_int un1, un0; // Norm. dividend LSD's + du_int vn1, vn0; // Norm. divisor digits + du_int q1, q0; // Quotient digits + du_int un64, un21, un10; // Dividend digit pairs + du_int rhat; // A remainder + si_int s; // Shift amount for normalization + + s = __builtin_clzll(v); + if (s > 0) { + // Normalize the divisor. + v = v << s; + un64 = (u1 << s) | (u0 >> (n_udword_bits - s)); + un10 = u0 << s; // Shift dividend left + } else { + // Avoid undefined behavior of (u0 >> 64). + un64 = u1; + un10 = u0; + } + + // Break divisor up into two 32-bit digits. + vn1 = v >> (n_udword_bits / 2); + vn0 = v & 0xFFFFFFFF; + + // Break right half of dividend into two digits. + un1 = un10 >> (n_udword_bits / 2); + un0 = un10 & 0xFFFFFFFF; + + // Compute the first quotient digit, q1. + q1 = un64 / vn1; + rhat = un64 - q1 * vn1; + + // q1 has at most error 2. No more than 2 iterations. + while (q1 >= b || q1 * vn0 > b * rhat + un1) { + q1 = q1 - 1; + rhat = rhat + vn1; + if (rhat >= b) + break; + } + + un21 = un64 * b + un1 - q1 * v; + + // Compute the second quotient digit. + q0 = un21 / vn1; + rhat = un21 - q0 * vn1; + + // q0 has at most error 2. No more than 2 iterations. + while (q0 >= b || q0 * vn0 > b * rhat + un0) { + q0 = q0 - 1; + rhat = rhat + vn1; + if (rhat >= b) + break; + } + + *r = (un21 * b + un0 - q0 * v) >> s; + return q1 * b + q0; +} + +static inline du_int udiv128by64to64(du_int u1, du_int u0, du_int v, + du_int *r) { +#if defined(__x86_64__) + du_int result; + __asm__("divq %[v]" + : "=a"(result), "=d"(*r) + : [ v ] "r"(v), "a"(u0), "d"(u1)); + return result; +#else + return udiv128by64to64default(u1, u0, v, r); +#endif +} + // Effects: if rem != 0, *rem = a % b // Returns: a / b -// Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide - COMPILER_RT_ABI tu_int __udivmodti4(tu_int a, tu_int b, tu_int *rem) { - const unsigned n_udword_bits = sizeof(du_int) * CHAR_BIT; const unsigned n_utword_bits = sizeof(tu_int) * CHAR_BIT; - utwords n; - n.all = a; - utwords d; - d.all = b; - utwords q; - utwords r; - unsigned sr; - // special cases, X is unknown, K != 0 - if (n.s.high == 0) { - if (d.s.high == 0) { - // 0 X - // --- - // 0 X - if (rem) - *rem = n.s.low % d.s.low; - return n.s.low / d.s.low; - } - // 0 X - // --- - // K X + utwords dividend; + dividend.all = a; + utwords divisor; + divisor.all = b; + utwords quotient; + utwords remainder; + if (divisor.all > dividend.all) { if (rem) - *rem = n.s.low; + *rem = dividend.all; return 0; } - // n.s.high != 0 - if (d.s.low == 0) { - if (d.s.high == 0) { - // K X - // --- - // 0 0 - if (rem) - *rem = n.s.high % d.s.low; - return n.s.high / d.s.low; - } - // d.s.high != 0 - if (n.s.low == 0) { - // K 0 - // --- - // K 0 - if (rem) { - r.s.high = n.s.high % d.s.high; - r.s.low = 0; - *rem = r.all; - } - return n.s.high / d.s.high; - } - // K K - // --- - // K 0 - if ((d.s.high & (d.s.high - 1)) == 0) /* if d is a power of 2 */ { - if (rem) { - r.s.low = n.s.low; - r.s.high = n.s.high & (d.s.high - 1); - *rem = r.all; - } - return n.s.high >> __builtin_ctzll(d.s.high); - } - // K K - // --- - // K 0 - sr = __builtin_clzll(d.s.high) - __builtin_clzll(n.s.high); - // 0 <= sr <= n_udword_bits - 2 or sr large - if (sr > n_udword_bits - 2) { - if (rem) - *rem = n.all; - return 0; - } - ++sr; - // 1 <= sr <= n_udword_bits - 1 - // q.all = n.all << (n_utword_bits - sr); - q.s.low = 0; - q.s.high = n.s.low << (n_udword_bits - sr); - // r.all = n.all >> sr; - r.s.high = n.s.high >> sr; - r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr); - } else /* d.s.low != 0 */ { - if (d.s.high == 0) { - // K X - // --- - // 0 K - if ((d.s.low & (d.s.low - 1)) == 0) /* if d is a power of 2 */ { - if (rem) - *rem = n.s.low & (d.s.low - 1); - if (d.s.low == 1) - return n.all; - sr = __builtin_ctzll(d.s.low); - q.s.high = n.s.high >> sr; - q.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr); - return q.all; - } - // K X - // --- - // 0 K - sr = 1 + n_udword_bits + __builtin_clzll(d.s.low) - - __builtin_clzll(n.s.high); - // 2 <= sr <= n_utword_bits - 1 - // q.all = n.all << (n_utword_bits - sr); - // r.all = n.all >> sr; - if (sr == n_udword_bits) { - q.s.low = 0; - q.s.high = n.s.low; - r.s.high = 0; - r.s.low = n.s.high; - } else if (sr < n_udword_bits) /* 2 <= sr <= n_udword_bits - 1 */ { - q.s.low = 0; - q.s.high = n.s.low << (n_udword_bits - sr); - r.s.high = n.s.high >> sr; - r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr); - } else /* n_udword_bits + 1 <= sr <= n_utword_bits - 1 */ { - q.s.low = n.s.low << (n_utword_bits - sr); - q.s.high = (n.s.high << (n_utword_bits - sr)) | - (n.s.low >> (sr - n_udword_bits)); - r.s.high = 0; - r.s.low = n.s.high >> (sr - n_udword_bits); - } + // When the divisor fits in 64 bits, we can use an optimized path. + if (divisor.s.high == 0) { + remainder.s.high = 0; + if (dividend.s.high < divisor.s.low) { + // The result fits in 64 bits. + quotient.s.low = udiv128by64to64(dividend.s.high, dividend.s.low, + divisor.s.low, &remainder.s.low); + quotient.s.high = 0; } else { - // K X - // --- - // K K - sr = __builtin_clzll(d.s.high) - __builtin_clzll(n.s.high); - // 0 <= sr <= n_udword_bits - 1 or sr large - if (sr > n_udword_bits - 1) { - if (rem) - *rem = n.all; - return 0; - } - ++sr; - // 1 <= sr <= n_udword_bits - // q.all = n.all << (n_utword_bits - sr); - // r.all = n.all >> sr; - q.s.low = 0; - if (sr == n_udword_bits) { - q.s.high = n.s.low; - r.s.high = 0; - r.s.low = n.s.high; - } else { - r.s.high = n.s.high >> sr; - r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr); - q.s.high = n.s.low << (n_udword_bits - sr); - } + // First, divide with the high part to get the remainder in dividend.s.high. + // After that dividend.s.high < divisor.s.low. + quotient.s.high = dividend.s.high / divisor.s.low; + dividend.s.high = dividend.s.high % divisor.s.low; + quotient.s.low = udiv128by64to64(dividend.s.high, dividend.s.low, + divisor.s.low, &remainder.s.low); } + if (rem) + *rem = remainder.all; + return quotient.all; } - // Not a special case - // q and r are initialized with: - // q.all = n.all << (n_utword_bits - sr); - // r.all = n.all >> sr; - // 1 <= sr <= n_utword_bits - 1 - su_int carry = 0; - for (; sr > 0; --sr) { - // r:q = ((r:q) << 1) | carry - r.s.high = (r.s.high << 1) | (r.s.low >> (n_udword_bits - 1)); - r.s.low = (r.s.low << 1) | (q.s.high >> (n_udword_bits - 1)); - q.s.high = (q.s.high << 1) | (q.s.low >> (n_udword_bits - 1)); - q.s.low = (q.s.low << 1) | carry; - // carry = 0; - // if (r.all >= d.all) + // 0 <= shift <= 63. + si_int shift = + __builtin_clzll(divisor.s.high) - __builtin_clzll(dividend.s.high); + divisor.all <<= shift; + quotient.s.high = 0; + quotient.s.low = 0; + for (; shift >= 0; --shift) { + quotient.s.low <<= 1; + // Branch free version of. + // if (dividend.all >= divisor.all) // { - // r.all -= d.all; - // carry = 1; + // dividend.all -= divisor.all; + // carry = 1; // } - const ti_int s = (ti_int)(d.all - r.all - 1) >> (n_utword_bits - 1); - carry = s & 1; - r.all -= d.all & s; + const ti_int s = + (ti_int)(divisor.all - dividend.all - 1) >> (n_utword_bits - 1); + quotient.s.low |= s & 1; + dividend.all -= divisor.all & s; + divisor.all >>= 1; } - q.all = (q.all << 1) | carry; if (rem) - *rem = r.all; - return q.all; + *rem = dividend.all; + return quotient.all; } #endif // CRT_HAS_128BIT diff --git a/compiler-rt/lib/profile/GCDAProfiling.c b/compiler-rt/lib/profile/GCDAProfiling.c index d15540d7c18a8..57d8dec423cc0 100644 --- a/compiler-rt/lib/profile/GCDAProfiling.c +++ b/compiler-rt/lib/profile/GCDAProfiling.c @@ -628,8 +628,14 @@ void llvm_writeout_files(void) { } } -COMPILER_RT_VISIBILITY -void llvm_delete_writeout_function_list(void) { +#ifndef _WIN32 +// __attribute__((destructor)) and destructors whose priorities are greater than +// 100 run before this function and can thus be tracked. The priority is +// compatible with GCC 7 onwards. +__attribute__((destructor(100))) +#endif +static void llvm_writeout_and_clear(void) { + llvm_writeout_files(); fn_list_remove(&writeout_fn_list); } @@ -710,8 +716,9 @@ void llvm_gcov_init(fn_ptr wfn, fn_ptr ffn, fn_ptr rfn) { /* Make sure we write out the data and delete the data structures. */ atexit(llvm_delete_reset_function_list); atexit(llvm_delete_flush_function_list); - atexit(llvm_delete_writeout_function_list); - atexit(llvm_writeout_files); +#ifdef _WIN32 + atexit(llvm_writeout_and_clear); +#endif } } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index 57f8b2d29442c..ea9c71ba88032 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -3092,6 +3092,34 @@ INTERCEPTOR(int, sendmmsg, int fd, struct __sanitizer_mmsghdr *msgvec, #define INIT_SENDMMSG #endif +#if SANITIZER_INTERCEPT_SYSMSG +INTERCEPTOR(int, msgsnd, int msqid, const void *msgp, SIZE_T msgsz, + int msgflg) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, msgsnd, msqid, msgp, msgsz, msgflg); + if (msgp) + COMMON_INTERCEPTOR_READ_RANGE(ctx, msgp, sizeof(long) + msgsz); + int res = REAL(msgsnd)(msqid, msgp, msgsz, msgflg); + return res; +} + +INTERCEPTOR(SSIZE_T, msgrcv, int msqid, void *msgp, SIZE_T msgsz, + long msgtyp, int msgflg) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, msgrcv, msqid, msgp, msgsz, msgtyp, msgflg); + SSIZE_T len = REAL(msgrcv)(msqid, msgp, msgsz, msgtyp, msgflg); + if (len != -1) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msgp, sizeof(long) + len); + return len; +} + +#define INIT_SYSMSG \ + COMMON_INTERCEPT_FUNCTION(msgsnd); \ + COMMON_INTERCEPT_FUNCTION(msgrcv); +#else +#define INIT_SYSMSG +#endif + #if SANITIZER_INTERCEPT_GETPEERNAME INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) { void *ctx; @@ -7271,23 +7299,26 @@ INTERCEPTOR(int, setttyentpath, char *path) { #endif #if SANITIZER_INTERCEPT_PROTOENT -INTERCEPTOR(struct __sanitizer_protoent *, getprotoent) { - void *ctx; - COMMON_INTERCEPTOR_ENTER(ctx, getprotoent); - struct __sanitizer_protoent *p = REAL(getprotoent)(); - if (p) { - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); +static void write_protoent(void *ctx, struct __sanitizer_protoent *p) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1); - SIZE_T pp_size = 1; // One handles the trailing \0 + SIZE_T pp_size = 1; // One handles the trailing \0 - for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1); + for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases, - pp_size * sizeof(char **)); - } + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases, + pp_size * sizeof(char **)); +} + +INTERCEPTOR(struct __sanitizer_protoent *, getprotoent) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getprotoent); + struct __sanitizer_protoent *p = REAL(getprotoent)(); + if (p) + write_protoent(ctx, p); return p; } @@ -7297,19 +7328,8 @@ INTERCEPTOR(struct __sanitizer_protoent *, getprotobyname, const char *name) { if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); struct __sanitizer_protoent *p = REAL(getprotobyname)(name); - if (p) { - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); - - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1); - - SIZE_T pp_size = 1; // One handles the trailing \0 - - for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1); - - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases, - pp_size * sizeof(char **)); - } + if (p) + write_protoent(ctx, p); return p; } @@ -7317,19 +7337,8 @@ INTERCEPTOR(struct __sanitizer_protoent *, getprotobynumber, int proto) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, getprotobynumber, proto); struct __sanitizer_protoent *p = REAL(getprotobynumber)(proto); - if (p) { - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); - - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1); - - SIZE_T pp_size = 1; // One handles the trailing \0 - - for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1); - - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases, - pp_size * sizeof(char **)); - } + if (p) + write_protoent(ctx, p); return p; } #define INIT_PROTOENT \ @@ -7340,6 +7349,58 @@ INTERCEPTOR(struct __sanitizer_protoent *, getprotobynumber, int proto) { #define INIT_PROTOENT #endif +#if SANITIZER_INTERCEPT_PROTOENT_R +INTERCEPTOR(int, getprotoent_r, struct __sanitizer_protoent *result_buf, + char *buf, SIZE_T buflen, struct __sanitizer_protoent **result) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getprotoent_r, result_buf, buf, buflen, + result); + int res = REAL(getprotoent_r)(result_buf, buf, buflen, result); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result); + if (!res && *result) + write_protoent(ctx, *result); + return res; +} + +INTERCEPTOR(int, getprotobyname_r, const char *name, + struct __sanitizer_protoent *result_buf, char *buf, SIZE_T buflen, + struct __sanitizer_protoent **result) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getprotobyname_r, name, result_buf, buf, + buflen, result); + if (name) + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + int res = REAL(getprotobyname_r)(name, result_buf, buf, buflen, result); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result); + if (!res && *result) + write_protoent(ctx, *result); + return res; +} + +INTERCEPTOR(int, getprotobynumber_r, int num, + struct __sanitizer_protoent *result_buf, char *buf, + SIZE_T buflen, struct __sanitizer_protoent **result) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getprotobynumber_r, num, result_buf, buf, + buflen, result); + int res = REAL(getprotobynumber_r)(num, result_buf, buf, buflen, result); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result); + if (!res && *result) + write_protoent(ctx, *result); + return res; +} + +#define INIT_PROTOENT_R \ + COMMON_INTERCEPT_FUNCTION(getprotoent_r); \ + COMMON_INTERCEPT_FUNCTION(getprotobyname_r); \ + COMMON_INTERCEPT_FUNCTION(getprotobynumber_r); +#else +#define INIT_PROTOENT_R +#endif + #if SANITIZER_INTERCEPT_NETENT INTERCEPTOR(struct __sanitizer_netent *, getnetent) { void *ctx; @@ -9879,6 +9940,7 @@ static void InitializeCommonInterceptors() { INIT_SENDMSG; INIT_RECVMMSG; INIT_SENDMMSG; + INIT_SYSMSG; INIT_GETPEERNAME; INIT_IOCTL; INIT_INET_ATON; @@ -10042,6 +10104,7 @@ static void InitializeCommonInterceptors() { INIT_STRMODE; INIT_TTYENT; INIT_PROTOENT; + INIT_PROTOENT_R; INIT_NETENT; INIT_GETMNTINFO; INIT_MI_VECTOR_HASH; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp index dffe2c9c47376..91caa6a35693b 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -2210,7 +2210,7 @@ void CheckNoDeepBind(const char *filename, int flag) { if (flag & RTLD_DEEPBIND) { Report( "You are trying to dlopen a %s shared library with RTLD_DEEPBIND flag" - " which is incompatibe with sanitizer runtime " + " which is incompatible with sanitizer runtime " "(see https://github.com/google/sanitizers/issues/611 for details" "). If you want to run %s library under sanitizers please remove " "RTLD_DEEPBIND from dlopen flags.\n", diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp index c22e7517fc6f8..7a3dfbcc27607 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp @@ -606,12 +606,22 @@ HandleSignalMode GetHandleSignalMode(int signum) { return result; } +// This corresponds to Triple::getMacOSXVersion() in the Clang driver. static MacosVersion GetMacosAlignedVersionInternal() { u16 kernel_major = GetDarwinKernelVersion().major; - const u16 version_offset = 4; - CHECK_GE(kernel_major, version_offset); - u16 macos_major = kernel_major - version_offset; - return MacosVersion(10, macos_major); + // Darwin 0-3 -> unsupported + // Darwin 4-19 -> macOS 10.x + // Darwin 20+ -> macOS 11+ + CHECK_GE(kernel_major, 4); + u16 major, minor; + if (kernel_major < 20) { + major = 10; + minor = kernel_major - 4; + } else { + major = 11 + kernel_major - 20; + minor = 0; + } + return MacosVersion(major, minor); } static_assert(sizeof(MacosVersion) == sizeof(atomic_uint32_t::Type), diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.h b/compiler-rt/lib/sanitizer_common/sanitizer_mac.h index 922307a9b9779..90ecff4815c2e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.h @@ -47,9 +47,7 @@ struct VersionBase { }; struct MacosVersion : VersionBase { - MacosVersion(u16 ten, u16 major) : VersionBase(ten, major) { - CHECK_EQ(ten, 10); - } + MacosVersion(u16 major, u16 minor) : VersionBase(major, minor) {} }; struct DarwinKernelVersion : VersionBase { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h index c68bfa2587558..f0b1e04d1dd68 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h @@ -132,6 +132,12 @@ # define SANITIZER_X32 0 #endif +#if defined(__i386__) || defined(_M_IX86) +# define SANITIZER_I386 1 +#else +# define SANITIZER_I386 0 +#endif + #if defined(__mips__) # define SANITIZER_MIPS 1 # if defined(__mips64) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index 9dd6d285f5940..2d48e9d0ae1ad 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -270,6 +270,7 @@ #define SANITIZER_INTERCEPT_SENDMSG SI_POSIX #define SANITIZER_INTERCEPT_RECVMMSG SI_LINUX #define SANITIZER_INTERCEPT_SENDMMSG SI_LINUX +#define SANITIZER_INTERCEPT_SYSMSG SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_GETPEERNAME SI_POSIX #define SANITIZER_INTERCEPT_IOCTL SI_POSIX #define SANITIZER_INTERCEPT_INET_ATON SI_POSIX @@ -341,7 +342,7 @@ #define SANITIZER_INTERCEPT_STATFS \ (SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_STATFS64 \ - ((SI_MAC && !SI_IOS) || SI_LINUX_NOT_ANDROID) + (((SI_MAC && !TARGET_CPU_ARM64) && !SI_IOS) || SI_LINUX_NOT_ANDROID) #define SANITIZER_INTERCEPT_STATVFS \ (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID) #define SANITIZER_INTERCEPT_STATVFS64 SI_LINUX_NOT_ANDROID @@ -544,7 +545,8 @@ #define SANITIZER_INTERCEPT_FGETLN (SI_NETBSD || SI_FREEBSD) #define SANITIZER_INTERCEPT_STRMODE (SI_NETBSD || SI_FREEBSD) #define SANITIZER_INTERCEPT_TTYENT SI_NETBSD -#define SANITIZER_INTERCEPT_PROTOENT SI_NETBSD +#define SANITIZER_INTERCEPT_PROTOENT (SI_NETBSD || SI_LINUX) +#define SANITIZER_INTERCEPT_PROTOENT_R (SI_LINUX_NOT_ANDROID) #define SANITIZER_INTERCEPT_NETENT SI_NETBSD #define SANITIZER_INTERCEPT_SETVBUF (SI_NETBSD || SI_FREEBSD || \ SI_LINUX || SI_MAC) @@ -596,7 +598,10 @@ #define SANITIZER_INTERCEPT_QSORT \ (SI_POSIX && !SI_IOSSIM && !SI_WATCHOS && !SI_TVOS && !SI_ANDROID) #define SANITIZER_INTERCEPT_QSORT_R (SI_LINUX && !SI_ANDROID) -#define SANITIZER_INTERCEPT_SIGALTSTACK SI_POSIX +// sigaltstack on i386 macOS cannot be intercepted due to setjmp() +// calling it and assuming that it does not clobber registers. +#define SANITIZER_INTERCEPT_SIGALTSTACK \ + (SI_POSIX && !(SANITIZER_MAC && SANITIZER_I386)) #define SANITIZER_INTERCEPT_UNAME (SI_POSIX && !SI_FREEBSD) #define SANITIZER_INTERCEPT___XUNAME SI_FREEBSD diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h index d80280d9bf8c8..ae54a8cf105ee 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h @@ -129,12 +129,6 @@ struct __sanitizer_shmid_ds { void *_shm_internal; }; -struct __sanitizer_protoent { - char *p_name; - char **p_aliases; - int p_proto; -}; - struct __sanitizer_netent { char *n_name; char **n_aliases; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp index e71515f12e94e..c052aa2bc9509 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp @@ -170,9 +170,9 @@ typedef struct user_fpregs elf_fpregset_t; namespace __sanitizer { unsigned struct_utsname_sz = sizeof(struct utsname); unsigned struct_stat_sz = sizeof(struct stat); -#if !SANITIZER_IOS +#if !SANITIZER_IOS && !(SANITIZER_MAC && TARGET_CPU_ARM64) unsigned struct_stat64_sz = sizeof(struct stat64); -#endif // !SANITIZER_IOS +#endif // !SANITIZER_IOS && !(SANITIZER_MAC && TARGET_CPU_ARM64) unsigned struct_rusage_sz = sizeof(struct rusage); unsigned struct_tm_sz = sizeof(struct tm); unsigned struct_passwd_sz = sizeof(struct passwd); @@ -197,9 +197,9 @@ namespace __sanitizer { unsigned struct_regex_sz = sizeof(regex_t); unsigned struct_regmatch_sz = sizeof(regmatch_t); -#if SANITIZER_MAC && !SANITIZER_IOS +#if (SANITIZER_MAC && !TARGET_CPU_ARM64) && !SANITIZER_IOS unsigned struct_statfs64_sz = sizeof(struct statfs64); -#endif // SANITIZER_MAC && !SANITIZER_IOS +#endif // (SANITIZER_MAC && !TARGET_CPU_ARM64) && !SANITIZER_IOS #if !SANITIZER_ANDROID unsigned struct_fstab_sz = sizeof(struct fstab); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h index f6c8a1450a932..658b0abaece82 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -704,6 +704,12 @@ struct __sanitizer_dl_phdr_info { extern unsigned struct_ElfW_Phdr_sz; #endif +struct __sanitizer_protoent { + char *p_name; + char **p_aliases; + int p_proto; +}; + struct __sanitizer_addrinfo { int ai_flags; int ai_family; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp index d7b931bc23795..3c379a8480250 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp @@ -78,13 +78,6 @@ static void InitializeSwiftDemangler() { // Attempts to demangle a Swift name. The demangler will return nullptr if a // non-Swift name is passed in. const char *DemangleSwift(const char *name) { - if (!name) return nullptr; - - // Check if we are dealing with a Swift mangled name first. - if (name[0] != '_' || name[1] != 'T') { - return nullptr; - } - if (swift_demangle_f) return swift_demangle_f(name, internal_strlen(name), 0, 0, 0); @@ -321,9 +314,10 @@ class Addr2LinePool : public SymbolizerTool { #if SANITIZER_SUPPORTS_WEAK_HOOKS extern "C" { -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE -bool __sanitizer_symbolize_code(const char *ModuleName, u64 ModuleOffset, - char *Buffer, int MaxLength); +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE bool +__sanitizer_symbolize_code(const char *ModuleName, u64 ModuleOffset, + char *Buffer, int MaxLength, + bool SymbolizeInlineFrames); SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE bool __sanitizer_symbolize_data(const char *ModuleName, u64 ModuleOffset, char *Buffer, int MaxLength); @@ -346,7 +340,8 @@ class InternalSymbolizer : public SymbolizerTool { bool SymbolizePC(uptr addr, SymbolizedStack *stack) override { bool result = __sanitizer_symbolize_code( - stack->info.module, stack->info.module_offset, buffer_, kBufferSize); + stack->info.module, stack->info.module_offset, buffer_, kBufferSize, + common_flags()->symbolize_inline_frames); if (result) ParseSymbolizePCOutput(buffer_, stack); return result; } diff --git a/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cpp b/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cpp index ba285bc1e8844..4902be0bf51ec 100644 --- a/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cpp +++ b/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include + #include #include "llvm/DebugInfo/Symbolize/DIPrinter.h" @@ -32,17 +33,25 @@ extern "C" { typedef uint64_t u64; bool __sanitizer_symbolize_code(const char *ModuleName, uint64_t ModuleOffset, - char *Buffer, int MaxLength) { + char *Buffer, int MaxLength, + bool SymbolizeInlineFrames) { std::string Result; { llvm::raw_string_ostream OS(Result); llvm::symbolize::DIPrinter Printer(OS); // TODO: it is neccessary to set proper SectionIndex here. // object::SectionedAddress::UndefSection works for only absolute addresses. - auto ResOrErr = getDefaultSymbolizer()->symbolizeInlinedCode( - ModuleName, - {ModuleOffset, llvm::object::SectionedAddress::UndefSection}); - Printer << (ResOrErr ? ResOrErr.get() : llvm::DIInliningInfo()); + if (SymbolizeInlineFrames) { + auto ResOrErr = getDefaultSymbolizer()->symbolizeInlinedCode( + ModuleName, + {ModuleOffset, llvm::object::SectionedAddress::UndefSection}); + Printer << (ResOrErr ? ResOrErr.get() : llvm::DIInliningInfo()); + } else { + auto ResOrErr = getDefaultSymbolizer()->symbolizeCode( + ModuleName, + {ModuleOffset, llvm::object::SectionedAddress::UndefSection}); + Printer << (ResOrErr ? ResOrErr.get() : llvm::DILineInfo()); + } } return __sanitizer::internal_snprintf(Buffer, MaxLength, "%s", Result.c_str()) < MaxLength; diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_mac_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_mac_test.cpp index b327ba96e2239..c8658ea55d034 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_mac_test.cpp +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_mac_test.cpp @@ -24,8 +24,12 @@ namespace __sanitizer { TEST(SanitizerMac, GetMacosAlignedVersion) { MacosVersion vers = GetMacosAlignedVersion(); - EXPECT_EQ(vers.major, 10); - EXPECT_EQ(vers.minor, GetDarwinKernelVersion().major - 4); + u16 kernel_major = GetDarwinKernelVersion().major; + bool macos_11 = (kernel_major >= 20); + u16 expected_major = macos_11 ? (kernel_major - 9) : 10; + u16 expected_minor = macos_11 ? 0 : (kernel_major - 4); + EXPECT_EQ(vers.major, expected_major); + EXPECT_EQ(vers.minor, expected_minor); } void ParseVersion(const char *vers, u16 *major, u16 *minor); diff --git a/compiler-rt/test/builtins/Unit/clzdi2_test.c b/compiler-rt/test/builtins/Unit/clzdi2_test.c index 3cbfb4b68b0dc..962f1dff45113 100644 --- a/compiler-rt/test/builtins/Unit/clzdi2_test.c +++ b/compiler-rt/test/builtins/Unit/clzdi2_test.c @@ -8,11 +8,11 @@ // Precondition: a != 0 -COMPILER_RT_ABI si_int __clzdi2(di_int a); +COMPILER_RT_ABI int __clzdi2(di_int a); -int test__clzdi2(di_int a, si_int expected) +int test__clzdi2(di_int a, int expected) { - si_int x = __clzdi2(a); + int x = __clzdi2(a); if (x != expected) printf("error in __clzdi2(0x%llX) = %d, expected %d\n", a, x, expected); return x != expected; diff --git a/compiler-rt/test/builtins/Unit/clzsi2_test.c b/compiler-rt/test/builtins/Unit/clzsi2_test.c index d12c59cf56a54..57562c497c5d0 100644 --- a/compiler-rt/test/builtins/Unit/clzsi2_test.c +++ b/compiler-rt/test/builtins/Unit/clzsi2_test.c @@ -8,11 +8,11 @@ // Precondition: a != 0 -COMPILER_RT_ABI si_int __clzsi2(si_int a); +COMPILER_RT_ABI int __clzsi2(si_int a); -int test__clzsi2(si_int a, si_int expected) +int test__clzsi2(si_int a, int expected) { - si_int x = __clzsi2(a); + int x = __clzsi2(a); if (x != expected) printf("error in __clzsi2(0x%X) = %d, expected %d\n", a, x, expected); return x != expected; diff --git a/compiler-rt/test/builtins/Unit/clzti2_test.c b/compiler-rt/test/builtins/Unit/clzti2_test.c index 3dbf907540210..13e0e698422f2 100644 --- a/compiler-rt/test/builtins/Unit/clzti2_test.c +++ b/compiler-rt/test/builtins/Unit/clzti2_test.c @@ -11,11 +11,11 @@ // Precondition: a != 0 -COMPILER_RT_ABI si_int __clzti2(ti_int a); +COMPILER_RT_ABI int __clzti2(ti_int a); -int test__clzti2(ti_int a, si_int expected) +int test__clzti2(ti_int a, int expected) { - si_int x = __clzti2(a); + int x = __clzti2(a); if (x != expected) { twords at; diff --git a/compiler-rt/test/builtins/Unit/ctzsi2_test.c b/compiler-rt/test/builtins/Unit/ctzsi2_test.c index 96db33983cc48..db6d4ce6a1621 100644 --- a/compiler-rt/test/builtins/Unit/ctzsi2_test.c +++ b/compiler-rt/test/builtins/Unit/ctzsi2_test.c @@ -8,11 +8,11 @@ // Precondition: a != 0 -COMPILER_RT_ABI si_int __ctzsi2(si_int a); +COMPILER_RT_ABI int __ctzsi2(si_int a); -int test__ctzsi2(si_int a, si_int expected) +int test__ctzsi2(si_int a, int expected) { - si_int x = __ctzsi2(a); + int x = __ctzsi2(a); if (x != expected) printf("error in __ctzsi2(0x%X) = %d, expected %d\n", a, x, expected); return x != expected; diff --git a/compiler-rt/test/builtins/Unit/ctzti2_test.c b/compiler-rt/test/builtins/Unit/ctzti2_test.c index a19de13c9a074..054776ef71cff 100644 --- a/compiler-rt/test/builtins/Unit/ctzti2_test.c +++ b/compiler-rt/test/builtins/Unit/ctzti2_test.c @@ -11,11 +11,11 @@ // Precondition: a != 0 -COMPILER_RT_ABI si_int __ctzti2(ti_int a); +COMPILER_RT_ABI int __ctzti2(ti_int a); -int test__ctzti2(ti_int a, si_int expected) +int test__ctzti2(ti_int a, int expected) { - si_int x = __ctzti2(a); + int x = __ctzti2(a); if (x != expected) { twords at; diff --git a/compiler-rt/test/builtins/Unit/ffsti2_test.c b/compiler-rt/test/builtins/Unit/ffsti2_test.c index 3ec7f02bca453..446b16fe3871c 100644 --- a/compiler-rt/test/builtins/Unit/ffsti2_test.c +++ b/compiler-rt/test/builtins/Unit/ffsti2_test.c @@ -10,11 +10,11 @@ // Returns: the index of the least significant 1-bit in a, or // the value zero if a is zero. The least significant bit is index one. -COMPILER_RT_ABI si_int __ffsti2(ti_int a); +COMPILER_RT_ABI int __ffsti2(ti_int a); -int test__ffsti2(ti_int a, si_int expected) +int test__ffsti2(ti_int a, int expected) { - si_int x = __ffsti2(a); + int x = __ffsti2(a); if (x != expected) { twords at; diff --git a/compiler-rt/test/builtins/Unit/lit.cfg.py b/compiler-rt/test/builtins/Unit/lit.cfg.py index 8fdb1a216ee26..c8888078be507 100644 --- a/compiler-rt/test/builtins/Unit/lit.cfg.py +++ b/compiler-rt/test/builtins/Unit/lit.cfg.py @@ -5,6 +5,17 @@ import lit.formats +# Choose between lit's internal shell pipeline runner and a real shell. If +# LIT_USE_INTERNAL_SHELL is in the environment, we use that as an override. +use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL") +if use_lit_shell: + # 0 is external, "" is default, and everything else is internal. + execute_external = (use_lit_shell == "0") +else: + # Otherwise we default to internal on Windows and external elsewhere, as + # bash on Windows is usually very slow. + execute_external = (not sys.platform in ['win32']) + def get_required_attr(config, attr_name): attr_value = getattr(config, attr_name, None) if attr_value == None: @@ -35,10 +46,16 @@ def get_required_attr(config, attr_name): else: base_lib = os.path.join(config.compiler_rt_libdir, "libclang_rt.builtins%s.a" % config.target_suffix) + if sys.platform in ['win32'] and execute_external: + # Don't pass dosish path separator to msys bash.exe. + base_lib = base_lib.replace('\\', '/') config.substitutions.append( ("%librt ", base_lib + ' -lc -lm ') ) builtins_source_dir = os.path.join( get_required_attr(config, "compiler_rt_src_root"), "lib", "builtins") +if sys.platform in ['win32'] and execute_external: + # Don't pass dosish path separator to msys bash.exe. + builtins_source_dir = builtins_source_dir.replace('\\', '/') builtins_lit_source_dir = get_required_attr(config, "builtins_lit_source_dir") extra_link_flags = ["-nodefaultlibs"] diff --git a/compiler-rt/test/builtins/Unit/paritydi2_test.c b/compiler-rt/test/builtins/Unit/paritydi2_test.c index 13218a9beeb62..2ea1ddc0977d8 100644 --- a/compiler-rt/test/builtins/Unit/paritydi2_test.c +++ b/compiler-rt/test/builtins/Unit/paritydi2_test.c @@ -7,7 +7,7 @@ // Returns: 1 if number of bits is odd else returns 0 -COMPILER_RT_ABI si_int __paritydi2(di_int a); +COMPILER_RT_ABI int __paritydi2(di_int a); int naive_parity(di_int a) { diff --git a/compiler-rt/test/builtins/Unit/paritysi2_test.c b/compiler-rt/test/builtins/Unit/paritysi2_test.c index 7aae131b7b07b..2bed010d9d4ad 100644 --- a/compiler-rt/test/builtins/Unit/paritysi2_test.c +++ b/compiler-rt/test/builtins/Unit/paritysi2_test.c @@ -7,7 +7,7 @@ // Returns: 1 if number of bits is odd else returns 0 -COMPILER_RT_ABI si_int __paritysi2(si_int a); +COMPILER_RT_ABI int __paritysi2(si_int a); int naive_parity(si_int a) { diff --git a/compiler-rt/test/builtins/Unit/parityti2_test.c b/compiler-rt/test/builtins/Unit/parityti2_test.c index 6644ee0ef0fa0..ec4cf45bf30d4 100644 --- a/compiler-rt/test/builtins/Unit/parityti2_test.c +++ b/compiler-rt/test/builtins/Unit/parityti2_test.c @@ -10,7 +10,7 @@ // Returns: 1 if number of bits is odd else returns 0 -COMPILER_RT_ABI si_int __parityti2(ti_int a); +COMPILER_RT_ABI int __parityti2(ti_int a); int naive_parity(ti_int a) { diff --git a/compiler-rt/test/builtins/Unit/popcountsi2_test.c b/compiler-rt/test/builtins/Unit/popcountsi2_test.c index 731e6212c06fc..7689267514744 100644 --- a/compiler-rt/test/builtins/Unit/popcountsi2_test.c +++ b/compiler-rt/test/builtins/Unit/popcountsi2_test.c @@ -7,7 +7,7 @@ // Returns: count of 1 bits -COMPILER_RT_ABI si_int __popcountsi2(si_int a); +COMPILER_RT_ABI int __popcountsi2(si_int a); int naive_popcount(si_int a) { diff --git a/compiler-rt/test/builtins/Unit/popcountti2_test.c b/compiler-rt/test/builtins/Unit/popcountti2_test.c index 53edd8c43b933..c3919dccdcb8c 100644 --- a/compiler-rt/test/builtins/Unit/popcountti2_test.c +++ b/compiler-rt/test/builtins/Unit/popcountti2_test.c @@ -10,7 +10,7 @@ // Returns: count of 1 bits -COMPILER_RT_ABI si_int __popcountti2(ti_int a); +COMPILER_RT_ABI int __popcountti2(ti_int a); int naive_popcount(ti_int a) { diff --git a/compiler-rt/test/builtins/Unit/powidf2_test.c b/compiler-rt/test/builtins/Unit/powidf2_test.c index 0c4e2138734bd..aa16b8542dae3 100644 --- a/compiler-rt/test/builtins/Unit/powidf2_test.c +++ b/compiler-rt/test/builtins/Unit/powidf2_test.c @@ -7,9 +7,9 @@ // Returns: a ^ b -COMPILER_RT_ABI double __powidf2(double a, si_int b); +COMPILER_RT_ABI double __powidf2(double a, int b); -int test__powidf2(double a, si_int b, double expected) +int test__powidf2(double a, int b, double expected) { double x = __powidf2(a, b); int correct = (x == expected) && (signbit(x) == signbit(expected)); @@ -51,9 +51,9 @@ int main() return 1; if (test__powidf2(0, 4, 0)) return 1; - if (test__powidf2(0, 0x7FFFFFFE, 0)) + if (test__powidf2(0, INT_MAX - 1, 0)) return 1; - if (test__powidf2(0, 0x7FFFFFFF, 0)) + if (test__powidf2(0, INT_MAX, 0)) return 1; if (test__powidf2(-0., 1, -0.)) @@ -64,9 +64,9 @@ int main() return 1; if (test__powidf2(-0., 4, 0)) return 1; - if (test__powidf2(-0., 0x7FFFFFFE, 0)) + if (test__powidf2(-0., INT_MAX - 1, 0)) return 1; - if (test__powidf2(-0., 0x7FFFFFFF, -0.)) + if (test__powidf2(-0., INT_MAX, -0.)) return 1; if (test__powidf2(1, 1, 1)) @@ -77,9 +77,9 @@ int main() return 1; if (test__powidf2(1, 4, 1)) return 1; - if (test__powidf2(1, 0x7FFFFFFE, 1)) + if (test__powidf2(1, INT_MAX - 1, 1)) return 1; - if (test__powidf2(1, 0x7FFFFFFF, 1)) + if (test__powidf2(1, INT_MAX, 1)) return 1; if (test__powidf2(INFINITY, 1, INFINITY)) @@ -90,9 +90,9 @@ int main() return 1; if (test__powidf2(INFINITY, 4, INFINITY)) return 1; - if (test__powidf2(INFINITY, 0x7FFFFFFE, INFINITY)) + if (test__powidf2(INFINITY, INT_MAX - 1, INFINITY)) return 1; - if (test__powidf2(INFINITY, 0x7FFFFFFF, INFINITY)) + if (test__powidf2(INFINITY, INT_MAX, INFINITY)) return 1; if (test__powidf2(-INFINITY, 1, -INFINITY)) @@ -103,9 +103,9 @@ int main() return 1; if (test__powidf2(-INFINITY, 4, INFINITY)) return 1; - if (test__powidf2(-INFINITY, 0x7FFFFFFE, INFINITY)) + if (test__powidf2(-INFINITY, INT_MAX - 1, INFINITY)) return 1; - if (test__powidf2(-INFINITY, 0x7FFFFFFF, -INFINITY)) + if (test__powidf2(-INFINITY, INT_MAX, -INFINITY)) return 1; if (test__powidf2(0, -1, INFINITY)) @@ -116,11 +116,11 @@ int main() return 1; if (test__powidf2(0, -4, INFINITY)) return 1; - if (test__powidf2(0, 0x80000002, INFINITY)) + if (test__powidf2(0, INT_MIN + 2, INFINITY)) return 1; - if (test__powidf2(0, 0x80000001, INFINITY)) + if (test__powidf2(0, INT_MIN + 1, INFINITY)) return 1; - if (test__powidf2(0, 0x80000000, INFINITY)) + if (test__powidf2(0, INT_MIN, INFINITY)) return 1; if (test__powidf2(-0., -1, -INFINITY)) @@ -131,11 +131,11 @@ int main() return 1; if (test__powidf2(-0., -4, INFINITY)) return 1; - if (test__powidf2(-0., 0x80000002, INFINITY)) + if (test__powidf2(-0., INT_MIN + 2, INFINITY)) return 1; - if (test__powidf2(-0., 0x80000001, -INFINITY)) + if (test__powidf2(-0., INT_MIN + 1, -INFINITY)) return 1; - if (test__powidf2(-0., 0x80000000, INFINITY)) + if (test__powidf2(-0., INT_MIN, INFINITY)) return 1; if (test__powidf2(1, -1, 1)) @@ -146,11 +146,11 @@ int main() return 1; if (test__powidf2(1, -4, 1)) return 1; - if (test__powidf2(1, 0x80000002, 1)) + if (test__powidf2(1, INT_MIN + 2, 1)) return 1; - if (test__powidf2(1, 0x80000001, 1)) + if (test__powidf2(1, INT_MIN + 1, 1)) return 1; - if (test__powidf2(1, 0x80000000, 1)) + if (test__powidf2(1, INT_MIN, 1)) return 1; if (test__powidf2(INFINITY, -1, 0)) @@ -161,11 +161,11 @@ int main() return 1; if (test__powidf2(INFINITY, -4, 0)) return 1; - if (test__powidf2(INFINITY, 0x80000002, 0)) + if (test__powidf2(INFINITY, INT_MIN + 2, 0)) return 1; - if (test__powidf2(INFINITY, 0x80000001, 0)) + if (test__powidf2(INFINITY, INT_MIN + 1, 0)) return 1; - if (test__powidf2(INFINITY, 0x80000000, 0)) + if (test__powidf2(INFINITY, INT_MIN, 0)) return 1; if (test__powidf2(-INFINITY, -1, -0.)) @@ -176,11 +176,11 @@ int main() return 1; if (test__powidf2(-INFINITY, -4, 0)) return 1; - if (test__powidf2(-INFINITY, 0x80000002, 0)) + if (test__powidf2(-INFINITY, INT_MIN + 2, 0)) return 1; - if (test__powidf2(-INFINITY, 0x80000001, -0.)) + if (test__powidf2(-INFINITY, INT_MIN + 1, -0.)) return 1; - if (test__powidf2(-INFINITY, 0x80000000, 0)) + if (test__powidf2(-INFINITY, INT_MIN, 0)) return 1; if (test__powidf2(2, 10, 1024.)) diff --git a/compiler-rt/test/builtins/Unit/powisf2_test.c b/compiler-rt/test/builtins/Unit/powisf2_test.c index e86901d574ad3..6da42d908d048 100644 --- a/compiler-rt/test/builtins/Unit/powisf2_test.c +++ b/compiler-rt/test/builtins/Unit/powisf2_test.c @@ -7,9 +7,9 @@ // Returns: a ^ b -COMPILER_RT_ABI float __powisf2(float a, si_int b); +COMPILER_RT_ABI float __powisf2(float a, int b); -int test__powisf2(float a, si_int b, float expected) +int test__powisf2(float a, int b, float expected) { float x = __powisf2(a, b); int correct = (x == expected) && (signbit(x) == signbit(expected)); @@ -51,9 +51,9 @@ int main() return 1; if (test__powisf2(0, 4, 0)) return 1; - if (test__powisf2(0, 0x7FFFFFFE, 0)) + if (test__powisf2(0, INT_MAX -1, 0)) return 1; - if (test__powisf2(0, 0x7FFFFFFF, 0)) + if (test__powisf2(0, INT_MAX, 0)) return 1; if (test__powisf2(-0., 1, -0.)) @@ -64,9 +64,9 @@ int main() return 1; if (test__powisf2(-0., 4, 0)) return 1; - if (test__powisf2(-0., 0x7FFFFFFE, 0)) + if (test__powisf2(-0., INT_MAX - 1, 0)) return 1; - if (test__powisf2(-0., 0x7FFFFFFF, -0.)) + if (test__powisf2(-0., INT_MAX, -0.)) return 1; if (test__powisf2(1, 1, 1)) @@ -77,9 +77,9 @@ int main() return 1; if (test__powisf2(1, 4, 1)) return 1; - if (test__powisf2(1, 0x7FFFFFFE, 1)) + if (test__powisf2(1, INT_MAX - 1, 1)) return 1; - if (test__powisf2(1, 0x7FFFFFFF, 1)) + if (test__powisf2(1, INT_MAX, 1)) return 1; if (test__powisf2(INFINITY, 1, INFINITY)) @@ -90,9 +90,9 @@ int main() return 1; if (test__powisf2(INFINITY, 4, INFINITY)) return 1; - if (test__powisf2(INFINITY, 0x7FFFFFFE, INFINITY)) + if (test__powisf2(INFINITY, INT_MAX - 1, INFINITY)) return 1; - if (test__powisf2(INFINITY, 0x7FFFFFFF, INFINITY)) + if (test__powisf2(INFINITY, INT_MAX, INFINITY)) return 1; if (test__powisf2(-INFINITY, 1, -INFINITY)) @@ -103,9 +103,9 @@ int main() return 1; if (test__powisf2(-INFINITY, 4, INFINITY)) return 1; - if (test__powisf2(-INFINITY, 0x7FFFFFFE, INFINITY)) + if (test__powisf2(-INFINITY, INT_MAX - 1, INFINITY)) return 1; - if (test__powisf2(-INFINITY, 0x7FFFFFFF, -INFINITY)) + if (test__powisf2(-INFINITY, INT_MAX, -INFINITY)) return 1; if (test__powisf2(0, -1, INFINITY)) @@ -116,11 +116,11 @@ int main() return 1; if (test__powisf2(0, -4, INFINITY)) return 1; - if (test__powisf2(0, 0x80000002, INFINITY)) + if (test__powisf2(0, INT_MIN + 2, INFINITY)) return 1; - if (test__powisf2(0, 0x80000001, INFINITY)) + if (test__powisf2(0, INT_MIN + 1, INFINITY)) return 1; - if (test__powisf2(0, 0x80000000, INFINITY)) + if (test__powisf2(0, INT_MIN, INFINITY)) return 1; if (test__powisf2(-0., -1, -INFINITY)) @@ -131,11 +131,11 @@ int main() return 1; if (test__powisf2(-0., -4, INFINITY)) return 1; - if (test__powisf2(-0., 0x80000002, INFINITY)) + if (test__powisf2(-0., INT_MIN + 2, INFINITY)) return 1; - if (test__powisf2(-0., 0x80000001, -INFINITY)) + if (test__powisf2(-0., INT_MIN + 1, -INFINITY)) return 1; - if (test__powisf2(-0., 0x80000000, INFINITY)) + if (test__powisf2(-0., INT_MIN, INFINITY)) return 1; if (test__powisf2(1, -1, 1)) @@ -146,11 +146,11 @@ int main() return 1; if (test__powisf2(1, -4, 1)) return 1; - if (test__powisf2(1, 0x80000002, 1)) + if (test__powisf2(1, INT_MIN + 2, 1)) return 1; - if (test__powisf2(1, 0x80000001, 1)) + if (test__powisf2(1, INT_MIN + 1, 1)) return 1; - if (test__powisf2(1, 0x80000000, 1)) + if (test__powisf2(1, INT_MIN, 1)) return 1; if (test__powisf2(INFINITY, -1, 0)) @@ -161,11 +161,11 @@ int main() return 1; if (test__powisf2(INFINITY, -4, 0)) return 1; - if (test__powisf2(INFINITY, 0x80000002, 0)) + if (test__powisf2(INFINITY, INT_MIN + 2, 0)) return 1; - if (test__powisf2(INFINITY, 0x80000001, 0)) + if (test__powisf2(INFINITY, INT_MIN + 1, 0)) return 1; - if (test__powisf2(INFINITY, 0x80000000, 0)) + if (test__powisf2(INFINITY, INT_MIN, 0)) return 1; if (test__powisf2(-INFINITY, -1, -0.)) @@ -176,11 +176,11 @@ int main() return 1; if (test__powisf2(-INFINITY, -4, 0)) return 1; - if (test__powisf2(-INFINITY, 0x80000002, 0)) + if (test__powisf2(-INFINITY, INT_MIN + 2, 0)) return 1; - if (test__powisf2(-INFINITY, 0x80000001, -0.)) + if (test__powisf2(-INFINITY, INT_MIN + 1, -0.)) return 1; - if (test__powisf2(-INFINITY, 0x80000000, 0)) + if (test__powisf2(-INFINITY, INT_MIN, 0)) return 1; if (test__powisf2(2, 10, 1024.)) diff --git a/compiler-rt/test/builtins/Unit/powitf2_test.c b/compiler-rt/test/builtins/Unit/powitf2_test.c index be16c5f45c32c..81331098730ac 100644 --- a/compiler-rt/test/builtins/Unit/powitf2_test.c +++ b/compiler-rt/test/builtins/Unit/powitf2_test.c @@ -10,9 +10,9 @@ // Returns: a ^ b -COMPILER_RT_ABI long double __powitf2(long double a, si_int b); +COMPILER_RT_ABI long double __powitf2(long double a, int b); -int test__powitf2(long double a, si_int b, long double expected) +int test__powitf2(long double a, int b, long double expected) { long double x = __powitf2(a, b); int correct = (x == expected) && (signbit(x) == signbit(expected)); @@ -57,9 +57,9 @@ int main() return 1; if (test__powitf2(0, 4, 0)) return 1; - if (test__powitf2(0, 0x7FFFFFFE, 0)) + if (test__powitf2(0, INT_MAX - 1, 0)) return 1; - if (test__powitf2(0, 0x7FFFFFFF, 0)) + if (test__powitf2(0, INT_MAX, 0)) return 1; if (test__powitf2(-0., 1, -0.)) @@ -70,9 +70,9 @@ int main() return 1; if (test__powitf2(-0., 4, 0)) return 1; - if (test__powitf2(-0., 0x7FFFFFFE, 0)) + if (test__powitf2(-0., INT_MAX - 1, 0)) return 1; - if (test__powitf2(-0., 0x7FFFFFFF, -0.)) + if (test__powitf2(-0., INT_MAX, -0.)) return 1; if (test__powitf2(1, 1, 1)) @@ -83,9 +83,9 @@ int main() return 1; if (test__powitf2(1, 4, 1)) return 1; - if (test__powitf2(1, 0x7FFFFFFE, 1)) + if (test__powitf2(1, INT_MAX - 1, 1)) return 1; - if (test__powitf2(1, 0x7FFFFFFF, 1)) + if (test__powitf2(1, INT_MAX, 1)) return 1; if (test__powitf2(INFINITY, 1, INFINITY)) @@ -96,9 +96,9 @@ int main() return 1; if (test__powitf2(INFINITY, 4, INFINITY)) return 1; - if (test__powitf2(INFINITY, 0x7FFFFFFE, INFINITY)) + if (test__powitf2(INFINITY, INT_MAX - 1, INFINITY)) return 1; - if (test__powitf2(INFINITY, 0x7FFFFFFF, INFINITY)) + if (test__powitf2(INFINITY, INT_MAX, INFINITY)) return 1; if (test__powitf2(-INFINITY, 1, -INFINITY)) @@ -109,9 +109,9 @@ int main() return 1; if (test__powitf2(-INFINITY, 4, INFINITY)) return 1; - if (test__powitf2(-INFINITY, 0x7FFFFFFE, INFINITY)) + if (test__powitf2(-INFINITY, INT_MAX - 1, INFINITY)) return 1; - if (test__powitf2(-INFINITY, 0x7FFFFFFF, -INFINITY)) + if (test__powitf2(-INFINITY, INT_MAX, -INFINITY)) return 1; if (test__powitf2(0, -1, INFINITY)) @@ -122,11 +122,11 @@ int main() return 1; if (test__powitf2(0, -4, INFINITY)) return 1; - if (test__powitf2(0, 0x80000002, INFINITY)) + if (test__powitf2(0, INT_MIN + 2, INFINITY)) return 1; - if (test__powitf2(0, 0x80000001, INFINITY)) + if (test__powitf2(0, INT_MIN + 1, INFINITY)) return 1; - if (test__powitf2(0, 0x80000000, INFINITY)) + if (test__powitf2(0, INT_MIN, INFINITY)) return 1; if (test__powitf2(-0., -1, -INFINITY)) @@ -137,11 +137,11 @@ int main() return 1; if (test__powitf2(-0., -4, INFINITY)) return 1; - if (test__powitf2(-0., 0x80000002, INFINITY)) + if (test__powitf2(-0., INT_MIN + 2, INFINITY)) return 1; - if (test__powitf2(-0., 0x80000001, -INFINITY)) + if (test__powitf2(-0., INT_MIN + 1, -INFINITY)) return 1; - if (test__powitf2(-0., 0x80000000, INFINITY)) + if (test__powitf2(-0., INT_MIN, INFINITY)) return 1; if (test__powitf2(1, -1, 1)) @@ -152,11 +152,11 @@ int main() return 1; if (test__powitf2(1, -4, 1)) return 1; - if (test__powitf2(1, 0x80000002, 1)) + if (test__powitf2(1, INT_MIN + 2, 1)) return 1; - if (test__powitf2(1, 0x80000001, 1)) + if (test__powitf2(1, INT_MIN + 1, 1)) return 1; - if (test__powitf2(1, 0x80000000, 1)) + if (test__powitf2(1, INT_MIN, 1)) return 1; if (test__powitf2(INFINITY, -1, 0)) @@ -167,11 +167,11 @@ int main() return 1; if (test__powitf2(INFINITY, -4, 0)) return 1; - if (test__powitf2(INFINITY, 0x80000002, 0)) + if (test__powitf2(INFINITY, INT_MIN + 2, 0)) return 1; - if (test__powitf2(INFINITY, 0x80000001, 0)) + if (test__powitf2(INFINITY, INT_MIN + 1, 0)) return 1; - if (test__powitf2(INFINITY, 0x80000000, 0)) + if (test__powitf2(INFINITY, INT_MIN, 0)) return 1; if (test__powitf2(-INFINITY, -1, -0.)) @@ -182,11 +182,11 @@ int main() return 1; if (test__powitf2(-INFINITY, -4, 0)) return 1; - if (test__powitf2(-INFINITY, 0x80000002, 0)) + if (test__powitf2(-INFINITY, INT_MIN + 2, 0)) return 1; - if (test__powitf2(-INFINITY, 0x80000001, -0.)) + if (test__powitf2(-INFINITY, INT_MIN + 1, -0.)) return 1; - if (test__powitf2(-INFINITY, 0x80000000, 0)) + if (test__powitf2(-INFINITY, INT_MIN, 0)) return 1; if (test__powitf2(2, 10, 1024.)) diff --git a/compiler-rt/test/builtins/Unit/powixf2_test.c b/compiler-rt/test/builtins/Unit/powixf2_test.c index 5ce3e522af458..856012ab32dbb 100644 --- a/compiler-rt/test/builtins/Unit/powixf2_test.c +++ b/compiler-rt/test/builtins/Unit/powixf2_test.c @@ -11,9 +11,9 @@ // Returns: a ^ b -COMPILER_RT_ABI long double __powixf2(long double a, si_int b); +COMPILER_RT_ABI long double __powixf2(long double a, int b); -int test__powixf2(long double a, si_int b, long double expected) +int test__powixf2(long double a, int b, long double expected) { long double x = __powixf2(a, b); int correct = (x == expected) && (signbit(x) == signbit(expected)); @@ -58,9 +58,9 @@ int main() return 1; if (test__powixf2(0, 4, 0)) return 1; - if (test__powixf2(0, 0x7FFFFFFE, 0)) + if (test__powixf2(0, INT_MAX - 1, 0)) return 1; - if (test__powixf2(0, 0x7FFFFFFF, 0)) + if (test__powixf2(0, INT_MAX, 0)) return 1; if (test__powixf2(-0., 1, -0.)) @@ -71,9 +71,9 @@ int main() return 1; if (test__powixf2(-0., 4, 0)) return 1; - if (test__powixf2(-0., 0x7FFFFFFE, 0)) + if (test__powixf2(-0., INT_MAX - 1, 0)) return 1; - if (test__powixf2(-0., 0x7FFFFFFF, -0.)) + if (test__powixf2(-0., INT_MAX, -0.)) return 1; if (test__powixf2(1, 1, 1)) @@ -84,9 +84,9 @@ int main() return 1; if (test__powixf2(1, 4, 1)) return 1; - if (test__powixf2(1, 0x7FFFFFFE, 1)) + if (test__powixf2(1, INT_MAX - 1, 1)) return 1; - if (test__powixf2(1, 0x7FFFFFFF, 1)) + if (test__powixf2(1, INT_MAX, 1)) return 1; if (test__powixf2(INFINITY, 1, INFINITY)) @@ -97,9 +97,9 @@ int main() return 1; if (test__powixf2(INFINITY, 4, INFINITY)) return 1; - if (test__powixf2(INFINITY, 0x7FFFFFFE, INFINITY)) + if (test__powixf2(INFINITY, INT_MAX - 1, INFINITY)) return 1; - if (test__powixf2(INFINITY, 0x7FFFFFFF, INFINITY)) + if (test__powixf2(INFINITY, INT_MAX, INFINITY)) return 1; if (test__powixf2(-INFINITY, 1, -INFINITY)) @@ -110,9 +110,9 @@ int main() return 1; if (test__powixf2(-INFINITY, 4, INFINITY)) return 1; - if (test__powixf2(-INFINITY, 0x7FFFFFFE, INFINITY)) + if (test__powixf2(-INFINITY, INT_MAX - 1, INFINITY)) return 1; - if (test__powixf2(-INFINITY, 0x7FFFFFFF, -INFINITY)) + if (test__powixf2(-INFINITY, INT_MAX, -INFINITY)) return 1; if (test__powixf2(0, -1, INFINITY)) @@ -123,11 +123,11 @@ int main() return 1; if (test__powixf2(0, -4, INFINITY)) return 1; - if (test__powixf2(0, 0x80000002, INFINITY)) + if (test__powixf2(0, INT_MIN + 2, INFINITY)) return 1; - if (test__powixf2(0, 0x80000001, INFINITY)) + if (test__powixf2(0, INT_MIN + 1, INFINITY)) return 1; - if (test__powixf2(0, 0x80000000, INFINITY)) + if (test__powixf2(0, INT_MIN, INFINITY)) return 1; if (test__powixf2(-0., -1, -INFINITY)) @@ -138,11 +138,11 @@ int main() return 1; if (test__powixf2(-0., -4, INFINITY)) return 1; - if (test__powixf2(-0., 0x80000002, INFINITY)) + if (test__powixf2(-0., INT_MIN + 2, INFINITY)) return 1; - if (test__powixf2(-0., 0x80000001, -INFINITY)) + if (test__powixf2(-0., INT_MIN + 1, -INFINITY)) return 1; - if (test__powixf2(-0., 0x80000000, INFINITY)) + if (test__powixf2(-0., INT_MIN, INFINITY)) return 1; if (test__powixf2(1, -1, 1)) @@ -153,11 +153,11 @@ int main() return 1; if (test__powixf2(1, -4, 1)) return 1; - if (test__powixf2(1, 0x80000002, 1)) + if (test__powixf2(1, INT_MIN + 2, 1)) return 1; - if (test__powixf2(1, 0x80000001, 1)) + if (test__powixf2(1, INT_MIN + 1, 1)) return 1; - if (test__powixf2(1, 0x80000000, 1)) + if (test__powixf2(1, INT_MIN, 1)) return 1; if (test__powixf2(INFINITY, -1, 0)) @@ -168,11 +168,11 @@ int main() return 1; if (test__powixf2(INFINITY, -4, 0)) return 1; - if (test__powixf2(INFINITY, 0x80000002, 0)) + if (test__powixf2(INFINITY, INT_MIN + 2, 0)) return 1; - if (test__powixf2(INFINITY, 0x80000001, 0)) + if (test__powixf2(INFINITY, INT_MIN + 1, 0)) return 1; - if (test__powixf2(INFINITY, 0x80000000, 0)) + if (test__powixf2(INFINITY, INT_MIN, 0)) return 1; if (test__powixf2(-INFINITY, -1, -0.)) @@ -183,11 +183,11 @@ int main() return 1; if (test__powixf2(-INFINITY, -4, 0)) return 1; - if (test__powixf2(-INFINITY, 0x80000002, 0)) + if (test__powixf2(-INFINITY, INT_MIN + 2, 0)) return 1; - if (test__powixf2(-INFINITY, 0x80000001, -0.)) + if (test__powixf2(-INFINITY, INT_MIN + 1, -0.)) return 1; - if (test__powixf2(-INFINITY, 0x80000000, 0)) + if (test__powixf2(-INFINITY, INT_MIN, 0)) return 1; if (test__powixf2(2, 10, 1024.)) diff --git a/compiler-rt/test/crt/lit.cfg.py b/compiler-rt/test/crt/lit.cfg.py index dc15e456fe199..68e7eda7d59ba 100644 --- a/compiler-rt/test/crt/lit.cfg.py +++ b/compiler-rt/test/crt/lit.cfg.py @@ -26,15 +26,15 @@ def get_library_path(file): config.target_cflags.strip(), '-print-file-name=%s' % file], stdout=subprocess.PIPE, - env=config.environment) + env=config.environment, + universal_newlines=True) if not cmd.stdout: lit_config.fatal("Couldn't find the library path for '%s'" % file) dir = cmd.stdout.read().strip() if sys.platform in ['win32'] and execute_external: # Don't pass dosish path separator to msys bash.exe. dir = dir.replace('\\', '/') - # Ensure the result is an ascii string, across Python2.5+ - Python3. - return str(dir.decode('ascii')) + return dir def get_libgcc_file_name(): @@ -42,15 +42,15 @@ def get_libgcc_file_name(): config.target_cflags.strip(), '-print-libgcc-file-name'], stdout=subprocess.PIPE, - env=config.environment) + env=config.environment, + universal_newlines=True) if not cmd.stdout: lit_config.fatal("Couldn't find the library path for '%s'" % file) dir = cmd.stdout.read().strip() if sys.platform in ['win32'] and execute_external: # Don't pass dosish path separator to msys bash.exe. dir = dir.replace('\\', '/') - # Ensure the result is an ascii string, across Python2.5+ - Python3. - return str(dir.decode('ascii')) + return dir def build_invocation(compile_flags): @@ -66,6 +66,11 @@ def build_invocation(compile_flags): base_lib = os.path.join( config.compiler_rt_libdir, "clang_rt.%%s%s.o" % config.target_suffix) + +if sys.platform in ['win32'] and execute_external: + # Don't pass dosish path separator to msys bash.exe. + base_lib = base_lib.replace('\\', '/') + config.substitutions.append(('%crtbegin', base_lib % "crtbegin")) config.substitutions.append(('%crtend', base_lib % "crtend")) diff --git a/compiler-rt/test/lit.common.cfg.py b/compiler-rt/test/lit.common.cfg.py index 98a2f3c03e609..9d0c214bd9a76 100644 --- a/compiler-rt/test/lit.common.cfg.py +++ b/compiler-rt/test/lit.common.cfg.py @@ -23,6 +23,9 @@ # bash on Windows is usually very slow. execute_external = (not sys.platform in ['win32']) +# Allow expanding substitutions that are based on other substitutions +config.recursiveExpansionLimit = 10 + # Setup test format. config.test_format = lit.formats.ShTest(execute_external) if execute_external: diff --git a/compiler-rt/test/lit.common.configured.in b/compiler-rt/test/lit.common.configured.in index a0203c0855651..4a3e268c8a6f9 100644 --- a/compiler-rt/test/lit.common.configured.in +++ b/compiler-rt/test/lit.common.configured.in @@ -48,6 +48,11 @@ config.available_features.add('target-is-%s' % config.target_arch) if config.enable_per_target_runtime_dir: set_default("target_suffix", "") +elif config.android: + if config.target_arch == "i386": + set_default("target_suffix", "-i686-android") + else: + set_default("target_suffix", "-%s-android" % config.target_arch) else: set_default("target_suffix", "-%s" % config.target_arch) diff --git a/compiler-rt/test/msan/sigwait.cpp b/compiler-rt/test/msan/sigwait.cpp index 222fc34a16982..80f3f21ffff3b 100644 --- a/compiler-rt/test/msan/sigwait.cpp +++ b/compiler-rt/test/msan/sigwait.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -19,7 +20,9 @@ void test_sigwait() { if (pid_t pid = fork()) { kill(pid, SIGUSR1); - _exit(0); + int child_stat; + wait(&child_stat); + _exit(!WIFEXITED(child_stat)); } else { int sig; int res = sigwait(&s, &sig); diff --git a/compiler-rt/test/profile/ContinuousSyncMode/online-merging.c b/compiler-rt/test/profile/ContinuousSyncMode/online-merging.c index a9f32b9c51e15..b3c33f339713c 100644 --- a/compiler-rt/test/profile/ContinuousSyncMode/online-merging.c +++ b/compiler-rt/test/profile/ContinuousSyncMode/online-merging.c @@ -8,9 +8,9 @@ // Create two DSOs and a driver program that uses them. // RUN: echo "void dso1(void) {}" > dso1.c // RUN: echo "void dso2(void) {}" > dso2.c -// RUN: %clang_pgogen -dynamiclib -o %t.dir/dso1.dylib dso1.c -// RUN: %clang_pgogen -dynamiclib -o %t.dir/dso2.dylib dso2.c -// RUN: %clang_pgogen -o main.exe %s %t.dir/dso1.dylib %t.dir/dso2.dylib +// RUN: %clang_pgogen -dynamiclib -o %t.dir/dso1.dylib dso1.c -mllvm -instrprof-atomic-counter-update-all=1 +// RUN: %clang_pgogen -dynamiclib -o %t.dir/dso2.dylib dso2.c -mllvm -instrprof-atomic-counter-update-all=1 +// RUN: %clang_pgogen -o main.exe %s %t.dir/dso1.dylib %t.dir/dso2.dylib -mllvm -instrprof-atomic-counter-update-all=1 // // === Round 1 === // Test merging+continuous mode without any file contention. diff --git a/compiler-rt/test/profile/Inputs/instrprof-gcov-__gcov_flush-multiple.c b/compiler-rt/test/profile/Inputs/instrprof-gcov-__gcov_flush-multiple.c deleted file mode 100644 index 56e0538b1e830..0000000000000 --- a/compiler-rt/test/profile/Inputs/instrprof-gcov-__gcov_flush-multiple.c +++ /dev/null @@ -1,18 +0,0 @@ -extern void __gcov_flush(); -extern int remove(const char *); -int main(void) { - __gcov_flush(); - - if (remove("instrprof-gcov-__gcov_flush-multiple.gcda") != 0) { - return 1; - } - - __gcov_flush(); - __gcov_flush(); - - if (remove("instrprof-gcov-__gcov_flush-multiple.gcda") != 0) { - return 1; - } - - return 0; -} diff --git a/compiler-rt/test/profile/Inputs/instrprof-gcov-__gcov_flush-multiple.c.gcov b/compiler-rt/test/profile/Inputs/instrprof-gcov-__gcov_flush-multiple.c.gcov deleted file mode 100644 index b0921d22461e2..0000000000000 --- a/compiler-rt/test/profile/Inputs/instrprof-gcov-__gcov_flush-multiple.c.gcov +++ /dev/null @@ -1,23 +0,0 @@ -// CHECK: -: 0:Source:{{.*}}Inputs{{[/\\]}}instrprof-gcov-__gcov_flush-multiple.c -// CHECK-NEXT: -: 0:Graph:instrprof-gcov-__gcov_flush-multiple.gcno -// CHECK-NEXT: -: 0:Data:instrprof-gcov-__gcov_flush-multiple.gcda -// CHECK-NEXT: -: 0:Runs:1 -// CHECK-NEXT: -: 0:Programs:1 -// CHECK-NEXT: -: 1:extern void __gcov_flush(); -// CHECK-NEXT: -: 2:extern int remove(const char *); -// CHECK-NEXT: #####: 3:int main(void) { -// CHECK-NEXT: #####: 4: __gcov_flush(); -// CHECK-NEXT: -: 5: -// CHECK-NEXT: #####: 6: if (remove("instrprof-gcov-__gcov_flush-multiple.gcda") != 0) { -// CHECK-NEXT: #####: 7: return 1; -// CHECK-NEXT: -: 8: } -// CHECK-NEXT: -: 9: -// CHECK-NEXT: #####: 10: __gcov_flush(); -// CHECK-NEXT: #####: 11: __gcov_flush(); -// CHECK-NEXT: -: 12: -// CHECK-NEXT: #####: 13: if (remove("instrprof-gcov-__gcov_flush-multiple.gcda") != 0) { -// CHECK-NEXT: #####: 14: return 1; -// CHECK-NEXT: -: 15: } -// CHECK-NEXT: -: 16: -// CHECK-NEXT: 1: 17: return 0; -// CHECK-NEXT: 1: 18:} diff --git a/compiler-rt/test/profile/Inputs/instrprof-gcov-execlp.c b/compiler-rt/test/profile/Inputs/instrprof-gcov-execlp.c deleted file mode 100644 index 5213a5b80360e..0000000000000 --- a/compiler-rt/test/profile/Inputs/instrprof-gcov-execlp.c +++ /dev/null @@ -1,15 +0,0 @@ -#include - -void func1() {} -void func2() {} - -int main(void) -{ - func1(); - - execlp("ls", "-l", "-h", (char*)0); - - func2(); - - return 0; -} diff --git a/compiler-rt/test/profile/Inputs/instrprof-gcov-execlp.c.gcov b/compiler-rt/test/profile/Inputs/instrprof-gcov-execlp.c.gcov deleted file mode 100644 index 810046aac396f..0000000000000 --- a/compiler-rt/test/profile/Inputs/instrprof-gcov-execlp.c.gcov +++ /dev/null @@ -1,23 +0,0 @@ -//CHECK: -: 0:Source:{{.*}}Inputs{{[/\\]}}instrprof-gcov-execlp.c -//CHECK-NEXT: -: 0:Graph:instrprof-gcov-execlp.gcno -//CHECK-NEXT: -: 0:Data:instrprof-gcov-execlp.gcda -//CHECK-NEXT: -: 0:Runs:1 -//CHECK-NEXT: -: 0:Programs:1 -//CHECK-NEXT: -: 1:#include -//CHECK-NEXT: -: 2: -//CHECK-NEXT:function func1 called 1 returned 100% blocks executed 100% -//CHECK-NEXT: 1: 3:void func1() {} -//CHECK-NEXT:function func2 called 0 returned 0% blocks executed 0% -//CHECK-NEXT: #####: 4:void func2() {} -//CHECK-NEXT: -: 5: -//CHECK-NEXT:function main called 1 returned 0% blocks executed 33% -//CHECK-NEXT: 1: 6:int main(void) -//CHECK-NEXT: -: 7:{ -//CHECK-NEXT: 1: 8: func1(); -//CHECK-NEXT: -: 9: -//CHECK-NEXT: 1: 10: execlp("ls", "-l", "-h", (char*)0); -//CHECK-NEXT: -: 11: -//CHECK-NEXT: #####: 12: func2(); -//CHECK-NEXT: -: 13: -//CHECK-NEXT: #####: 14: return 0; -//CHECK-NEXT: -: 15:} diff --git a/compiler-rt/test/profile/Inputs/instrprof-gcov-execvp.c b/compiler-rt/test/profile/Inputs/instrprof-gcov-execvp.c deleted file mode 100644 index f2e411c2a42e8..0000000000000 --- a/compiler-rt/test/profile/Inputs/instrprof-gcov-execvp.c +++ /dev/null @@ -1,17 +0,0 @@ -#include - -void func1() {} -void func2() {} - -int main(void) -{ - char *const args[] = {"-l", "-h", (char*)0}; - - func1(); - - execvp("ls", args); - - func2(); - - return 0; -} diff --git a/compiler-rt/test/profile/Inputs/instrprof-gcov-execvp.c.gcov b/compiler-rt/test/profile/Inputs/instrprof-gcov-execvp.c.gcov deleted file mode 100644 index e896cb8917e70..0000000000000 --- a/compiler-rt/test/profile/Inputs/instrprof-gcov-execvp.c.gcov +++ /dev/null @@ -1,25 +0,0 @@ -//CHECK: -: 0:Source:{{.*}}Inputs{{[/\\]}}instrprof-gcov-execvp.c -//CHECK-NEXT: -: 0:Graph:instrprof-gcov-execvp.gcno -//CHECK-NEXT: -: 0:Data:instrprof-gcov-execvp.gcda -//CHECK-NEXT: -: 0:Runs:1 -//CHECK-NEXT: -: 0:Programs:1 -//CHECK-NEXT: -: 1:#include -//CHECK-NEXT: -: 2: -//CHECK-NEXT:function func1 called 1 returned 100% blocks executed 100% -//CHECK-NEXT: 1: 3:void func1() {} -//CHECK-NEXT:function func2 called 0 returned 0% blocks executed 0% -//CHECK-NEXT: #####: 4:void func2() {} -//CHECK-NEXT: -: 5: -//CHECK-NEXT:function main called 1 returned 0% blocks executed 33% -//CHECK-NEXT: 1: 6:int main(void) -//CHECK-NEXT: -: 7:{ -//CHECK-NEXT: 1: 8: char *const args[] = {"-l", "-h", (char*)0}; -//CHECK-NEXT: -: 9: -//CHECK-NEXT: 1: 10: func1(); -//CHECK-NEXT: -: 11: -//CHECK-NEXT: 1: 12: execvp("ls", args); -//CHECK-NEXT: -: 13: -//CHECK-NEXT: #####: 14: func2(); -//CHECK-NEXT: -: 15: -//CHECK-NEXT: #####: 16: return 0; -//CHECK-NEXT: -: 17:} diff --git a/compiler-rt/test/profile/Inputs/instrprof-gcov-fork.c b/compiler-rt/test/profile/Inputs/instrprof-gcov-fork.c deleted file mode 100644 index 818c459c50ddc..0000000000000 --- a/compiler-rt/test/profile/Inputs/instrprof-gcov-fork.c +++ /dev/null @@ -1,15 +0,0 @@ -#include - -void func1() {} -void func2() {} - -int main(void) -{ - func1(); - - fork(); - - func2(); - - return 0; -} diff --git a/compiler-rt/test/profile/Inputs/instrprof-gcov-fork.c.gcov b/compiler-rt/test/profile/Inputs/instrprof-gcov-fork.c.gcov deleted file mode 100644 index 2825bd5802a79..0000000000000 --- a/compiler-rt/test/profile/Inputs/instrprof-gcov-fork.c.gcov +++ /dev/null @@ -1,23 +0,0 @@ -// CHECK: -: 0:Source:{{.*}}Inputs{{[/\\]}}instrprof-gcov-fork.c -// CHECK-NEXT: -: 0:Graph:instrprof-gcov-fork.gcno -// CHECK-NEXT: -: 0:Data:instrprof-gcov-fork.gcda -// CHECK-NEXT: -: 0:Runs:1 -// CHECK-NEXT: -: 0:Programs:1 -// CHECK-NEXT: -: 1:#include -// CHECK-NEXT: -: 2: -// CHECK-NEXT:function func1 called 1 returned 100% blocks executed 100% -// CHECK-NEXT: 1: 3:void func1() {} -// CHECK-NEXT:function func2 called 2 returned 100% blocks executed 100% -// CHECK-NEXT: 2: 4:void func2() {} -// CHECK-NEXT: -: 5: -// CHECK-NEXT:function main called 1 returned 200% blocks executed 100% -// CHECK-NEXT: 1: 6:int main(void) -// CHECK-NEXT: -: 7:{ -// CHECK-NEXT: 1: 8: func1(); -// CHECK-NEXT: -: 9: -// CHECK-NEXT: 1: 10: fork(); -// CHECK-NEXT: -: 11: -// CHECK-NEXT: 2: 12: func2(); -// CHECK-NEXT: -: 13: -// CHECK-NEXT: 2: 14: return 0; -// CHECK-NEXT: -: 15:} diff --git a/compiler-rt/test/profile/Inputs/instrprof-shared-lib.c.gcov b/compiler-rt/test/profile/Inputs/instrprof-shared-lib.c.gcov deleted file mode 100644 index 7e6d741d5b104..0000000000000 --- a/compiler-rt/test/profile/Inputs/instrprof-shared-lib.c.gcov +++ /dev/null @@ -1,14 +0,0 @@ -// CHECK: -: 0:Source:{{.*}}Inputs{{[/\\]}}instrprof-shared-lib.c -// CHECK-NEXT: -: 0:Graph:instrprof-shared-lib.gcno -// CHECK-NEXT: -: 0:Data:instrprof-shared-lib.gcda -// CHECK-NEXT: -: 0:Runs:1 -// CHECK-NEXT: -: 0:Programs:1 -// CHECK-NEXT: -: 1:int g1 = 0; -// CHECK-NEXT: -: 2:int g2 = 1; -// CHECK-NEXT: -: 3: -// CHECK-NEXT: 1: 4:void foo(int n) { -// CHECK-NEXT: 1: 5: if (n % 5 == 0) -// CHECK-NEXT: #####: 6: g1++; -// CHECK-NEXT: -: 7: else -// CHECK-NEXT: 1: 8: g2++; -// CHECK-NEXT: 1: 9:} diff --git a/compiler-rt/test/profile/Inputs/instrprof-shared-lib_called-twice.c.gcov b/compiler-rt/test/profile/Inputs/instrprof-shared-lib_called-twice.c.gcov deleted file mode 100644 index 993c6cc508b28..0000000000000 --- a/compiler-rt/test/profile/Inputs/instrprof-shared-lib_called-twice.c.gcov +++ /dev/null @@ -1,14 +0,0 @@ -// CHECK: -: 0:Source:{{.*}}Inputs{{[/\\]}}instrprof-shared-lib.c -// CHECK-NEXT: -: 0:Graph:instrprof-shared-lib.gcno -// CHECK-NEXT: -: 0:Data:instrprof-shared-lib.gcda -// CHECK-NEXT: -: 0:Runs:1 -// CHECK-NEXT: -: 0:Programs:1 -// CHECK-NEXT: -: 1:int g1 = 0; -// CHECK-NEXT: -: 2:int g2 = 1; -// CHECK-NEXT: -: 3: -// CHECK-NEXT: 2: 4:void foo(int n) { -// CHECK-NEXT: 2: 5: if (n % 5 == 0) -// CHECK-NEXT: #####: 6: g1++; -// CHECK-NEXT: -: 7: else -// CHECK-NEXT: 2: 8: g2++; -// CHECK-NEXT: 2: 9:} diff --git a/compiler-rt/test/profile/Inputs/instrprof-shared-main-gcov-flush.c b/compiler-rt/test/profile/Inputs/instrprof-shared-main-gcov-flush.c deleted file mode 100644 index 9f41b7e6362aa..0000000000000 --- a/compiler-rt/test/profile/Inputs/instrprof-shared-main-gcov-flush.c +++ /dev/null @@ -1,36 +0,0 @@ -extern void foo(int n); -extern void __gcov_flush(void); - -int bar1 = 0; -int bar2 = 1; - -void bar(int n) { - if (n % 5 == 0) - bar1++; - else - bar2++; -} - -int main(int argc, char *argv[]) { -#ifdef SHARED_CALL_BEFORE_GCOV_FLUSH - foo(1); -#endif - - bar(5); - - __gcov_flush(); - - bar(5); - -#ifdef SHARED_CALL_AFTER_GCOV_FLUSH - foo(1); -#endif - -#ifdef EXIT_ABRUPTLY - _exit(0); -#endif - - bar(5); - - return 0; -} diff --git a/compiler-rt/test/profile/Inputs/instrprof-shared-main-gcov-flush_no-writeout.c.gcov b/compiler-rt/test/profile/Inputs/instrprof-shared-main-gcov-flush_no-writeout.c.gcov deleted file mode 100644 index 82a489158a33a..0000000000000 --- a/compiler-rt/test/profile/Inputs/instrprof-shared-main-gcov-flush_no-writeout.c.gcov +++ /dev/null @@ -1,41 +0,0 @@ -// CHECK: -: 0:Source:{{.*}}Inputs{{[/\\]}}instrprof-shared-main-gcov-flush.c -// CHECK-NEXT: -: 0:Graph:instrprof-shared-main-gcov-flush.gcno -// CHECK-NEXT: -: 0:Data:instrprof-shared-main-gcov-flush.gcda -// CHECK-NEXT: -: 0:Runs:1 -// CHECK-NEXT: -: 0:Programs:1 -// CHECK-NEXT: -: 1:extern void foo(int n); -// CHECK-NEXT: -: 2:extern void __gcov_flush(void); -// CHECK-NEXT: -: 3: -// CHECK-NEXT: -: 4:int bar1 = 0; -// CHECK-NEXT: -: 5:int bar2 = 1; -// CHECK-NEXT: -: 6: -// CHECK-NEXT: 1: 7:void bar(int n) { -// CHECK-NEXT: 1: 8: if (n % 5 == 0) -// CHECK-NEXT: 1: 9: bar1++; -// CHECK-NEXT: -: 10: else -// CHECK-NEXT: #####: 11: bar2++; -// CHECK-NEXT: 1: 12:} -// CHECK-NEXT: -: 13: -// CHECK-NEXT: 1: 14:int main(int argc, char *argv[]) { -// CHECK-NEXT: -: 15:#ifdef SHARED_CALL_BEFORE_GCOV_FLUSH -// CHECK-NEXT: 1: 16: foo(1); -// CHECK-NEXT: -: 17:#endif -// CHECK-NEXT: -: 18: -// CHECK-NEXT: 1: 19: bar(5); -// CHECK-NEXT: -: 20: -// CHECK-NEXT: 1: 21: __gcov_flush(); -// CHECK-NEXT: -: 22: -// CHECK-NEXT: 1: 23: bar(5); -// CHECK-NEXT: -: 24: -// CHECK-NEXT: -: 25:#ifdef SHARED_CALL_AFTER_GCOV_FLUSH -// CHECK-NEXT: 1: 26: foo(1); -// CHECK-NEXT: -: 27:#endif -// CHECK-NEXT: -: 28: -// CHECK-NEXT: -: 29:#ifdef EXIT_ABRUPTLY -// CHECK-NEXT: 1: 30: _exit(0); -// CHECK-NEXT: -: 31:#endif -// CHECK-NEXT: -: 32: -// CHECK-NEXT: -: 33: bar(5); -// CHECK-NEXT: -: 34: -// CHECK-NEXT: -: 35: return 0; -// CHECK-NEXT: -: 36:} diff --git a/compiler-rt/test/profile/Inputs/instrprof-shared-main-gcov-flush_shared-call-after.c.gcov b/compiler-rt/test/profile/Inputs/instrprof-shared-main-gcov-flush_shared-call-after.c.gcov deleted file mode 100644 index 5cc26580b2226..0000000000000 --- a/compiler-rt/test/profile/Inputs/instrprof-shared-main-gcov-flush_shared-call-after.c.gcov +++ /dev/null @@ -1,41 +0,0 @@ -// CHECK: -: 0:Source:{{.*}}Inputs{{[/\\]}}instrprof-shared-main-gcov-flush.c -// CHECK-NEXT: -: 0:Graph:instrprof-shared-main-gcov-flush.gcno -// CHECK-NEXT: -: 0:Data:instrprof-shared-main-gcov-flush.gcda -// CHECK-NEXT: -: 0:Runs:1 -// CHECK-NEXT: -: 0:Programs:1 -// CHECK-NEXT: -: 1:extern void foo(int n); -// CHECK-NEXT: -: 2:extern void __gcov_flush(void); -// CHECK-NEXT: -: 3: -// CHECK-NEXT: -: 4:int bar1 = 0; -// CHECK-NEXT: -: 5:int bar2 = 1; -// CHECK-NEXT: -: 6: -// CHECK-NEXT: 3: 7:void bar(int n) { -// CHECK-NEXT: 3: 8: if (n % 5 == 0) -// CHECK-NEXT: 3: 9: bar1++; -// CHECK-NEXT: -: 10: else -// CHECK-NEXT: #####: 11: bar2++; -// CHECK-NEXT: 3: 12:} -// CHECK-NEXT: -: 13: -// CHECK-NEXT: 1: 14:int main(int argc, char *argv[]) { -// CHECK-NEXT: -: 15:#ifdef SHARED_CALL_BEFORE_GCOV_FLUSH -// CHECK-NEXT: -: 16: foo(1); -// CHECK-NEXT: -: 17:#endif -// CHECK-NEXT: -: 18: -// CHECK-NEXT: 1: 19: bar(5); -// CHECK-NEXT: -: 20: -// CHECK-NEXT: 1: 21: __gcov_flush(); -// CHECK-NEXT: -: 22: -// CHECK-NEXT: 1: 23: bar(5); -// CHECK-NEXT: -: 24: -// CHECK-NEXT: -: 25:#ifdef SHARED_CALL_AFTER_GCOV_FLUSH -// CHECK-NEXT: 1: 26: foo(1); -// CHECK-NEXT: -: 27:#endif -// CHECK-NEXT: -: 28: -// CHECK-NEXT: -: 29:#ifdef EXIT_ABRUPTLY -// CHECK-NEXT: -: 30: _exit(0); -// CHECK-NEXT: -: 31:#endif -// CHECK-NEXT: -: 32: -// CHECK-NEXT: 1: 33: bar(5); -// CHECK-NEXT: -: 34: -// CHECK-NEXT: 1: 35: return 0; -// CHECK-NEXT: -: 36:} diff --git a/compiler-rt/test/profile/Inputs/instrprof-shared-main-gcov-flush_shared-call-before-after.c.gcov b/compiler-rt/test/profile/Inputs/instrprof-shared-main-gcov-flush_shared-call-before-after.c.gcov deleted file mode 100644 index 7a6800c47f84f..0000000000000 --- a/compiler-rt/test/profile/Inputs/instrprof-shared-main-gcov-flush_shared-call-before-after.c.gcov +++ /dev/null @@ -1,41 +0,0 @@ -// CHECK: -: 0:Source:{{.*}}Inputs{{[/\\]}}instrprof-shared-main-gcov-flush.c -// CHECK-NEXT: -: 0:Graph:instrprof-shared-main-gcov-flush.gcno -// CHECK-NEXT: -: 0:Data:instrprof-shared-main-gcov-flush.gcda -// CHECK-NEXT: -: 0:Runs:1 -// CHECK-NEXT: -: 0:Programs:1 -// CHECK-NEXT: -: 1:extern void foo(int n); -// CHECK-NEXT: -: 2:extern void __gcov_flush(void); -// CHECK-NEXT: -: 3: -// CHECK-NEXT: -: 4:int bar1 = 0; -// CHECK-NEXT: -: 5:int bar2 = 1; -// CHECK-NEXT: -: 6: -// CHECK-NEXT: 3: 7:void bar(int n) { -// CHECK-NEXT: 3: 8: if (n % 5 == 0) -// CHECK-NEXT: 3: 9: bar1++; -// CHECK-NEXT: -: 10: else -// CHECK-NEXT: #####: 11: bar2++; -// CHECK-NEXT: 3: 12:} -// CHECK-NEXT: -: 13: -// CHECK-NEXT: 1: 14:int main(int argc, char *argv[]) { -// CHECK-NEXT: -: 15:#ifdef SHARED_CALL_BEFORE_GCOV_FLUSH -// CHECK-NEXT: 1: 16: foo(1); -// CHECK-NEXT: -: 17:#endif -// CHECK-NEXT: -: 18: -// CHECK-NEXT: 1: 19: bar(5); -// CHECK-NEXT: -: 20: -// CHECK-NEXT: 1: 21: __gcov_flush(); -// CHECK-NEXT: -: 22: -// CHECK-NEXT: 1: 23: bar(5); -// CHECK-NEXT: -: 24: -// CHECK-NEXT: -: 25:#ifdef SHARED_CALL_AFTER_GCOV_FLUSH -// CHECK-NEXT: 1: 26: foo(1); -// CHECK-NEXT: -: 27:#endif -// CHECK-NEXT: -: 28: -// CHECK-NEXT: -: 29:#ifdef EXIT_ABRUPTLY -// CHECK-NEXT: -: 30: _exit(0); -// CHECK-NEXT: -: 31:#endif -// CHECK-NEXT: -: 32: -// CHECK-NEXT: 1: 33: bar(5); -// CHECK-NEXT: -: 34: -// CHECK-NEXT: 1: 35: return 0; -// CHECK-NEXT: -: 36:} diff --git a/compiler-rt/test/profile/Inputs/instrprof-shared-main-gcov-flush_shared-call-before.c.gcov b/compiler-rt/test/profile/Inputs/instrprof-shared-main-gcov-flush_shared-call-before.c.gcov deleted file mode 100644 index 49995fdc86350..0000000000000 --- a/compiler-rt/test/profile/Inputs/instrprof-shared-main-gcov-flush_shared-call-before.c.gcov +++ /dev/null @@ -1,41 +0,0 @@ -// CHECK: -: 0:Source:{{.*}}Inputs{{[/\\]}}instrprof-shared-main-gcov-flush.c -// CHECK-NEXT: -: 0:Graph:instrprof-shared-main-gcov-flush.gcno -// CHECK-NEXT: -: 0:Data:instrprof-shared-main-gcov-flush.gcda -// CHECK-NEXT: -: 0:Runs:1 -// CHECK-NEXT: -: 0:Programs:1 -// CHECK-NEXT: -: 1:extern void foo(int n); -// CHECK-NEXT: -: 2:extern void __gcov_flush(void); -// CHECK-NEXT: -: 3: -// CHECK-NEXT: -: 4:int bar1 = 0; -// CHECK-NEXT: -: 5:int bar2 = 1; -// CHECK-NEXT: -: 6: -// CHECK-NEXT: 3: 7:void bar(int n) { -// CHECK-NEXT: 3: 8: if (n % 5 == 0) -// CHECK-NEXT: 3: 9: bar1++; -// CHECK-NEXT: -: 10: else -// CHECK-NEXT: #####: 11: bar2++; -// CHECK-NEXT: 3: 12:} -// CHECK-NEXT: -: 13: -// CHECK-NEXT: 1: 14:int main(int argc, char *argv[]) { -// CHECK-NEXT: -: 15:#ifdef SHARED_CALL_BEFORE_GCOV_FLUSH -// CHECK-NEXT: 1: 16: foo(1); -// CHECK-NEXT: -: 17:#endif -// CHECK-NEXT: -: 18: -// CHECK-NEXT: 1: 19: bar(5); -// CHECK-NEXT: -: 20: -// CHECK-NEXT: 1: 21: __gcov_flush(); -// CHECK-NEXT: -: 22: -// CHECK-NEXT: 1: 23: bar(5); -// CHECK-NEXT: -: 24: -// CHECK-NEXT: -: 25:#ifdef SHARED_CALL_AFTER_GCOV_FLUSH -// CHECK-NEXT: -: 26: foo(1); -// CHECK-NEXT: -: 27:#endif -// CHECK-NEXT: -: 28: -// CHECK-NEXT: -: 29:#ifdef EXIT_ABRUPTLY -// CHECK-NEXT: -: 30: _exit(0); -// CHECK-NEXT: -: 31:#endif -// CHECK-NEXT: -: 32: -// CHECK-NEXT: 1: 33: bar(5); -// CHECK-NEXT: -: 34: -// CHECK-NEXT: 1: 35: return 0; -// CHECK-NEXT: -: 36:} diff --git a/compiler-rt/test/profile/Posix/gcov-destructor.c b/compiler-rt/test/profile/Posix/gcov-destructor.c new file mode 100644 index 0000000000000..c6fa144bcb39f --- /dev/null +++ b/compiler-rt/test/profile/Posix/gcov-destructor.c @@ -0,0 +1,34 @@ +/// Test that destructors and destructors whose priorities are greater than 100 are tracked. +// RUN: mkdir -p %t.dir && cd %t.dir +// RUN: %clang --coverage %s -o %t +// RUN: rm -f gcov-destructor.gcda && %run %t +// RUN: llvm-cov gcov -t gcov-destructor.gcda | FileCheck %s +// UNSUPPORTED: darwin + +#include + +void before_exec() {} // CHECK: 1: [[#@LINE]]:void before_exec +void after_exec() {} // CHECK-NEXT: 1: [[#@LINE]]:void after_exec + +__attribute__((constructor)) // CHECK: -: [[#@LINE]]:__attribute__ +void constructor() {} // CHECK-NEXT: 1: [[#@LINE]]: + +/// Runs before __llvm_gcov_writeout. +__attribute__((destructor)) // CHECK: -: [[#@LINE]]:__attribute__ +void destructor() {} // CHECK-NEXT: 1: [[#@LINE]]: + +__attribute__((destructor(101))) // CHECK: -: [[#@LINE]]:__attribute__ +void destructor_101() {} // CHECK-NEXT: 1: [[#@LINE]]: + +/// Runs after __llvm_gcov_writeout. +__attribute__((destructor(99))) // CHECK: -: [[#@LINE]]:__attribute__ +void destructor_99() {} // CHECK-NEXT: #####: [[#@LINE]]: + +int main() { + before_exec(); + // Implicit writeout. + execl("/not_exist", "not_exist", (char *)0); + // Still tracked. + after_exec(); + return 0; +} diff --git a/compiler-rt/test/profile/Posix/gcov-execlp.c b/compiler-rt/test/profile/Posix/gcov-execlp.c new file mode 100644 index 0000000000000..0b70e9c697904 --- /dev/null +++ b/compiler-rt/test/profile/Posix/gcov-execlp.c @@ -0,0 +1,28 @@ +/// A basic block with fork/exec* is split. .gcda is flushed immediately before +/// fork/exec* so the lines before exec* are counted once while succeeding +/// lines are not counted. +// RUN: mkdir -p %t.d && cd %t.d +// RUN: %clang --coverage %s -o %t +// RUN: test -f gcov-execlp.gcno +// RUN: rm -f gcov-execlp.gcda && %run %t +// RUN: llvm-cov gcov -t gcov-execlp.gcda | FileCheck %s --check-prefixes=CHECK,EXECLP + +// RUN: %clang --coverage -DEXECVP %s -o %t +// RUN: rm -f gcov-execlp.gcda && %run %t +// RUN: llvm-cov gcov -t gcov-execlp.gcda | FileCheck %s --check-prefixes=CHECK,EXECVP + +#include + +void func1(void) {} // CHECK: 1: [[#@LINE]]:void func1(void) +void func2(void) {} // CHECK-NEXT: #####: [[#@LINE]]: +int main(void) { // CHECK-NEXT: 1: [[#@LINE]]: + func1(); // CHECK-NEXT: 1: [[#@LINE]]: +#ifdef EXECVP + char *argv[] = {"ls", "-l", "-h", (char *)0}; + execvp("ls", argv); // EXECVP: 1: [[#@LINE]]: execvp +#else + execlp("ls", "-l", "-h", (char *)0); // EXECLP: 1: [[#@LINE]]: execlp +#endif + func2(); // CHECK: #####: [[#@LINE]]: func2 + return 0; // CHECK-NEXT: #####: [[#@LINE]]: +} diff --git a/compiler-rt/test/profile/Posix/gcov-fork.c b/compiler-rt/test/profile/Posix/gcov-fork.c new file mode 100644 index 0000000000000..4942d5ac92888 --- /dev/null +++ b/compiler-rt/test/profile/Posix/gcov-fork.c @@ -0,0 +1,24 @@ +/// A basic block with fork/exec* is split. .gcda is flushed immediately before +/// fork/exec* so the lines before fork are counted once while succeeding +/// lines are counted twice. +// UNSUPPORTED: darwin +/// FIXME: http://lab.llvm.org:8011/builders/clang-ppc64be-linux/builds/50913 +// UNSUPPORTED: host-byteorder-big-endian + +// RUN: mkdir -p %t.d && cd %t.d +// RUN: %clang --coverage %s -o %t +// RUN: test -f gcov-fork.gcno + +// RUN: rm -f gcov-fork.gcda && %run %t +// RUN: llvm-cov gcov -t gcov-fork.gcda | FileCheck %s + +#include + +void func1() {} // CHECK: 1: [[#@LINE]]:void func1() +void func2() {} // CHECK-NEXT: 2: [[#@LINE]]: +int main(void) { // CHECK-NEXT: 1: [[#@LINE]]: + func1(); // CHECK-NEXT: 1: [[#@LINE]]: + if (fork() == -1) return 1; // CHECK-NEXT: 1: [[#@LINE]]: + func2(); // CHECK-NEXT: 2: [[#@LINE]]: + return 0; // CHECK-NEXT: 2: [[#@LINE]]: +} diff --git a/compiler-rt/test/profile/Posix/gcov-shared-flush.c b/compiler-rt/test/profile/Posix/gcov-shared-flush.c new file mode 100644 index 0000000000000..97d44ad5204e1 --- /dev/null +++ b/compiler-rt/test/profile/Posix/gcov-shared-flush.c @@ -0,0 +1,113 @@ +/// This test fails on Mac (https://bugs.llvm.org/show_bug.cgi?id=38134) +// XFAIL: darwin + +// RUN: mkdir -p %t.d && cd %t.d + +// RUN: %clang -E -DSHARED %s -o shared.c +// RUN: %clang --coverage -fPIC -shared shared.c -o libfunc.so +// RUN: test -f shared.gcno + +/// Test the case where we exit abruptly after calling __gcov_flush, which means we don't write out the counters at exit. +// RUN: %clang -DEXIT_ABRUPTLY -DSHARED_CALL_BEFORE_FLUSH -DSHARED_CALL_AFTER_FLUSH --coverage %s -L%t.d -rpath %t.d -lfunc -o %t +// RUN: test -f gcov-shared-flush.gcno + +// RUN: rm -f gcov-shared-flush.gcda shared.gcda +// RUN: %run %t +// RUN: llvm-cov gcov -t gcov-shared-flush.gcda | FileCheck %s --check-prefix=NO_WRITEOUT +// RUN: llvm-cov gcov -t shared.gcda | FileCheck %s --check-prefix=SHARED + +// NO_WRITEOUT: -: [[#%u,L:]]:#ifdef EXIT_ABRUPTLY +// NO_WRITEOUT-NEXT: 1: [[#%u,L+1]]: _exit(0); + +// SHARED: 1: {{[[0-9]+}}:void foo(int n) + +/// Test the case where we exit normally and we have a call to the shared library function before __gcov_flush. +// RUN: %clang -DSHARED_CALL_BEFORE_FLUSH --coverage %s -L%t.d -rpath %t.d -lfunc -o %t +// RUN: test -f gcov-shared-flush.gcno + +// RUN: rm -f gcov-shared-flush.gcda shared.gcda +// RUN: %run %t +// RUN: llvm-cov gcov -t gcov-shared-flush.gcda | FileCheck %s --check-prefix=BEFORE +// RUN: llvm-cov gcov -t shared.gcda | FileCheck %s --check-prefix=SHARED_ONCE + +// BEFORE: -: {{[0-9]+}}:#ifdef SHARED_CALL_BEFORE_FLUSH +// BEFORE-NEXT: 1: {{[0-9]+}}: foo(1); +// BEFORE: 1: {{[0-9]+}}: __gcov_flush(); +// BEFORE: -: {{[0-9]+}}:#ifdef SHARED_CALL_AFTER_FLUSH +// BEFORE-NEXT: -: {{[0-9]+}}: foo(1); +// BEFORE: 1: {{[0-9]+}}: bar(5); + +// SHARED_ONCE: 1: {{[0-9]+}}:void foo(int n) + +// # Test the case where we exit normally and we have a call to the shared library function after __gcov_flush. +// RUN: %clang -DSHARED_CALL_AFTER_FLUSH --coverage %s -L%t.d -rpath %t.d -lfunc -o %t +// RUN: test -f gcov-shared-flush.gcno + +// RUN: rm -f gcov-shared-flush.gcda shared.gcda +// RUN: %run %t +// RUN: llvm-cov gcov -t gcov-shared-flush.gcda | FileCheck %s --check-prefix=AFTER +// RUN: llvm-cov gcov -t shared.gcda > 2s.txt + +// AFTER: -: {{[0-9]+}}:#ifdef SHARED_CALL_BEFORE_FLUSH +// AFTER-NEXT: -: {{[0-9]+}}: foo(1); +// AFTER: 1: {{[0-9]+}}: __gcov_flush(); +// AFTER: -: {{[0-9]+}}:#ifdef SHARED_CALL_AFTER_FLUSH +// AFTER-NEXT: 1: {{[0-9]+}}: foo(1); +// AFTER: 1: {{[0-9]+}}: bar(5); + +// # Test the case where we exit normally and we have calls to the shared library function before and after __gcov_flush. +// RUN: %clang -DSHARED_CALL_BEFORE_FLUSH -DSHARED_CALL_AFTER_FLUSH --coverage %s -L%t.d -rpath %t.d -lfunc -o %t +// RUN: test -f gcov-shared-flush.gcno + +// RUN: rm -f gcov-shared-flush.gcda shared.gcda +// RUN: %run %t +// RUN: llvm-cov gcov -t gcov-shared-flush.gcda | FileCheck %s --check-prefix=BEFORE_AFTER +// RUN: llvm-cov gcov -t shared.gcda | FileCheck %s --check-prefix=SHARED_TWICE + +// BEFORE_AFTER: -: {{[0-9]+}}:#ifdef SHARED_CALL_BEFORE_FLUSH +// BEFORE_AFTER-NEXT: 1: {{[0-9]+}}: foo(1); +// BEFORE_AFTER: 1: {{[0-9]+}}: __gcov_flush(); +// BEFORE_AFTER: -: {{[0-9]+}}:#ifdef SHARED_CALL_AFTER_FLUSH +// BEFORE_AFTER-NEXT: 1: {{[0-9]+}}: foo(1); +// BEFORE_AFTER: 1: {{[0-9]+}}: bar(5); + +// SHARED_TWICE: 2: {{[0-9]+}}:void foo(int n) + +#ifdef SHARED +void foo(int n) { +} +#else +extern void foo(int n); +extern void __gcov_flush(void); + +int bar1 = 0; +int bar2 = 1; + +void bar(int n) { + if (n % 5 == 0) + bar1++; + else + bar2++; +} + +int main(int argc, char *argv[]) { +#ifdef SHARED_CALL_BEFORE_FLUSH + foo(1); +#endif + + bar(5); + __gcov_flush(); + bar(5); + +#ifdef SHARED_CALL_AFTER_FLUSH + foo(1); +#endif + +#ifdef EXIT_ABRUPTLY + _exit(0); +#endif + + bar(5); + return 0; +} +#endif diff --git a/compiler-rt/test/profile/Posix/instrprof-gcov-execlp.test b/compiler-rt/test/profile/Posix/instrprof-gcov-execlp.test deleted file mode 100644 index 1d136ce97907e..0000000000000 --- a/compiler-rt/test/profile/Posix/instrprof-gcov-execlp.test +++ /dev/null @@ -1,10 +0,0 @@ -RUN: mkdir -p %t.d -RUN: cd %t.d - -RUN: %clang --coverage -o %t %S/../Inputs/instrprof-gcov-execlp.c -RUN: test -f instrprof-gcov-execlp.gcno - -RUN: rm -f instrprof-gcov-execlp.gcda -RUN: %run %t -RUN: llvm-cov gcov -b -c instrprof-gcov-execlp.gcda -RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-gcov-execlp.c.gcov %S/../Inputs/instrprof-gcov-execlp.c.gcov diff --git a/compiler-rt/test/profile/Posix/instrprof-gcov-execvp.test b/compiler-rt/test/profile/Posix/instrprof-gcov-execvp.test deleted file mode 100644 index 8e5cbc6095092..0000000000000 --- a/compiler-rt/test/profile/Posix/instrprof-gcov-execvp.test +++ /dev/null @@ -1,10 +0,0 @@ -RUN: mkdir -p %t.d -RUN: cd %t.d - -RUN: %clang --coverage -o %t %S/../Inputs/instrprof-gcov-execvp.c -RUN: test -f instrprof-gcov-execvp.gcno - -RUN: rm -f instrprof-gcov-execvp.gcda -RUN: %run %t -RUN: llvm-cov gcov -b -c instrprof-gcov-execvp.gcda -RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-gcov-execvp.c.gcov %S/../Inputs/instrprof-gcov-execvp.c.gcov diff --git a/compiler-rt/test/profile/Posix/instrprof-gcov-fork.test b/compiler-rt/test/profile/Posix/instrprof-gcov-fork.test deleted file mode 100644 index 31b6a23be49cd..0000000000000 --- a/compiler-rt/test/profile/Posix/instrprof-gcov-fork.test +++ /dev/null @@ -1,13 +0,0 @@ -UNSUPPORTED: linux -UNSUPPORTED: darwin - -RUN: mkdir -p %t.d -RUN: cd %t.d - -RUN: %clang --coverage -o %t %S/../Inputs/instrprof-gcov-fork.c -RUN: test -f instrprof-gcov-fork.gcno - -RUN: rm -f instrprof-gcov-fork.gcda -RUN: %run %t -RUN: llvm-cov gcov -b -c instrprof-gcov-fork.gcda -RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-gcov-fork.c.gcov %S/../Inputs/instrprof-gcov-fork.c.gcov diff --git a/compiler-rt/test/profile/Posix/instrprof-shared-gcov-flush.test b/compiler-rt/test/profile/Posix/instrprof-shared-gcov-flush.test deleted file mode 100644 index 8d530fd452a7b..0000000000000 --- a/compiler-rt/test/profile/Posix/instrprof-shared-gcov-flush.test +++ /dev/null @@ -1,52 +0,0 @@ -# This test fails on Mac (https://bugs.llvm.org/show_bug.cgi?id=38134) -XFAIL: darwin - -RUN: mkdir -p %t.d -RUN: cd %t.d - -RUN: %clang --coverage -o libfunc.so -fPIC -shared %S/../Inputs/instrprof-shared-lib.c -RUN: test -f instrprof-shared-lib.gcno - -# Test the case where we exit abruptly after calling __gcov_flush, which means we don't write out the counters at exit. -RUN: %clang -DEXIT_ABRUPTLY -DSHARED_CALL_BEFORE_GCOV_FLUSH -DSHARED_CALL_AFTER_GCOV_FLUSH --coverage -o %t -L%t.d -rpath %t.d -lfunc %S/../Inputs/instrprof-shared-main-gcov-flush.c -RUN: test -f instrprof-shared-main-gcov-flush.gcno - -RUN: rm -f instrprof-shared-main-gcov-flush.gcda instrprof-shared-lib.gcda -RUN: %run %t -RUN: llvm-cov gcov instrprof-shared-main-gcov-flush.gcda -RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-shared-main-gcov-flush.c.gcov %S/../Inputs/instrprof-shared-main-gcov-flush_no-writeout.c.gcov -RUN: llvm-cov gcov instrprof-shared-lib.gcda -RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-shared-lib.c.gcov %S/../Inputs/instrprof-shared-lib.c.gcov - -# Test the case where we exit normally and we have a call to the shared library function before __gcov_flush. -RUN: %clang -DSHARED_CALL_BEFORE_GCOV_FLUSH --coverage -o %t -L%t.d -rpath %t.d -lfunc %S/../Inputs/instrprof-shared-main-gcov-flush.c -RUN: test -f instrprof-shared-main-gcov-flush.gcno - -RUN: rm -f instrprof-shared-main-gcov-flush.gcda instrprof-shared-lib.gcda -RUN: %run %t -RUN: llvm-cov gcov instrprof-shared-main-gcov-flush.gcda -RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-shared-main-gcov-flush.c.gcov %S/../Inputs/instrprof-shared-main-gcov-flush_shared-call-before.c.gcov -RUN: llvm-cov gcov instrprof-shared-lib.gcda -RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-shared-lib.c.gcov %S/../Inputs/instrprof-shared-lib.c.gcov - -# Test the case where we exit normally and we have a call to the shared library function after __gcov_flush. -RUN: %clang -DSHARED_CALL_AFTER_GCOV_FLUSH --coverage -o %t -L%t.d -rpath %t.d -lfunc %S/../Inputs/instrprof-shared-main-gcov-flush.c -RUN: test -f instrprof-shared-main-gcov-flush.gcno - -RUN: rm -f instrprof-shared-main-gcov-flush.gcda instrprof-shared-lib.gcda -RUN: %run %t -RUN: llvm-cov gcov instrprof-shared-main-gcov-flush.gcda -RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-shared-main-gcov-flush.c.gcov %S/../Inputs/instrprof-shared-main-gcov-flush_shared-call-after.c.gcov -RUN: llvm-cov gcov instrprof-shared-lib.gcda -RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-shared-lib.c.gcov %S/../Inputs/instrprof-shared-lib.c.gcov - -# Test the case where we exit normally and we have calls to the shared library function before and after __gcov_flush. -RUN: %clang -DSHARED_CALL_BEFORE_GCOV_FLUSH -DSHARED_CALL_AFTER_GCOV_FLUSH --coverage -o %t -L%t.d -rpath %t.d -lfunc %S/../Inputs/instrprof-shared-main-gcov-flush.c -RUN: test -f instrprof-shared-main-gcov-flush.gcno - -RUN: rm -f instrprof-shared-main-gcov-flush.gcda instrprof-shared-lib.gcda -RUN: %run %t -RUN: llvm-cov gcov instrprof-shared-main-gcov-flush.gcda -RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-shared-main-gcov-flush.c.gcov %S/../Inputs/instrprof-shared-main-gcov-flush_shared-call-before-after.c.gcov -RUN: llvm-cov gcov instrprof-shared-lib.gcda -RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-shared-lib.c.gcov %S/../Inputs/instrprof-shared-lib_called-twice.c.gcov diff --git a/compiler-rt/test/profile/gcov-__gcov_flush-terminate.c b/compiler-rt/test/profile/gcov-__gcov_flush-terminate.c index c0c443c0e9ddc..5303e045063e8 100644 --- a/compiler-rt/test/profile/gcov-__gcov_flush-terminate.c +++ b/compiler-rt/test/profile/gcov-__gcov_flush-terminate.c @@ -9,23 +9,14 @@ // CHECK: -: 0:Runs:1 // CHECK-NEXT: -: 0:Programs:1 -// CHECK: -: 1:void __gcov_flush(void); -// CHECK-NEXT: -: 2: -// CHECK-NEXT: 1: 3:int main(void) { -// CHECK-NEXT: 1: 4: int i = 22; -// CHECK-NEXT: 1: 5: __gcov_flush(); -// CHECK-NEXT: 1: 6: i = 42; -// CHECK-NEXT: 1: 7: __builtin_trap(); -// CHECK-NEXT: 1: 8: i = 84; -// CHECK-NEXT: 1: 9: return 0; void __gcov_flush(void); -int main(void) { - int i = 22; - __gcov_flush(); - i = 42; - __builtin_trap(); - i = 84; - return 0; +int main(void) { // CHECK: 1: [[#@LINE]]:int main(void) + int i = 22; // CHECK-NEXT: 1: [[#@LINE]]: + __gcov_flush(); // CHECK-NEXT: 1: [[#@LINE]]: + i = 42; // CHECK-NEXT: 1: [[#@LINE]]: + __builtin_trap(); // CHECK-NEXT: 1: [[#@LINE]]: + i = 84; // CHECK-NEXT: 1: [[#@LINE]]: + return 0; // CHECK-NEXT: 1: [[#@LINE]]: } diff --git a/compiler-rt/test/profile/gcov-dump-and-remove.c b/compiler-rt/test/profile/gcov-dump-and-remove.c new file mode 100644 index 0000000000000..1dcf7b5bd5ca8 --- /dev/null +++ b/compiler-rt/test/profile/gcov-dump-and-remove.c @@ -0,0 +1,24 @@ +/// Test we close file handle on flush, so the .gcda file can be deleted on +/// Windows while the process is still running. In addition, test we create +/// a new .gcda on flush, so there is a file when the process exists. +// RUN: mkdir -p %t.d && cd %t.d +// RUN: %clang --coverage -o %t %s +// RUN: test -f gcov-dump-and-remove.gcno + +// RUN: rm -f gcov-dump-and-remove.gcda && %run %t +// RUN: llvm-cov gcov -t gcov-dump-and-remove.gcda | FileCheck %s + +extern void __gcov_flush(void); +extern int remove(const char *); // CHECK: -: [[#@LINE]]:extern int remove +int main(void) { // CHECK-NEXT: #####: [[#@LINE]]: + __gcov_flush(); // CHECK-NEXT: #####: [[#@LINE]]: + if (remove("gcov-dump-and-remove.gcda") != 0) // CHECK-NEXT: #####: [[#@LINE]]: + return 1; // CHECK-NEXT: #####: [[#@LINE]]: return 1; + // CHECK-NEXT: -: [[#@LINE]]: + __gcov_flush(); // CHECK-NEXT: #####: [[#@LINE]]: + __gcov_flush(); // CHECK-NEXT: #####: [[#@LINE]]: + if (remove("gcov-dump-and-remove.gcda") != 0) // CHECK-NEXT: #####: [[#@LINE]]: + return 1; // CHECK-NEXT: #####: [[#@LINE]]: return 1; + + return 0; +} diff --git a/compiler-rt/test/profile/instrprof-gcov-__gcov_flush-multiple.test b/compiler-rt/test/profile/instrprof-gcov-__gcov_flush-multiple.test deleted file mode 100644 index fdc93c93e0b06..0000000000000 --- a/compiler-rt/test/profile/instrprof-gcov-__gcov_flush-multiple.test +++ /dev/null @@ -1,10 +0,0 @@ -RUN: mkdir -p %t.d -RUN: cd %t.d - -RUN: %clang --coverage -o %t %S/Inputs/instrprof-gcov-__gcov_flush-multiple.c -RUN: test -f instrprof-gcov-__gcov_flush-multiple.gcno - -RUN: rm -f instrprof-gcov-__gcov_flush-multiple.gcda -RUN: %run %t -RUN: llvm-cov gcov instrprof-gcov-__gcov_flush-multiple.gcda -RUN: FileCheck --match-full-lines --strict-whitespace --input-file instrprof-gcov-__gcov_flush-multiple.c.gcov %S/Inputs/instrprof-gcov-__gcov_flush-multiple.c.gcov diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/protoent.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/protoent.cpp new file mode 100644 index 0000000000000..a1a93badf6b81 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/protoent.cpp @@ -0,0 +1,69 @@ +// RUN: %clangxx -std=c++11 -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s +// REQUIRES: !android + +#include +#include +#include +#include + +void print_protoent(protoent *curr_entry) { + fprintf(stderr, "%s (%d)\n", curr_entry->p_name, curr_entry->p_proto); + + char **aliases = curr_entry->p_aliases; + while (char *alias = *aliases++) { + fprintf(stderr, " alias %s\n", alias); + } +} + +void print_all_protoent() { + protoent entry; + char buf[1024]; + protoent *curr_entry; + + while (getprotoent_r(&entry, buf, sizeof(buf), &curr_entry) != ENOENT && curr_entry) { + print_protoent(curr_entry); + } +} + +void print_protoent_by_name(const char *name) { + protoent entry; + char buf[1024]; + protoent *curr_entry; + + int res = getprotobyname_r(name, &entry, buf, sizeof(buf), &curr_entry); + assert(!res && curr_entry); + print_protoent(curr_entry); +} + +void print_protoent_by_num(int num) { + protoent entry; + char buf[1024]; + protoent *curr_entry; + + int res = getprotobynumber_r(num, &entry, buf, sizeof(buf), &curr_entry); + assert(!res && curr_entry); + print_protoent(curr_entry); +} + +int main() { + // CHECK: All protoent + // CHECK: ip (0) + // CHECK-NEXT: alias IP + // CHECK: ipv6 (41) + // CHECK-NEXT: alias IPv6 + fprintf(stderr, "All protoent\n"); + print_all_protoent(); + + // CHECK: Protoent by name + // CHECK-NEXT: ipv6 (41) + // CHECK-NEXT: alias IPv6 + fprintf(stderr, "Protoent by name\n"); + print_protoent_by_name("ipv6"); + + // CHECK: Protoent by num + // CHECK-NEXT: udp (17) + // CHECK-NEXT: alias UDP + fprintf(stderr, "Protoent by num\n"); + print_protoent_by_num(17); + return 0; +} diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/sysmsg.c b/compiler-rt/test/sanitizer_common/TestCases/Linux/sysmsg.c new file mode 100644 index 0000000000000..bc7776f2b3d39 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/sysmsg.c @@ -0,0 +1,36 @@ +// RUN: %clang -O1 %s -o %t && %run %t +// UNSUPPORTED: android +#include +#include +#include +#include +#include + +#define CHECK_STRING "hello, world!" +#define MSG_BUFLEN 0x100 + +int main() { + int msgq = msgget(IPC_PRIVATE, 0666); + assert(msgq != -1); + + struct msg_s { + long mtype; + char string[MSG_BUFLEN]; + }; + + struct msg_s msg = { + .mtype = 1}; + strcpy(msg.string, CHECK_STRING); + int res = msgsnd(msgq, &msg, MSG_BUFLEN, IPC_NOWAIT); + if (res) { + fprintf(stderr, "Error sending message! %s\n", strerror(errno)); + return -1; + } + + struct msg_s rcv_msg; + ssize_t len = msgrcv(msgq, &rcv_msg, MSG_BUFLEN, msg.mtype, IPC_NOWAIT); + assert(len == MSG_BUFLEN); + assert(msg.mtype == rcv_msg.mtype); + assert(!memcmp(msg.string, rcv_msg.string, MSG_BUFLEN)); + return 0; +} diff --git a/debuginfo-tests/CMakeLists.txt b/debuginfo-tests/CMakeLists.txt index addf13d50f49b..d3ac0a4aad90a 100644 --- a/debuginfo-tests/CMakeLists.txt +++ b/debuginfo-tests/CMakeLists.txt @@ -16,11 +16,27 @@ set(DEBUGINFO_TEST_DEPS clang FileCheck count + llvm-config llvm-objdump check-gdb-llvm-support not ) +if("compiler-rt" IN_LIST LLVM_ENABLE_PROJECTS) + # llgdb-tests/asan.c and other asan* files. + if(TARGET asan) + list(APPEND DEBUGINFO_TEST_DEPS asan) + endif() + # llgdb-tests/safestack.c + if(TARGET safestack) + list(APPEND DEBUGINFO_TEST_DEPS safestack) + endif() +endif() +# Many dexter tests depend on lldb. +if("lldb" IN_LIST LLVM_ENABLE_PROJECTS) + list(APPEND DEBUGINFO_TEST_DEPS lldb lldb-server) +endif() + # The Windows builder scripts pass -fuse-ld=lld. if (WIN32) set(DEBUGINFO_TEST_DEPS ${DEBUGINFO_TEST_DEPS} lld) @@ -42,4 +58,9 @@ add_lit_testsuite(check-debuginfo "Running debug info integration tests" DEPENDS ${DEBUGINFO_TEST_DEPS} ) +# Add check-debuginfo-* targets. +add_lit_testsuites(DEBUGINFO ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS ${DEBUGINFO_TEST_DEPS} + ) + set_target_properties(check-debuginfo PROPERTIES FOLDER "Debug info tests") diff --git a/debuginfo-tests/dexter/feature_tests/commands/perfect/lit.local.cfg b/debuginfo-tests/dexter/feature_tests/commands/perfect/lit.local.cfg new file mode 100644 index 0000000000000..7d1dd8b7b9026 --- /dev/null +++ b/debuginfo-tests/dexter/feature_tests/commands/perfect/lit.local.cfg @@ -0,0 +1,2 @@ +if not 'lldb' in config.available_features: + config.unsupported = True diff --git a/debuginfo-tests/dexter/feature_tests/subtools/view.cpp b/debuginfo-tests/dexter/feature_tests/subtools/view.cpp index 03e0b9420fb1d..93a51062b4421 100644 --- a/debuginfo-tests/dexter/feature_tests/subtools/view.cpp +++ b/debuginfo-tests/dexter/feature_tests/subtools/view.cpp @@ -1,3 +1,4 @@ +// REQUIRES: lldb // Purpose: // Check the `view` subtool works with typical inputs. // diff --git a/flang/.clang-tidy b/flang/.clang-tidy new file mode 100644 index 0000000000000..be9a2b704edd0 --- /dev/null +++ b/flang/.clang-tidy @@ -0,0 +1 @@ +Checks: '-*,llvm-*,-llvm-include-order,misc-*,-misc-no-recursion,-misc-unused-parameters,-misc-non-private-member-variables-in-classes' diff --git a/flang/CMakeLists.txt b/flang/CMakeLists.txt index 5c4aad9bd65d7..feb9544209bf0 100644 --- a/flang/CMakeLists.txt +++ b/flang/CMakeLists.txt @@ -50,6 +50,7 @@ option(FLANG_ENABLE_WERROR "Fail and stop building flang if a warning is trigger if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) message("Building Flang as a standalone project.") project(Flang) + set(FLANG_STANDALONE_BUILD ON) set(FLANG_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) if (NOT MSVC_IDE) @@ -179,6 +180,7 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) endif() else() + set(FLANG_STANDALONE_BUILD OFF) option(FLANG_INCLUDE_TESTS "Generate build targets for the Flang unit tests." ${LLVM_INCLUDE_TESTS}) diff --git a/flang/documentation/Intrinsics.md b/flang/documentation/Intrinsics.md index 381f3a3c34b85..8fd06766710c6 100644 --- a/flang/documentation/Intrinsics.md +++ b/flang/documentation/Intrinsics.md @@ -701,7 +701,7 @@ This phase currently supports all the intrinsic procedures listed above but the | Intrinsic Category | Intrinsic Procedures Lacking Support | | --- | --- | -| Coarray intrinsic functions | LCOBOUND, UCOBOUND, FAILED_IMAGES, GET_TEAM, IMAGE_INDEX, NUM_IMAGES, STOPPED_IMAGES, TEAM_NUMBER, THIS_IMAGE, COSHAPE | +| Coarray intrinsic functions | LCOBOUND, UCOBOUND, FAILED_IMAGES, GET_TEAM, IMAGE_INDEX, STOPPED_IMAGES, TEAM_NUMBER, THIS_IMAGE, COSHAPE | | Object characteristic inquiry functions | ALLOCATED, ASSOCIATED, EXTENDS_TYPE_OF, IS_CONTIGUOUS, PRESENT, RANK, SAME_TYPE, STORAGE_SIZE | | Type inquiry intrinsic functions | BIT_SIZE, DIGITS, EPSILON, HUGE, KIND, MAXEXPONENT, MINEXPONENT, NEW_LINE, PRECISION, RADIX, RANGE, TINY| | Non-standard intrinsic functions | AND, OR, XOR, LSHIFT, RSHIFT, SHIFT, ZEXT, IZEXT, COSD, SIND, TAND, ACOSD, ASIND, ATAND, ATAN2D, COMPL, DCMPLX, EQV, NEQV, INT8, JINT, JNINT, KNINT, LOC, QCMPLX, DREAL, DFLOAT, QEXT, QFLOAT, QREAL, DNUM, NUM, JNUM, KNUM, QNUM, RNUM, RAN, RANF, ILEN, SIZEOF, MCLOCK, SECNDS, COTAN, IBCHNG, ISHA, ISHC, ISHL, IXOR, IARG, IARGC, NARGS, NUMARG, BADDRESS, IADDR, CACHESIZE, EOF, FP_CLASS, INT_PTR_KIND, ISNAN, MALLOC | diff --git a/flang/include/flang/Common/enum-set.h b/flang/include/flang/Common/enum-set.h index 5346cceaadfab..a7bdc757a1c97 100644 --- a/flang/include/flang/Common/enum-set.h +++ b/flang/include/flang/Common/enum-set.h @@ -16,7 +16,6 @@ #include "constexpr-bitset.h" #include "idioms.h" -#include "llvm/Support/raw_ostream.h" #include #include #include @@ -190,7 +189,7 @@ template class EnumSet { // std::bitset: just iterate for (std::size_t j{0}; j < BITS; ++j) { auto enumerator{static_cast(j)}; - if (bitset_.test(enumerator)) { + if (bitset_.test(j)) { return {enumerator}; } } @@ -206,8 +205,8 @@ template class EnumSet { } } - llvm::raw_ostream &Dump( - llvm::raw_ostream &o, std::string EnumToString(enumerationType)) const { + template + STREAM &Dump(STREAM &o, std::string EnumToString(enumerationType)) const { char sep{'{'}; IterateOverMembers([&](auto e) { o << sep << EnumToString(e); diff --git a/flang/include/flang/Common/idioms.h b/flang/include/flang/Common/idioms.h index 3f4f8f2eec6ba..6e499eb04f36a 100644 --- a/flang/include/flang/Common/idioms.h +++ b/flang/include/flang/Common/idioms.h @@ -23,6 +23,7 @@ #error g++ >= 7.2 is required #endif +#include "llvm/Support/Compiler.h" #include #include #include @@ -108,10 +109,6 @@ template visitors(LAMBDAS... x) -> visitors; } \ template constexpr bool T{class_trait_ns_##T::trait_value()}; -#if !defined ATTRIBUTE_UNUSED && (__clang__ || __GNUC__) -#define ATTRIBUTE_UNUSED __attribute__((unused)) -#endif - // Define enum class NAME with the given enumerators, a static // function EnumToString() that maps enumerators to std::string, // and a constant NAME_enumSize that captures the number of items @@ -126,11 +123,11 @@ template struct ListItemCount { #define ENUM_CLASS(NAME, ...) \ enum class NAME { __VA_ARGS__ }; \ - ATTRIBUTE_UNUSED static constexpr std::size_t NAME##_enumSize{[] { \ + LLVM_ATTRIBUTE_UNUSED static constexpr std::size_t NAME##_enumSize{[] { \ enum { __VA_ARGS__ }; \ return Fortran::common::ListItemCount{__VA_ARGS__}.value; \ }()}; \ - ATTRIBUTE_UNUSED static inline std::string EnumToString(NAME e) { \ + LLVM_ATTRIBUTE_UNUSED static inline std::string EnumToString(NAME e) { \ return Fortran::common::EnumIndexToString( \ static_cast(e), #__VA_ARGS__); \ } diff --git a/flang/include/flang/Common/indirection.h b/flang/include/flang/Common/indirection.h index f34d561ae0492..fec3bc7ae8dad 100644 --- a/flang/include/flang/Common/indirection.h +++ b/flang/include/flang/Common/indirection.h @@ -122,20 +122,49 @@ template class Indirection { template using CopyableIndirection = Indirection; -// For use with std::unique_ptr<> when declaring owning pointers to -// forward-referenced types, here's a minimal custom deleter that avoids -// some of the drama with std::default_delete<>. Invoke DEFINE_DELETER() -// later in exactly one C++ source file where a complete definition of the -// type is visible. Be advised, std::unique_ptr<> does not have copy -// semantics; if you need ownership, copy semantics, and nullability, -// std::optional> works. -template class Deleter { +// A variation of std::unique_ptr<> with a reified deletion routine. +// Used to avoid dependence cycles between shared libraries. +template class ForwardOwningPointer { public: - void operator()(A *) const; + ForwardOwningPointer() {} + ForwardOwningPointer(A *p, void (*del)(A *)) : p_{p}, deleter_{del} {} + ForwardOwningPointer(ForwardOwningPointer &&that) + : p_{that.p_}, deleter_{that.deleter_} { + that.p_ = nullptr; + } + ForwardOwningPointer &operator=(ForwardOwningPointer &&that) { + p_ = that.p_; + that.p_ = nullptr; + deleter_ = that.deleter_; + return *this; + } + ~ForwardOwningPointer() { + if (p_) { + deleter_(p_); + } + } + + A &operator*() const { return *p_; } + A *operator->() const { return p_; } + operator bool() const { return p_ != nullptr; } + A *get() { return p_; } + A *release() { + A *result{p_}; + p_ = nullptr; + return result; + } + + void Reset(A *p, void (*del)(A *)) { + if (p_) { + deleter_(p_); + } + p_ = p; + deleter_ = del; + } + +private: + A *p_{nullptr}; + void (*deleter_)(A *){nullptr}; }; } // namespace Fortran::common -#define DEFINE_DELETER(A) \ - template <> void Fortran::common::Deleter::operator()(A *p) const { \ - delete p; \ - } #endif // FORTRAN_COMMON_INDIRECTION_H_ diff --git a/flang/include/flang/Evaluate/call.h b/flang/include/flang/Evaluate/call.h index 15fe5b879dc4c..71e0610549282 100644 --- a/flang/include/flang/Evaluate/call.h +++ b/flang/include/flang/Evaluate/call.h @@ -190,9 +190,12 @@ struct ProcedureDesignator { class ProcedureRef { public: CLASS_BOILERPLATE(ProcedureRef) - ProcedureRef(ProcedureDesignator &&p, ActualArguments &&a) - : proc_{std::move(p)}, arguments_(std::move(a)) {} + ProcedureRef(ProcedureDesignator &&p, ActualArguments &&a, + bool hasAlternateReturns = false) + : proc_{std::move(p)}, arguments_{std::move(a)}, + hasAlternateReturns_{hasAlternateReturns} {} ~ProcedureRef(); + static void Deleter(ProcedureRef *); ProcedureDesignator &proc() { return proc_; } const ProcedureDesignator &proc() const { return proc_; } @@ -202,12 +205,14 @@ class ProcedureRef { std::optional> LEN() const; int Rank() const; bool IsElemental() const { return proc_.IsElemental(); } + bool hasAlternateReturns() const { return hasAlternateReturns_; } bool operator==(const ProcedureRef &) const; llvm::raw_ostream &AsFortran(llvm::raw_ostream &) const; protected: ProcedureDesignator proc_; ActualArguments arguments_; + bool hasAlternateReturns_; }; template class FunctionRef : public ProcedureRef { diff --git a/flang/include/flang/Evaluate/expression.h b/flang/include/flang/Evaluate/expression.h index 095783231b660..3569b68fd9d2e 100644 --- a/flang/include/flang/Evaluate/expression.h +++ b/flang/include/flang/Evaluate/expression.h @@ -841,6 +841,7 @@ struct GenericExprWrapper { explicit GenericExprWrapper(std::optional> &&x) : v{std::move(x)} {} ~GenericExprWrapper(); + static void Deleter(GenericExprWrapper *); std::optional> v; // vacant if error }; @@ -849,6 +850,7 @@ struct GenericAssignmentWrapper { GenericAssignmentWrapper() {} explicit GenericAssignmentWrapper(Assignment &&x) : v{std::move(x)} {} ~GenericAssignmentWrapper(); + static void Deleter(GenericAssignmentWrapper *); std::optional v; // vacant if error }; diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h index 84de29bd7fec8..e64aaece15bf8 100644 --- a/flang/include/flang/Evaluate/tools.h +++ b/flang/include/flang/Evaluate/tools.h @@ -908,6 +908,7 @@ bool IsProcedure(const Symbol &); bool IsProcedurePointer(const Symbol &); bool IsSaved(const Symbol &); // saved implicitly or explicitly bool IsDummy(const Symbol &); +bool IsFunctionResult(const Symbol &); // Follow use, host, and construct assocations to a variable, if any. const Symbol *GetAssociationRoot(const Symbol &); diff --git a/flang/include/flang/Evaluate/type.h b/flang/include/flang/Evaluate/type.h index 197fb3291dd42..c62d633563430 100644 --- a/flang/include/flang/Evaluate/type.h +++ b/flang/include/flang/Evaluate/type.h @@ -146,7 +146,7 @@ class DynamicType { DynamicType ResultTypeForMultiply(const DynamicType &) const; bool IsAssumedLengthCharacter() const; - bool IsUnknownLengthCharacter() const; + bool IsNonConstantLengthCharacter() const; bool IsTypelessIntrinsicArgument() const; constexpr bool IsAssumedType() const { // TYPE(*) return kind_ == AssumedTypeKind; diff --git a/flang/include/flang/Lower/.clang-tidy b/flang/include/flang/Lower/.clang-tidy new file mode 100644 index 0000000000000..87ec2ff53af6e --- /dev/null +++ b/flang/include/flang/Lower/.clang-tidy @@ -0,0 +1,19 @@ +# Almost identical to the top-level .clang-tidy, except that {Member,Parameter,Variable}Case use camelBack. +Checks: '-*,clang-diagnostic-*,llvm-*,misc-*,-misc-unused-parameters,-misc-non-private-member-variables-in-classes,readability-identifier-naming' +CheckOptions: + - key: readability-identifier-naming.ClassCase + value: CamelCase + - key: readability-identifier-naming.EnumCase + value: CamelCase + - key: readability-identifier-naming.FunctionCase + value: camelBack + - key: readability-identifier-naming.MemberCase + value: camelBack + - key: readability-identifier-naming.ParameterCase + value: camelBack + - key: readability-identifier-naming.UnionCase + value: CamelCase + - key: readability-identifier-naming.VariableCase + value: camelBack + - key: readability-identifier-naming.IgnoreMainLikeFunctions + value: 1 diff --git a/flang/include/flang/Lower/AbstractConverter.h b/flang/include/flang/Lower/AbstractConverter.h index 0716b841fa1e7..190e69230c8e1 100644 --- a/flang/include/flang/Lower/AbstractConverter.h +++ b/flang/include/flang/Lower/AbstractConverter.h @@ -9,11 +9,127 @@ #ifndef FORTRAN_LOWER_ABSTRACTCONVERTER_H #define FORTRAN_LOWER_ABSTRACTCONVERTER_H -namespace Fortran::lower { +#include "flang/Common/Fortran.h" +#include "mlir/IR/Module.h" -// temporary stub -class AbstractConverter; +namespace Fortran { +namespace common { +template +class Reference; +} +namespace evaluate { +struct DataRef; +template +class Expr; +class FoldingContext; +struct SomeType; +} // namespace evaluate -} // namespace Fortran::lower +namespace parser { +class CharBlock; +} +namespace semantics { +class Symbol; +} + +namespace lower { +namespace pft { +struct Variable; +} + +using SomeExpr = Fortran::evaluate::Expr; +using SymbolRef = Fortran::common::Reference; +class FirOpBuilder; + +//===----------------------------------------------------------------------===// +// AbstractConverter interface +//===----------------------------------------------------------------------===// + +/// The abstract interface for converter implementations to lower Fortran +/// front-end fragments such as expressions, types, etc. to the FIR dialect of +/// MLIR. +class AbstractConverter { +public: + //===--------------------------------------------------------------------===// + // Symbols + //===--------------------------------------------------------------------===// + + /// Get the mlir instance of a symbol. + virtual mlir::Value getSymbolAddress(SymbolRef sym) = 0; + + //===--------------------------------------------------------------------===// + // Expressions + //===--------------------------------------------------------------------===// + + /// Generate the address of the location holding the expression, someExpr + virtual mlir::Value genExprAddr(const SomeExpr &, + mlir::Location *loc = nullptr) = 0; + /// Generate the address of the location holding the expression, someExpr + mlir::Value genExprAddr(const SomeExpr *someExpr, mlir::Location loc) { + return genExprAddr(*someExpr, &loc); + } + + /// Generate the computations of the expression to produce a value + virtual mlir::Value genExprValue(const SomeExpr &, + mlir::Location *loc = nullptr) = 0; + /// Generate the computations of the expression, someExpr, to produce a value + mlir::Value genExprValue(const SomeExpr *someExpr, mlir::Location loc) { + return genExprValue(*someExpr, &loc); + } + + /// Get FoldingContext that is required for some expression + /// analysis. + virtual Fortran::evaluate::FoldingContext &getFoldingContext() = 0; + + //===--------------------------------------------------------------------===// + // Types + //===--------------------------------------------------------------------===// + + /// Generate the type of a DataRef + virtual mlir::Type genType(const Fortran::evaluate::DataRef &) = 0; + /// Generate the type of an Expr + virtual mlir::Type genType(const SomeExpr &) = 0; + /// Generate the type of a Symbol + virtual mlir::Type genType(SymbolRef) = 0; + /// Generate the type from a category + virtual mlir::Type genType(Fortran::common::TypeCategory tc) = 0; + /// Generate the type from a category and kind + virtual mlir::Type genType(Fortran::common::TypeCategory tc, int kind) = 0; + /// Generate the type from a Variable + virtual mlir::Type genType(const pft::Variable &) = 0; + + //===--------------------------------------------------------------------===// + // Locations + //===--------------------------------------------------------------------===// + + /// Get the converter's current location + virtual mlir::Location getCurrentLocation() = 0; + /// Generate a dummy location + virtual mlir::Location genLocation() = 0; + /// Generate the location as converted from a CharBlock + virtual mlir::Location genLocation(const Fortran::parser::CharBlock &) = 0; + + //===--------------------------------------------------------------------===// + // FIR/MLIR + //===--------------------------------------------------------------------===// + + /// Get the OpBuilder + virtual Fortran::lower::FirOpBuilder &getFirOpBuilder() = 0; + /// Get the ModuleOp + virtual mlir::ModuleOp &getModuleOp() = 0; + /// Get the MLIRContext + virtual mlir::MLIRContext &getMLIRContext() = 0; + /// Unique a symbol + virtual std::string mangleName(const Fortran::semantics::Symbol &) = 0; + /// Unique a compiler generated identifier. A short prefix should be provided + /// to hint at the origin of the identifier. + virtual std::string uniqueCGIdent(llvm::StringRef prefix, + llvm::StringRef name) = 0; + + virtual ~AbstractConverter() = default; +}; + +} // namespace lower +} // namespace Fortran #endif // FORTRAN_LOWER_ABSTRACTCONVERTER_H diff --git a/flang/include/flang/Lower/Bridge.h b/flang/include/flang/Lower/Bridge.h new file mode 100644 index 0000000000000..aee7a0ef5bd8d --- /dev/null +++ b/flang/include/flang/Lower/Bridge.h @@ -0,0 +1,117 @@ +//===-- Lower/Bridge.h -- main interface to lowering ------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Implements lowering. Convert Fortran source to +/// [MLIR](https://github.com/tensorflow/mlir). +/// +/// [Coding style](https://llvm.org/docs/CodingStandards.html) +/// +//===----------------------------------------------------------------------===// + +#ifndef FORTRAN_LOWER_BRIDGE_H +#define FORTRAN_LOWER_BRIDGE_H + +#include "flang/Common/Fortran.h" +#include "flang/Lower/AbstractConverter.h" +#include "flang/Optimizer/Support/KindMapping.h" +#include "mlir/IR/Module.h" + +namespace fir { +struct NameUniquer; +} + +namespace Fortran { +namespace common { +class IntrinsicTypeDefaultKinds; +} // namespace common +namespace evaluate { +class IntrinsicProcTable; +} // namespace evaluate +namespace parser { +class CookedSource; +struct Program; +} // namespace parser +namespace semantics { +class SemanticsContext; +} // namespace semantics + +namespace lower { + +//===----------------------------------------------------------------------===// +// Lowering bridge +//===----------------------------------------------------------------------===// + +/// The lowering bridge converts the front-end parse trees and semantics +/// checking residual to MLIR (FIR dialect) code. +class LoweringBridge { +public: + /// Create a lowering bridge instance. + static LoweringBridge + create(const Fortran::common::IntrinsicTypeDefaultKinds &defaultKinds, + const Fortran::evaluate::IntrinsicProcTable &intrinsics, + const Fortran::parser::CookedSource &cooked) { + return LoweringBridge{defaultKinds, intrinsics, cooked}; + } + + //===--------------------------------------------------------------------===// + // Getters + //===--------------------------------------------------------------------===// + + mlir::MLIRContext &getMLIRContext() { return *context.get(); } + mlir::ModuleOp &getModule() { return *module.get(); } + const Fortran::common::IntrinsicTypeDefaultKinds &getDefaultKinds() const { + return defaultKinds; + } + const Fortran::evaluate::IntrinsicProcTable &getIntrinsicTable() const { + return intrinsics; + } + const Fortran::parser::CookedSource *getCookedSource() const { + return cooked; + } + + /// Get the kind map. + const fir::KindMapping &getKindMap() const { return kindMap; } + + /// Create a folding context. Careful: this is very expensive. + Fortran::evaluate::FoldingContext createFoldingContext() const; + + bool validModule() { return getModule(); } + + //===--------------------------------------------------------------------===// + // Perform the creation of an mlir::ModuleOp + //===--------------------------------------------------------------------===// + + /// Read in an MLIR input file rather than lowering Fortran sources. + /// This is intended to be used for testing. + void parseSourceFile(llvm::SourceMgr &); + + /// Cross the bridge from the Fortran parse-tree, etc. to MLIR dialects + void lower(const Fortran::parser::Program &program, fir::NameUniquer &uniquer, + const Fortran::semantics::SemanticsContext &semanticsContext); + +private: + explicit LoweringBridge( + const Fortran::common::IntrinsicTypeDefaultKinds &defaultKinds, + const Fortran::evaluate::IntrinsicProcTable &intrinsics, + const Fortran::parser::CookedSource &cooked); + LoweringBridge() = delete; + LoweringBridge(const LoweringBridge &) = delete; + + const Fortran::common::IntrinsicTypeDefaultKinds &defaultKinds; + const Fortran::evaluate::IntrinsicProcTable &intrinsics; + const Fortran::parser::CookedSource *cooked; + std::unique_ptr context; + std::unique_ptr module; + fir::KindMapping kindMap; +}; + +} // namespace lower +} // namespace Fortran + +#endif // FORTRAN_LOWER_BRIDGE_H diff --git a/flang/include/flang/Lower/CharacterExpr.h b/flang/include/flang/Lower/CharacterExpr.h new file mode 100644 index 0000000000000..6f75448a5dbbf --- /dev/null +++ b/flang/include/flang/Lower/CharacterExpr.h @@ -0,0 +1,153 @@ +//===-- Lower/CharacterExpr.h -- lowering of characters ---------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef FORTRAN_LOWER_CHARACTEREXPR_H +#define FORTRAN_LOWER_CHARACTEREXPR_H + +#include "flang/Lower/FIRBuilder.h" +#include "flang/Lower/Support/BoxValue.h" + +namespace Fortran::lower { + +/// Helper to facilitate lowering of CHARACTER in FIR. +class CharacterExprHelper { +public: + /// Constructor. + explicit CharacterExprHelper(FirOpBuilder &builder, mlir::Location loc) + : builder{builder}, loc{loc} {} + CharacterExprHelper(const CharacterExprHelper &) = delete; + + /// Unless otherwise stated, all mlir::Value inputs of these pseudo-fir ops + /// must be of type: + /// - fir.boxchar (dynamic length character), + /// - fir.ref>> (character with compile time + /// constant length), + /// - fir.array> (compile time constant character) + + /// Copy the \p count first characters of \p src into \p dest. + /// \p count can have any integer type. + void createCopy(mlir::Value dest, mlir::Value src, mlir::Value count); + + /// Set characters of \p str at position [\p lower, \p upper) to blanks. + /// \p lower and \upper bounds are zero based. + /// If \p upper <= \p lower, no padding is done. + /// \p upper and \p lower can have any integer type. + void createPadding(mlir::Value str, mlir::Value lower, mlir::Value upper); + + /// Create str(lb:ub), lower bounds must always be specified, upper + /// bound is optional. + mlir::Value createSubstring(mlir::Value str, + llvm::ArrayRef bounds); + + /// Return blank character of given \p type !fir.char + mlir::Value createBlankConstant(fir::CharacterType type); + + /// Lower \p lhs = \p rhs where \p lhs and \p rhs are scalar characters. + /// It handles cases where \p lhs and \p rhs may overlap. + void createAssign(mlir::Value lhs, mlir::Value rhs); + + /// Lower an assignment where the buffer and LEN parameter are known and do + /// not need to be unboxed. + void createAssign(mlir::Value lptr, mlir::Value llen, mlir::Value rptr, + mlir::Value rlen); + + /// Create lhs // rhs in temp obtained with fir.alloca + mlir::Value createConcatenate(mlir::Value lhs, mlir::Value rhs); + + /// LEN_TRIM intrinsic. + mlir::Value createLenTrim(mlir::Value str); + + /// Embox \p addr and \p len and return fir.boxchar. + /// Take care of type conversions before emboxing. + /// \p len is converted to the integer type for character lengths if needed. + mlir::Value createEmboxChar(mlir::Value addr, mlir::Value len); + + /// Unbox \p boxchar into (fir.ref>, getLengthType()). + std::pair createUnboxChar(mlir::Value boxChar); + + /// Allocate a temp of fir::CharacterType type and length len. + /// Returns related fir.ref>. + mlir::Value createCharacterTemp(mlir::Type type, mlir::Value len); + + /// Allocate a temp of compile time constant length. + /// Returns related fir.ref>>. + mlir::Value createCharacterTemp(mlir::Type type, int len) { + return createTemp(type, len); + } + + /// Return buffer/length pair of character str, if str is a constant, + /// it is allocated into a temp, otherwise, its memory reference is + /// returned as the buffer. + /// The buffer type of str is of type: + /// - fir.ref>> if str has compile time + /// constant length. + /// - fir.ref> if str has dynamic length. + std::pair materializeCharacter(mlir::Value str); + + /// Return true if \p type is a character literal type (is + /// fir.array>).; + static bool isCharacterLiteral(mlir::Type type); + + /// Return true if \p type is one of the following type + /// - fir.boxchar + /// - fir.ref>> + /// - fir.array> + static bool isCharacter(mlir::Type type); + + /// Extract the kind of a character type + static int getCharacterKind(mlir::Type type); + + /// Return the integer type that must be used to manipulate + /// Character lengths. TODO: move this to FirOpBuilder? + mlir::Type getLengthType() { return builder.getIndexType(); } + + /// Create an extended value from: + /// - fir.boxchar + /// - fir.ref>> + /// - fir.array> + /// - fir.char + /// - fir.ref> + /// If the no length is passed, it is attempted to be extracted from \p + /// character (or its type). This will crash if this is not possible. + /// The returned value is a CharBoxValue if \p character is a scalar, + /// otherwise it is a CharArrayBoxValue. + fir::ExtendedValue toExtendedValue(mlir::Value character, + mlir::Value len = {}); + +private: + fir::CharBoxValue materializeValue(const fir::CharBoxValue &str); + fir::CharBoxValue toDataLengthPair(mlir::Value character); + mlir::Type getReferenceType(const fir::CharBoxValue &c) const; + mlir::Value createEmbox(const fir::CharBoxValue &str); + mlir::Value createLoadCharAt(const fir::CharBoxValue &str, mlir::Value index); + void createStoreCharAt(const fir::CharBoxValue &str, mlir::Value index, + mlir::Value c); + void createCopy(const fir::CharBoxValue &dest, const fir::CharBoxValue &src, + mlir::Value count); + void createPadding(const fir::CharBoxValue &str, mlir::Value lower, + mlir::Value upper); + fir::CharBoxValue createTemp(mlir::Type type, mlir::Value len); + void createLengthOneAssign(const fir::CharBoxValue &lhs, + const fir::CharBoxValue &rhs); + void createAssign(const fir::CharBoxValue &lhs, const fir::CharBoxValue &rhs); + fir::CharBoxValue createConcatenate(const fir::CharBoxValue &lhs, + const fir::CharBoxValue &rhs); + fir::CharBoxValue createSubstring(const fir::CharBoxValue &str, + llvm::ArrayRef bounds); + mlir::Value createLenTrim(const fir::CharBoxValue &str); + mlir::Value createTemp(mlir::Type type, int len); + mlir::Value createBlankConstantCode(fir::CharacterType type); + +private: + FirOpBuilder &builder; + mlir::Location loc; +}; + +} // namespace Fortran::lower + +#endif // FORTRAN_LOWER_CHARACTEREXPR_H diff --git a/flang/include/flang/Lower/CharacterRuntime.h b/flang/include/flang/Lower/CharacterRuntime.h new file mode 100644 index 0000000000000..d2992f76406ae --- /dev/null +++ b/flang/include/flang/Lower/CharacterRuntime.h @@ -0,0 +1,36 @@ +//===-- Lower/CharacterRuntime.h -- lower CHARACTER operations --*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef FORTRAN_LOWER_CHARACTERRUNTIME_H +#define FORTRAN_LOWER_CHARACTERRUNTIME_H + +#include "mlir/Dialect/StandardOps/IR/Ops.h" + +namespace Fortran { +namespace lower { +class AbstractConverter; + +/// Generate call to a character comparison for two ssa-values of type +/// `boxchar`. +mlir::Value genBoxCharCompare(AbstractConverter &converter, mlir::Location loc, + mlir::CmpIPredicate cmp, mlir::Value lhs, + mlir::Value rhs); + +/// Generate call to a character comparison op for two unboxed variables. There +/// are 4 arguments, 2 for the lhs and 2 for the rhs. Each CHARACTER must pass a +/// reference to its buffer (`ref>`) and its LEN type parameter (some +/// integral type). +mlir::Value genRawCharCompare(AbstractConverter &converter, mlir::Location loc, + mlir::CmpIPredicate cmp, mlir::Value lhsBuff, + mlir::Value lhsLen, mlir::Value rhsBuff, + mlir::Value rhsLen); + +} // namespace lower +} // namespace Fortran + +#endif // FORTRAN_LOWER_CHARACTERRUNTIME_H diff --git a/flang/include/flang/Lower/Coarray.h b/flang/include/flang/Lower/Coarray.h new file mode 100644 index 0000000000000..e32c82d36e55e --- /dev/null +++ b/flang/include/flang/Lower/Coarray.h @@ -0,0 +1,78 @@ +//===-- Lower/Coarray.h -- image related lowering ---------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef FORTRAN_LOWER_COARRAY_H +#define FORTRAN_LOWER_COARRAY_H + +#include "flang/Lower/AbstractConverter.h" +#include "flang/Lower/Support/BoxValue.h" + +namespace Fortran { + +namespace parser { +struct ChangeTeamConstruct; +struct ChangeTeamStmt; +struct EndChangeTeamStmt; +struct FormTeamStmt; +} // namespace parser + +namespace evaluate { +class CoarrayRef; +} // namespace evaluate + +namespace lower { + +class SymMap; + +namespace pft { +struct Evaluation; +} // namespace pft + +//===----------------------------------------------------------------------===// +// TEAM constructs +//===----------------------------------------------------------------------===// + +void genChangeTeamConstruct(AbstractConverter &, pft::Evaluation &eval, + const parser::ChangeTeamConstruct &); +void genChangeTeamStmt(AbstractConverter &, pft::Evaluation &eval, + const parser::ChangeTeamStmt &); +void genEndChangeTeamStmt(AbstractConverter &, pft::Evaluation &eval, + const parser::EndChangeTeamStmt &); +void genFormTeamStatement(AbstractConverter &, pft::Evaluation &eval, + const parser::FormTeamStmt &); + +//===----------------------------------------------------------------------===// +// COARRAY expressions +//===----------------------------------------------------------------------===// + +/// Coarray expression lowering helper. A coarray expression is expected to be +/// lowered into runtime support calls. For example, expressions may use a +/// message-passing runtime to access another image's data. +class CoarrayExprHelper { +public: + explicit CoarrayExprHelper(AbstractConverter &converter, mlir::Location loc, + SymMap &syms) + : converter{converter}, symMap{syms}, loc{loc} {} + CoarrayExprHelper(const CoarrayExprHelper &) = delete; + + /// Generate the address of a co-array expression. + fir::ExtendedValue genAddr(const evaluate::CoarrayRef &expr); + + /// Generate the value of a co-array expression. + fir::ExtendedValue genValue(const evaluate::CoarrayRef &expr); + +private: + AbstractConverter &converter; + SymMap &symMap; + mlir::Location loc; +}; + +} // namespace lower +} // namespace Fortran + +#endif // FORTRAN_LOWER_COARRAY_H diff --git a/flang/include/flang/Lower/FIRBuilder.h b/flang/include/flang/Lower/FIRBuilder.h index f1fb15048c955..fa9efe267b54a 100644 --- a/flang/include/flang/Lower/FIRBuilder.h +++ b/flang/include/flang/Lower/FIRBuilder.h @@ -70,6 +70,10 @@ class FirOpBuilder : public mlir::OpBuilder { /// Safely create a reference type to the type `eleTy`. mlir::Type getRefType(mlir::Type eleTy); + /// Create a null constant of type RefType and value 0. Need to pass in the + /// Location information. + mlir::Value createNullConstant(mlir::Location loc); + /// Create an integer constant of type \p type and value \p i. mlir::Value createIntegerConstant(mlir::Location loc, mlir::Type integerType, std::int64_t i); diff --git a/flang/include/flang/Lower/IO.h b/flang/include/flang/Lower/IO.h new file mode 100644 index 0000000000000..9d5147f8e42a9 --- /dev/null +++ b/flang/include/flang/Lower/IO.h @@ -0,0 +1,98 @@ +//===-- Lower/IO.h -- lower I/O statements ----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef FORTRAN_LOWER_IO_H +#define FORTRAN_LOWER_IO_H + +#include "flang/Common/reference.h" +#include "flang/Semantics/symbol.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallSet.h" + +namespace mlir { +class Value; +} // namespace mlir + +namespace Fortran { +namespace parser { +using Label = std::uint64_t; +struct BackspaceStmt; +struct CloseStmt; +struct EndfileStmt; +struct FlushStmt; +struct InquireStmt; +struct OpenStmt; +struct PrintStmt; +struct ReadStmt; +struct RewindStmt; +struct WaitStmt; +struct WriteStmt; +} // namespace parser + +namespace lower { + +class AbstractConverter; +class BridgeImpl; + +namespace pft { +struct Evaluation; +using LabelEvalMap = llvm::DenseMap; +using SymbolRef = Fortran::common::Reference; +using LabelSet = llvm::SmallSet; +using SymbolLabelMap = llvm::DenseMap; +} // namespace pft + +/// Generate IO call(s) for BACKSPACE; return the IOSTAT code +mlir::Value genBackspaceStatement(AbstractConverter &, + const parser::BackspaceStmt &); + +/// Generate IO call(s) for CLOSE; return the IOSTAT code +mlir::Value genCloseStatement(AbstractConverter &, const parser::CloseStmt &); + +/// Generate IO call(s) for ENDFILE; return the IOSTAT code +mlir::Value genEndfileStatement(AbstractConverter &, + const parser::EndfileStmt &); + +/// Generate IO call(s) for FLUSH; return the IOSTAT code +mlir::Value genFlushStatement(AbstractConverter &, const parser::FlushStmt &); + +/// Generate IO call(s) for INQUIRE; return the IOSTAT code +mlir::Value genInquireStatement(AbstractConverter &, + const parser::InquireStmt &); + +/// Generate IO call(s) for OPEN; return the IOSTAT code +mlir::Value genOpenStatement(AbstractConverter &, const parser::OpenStmt &); + +/// Generate IO call(s) for PRINT +void genPrintStatement(AbstractConverter &converter, + const parser::PrintStmt &stmt, + pft::LabelEvalMap &labelMap, + pft::SymbolLabelMap &assignMap); + +/// Generate IO call(s) for READ; return the IOSTAT code +mlir::Value genReadStatement(AbstractConverter &converter, + const parser::ReadStmt &stmt, + pft::LabelEvalMap &labelMap, + pft::SymbolLabelMap &assignMap); + +/// Generate IO call(s) for REWIND; return the IOSTAT code +mlir::Value genRewindStatement(AbstractConverter &, const parser::RewindStmt &); + +/// Generate IO call(s) for WAIT; return the IOSTAT code +mlir::Value genWaitStatement(AbstractConverter &, const parser::WaitStmt &); + +/// Generate IO call(s) for WRITE; return the IOSTAT code +mlir::Value genWriteStatement(AbstractConverter &converter, + const parser::WriteStmt &stmt, + pft::LabelEvalMap &labelMap, + pft::SymbolLabelMap &assignMap); + +} // namespace lower +} // namespace Fortran + +#endif // FORTRAN_LOWER_IO_H diff --git a/flang/include/flang/Lower/IntrinsicCall.h b/flang/include/flang/Lower/IntrinsicCall.h new file mode 100644 index 0000000000000..2db1bda335b53 --- /dev/null +++ b/flang/include/flang/Lower/IntrinsicCall.h @@ -0,0 +1,67 @@ +//===-- Lower/IntrinsicCall.h -- lowering of intrinsics ---------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef FORTRAN_LOWER_INTRINSICCALL_H +#define FORTRAN_LOWER_INTRINSICCALL_H + +#include "flang/Lower/FIRBuilder.h" + +namespace fir { +class ExtendedValue; +} + +namespace Fortran::lower { + +// TODO: Expose interface to get specific intrinsic function address. +// TODO: Handle intrinsic subroutine. +// TODO: Intrinsics that do not require their arguments to be defined +// (e.g shape inquiries) might not fit in the current interface that +// requires mlir::Value to be provided. +// TODO: Error handling interface ? +// TODO: Implementation is incomplete. Many intrinsics to tbd. + +/// Helper for building calls to intrinsic functions in the runtime support +/// libraries. + +/// Generate the FIR+MLIR operations for the generic intrinsic \p name +/// with arguments \p args and expected result type \p resultType. +/// Returned mlir::Value is the returned Fortran intrinsic value. +fir::ExtendedValue genIntrinsicCall(FirOpBuilder &, mlir::Location, + llvm::StringRef name, mlir::Type resultType, + llvm::ArrayRef args); + +/// Get SymbolRefAttr of runtime (or wrapper function containing inlined +// implementation) of an unrestricted intrinsic (defined by its signature +// and generic name) +mlir::SymbolRefAttr +getUnrestrictedIntrinsicSymbolRefAttr(FirOpBuilder &, mlir::Location, + llvm::StringRef name, + mlir::FunctionType signature); + +//===--------------------------------------------------------------------===// +// Direct access to intrinsics that may be used by lowering outside +// of intrinsic call lowering. +//===--------------------------------------------------------------------===// + +/// Generate maximum. There must be at least one argument and all arguments +/// must have the same type. +mlir::Value genMax(FirOpBuilder &, mlir::Location, + llvm::ArrayRef args); + +/// Generate minimum. Same constraints as genMax. +mlir::Value genMin(FirOpBuilder &, mlir::Location, + llvm::ArrayRef args); + +/// Generate power function x**y with given the expected +/// result type. +mlir::Value genPow(FirOpBuilder &, mlir::Location, mlir::Type resultType, + mlir::Value x, mlir::Value y); + +} // namespace Fortran::lower + +#endif // FORTRAN_LOWER_INTRINSICCALL_H diff --git a/flang/include/flang/Lower/Mangler.h b/flang/include/flang/Lower/Mangler.h index b13b51355c812..7e18c069fc343 100644 --- a/flang/include/flang/Lower/Mangler.h +++ b/flang/include/flang/Lower/Mangler.h @@ -5,19 +5,32 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// +// +// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ +// +//===----------------------------------------------------------------------===// -#ifndef FORTRAN_LOWER_MANGLER_H_ -#define FORTRAN_LOWER_MANGLER_H_ +#ifndef FORTRAN_LOWER_MANGLER_H +#define FORTRAN_LOWER_MANGLER_H +#include "mlir/IR/StandardTypes.h" +#include "llvm/ADT/StringRef.h" #include namespace fir { struct NameUniquer; -} -namespace llvm { -class StringRef; -} +/// Returns a name suitable to define mlir functions for Fortran intrinsic +/// Procedure. These names are guaranteed to not conflict with user defined +/// procedures. This is needed to implement Fortran generic intrinsics as +/// several mlir functions specialized for the argument types. +/// The result is guaranteed to be distinct for different mlir::FunctionType +/// arguments. The mangling pattern is: +/// fir...... +/// e.g ACOS(COMPLEX(4)) is mangled as fir.acos.z4.z4 +std::string mangleIntrinsicProcedure(llvm::StringRef genericName, + mlir::FunctionType); +} // namespace fir namespace Fortran { namespace common { @@ -41,4 +54,4 @@ std::string demangleName(llvm::StringRef name); } // namespace lower } // namespace Fortran -#endif // FORTRAN_LOWER_MANGLER_H_ +#endif // FORTRAN_LOWER_MANGLER_H diff --git a/flang/include/flang/Lower/PFTBuilder.h b/flang/include/flang/Lower/PFTBuilder.h index 852700b8c0b15..1201470de704c 100644 --- a/flang/include/flang/Lower/PFTBuilder.h +++ b/flang/include/flang/Lower/PFTBuilder.h @@ -234,6 +234,12 @@ struct Evaluation : EvaluationVariant { return visit(common::visitors{ [](auto &r) { return pft::isDirective>; }}); } + constexpr bool isNopConstructStmt() const { + return visit(common::visitors{[](auto &r) { + return pft::isNopConstructStmt>; + }}); + } + /// Return the predicate: "This is a non-initial, non-terminal construct /// statement." For an IfConstruct, this is ElseIfStmt and ElseStmt. constexpr bool isIntermediateConstructStmt() const { @@ -241,14 +247,40 @@ struct Evaluation : EvaluationVariant { return pft::isIntermediateConstructStmt>; }}); } - constexpr bool isNopConstructStmt() const { - return visit(common::visitors{[](auto &r) { - return pft::isNopConstructStmt>; - }}); + + /// Return the first non-nop successor of an evaluation, possibly exiting + /// from one or more enclosing constructs. + Evaluation &nonNopSuccessor() const { + Evaluation *successor = lexicalSuccessor; + if (successor && successor->isNopConstructStmt()) { + successor = successor->parentConstruct->constructExit; + } + assert(successor && "missing successor"); + return *successor; } - /// Return FunctionLikeUnit to which this evaluation - /// belongs. Nullptr if it does not belong to such unit. + /// Return true if this Evaluation has at least one nested evaluation. + bool hasNestedEvaluations() const { + return evaluationList && !evaluationList->empty(); + } + + /// Return nested evaluation list. + EvaluationList &getNestedEvaluations() { + assert(evaluationList && "no nested evaluations"); + return *evaluationList; + } + + Evaluation &getFirstNestedEvaluation() { + assert(hasNestedEvaluations() && "no nested evaluations"); + return evaluationList->front(); + } + + Evaluation &getLastNestedEvaluation() { + assert(hasNestedEvaluations() && "no nested evaluations"); + return evaluationList->back(); + } + + /// Return the FunctionLikeUnit containing this evaluation (or nullptr). FunctionLikeUnit *getOwningProcedure() const; bool lowerAsStructured() const; @@ -297,9 +329,9 @@ struct Evaluation : EvaluationVariant { Evaluation *controlSuccessor{nullptr}; // set for some statements Evaluation *constructExit{nullptr}; // set for constructs bool isNewBlock{false}; // evaluation begins a new basic block - bool isUnstructured{false}; // evaluation has unstructured control flow - bool skip{false}; // evaluation has been processed in advance - class mlir::Block *block{nullptr}; // isNewBlock block + bool isUnstructured{false}; // evaluation has unstructured control flow + bool skip{false}; // evaluation has been processed in advance + mlir::Block *block{nullptr}; // isNewBlock block llvm::SmallVector localBlocks{}; // construct local blocks int printIndex{0}; // (ActionStmt, ConstructStmt) evaluation index for dumps }; @@ -333,13 +365,13 @@ struct Variable { : sym{&sym}, depth{depth}, global{global} {} const Fortran::semantics::Symbol &getSymbol() const { return *sym; } - + bool isGlobal() const { return global; } bool isHeapAlloc() const { return heapAlloc; } bool isPointer() const { return pointer; } bool isTarget() const { return target; } int getDepth() const { return depth; } - + void setHeapAlloc(bool to = true) { heapAlloc = to; } void setPointer(bool to = true) { pointer = to; } void setTarget(bool to = true) { target = to; } diff --git a/flang/include/flang/Lower/Runtime.h b/flang/include/flang/Lower/Runtime.h new file mode 100644 index 0000000000000..dcfce8ff63c31 --- /dev/null +++ b/flang/include/flang/Lower/Runtime.h @@ -0,0 +1,57 @@ +//===-- Lower/Runtime.h -- Fortran runtime codegen interface ----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Builder routines for constructing the FIR dialect of MLIR. As FIR is a +// dialect of MLIR, it makes extensive use of MLIR interfaces and MLIR's coding +// style (https://mlir.llvm.org/getting_started/DeveloperGuide/) is used in this +// module. +// +//===----------------------------------------------------------------------===// + +#ifndef FORTRAN_LOWER_RUNTIME_H +#define FORTRAN_LOWER_RUNTIME_H + +namespace Fortran { + +namespace parser { +struct EventPostStmt; +struct EventWaitStmt; +struct LockStmt; +struct PauseStmt; +struct StopStmt; +struct SyncAllStmt; +struct SyncImagesStmt; +struct SyncMemoryStmt; +struct SyncTeamStmt; +struct UnlockStmt; +} // namespace parser + +namespace lower { + +class AbstractConverter; + +// Lowering of Fortran statement related runtime (other than IO and maths) + +void genEventPostStatement(AbstractConverter &, const parser::EventPostStmt &); +void genEventWaitStatement(AbstractConverter &, const parser::EventWaitStmt &); +void genLockStatement(AbstractConverter &, const parser::LockStmt &); +void genFailImageStatement(AbstractConverter &); +void genStopStatement(AbstractConverter &, const parser::StopStmt &); +void genSyncAllStatement(AbstractConverter &, const parser::SyncAllStmt &); +void genSyncImagesStatement(AbstractConverter &, + const parser::SyncImagesStmt &); +void genSyncMemoryStatement(AbstractConverter &, + const parser::SyncMemoryStmt &); +void genSyncTeamStatement(AbstractConverter &, const parser::SyncTeamStmt &); +void genUnlockStatement(AbstractConverter &, const parser::UnlockStmt &); +void genPauseStatement(AbstractConverter &, const parser::PauseStmt &); + +} // namespace lower +} // namespace Fortran + +#endif // FORTRAN_LOWER_RUNTIME_H diff --git a/flang/include/flang/Lower/Support/BoxValue.h b/flang/include/flang/Lower/Support/BoxValue.h index 3516cd352969c..0d5dec97ef097 100644 --- a/flang/include/flang/Lower/Support/BoxValue.h +++ b/flang/include/flang/Lower/Support/BoxValue.h @@ -11,6 +11,7 @@ #include "mlir/IR/Value.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -67,7 +68,7 @@ class CharBoxValue : public AbstractBox { friend llvm::raw_ostream &operator<<(llvm::raw_ostream &, const CharBoxValue &); - void dump() const { llvm::errs() << *this; } + LLVM_DUMP_METHOD void dump() const { llvm::errs() << *this; } protected: mlir::Value len; @@ -117,7 +118,7 @@ class ArrayBoxValue : public AbstractBox, public AbstractArrayBox { friend llvm::raw_ostream &operator<<(llvm::raw_ostream &, const ArrayBoxValue &); - void dump() const { operator<<(llvm::errs(), *this); } + LLVM_DUMP_METHOD void dump() const { operator<<(llvm::errs(), *this); } }; /// Expressions of type CHARACTER and with rank > 0. @@ -134,7 +135,7 @@ class CharArrayBoxValue : public CharBoxValue, public AbstractArrayBox { friend llvm::raw_ostream &operator<<(llvm::raw_ostream &, const CharArrayBoxValue &); - void dump() const { operator<<(llvm::errs(), *this); } + LLVM_DUMP_METHOD void dump() const { operator<<(llvm::errs(), *this); } }; /// Expressions that are procedure POINTERs may need a set of references to @@ -152,7 +153,7 @@ class ProcBoxValue : public AbstractBox { friend llvm::raw_ostream &operator<<(llvm::raw_ostream &, const ProcBoxValue &); - void dump() const { operator<<(llvm::errs(), *this); } + LLVM_DUMP_METHOD void dump() const { operator<<(llvm::errs(), *this); } protected: mlir::Value hostContext; @@ -185,7 +186,7 @@ class BoxValue : public AbstractBox, public AbstractArrayBox { } friend llvm::raw_ostream &operator<<(llvm::raw_ostream &, const BoxValue &); - void dump() const { operator<<(llvm::errs(), *this); } + LLVM_DUMP_METHOD void dump() const { operator<<(llvm::errs(), *this); } protected: mlir::Value len; @@ -220,7 +221,7 @@ class ExtendedValue { } /// LLVM style debugging of extended values - void dump() const { llvm::errs() << *this << '\n'; } + LLVM_DUMP_METHOD void dump() const { llvm::errs() << *this << '\n'; } friend llvm::raw_ostream &operator<<(llvm::raw_ostream &, const ExtendedValue &); diff --git a/flang/include/flang/Optimizer/.clang-tidy b/flang/include/flang/Optimizer/.clang-tidy new file mode 100644 index 0000000000000..87ec2ff53af6e --- /dev/null +++ b/flang/include/flang/Optimizer/.clang-tidy @@ -0,0 +1,19 @@ +# Almost identical to the top-level .clang-tidy, except that {Member,Parameter,Variable}Case use camelBack. +Checks: '-*,clang-diagnostic-*,llvm-*,misc-*,-misc-unused-parameters,-misc-non-private-member-variables-in-classes,readability-identifier-naming' +CheckOptions: + - key: readability-identifier-naming.ClassCase + value: CamelCase + - key: readability-identifier-naming.EnumCase + value: CamelCase + - key: readability-identifier-naming.FunctionCase + value: camelBack + - key: readability-identifier-naming.MemberCase + value: camelBack + - key: readability-identifier-naming.ParameterCase + value: camelBack + - key: readability-identifier-naming.UnionCase + value: CamelCase + - key: readability-identifier-naming.VariableCase + value: camelBack + - key: readability-identifier-naming.IgnoreMainLikeFunctions + value: 1 diff --git a/flang/include/flang/Optimizer/CMakeLists.txt b/flang/include/flang/Optimizer/CMakeLists.txt index 0ca0f41c5af49..0fa521d5b9670 100644 --- a/flang/include/flang/Optimizer/CMakeLists.txt +++ b/flang/include/flang/Optimizer/CMakeLists.txt @@ -1 +1,3 @@ +add_subdirectory(CodeGen) add_subdirectory(Dialect) +add_subdirectory(Transforms) diff --git a/flang/include/flang/Optimizer/CodeGen/CGPasses.td b/flang/include/flang/Optimizer/CodeGen/CGPasses.td new file mode 100644 index 0000000000000..187147b8375fd --- /dev/null +++ b/flang/include/flang/Optimizer/CodeGen/CGPasses.td @@ -0,0 +1,24 @@ +//===-- CGPasses.td - code gen pass definition file --------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains definitions for passes within the Optimizer/CodeGen/ +// directory. +// +//===----------------------------------------------------------------------===// + +#ifndef FLANG_OPTIMIZER_CODEGEN_PASSES +#define FLANG_OPTIMIZER_CODEGEN_PASSES + +include "mlir/Pass/PassBase.td" + +def CodeGenRewrite : FunctionPass<"cg-rewrite"> { + let summary = "Rewrite some FIR ops into their code-gen forms."; + let constructor = "fir::createFirCodeGenRewritePass()"; +} + +#endif // FLANG_OPTIMIZER_CODEGEN_PASSES diff --git a/flang/include/flang/Optimizer/CodeGen/CMakeLists.txt b/flang/include/flang/Optimizer/CodeGen/CMakeLists.txt new file mode 100644 index 0000000000000..ab6526ee18330 --- /dev/null +++ b/flang/include/flang/Optimizer/CodeGen/CMakeLists.txt @@ -0,0 +1,6 @@ + +set(LLVM_TARGET_DEFINITIONS CGPasses.td) +mlir_tablegen(CGPasses.h.inc -gen-pass-decls) +add_public_tablegen_target(FIROptCodeGenPassIncGen) + +add_mlir_doc(Passes -gen-pass-doc OptimizerCodeGenPasses ./) diff --git a/flang/include/flang/Optimizer/CodeGen/CodeGen.h b/flang/include/flang/Optimizer/CodeGen/CodeGen.h index 9f6936e34e17b..9b968172f3486 100644 --- a/flang/include/flang/Optimizer/CodeGen/CodeGen.h +++ b/flang/include/flang/Optimizer/CodeGen/CodeGen.h @@ -9,19 +9,18 @@ #ifndef OPTIMIZER_CODEGEN_CODEGEN_H #define OPTIMIZER_CODEGEN_CODEGEN_H +#include "mlir/Pass/Pass.h" +#include "mlir/Pass/PassRegistry.h" #include -namespace llvm { -class raw_ostream; -} -namespace mlir { -class Pass; -} - namespace fir { struct NameUniquer; +/// Prerequiste pass for code gen. Perform intermediate rewrites to perform +/// the code gen (to LLVM-IR dialect) conversion. +std::unique_ptr createFirCodeGenRewritePass(); + /// Convert FIR to the LLVM IR dialect std::unique_ptr createFIRToLLVMPass(NameUniquer &uniquer); @@ -29,6 +28,13 @@ std::unique_ptr createFIRToLLVMPass(NameUniquer &uniquer); std::unique_ptr createLLVMDialectToLLVMPass(llvm::raw_ostream &output); +inline void registerOptCodeGenPasses() { + using mlir::Pass; +// declarative passes +#define GEN_PASS_REGISTRATION +#include "flang/Optimizer/CodeGen/CGPasses.h.inc" +} + } // namespace fir #endif // OPTIMIZER_CODEGEN_CODEGEN_H diff --git a/flang/include/flang/Optimizer/Dialect/FIRAttr.h b/flang/include/flang/Optimizer/Dialect/FIRAttr.h index 57ce5f13bf652..0b22bc21224cb 100644 --- a/flang/include/flang/Optimizer/Dialect/FIRAttr.h +++ b/flang/include/flang/Optimizer/Dialect/FIRAttr.h @@ -75,7 +75,8 @@ class SubclassAttr /// A case selector of `CASE (n:m)` corresponds to any value from `n` to `m` and /// is encoded as `#fir.interval, %n, %m`. class ClosedIntervalAttr - : public mlir::Attribute::AttrBase { + : public mlir::Attribute::AttrBase { public: using Base::Base; @@ -91,7 +92,9 @@ class ClosedIntervalAttr /// an ssa-value. /// A case selector of `CASE (:m)` corresponds to any value up to and including /// `m` and is encoded as `#fir.upper, %m`. -class UpperBoundAttr : public mlir::Attribute::AttrBase { +class UpperBoundAttr + : public mlir::Attribute::AttrBase { public: using Base::Base; @@ -107,7 +110,9 @@ class UpperBoundAttr : public mlir::Attribute::AttrBase { /// an ssa-value. /// A case selector of `CASE (n:)` corresponds to any value down to and /// including `n` and is encoded as `#fir.lower, %n`. -class LowerBoundAttr : public mlir::Attribute::AttrBase { +class LowerBoundAttr + : public mlir::Attribute::AttrBase { public: using Base::Base; @@ -123,7 +128,9 @@ class LowerBoundAttr : public mlir::Attribute::AttrBase { /// interval contains exactly one value. /// A case selector of `CASE (p)` corresponds to exactly the value `p` and is /// encoded as `#fir.point, %p`. -class PointIntervalAttr : public mlir::Attribute::AttrBase { +class PointIntervalAttr + : public mlir::Attribute::AttrBase { public: using Base::Base; diff --git a/flang/include/flang/Optimizer/Dialect/FIRType.h b/flang/include/flang/Optimizer/Dialect/FIRType.h index 3749c87b9e947..b1f1cc85b744a 100644 --- a/flang/include/flang/Optimizer/Dialect/FIRType.h +++ b/flang/include/flang/Optimizer/Dialect/FIRType.h @@ -242,7 +242,7 @@ class DimsType : public mlir::Type::TypeBase() || t.isa(); } +/// Is `t` an integral type? +inline bool isa_integer(mlir::Type t) { + return t.isa() || t.isa() || + t.isa(); +} + /// Is `t` a FIR or MLIR Complex type? inline bool isa_complex(mlir::Type t) { return t.isa() || t.isa(); diff --git a/flang/include/flang/Optimizer/Support/KindMapping.h b/flang/include/flang/Optimizer/Support/KindMapping.h index 8c8ed1f24afdd..b65f8285c3a81 100644 --- a/flang/include/flang/Optimizer/Support/KindMapping.h +++ b/flang/include/flang/Optimizer/Support/KindMapping.h @@ -1,4 +1,4 @@ -//===-- Optimizer/Support/KindMapping.h -------------------------*- C++ -*-===// +//===-- Optimizer/Support/KindMapping.h -- support kind mapping -*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -14,15 +14,9 @@ #include "llvm/IR/Type.h" namespace llvm { -template -class Optional; struct fltSemantics; } // namespace llvm -namespace mlir { -class MLIRContext; -} // namespace mlir - namespace fir { /// The kind mapping is an encoded string that informs FIR how the Fortran KIND @@ -57,24 +51,27 @@ class KindMapping { explicit KindMapping(mlir::MLIRContext *context, llvm::StringRef map); /// Get the size in bits of !fir.char - Bitsize getCharacterBitsize(KindTy kind); + Bitsize getCharacterBitsize(KindTy kind) const; /// Get the size in bits of !fir.int - Bitsize getIntegerBitsize(KindTy kind); + Bitsize getIntegerBitsize(KindTy kind) const; /// Get the size in bits of !fir.logical - Bitsize getLogicalBitsize(KindTy kind); + Bitsize getLogicalBitsize(KindTy kind) const; + + /// Get the size in bits of !fir.real + Bitsize getRealBitsize(KindTy kind) const; /// Get the LLVM Type::TypeID of !fir.real - LLVMTypeID getRealTypeID(KindTy kind); + LLVMTypeID getRealTypeID(KindTy kind) const; /// Get the LLVM Type::TypeID of !fir.complex - LLVMTypeID getComplexTypeID(KindTy kind); + LLVMTypeID getComplexTypeID(KindTy kind) const; mlir::MLIRContext *getContext() const { return context; } /// Get the float semantics of !fir.real - const llvm::fltSemantics &getFloatSemantics(KindTy kind); + const llvm::fltSemantics &getFloatSemantics(KindTy kind) const; private: MatchResult badMapString(const llvm::Twine &ptr); diff --git a/flang/include/flang/Optimizer/Transforms/CMakeLists.txt b/flang/include/flang/Optimizer/Transforms/CMakeLists.txt new file mode 100644 index 0000000000000..fde17eb88622e --- /dev/null +++ b/flang/include/flang/Optimizer/Transforms/CMakeLists.txt @@ -0,0 +1,6 @@ + +set(LLVM_TARGET_DEFINITIONS Passes.td) +mlir_tablegen(Passes.h.inc -gen-pass-decls) +add_public_tablegen_target(FIROptTransformsPassIncGen) + +add_mlir_doc(Passes -gen-pass-doc OptimizerTransformPasses ./) diff --git a/flang/include/flang/Optimizer/Transforms/Passes.h b/flang/include/flang/Optimizer/Transforms/Passes.h new file mode 100644 index 0000000000000..9377c2dc61cc3 --- /dev/null +++ b/flang/include/flang/Optimizer/Transforms/Passes.h @@ -0,0 +1,58 @@ +//===-- Optimizer/Transforms/Passes.h ---------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef OPTIMIZER_TRANSFORMS_PASSES_H +#define OPTIMIZER_TRANSFORMS_PASSES_H + +#include "mlir/Pass/Pass.h" +#include "mlir/Pass/PassRegistry.h" +#include + +namespace mlir { +class BlockAndValueMapping; +class Operation; +class Pass; +class Region; +} // namespace mlir + +namespace fir { + +/// Convert fir.select_type to the standard dialect +std::unique_ptr createControlFlowLoweringPass(); + +/// Effects aware CSE pass +std::unique_ptr createCSEPass(); + +/// Convert FIR loop constructs to the Affine dialect +std::unique_ptr createPromoteToAffinePass(); + +/// Convert `fir.do_loop` and `fir.if` to a CFG. This +/// conversion enables the `createLowerToCFGPass` to transform these to CFG +/// form. +std::unique_ptr createFirToCfgPass(); + +/// A pass to convert the FIR dialect from "Mem-SSA" form to "Reg-SSA" +/// form. This pass is a port of LLVM's mem2reg pass, but modified for the FIR +/// dialect as well as the restructuring of MLIR's representation to present PHI +/// nodes as block arguments. +std::unique_ptr createMemToRegPass(); + +/// Support for inlining on FIR. +bool canLegallyInline(mlir::Operation *op, mlir::Region *reg, + mlir::BlockAndValueMapping &map); + +inline void registerOptTransformPasses() { +using mlir::Pass; +// declarative passes +#define GEN_PASS_REGISTRATION +#include "flang/Optimizer/Transforms/Passes.h.inc" +} + +} // namespace fir + +#endif // OPTIMIZER_TRANSFORMS_PASSES_H diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td new file mode 100644 index 0000000000000..c558d99af8dc3 --- /dev/null +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -0,0 +1,51 @@ +//===-- Passes.td - Transforms pass definition file --------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains definitions for passes within the Optimizer/Transforms/ +// directory. +// +//===----------------------------------------------------------------------===// + +#ifndef FLANG_OPTIMIZER_TRANSFORMS_PASSES +#define FLANG_OPTIMIZER_TRANSFORMS_PASSES + +include "mlir/Pass/PassBase.td" + +def AffineDialectPromotion : FunctionPass<"promote-to-affine"> { + let summary = "Promotes fir.loop and fir.where to affine.for and affine.if where possible"; + let description = [{ + TODO + }]; + let constructor = "fir::createPromoteToAffinePass()"; +} + +def BasicCSE : FunctionPass<"basic-cse"> { + let summary = "Basic common sub-expression elimination"; + let description = [{ + TODO + }]; + let constructor = "fir::createCSEPass()"; +} + +def ControlFlowLowering : FunctionPass<"lower-control-flow"> { + let summary = "Convert affine dialect, fir.select_type to standard dialect"; + let description = [{ + TODO + }]; + let constructor = "fir::createControlFlowLoweringPass()"; +} + +def CFGConversion : FunctionPass<"cfg-conversion"> { + let summary = "Convert FIR structured control flow ops to CFG ops."; + let description = [{ + TODO + }]; + let constructor = "fir::createFirToCfgPass()"; +} + +#endif // FLANG_OPTIMIZER_TRANSFORMS_PASSES diff --git a/flang/include/flang/Parser/characters.h b/flang/include/flang/Parser/characters.h index c18140780956a..eefb524e5d879 100644 --- a/flang/include/flang/Parser/characters.h +++ b/flang/include/flang/Parser/characters.h @@ -96,9 +96,9 @@ inline constexpr bool IsSameApartFromCase(char x, char y) { inline constexpr char DecimalDigitValue(char ch) { return ch - '0'; } inline constexpr char HexadecimalDigitValue(char ch) { - return IsUpperCaseLetter(ch) - ? ch - 'A' + 10 - : IsLowerCaseLetter(ch) ? ch - 'a' + 10 : DecimalDigitValue(ch); + return IsUpperCaseLetter(ch) ? ch - 'A' + 10 + : IsLowerCaseLetter(ch) ? ch - 'a' + 10 + : DecimalDigitValue(ch); } inline constexpr std::optional BackslashEscapeValue(char ch) { diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index ad93fcd257954..59333c7405ffa 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -409,7 +409,11 @@ class ParseTreeDumper { NODE(parser, OmpBeginLoopDirective) NODE(parser, OmpBeginSectionsDirective) NODE(parser, OmpBlockDirective) - NODE_ENUM(OmpBlockDirective, Directive) + static std::string GetNodeName(const llvm::omp::Directive &x) { + return llvm::Twine( + "llvm::omp::Directive = ", llvm::omp::getOpenMPDirectiveName(x)) + .str(); + } NODE(parser, OmpCancelType) NODE_ENUM(OmpCancelType, Type) NODE(parser, OmpClause) @@ -477,7 +481,6 @@ class ParseTreeDumper { NODE(parser, OmpLinearModifier) NODE_ENUM(OmpLinearModifier, Type) NODE(parser, OmpLoopDirective) - NODE_ENUM(OmpLoopDirective, Directive) NODE(parser, OmpMapClause) NODE(parser, OmpMapType) NODE(OmpMapType, Always) @@ -505,9 +508,7 @@ class ParseTreeDumper { NODE_ENUM(OmpScheduleModifierType, ModType) NODE(parser, OmpSectionBlocks) NODE(parser, OmpSectionsDirective) - NODE_ENUM(OmpSectionsDirective, Directive) NODE(parser, OmpSimpleStandaloneDirective) - NODE_ENUM(OmpSimpleStandaloneDirective, Directive) NODE(parser, Only) NODE(parser, OpenMPAtomicConstruct) NODE(parser, OpenMPBlockConstruct) @@ -520,6 +521,8 @@ class ParseTreeDumper { NODE(parser, OpenMPDeclareReductionConstruct) NODE(parser, OpenMPDeclareSimdConstruct) NODE(parser, OpenMPDeclareTargetConstruct) + NODE(parser, OmpFlushMemoryClause) + NODE_ENUM(OmpFlushMemoryClause, FlushMemoryOrder) NODE(parser, OpenMPFlushConstruct) NODE(parser, OpenMPLoopConstruct) NODE(parser, OpenMPSimpleStandaloneConstruct) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index 933638d039d35..67fd5741b0975 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -25,6 +25,7 @@ #include "flang/Common/Fortran.h" #include "flang/Common/idioms.h" #include "flang/Common/indirection.h" +#include "llvm/Frontend/OpenMP/OMPConstants.h" #include #include #include @@ -1394,8 +1395,7 @@ WRAPPER_CLASS(ContiguousStmt, std::list); using ConstantSubobject = Constant>; // Represents an analyzed expression -using TypedExpr = std::unique_ptr>; +using TypedExpr = common::ForwardOwningPointer; // R845 data-stmt-constant -> // scalar-constant | scalar-constant-subobject | @@ -1918,8 +1918,8 @@ struct DeallocateStmt { // R1032 assignment-stmt -> variable = expr struct AssignmentStmt { TUPLE_CLASS_BOILERPLATE(AssignmentStmt); - using TypedAssignment = std::unique_ptr>; + using TypedAssignment = + common::ForwardOwningPointer; mutable TypedAssignment typedAssignment; std::tuple t; }; @@ -3139,8 +3139,7 @@ struct FunctionReference { // R1521 call-stmt -> CALL procedure-designator [( [actual-arg-spec-list] )] struct CallStmt { WRAPPER_CLASS_BOILERPLATE(CallStmt, Call); - mutable std::unique_ptr> + mutable common::ForwardOwningPointer typedCall; // filled by semantics }; @@ -3495,8 +3494,7 @@ struct OmpClauseList { // 2.7.2 SECTIONS // 2.11.2 PARALLEL SECTIONS struct OmpSectionsDirective { - ENUM_CLASS(Directive, Sections, ParallelSections); - WRAPPER_CLASS_BOILERPLATE(OmpSectionsDirective, Directive); + WRAPPER_CLASS_BOILERPLATE(OmpSectionsDirective, llvm::omp::Directive); CharBlock source; }; @@ -3527,10 +3525,7 @@ struct OpenMPSectionsConstruct { // OpenMP directive beginning or ending a block struct OmpBlockDirective { - ENUM_CLASS(Directive, Master, Ordered, Parallel, ParallelWorkshare, Single, - Target, TargetData, TargetParallel, TargetTeams, Task, Taskgroup, Teams, - Workshare); - WRAPPER_CLASS_BOILERPLATE(OmpBlockDirective, Directive); + WRAPPER_CLASS_BOILERPLATE(OmpBlockDirective, llvm::omp::Directive); CharBlock source; }; @@ -3684,15 +3679,7 @@ struct OpenMPAtomicConstruct { // OpenMP directives that associate with loop(s) struct OmpLoopDirective { - ENUM_CLASS(Directive, Distribute, DistributeParallelDo, - DistributeParallelDoSimd, DistributeSimd, ParallelDo, ParallelDoSimd, Do, - DoSimd, Simd, TargetParallelDo, TargetParallelDoSimd, - TargetTeamsDistribute, TargetTeamsDistributeParallelDo, - TargetTeamsDistributeParallelDoSimd, TargetTeamsDistributeSimd, - TargetSimd, Taskloop, TaskloopSimd, TeamsDistribute, - TeamsDistributeParallelDo, TeamsDistributeParallelDoSimd, - TeamsDistributeSimd) - WRAPPER_CLASS_BOILERPLATE(OmpLoopDirective, Directive); + WRAPPER_CLASS_BOILERPLATE(OmpLoopDirective, llvm::omp::Directive); CharBlock source; }; @@ -3718,17 +3705,27 @@ struct OpenMPCancelConstruct { std::tuple> t; }; -// 2.13.7 flush -> FLUSH [(variable-name-list)] +// 2.17.8 Flush Construct [OpenMP 5.0] +// memory-order-clause -> acq_rel +// release +// acquire +struct OmpFlushMemoryClause { + ENUM_CLASS(FlushMemoryOrder, AcqRel, Release, Acquire) + WRAPPER_CLASS_BOILERPLATE(OmpFlushMemoryClause, FlushMemoryOrder); + CharBlock source; +}; + +// 2.17.8 flush -> FLUSH [memory-order-clause] [(variable-name-list)] struct OpenMPFlushConstruct { TUPLE_CLASS_BOILERPLATE(OpenMPFlushConstruct); CharBlock source; - std::tuple> t; + std::tuple, + std::optional> + t; }; struct OmpSimpleStandaloneDirective { - ENUM_CLASS(Directive, Barrier, Taskwait, Taskyield, TargetEnterData, - TargetExitData, TargetUpdate, Ordered) - WRAPPER_CLASS_BOILERPLATE(OmpSimpleStandaloneDirective, Directive); + WRAPPER_CLASS_BOILERPLATE(OmpSimpleStandaloneDirective, llvm::omp::Directive); CharBlock source; }; diff --git a/flang/include/flang/Parser/tools.h b/flang/include/flang/Parser/tools.h index c918425a29787..fa6ecd08a3186 100644 --- a/flang/include/flang/Parser/tools.h +++ b/flang/include/flang/Parser/tools.h @@ -99,6 +99,8 @@ template A *Unwrap(B &x) { // Get the CoindexedNamedObject if the entity is a coindexed object. const CoindexedNamedObject *GetCoindexedNamedObject(const AllocateObject &); const CoindexedNamedObject *GetCoindexedNamedObject(const DataRef &); +const CoindexedNamedObject *GetCoindexedNamedObject(const Designator &); +const CoindexedNamedObject *GetCoindexedNamedObject(const Variable &); // Detects parse tree nodes with "source" members. template struct HasSource : std::false_type {}; diff --git a/flang/include/flang/Semantics/expression.h b/flang/include/flang/Semantics/expression.h index 1b94ce62a996e..4148a0d605d86 100644 --- a/flang/include/flang/Semantics/expression.h +++ b/flang/include/flang/Semantics/expression.h @@ -70,7 +70,8 @@ class IntrinsicProcTable; struct SetExprHelper { explicit SetExprHelper(GenericExprWrapper &&expr) : expr_{std::move(expr)} {} void Set(parser::TypedExpr &x) { - x.reset(new GenericExprWrapper{std::move(expr_)}); + x.Reset(new GenericExprWrapper{std::move(expr_)}, + evaluate::GenericExprWrapper::Deleter); } void Set(const parser::Expr &x) { Set(x.typedExpr); } void Set(const parser::Variable &x) { Set(x.typedExpr); } diff --git a/flang/include/flang/Semantics/scope.h b/flang/include/flang/Semantics/scope.h index 3913889ac27b9..a67a008889276 100644 --- a/flang/include/flang/Semantics/scope.h +++ b/flang/include/flang/Semantics/scope.h @@ -38,9 +38,10 @@ class SemanticsContext; // the indices for an array element, and the lower bound for a substring. struct EquivalenceObject { EquivalenceObject(Symbol &symbol, std::vector subscripts, - std::optional substringStart) - : symbol{symbol}, subscripts{subscripts}, substringStart{substringStart} { - } + std::optional substringStart, parser::CharBlock source) + : symbol{symbol}, subscripts{subscripts}, + substringStart{substringStart}, source{source} {} + bool operator==(const EquivalenceObject &) const; bool operator<(const EquivalenceObject &) const; std::string AsFortran() const; @@ -48,6 +49,7 @@ struct EquivalenceObject { Symbol &symbol; std::vector subscripts; // for array elem std::optional substringStart; + parser::CharBlock source; }; using EquivalenceSet = std::vector; @@ -263,8 +265,9 @@ class Scope { // Inline so that it can be called from Evaluate without a link-time dependency. inline const Symbol *Scope::GetSymbol() const { - return symbol_ ? symbol_ - : derivedTypeSpec_ ? &derivedTypeSpec_->typeSymbol() : nullptr; + return symbol_ ? symbol_ + : derivedTypeSpec_ ? &derivedTypeSpec_->typeSymbol() + : nullptr; } } // namespace Fortran::semantics diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h index 0de6e462133d1..227f951aef5f0 100644 --- a/flang/include/flang/Semantics/symbol.h +++ b/flang/include/flang/Semantics/symbol.h @@ -423,7 +423,6 @@ struct GenericKind { class GenericDetails { public: GenericDetails() {} - GenericDetails(const SymbolVector &specificProcs); GenericKind kind() const { return kind_; } void set_kind(GenericKind kind) { kind_ = kind; } diff --git a/flang/include/flang/Semantics/tools.h b/flang/include/flang/Semantics/tools.h index 86a766bf963c4..f63e4ccbc687c 100644 --- a/flang/include/flang/Semantics/tools.h +++ b/flang/include/flang/Semantics/tools.h @@ -85,7 +85,6 @@ bool IsPointerDummy(const Symbol &); bool IsBindCProcedure(const Symbol &); bool IsBindCProcedure(const Scope &); bool IsProcName(const Symbol &); // proc-name -bool IsFunctionResult(const Symbol &); bool IsFunctionResultWithSameNameAsFunction(const Symbol &); bool IsExtensibleType(const DerivedTypeSpec *); bool IsBuiltinDerivedType(const DerivedTypeSpec *derived, const char *name); @@ -100,6 +99,7 @@ bool IsInitialized(const Symbol &, bool ignoreDATAstatements = false); bool HasIntrinsicTypeName(const Symbol &); bool IsSeparateModuleProcedureInterface(const Symbol *); bool IsAutomatic(const Symbol &); +bool HasAlternateReturns(const Symbol &); // Return an ultimate component of type that matches predicate, or nullptr. const Symbol *FindUltimateComponent(const DerivedTypeSpec &type, diff --git a/flang/lib/Decimal/big-radix-floating-point.h b/flang/lib/Decimal/big-radix-floating-point.h index 18626e2b55df4..53bd9d7249145 100644 --- a/flang/lib/Decimal/big-radix-floating-point.h +++ b/flang/lib/Decimal/big-radix-floating-point.h @@ -27,7 +27,6 @@ #include "flang/Common/unsigned-const-division.h" #include "flang/Decimal/binary-floating-point.h" #include "flang/Decimal/decimal.h" -#include "llvm/Support/raw_ostream.h" #include #include #include @@ -112,7 +111,7 @@ template class BigRadixFloatingPointNumber { void Minimize( BigRadixFloatingPointNumber &&less, BigRadixFloatingPointNumber &&more); - llvm::raw_ostream &Dump(llvm::raw_ostream &) const; + template STREAM &Dump(STREAM &) const; private: BigRadixFloatingPointNumber(const BigRadixFloatingPointNumber &that) diff --git a/flang/lib/Decimal/binary-to-decimal.cpp b/flang/lib/Decimal/binary-to-decimal.cpp index 02e39c241ee1a..ad30b4d854033 100644 --- a/flang/lib/Decimal/binary-to-decimal.cpp +++ b/flang/lib/Decimal/binary-to-decimal.cpp @@ -389,8 +389,8 @@ ConversionToDecimalResult ConvertLongDoubleToDecimal(char *buffer, } template -llvm::raw_ostream &BigRadixFloatingPointNumber::Dump( - llvm::raw_ostream &o) const { +template +STREAM &BigRadixFloatingPointNumber::Dump(STREAM &o) const { if (isNegative_) { o << '-'; } diff --git a/flang/lib/Evaluate/CMakeLists.txt b/flang/lib/Evaluate/CMakeLists.txt index ddcdc80186586..9ab83d7c1c258 100644 --- a/flang/lib/Evaluate/CMakeLists.txt +++ b/flang/lib/Evaluate/CMakeLists.txt @@ -1,3 +1,13 @@ +if (LIBPGMATH_DIR) + # If pgmath library is found, it can be used for constant folding. + find_library(LIBPGMATH pgmath PATHS ${LIBPGMATH_DIR}) + if(LIBPGMATH) + add_compile_definitions(LINK_WITH_LIBPGMATH) + message(STATUS "Found libpgmath: ${LIBPGMATH}") + else() + message(STATUS "Libpgmath not found in: ${LIBPGMATH_DIR}") + endif() +endif() add_flang_library(FortranEvaluate call.cpp @@ -31,18 +41,10 @@ add_flang_library(FortranEvaluate LINK_LIBS FortranCommon FortranDecimal - FortranSemantics FortranParser + ${LIBPGMATH} + + DEPENDS + omp_gen ) -if (LIBPGMATH_DIR) - # If pgmath library is found, it can be used for constant folding. - find_library(LIBPGMATH pgmath PATHS ${LIBPGMATH_DIR}) - if(LIBPGMATH) - add_compile_definitions(LINK_WITH_LIBPGMATH) - target_link_libraries(FortranEvaluate ${LIBPGMATH}) - message(STATUS "Found libpgmath: ${LIBPGMATH}") - else() - message(STATUS "Libpgmath not found in: ${LIBPGMATH_DIR}") - endif() -endif() diff --git a/flang/lib/Evaluate/call.cpp b/flang/lib/Evaluate/call.cpp index c9d6fe0ddb807..b4cf0dc3af3ab 100644 --- a/flang/lib/Evaluate/call.cpp +++ b/flang/lib/Evaluate/call.cpp @@ -212,6 +212,7 @@ int ProcedureRef::Rank() const { ProcedureRef::~ProcedureRef() {} +void ProcedureRef::Deleter(ProcedureRef *p) { delete p; } + FOR_EACH_SPECIFIC_TYPE(template class FunctionRef, ) } // namespace Fortran::evaluate -DEFINE_DELETER(Fortran::evaluate::ProcedureRef) diff --git a/flang/lib/Evaluate/expression.cpp b/flang/lib/Evaluate/expression.cpp index 604e4ff41ce23..5a456648b8254 100644 --- a/flang/lib/Evaluate/expression.cpp +++ b/flang/lib/Evaluate/expression.cpp @@ -223,8 +223,14 @@ StructureConstructor &StructureConstructor::Add( GenericExprWrapper::~GenericExprWrapper() {} +void GenericExprWrapper::Deleter(GenericExprWrapper *p) { delete p; } + GenericAssignmentWrapper::~GenericAssignmentWrapper() {} +void GenericAssignmentWrapper::Deleter(GenericAssignmentWrapper *p) { + delete p; +} + template int Expr>::GetKind() const { return std::visit( [](const auto &kx) { return std::decay_t::Result::kind; }, @@ -243,5 +249,3 @@ std::optional> Expr::LEN() const { INSTANTIATE_EXPRESSION_TEMPLATES } // namespace Fortran::evaluate -DEFINE_DELETER(Fortran::evaluate::GenericExprWrapper) -DEFINE_DELETER(Fortran::evaluate::GenericAssignmentWrapper) diff --git a/flang/lib/Evaluate/fold-integer.cpp b/flang/lib/Evaluate/fold-integer.cpp index 3472f9a444c15..9b96a479df597 100644 --- a/flang/lib/Evaluate/fold-integer.cpp +++ b/flang/lib/Evaluate/fold-integer.cpp @@ -157,9 +157,8 @@ Expr> FoldIntrinsicFunction( } else if (name == "ceiling" || name == "floor" || name == "nint") { if (const auto *cx{UnwrapExpr>(args[0])}) { // NINT rounds ties away from zero, not to even - common::RoundingMode mode{name == "ceiling" - ? common::RoundingMode::Up - : name == "floor" ? common::RoundingMode::Down + common::RoundingMode mode{name == "ceiling" ? common::RoundingMode::Up + : name == "floor" ? common::RoundingMode::Down : common::RoundingMode::TiesAwayFromZero}; return std::visit( [&](const auto &kx) { @@ -322,8 +321,8 @@ Expr> FoldIntrinsicFunction( return name == "index" ? CharacterUtils::INDEX(str, other) : name == "scan" - ? CharacterUtils::SCAN(str, other) - : CharacterUtils::VERIFY(str, other); + ? CharacterUtils::SCAN(str, other) + : CharacterUtils::VERIFY(str, other); }}); } }, @@ -613,7 +612,9 @@ Expr> FoldOperation( if (iter != scope->end()) { const Symbol &symbol{*iter->second}; const auto *details{symbol.detailsIf()}; - if (details && details->init()) { + if (details && details->init() && + (details->attr() == common::TypeParamAttr::Kind || + IsConstantExpr(*details->init()))) { Expr expr{*details->init()}; return Fold(context, Expr{ diff --git a/flang/lib/Evaluate/fold-real.cpp b/flang/lib/Evaluate/fold-real.cpp index 657bc0c2033f3..e3db35caf7e2e 100644 --- a/flang/lib/Evaluate/fold-real.cpp +++ b/flang/lib/Evaluate/fold-real.cpp @@ -42,7 +42,7 @@ Expr> FoldIntrinsicFunction( return RewriteSpecificMINorMAX(context, std::move(funcRef)); } else if (name == "atan" || name == "atan2" || name == "hypot" || name == "mod") { - std::string localName{name == "atan2" ? "atan" : name}; + std::string localName{name == "atan" ? "atan2" : name}; CHECK(args.size() == 2); if (auto callable{ context.hostIntrinsicsLibrary() diff --git a/flang/lib/Evaluate/host.cpp b/flang/lib/Evaluate/host.cpp index ea831274b9425..c9aa5c4bbce3b 100644 --- a/flang/lib/Evaluate/host.cpp +++ b/flang/lib/Evaluate/host.cpp @@ -11,6 +11,9 @@ #include "flang/Common/idioms.h" #include "llvm/Support/Errno.h" #include +#if __x86_64__ +#include +#endif namespace Fortran::evaluate::host { using namespace Fortran::parser::literals; @@ -18,39 +21,42 @@ using namespace Fortran::parser::literals; void HostFloatingPointEnvironment::SetUpHostFloatingPointEnvironment( FoldingContext &context) { errno = 0; + std::fenv_t currentFenv; if (feholdexcept(&originalFenv_) != 0) { common::die("Folding with host runtime: feholdexcept() failed: %s", llvm::sys::StrError(errno).c_str()); return; } - if (fegetenv(¤tFenv_) != 0) { + if (fegetenv(¤tFenv) != 0) { common::die("Folding with host runtime: fegetenv() failed: %s", llvm::sys::StrError(errno).c_str()); return; } #if __x86_64__ hasSubnormalFlushingHardwareControl_ = true; + originalMxcsr = _mm_getcsr(); + unsigned int currentMxcsr{originalMxcsr}; if (context.flushSubnormalsToZero()) { - currentFenv_.__mxcsr |= 0x8000; // result - currentFenv_.__mxcsr |= 0x0040; // operands + currentMxcsr |= 0x8000; + currentMxcsr |= 0x0040; } else { - currentFenv_.__mxcsr &= ~0x8000; // result - currentFenv_.__mxcsr &= ~0x0040; // operands + currentMxcsr &= ~0x8000; + currentMxcsr &= ~0x0040; } #elif defined(__aarch64__) #if defined(__GNU_LIBRARY__) hasSubnormalFlushingHardwareControl_ = true; if (context.flushSubnormalsToZero()) { - currentFenv_.__fpcr |= (1U << 24); // control register + currentFenv.__fpcr |= (1U << 24); // control register } else { - currentFenv_.__fpcr &= ~(1U << 24); // control register + currentFenv.__fpcr &= ~(1U << 24); // control register } #elif defined(__BIONIC__) hasSubnormalFlushingHardwareControl_ = true; if (context.flushSubnormalsToZero()) { - currentFenv_.__control |= (1U << 24); // control register + currentFenv.__control |= (1U << 24); // control register } else { - currentFenv_.__control &= ~(1U << 24); // control register + currentFenv.__control &= ~(1U << 24); // control register } #else // If F18 is built with other C libraries on AArch64, software flushing will @@ -70,11 +76,15 @@ void HostFloatingPointEnvironment::SetUpHostFloatingPointEnvironment( hardwareFlagsAreReliable_ = false; #endif errno = 0; - if (fesetenv(¤tFenv_) != 0) { + if (fesetenv(¤tFenv) != 0) { common::die("Folding with host runtime: fesetenv() failed: %s", llvm::sys::StrError(errno).c_str()); return; } +#if __x86_64__ + _mm_setcsr(currentMxcsr); +#endif + switch (context.rounding().mode) { case common::RoundingMode::TiesToEven: fesetround(FE_TONEAREST); @@ -141,6 +151,10 @@ void HostFloatingPointEnvironment::CheckAndRestoreFloatingPointEnvironment( "Folding with host runtime: fesetenv() failed while restoring fenv: %s", llvm::sys::StrError(errno).c_str()); } +#if __x86_64__ + _mm_setcsr(originalMxcsr); +#endif + errno = 0; } } // namespace Fortran::evaluate::host diff --git a/flang/lib/Evaluate/host.h b/flang/lib/Evaluate/host.h index 20355ae3147a9..2fac0424f17cc 100644 --- a/flang/lib/Evaluate/host.h +++ b/flang/lib/Evaluate/host.h @@ -41,7 +41,9 @@ class HostFloatingPointEnvironment { private: std::fenv_t originalFenv_; - std::fenv_t currentFenv_; +#if __x86_64__ + unsigned int originalMxcsr; +#endif RealFlags flags_; bool hasSubnormalFlushingHardwareControl_{false}; bool hardwareFlagsAreReliable_{true}; diff --git a/flang/lib/Evaluate/intrinsics-library.cpp b/flang/lib/Evaluate/intrinsics-library.cpp index 84c71e145bb60..c81ad4f34563a 100644 --- a/flang/lib/Evaluate/intrinsics-library.cpp +++ b/flang/lib/Evaluate/intrinsics-library.cpp @@ -57,7 +57,7 @@ static void AddLibmRealHostProcedures( {"asin", F{std::asin}, true}, {"asinh", F{std::asinh}, true}, {"atan", F{std::atan}, true}, - {"atan", F2{std::atan2}, true}, + {"atan2", F2{std::atan2}, true}, {"atanh", F{std::atanh}, true}, {"cos", F{std::cos}, true}, {"cosh", F{std::cosh}, true}, @@ -135,7 +135,8 @@ static void AddLibmComplexHostProcedures( } } -void InitHostIntrinsicLibraryWithLibm(HostIntrinsicProceduresLibrary &lib) { +[[maybe_unused]] static void InitHostIntrinsicLibraryWithLibm( + HostIntrinsicProceduresLibrary &lib) { if constexpr (host::FortranTypeExists()) { AddLibmRealHostProcedures(lib); } @@ -158,397 +159,213 @@ void InitHostIntrinsicLibraryWithLibm(HostIntrinsicProceduresLibrary &lib) { } #if LINK_WITH_LIBPGMATH -namespace pgmath { -// Define mapping between numerical intrinsics and libpgmath symbols -// namespace is used to have shorter names on repeated patterns. -// A class would be better to hold all these defs, but GCC does not -// support specialization of template variables inside class even -// if it is C++14 standard compliant here because there are only full -// specializations. - -// List of intrinsics that have libpgmath implementations that can be used for -// constant folding The tag names must match the name used inside libpgmath name -// so that the macro below work. -enum class I { - acos, - acosh, - asin, - asinh, - atan, - atan2, - atanh, - bessel_j0, - bessel_j1, - bessel_jn, - bessel_y0, - bessel_y1, - bessel_yn, - cos, - cosh, - erf, - erfc, - erfc_scaled, - exp, - gamma, - hypot, - log, - log10, - log_gamma, - mod, - pow, - sin, - sinh, - sqrt, - tan, - tanh -}; +// Only use libpgmath for folding if it is available. +// First declare all libpgmaths functions +#define PGMATH_DECLARE +#include "../runtime/pgmath.h.inc" // Library versions: P for Precise, R for Relaxed, F for Fast enum class L { F, R, P }; -struct NoSuchRuntimeSymbol {}; -template constexpr auto Sym{NoSuchRuntimeSymbol{}}; - -// Macros to declare fast/relaxed/precise libpgmath variants. -#define DECLARE_PGMATH_FAST_REAL(func) \ - extern "C" float __fs_##func##_1(float); \ - extern "C" double __fd_##func##_1(double); \ - template <> constexpr auto Sym{__fs_##func##_1}; \ - template <> constexpr auto Sym{__fd_##func##_1}; - -#define DECLARE_PGMATH_FAST_COMPLEX(func) \ - extern "C" float _Complex __fc_##func##_1(float _Complex); \ - extern "C" double _Complex __fz_##func##_1(double _Complex); \ - template <> \ - constexpr auto Sym>{__fc_##func##_1}; \ - template <> \ - constexpr auto Sym>{__fz_##func##_1}; - -#define DECLARE_PGMATH_FAST_ALL_FP(func) \ - DECLARE_PGMATH_FAST_REAL(func) \ - DECLARE_PGMATH_FAST_COMPLEX(func) - -#define DECLARE_PGMATH_PRECISE_REAL(func) \ - extern "C" float __ps_##func##_1(float); \ - extern "C" double __pd_##func##_1(double); \ - template <> constexpr auto Sym{__ps_##func##_1}; \ - template <> constexpr auto Sym{__pd_##func##_1}; - -#define DECLARE_PGMATH_PRECISE_COMPLEX(func) \ - extern "C" float _Complex __pc_##func##_1(float _Complex); \ - extern "C" double _Complex __pz_##func##_1(double _Complex); \ - template <> \ - constexpr auto Sym>{__pc_##func##_1}; \ - template <> \ - constexpr auto Sym>{__pz_##func##_1}; - -#define DECLARE_PGMATH_PRECISE_ALL_FP(func) \ - DECLARE_PGMATH_PRECISE_REAL(func) \ - DECLARE_PGMATH_PRECISE_COMPLEX(func) - -#define DECLARE_PGMATH_RELAXED_REAL(func) \ - extern "C" float __rs_##func##_1(float); \ - extern "C" double __rd_##func##_1(double); \ - template <> constexpr auto Sym{__rs_##func##_1}; \ - template <> constexpr auto Sym{__rd_##func##_1}; - -#define DECLARE_PGMATH_RELAXED_COMPLEX(func) \ - extern "C" float _Complex __rc_##func##_1(float _Complex); \ - extern "C" double _Complex __rz_##func##_1(double _Complex); \ - template <> \ - constexpr auto Sym>{__rc_##func##_1}; \ - template <> \ - constexpr auto Sym>{__rz_##func##_1}; - -#define DECLARE_PGMATH_RELAXED_ALL_FP(func) \ - DECLARE_PGMATH_RELAXED_REAL(func) \ - DECLARE_PGMATH_RELAXED_COMPLEX(func) - -#define DECLARE_PGMATH_REAL(func) \ - DECLARE_PGMATH_FAST_REAL(func) \ - DECLARE_PGMATH_PRECISE_REAL(func) \ - DECLARE_PGMATH_RELAXED_REAL(func) - -#define DECLARE_PGMATH_COMPLEX(func) \ - DECLARE_PGMATH_FAST_COMPLEX(func) \ - DECLARE_PGMATH_PRECISE_COMPLEX(func) \ - DECLARE_PGMATH_RELAXED_COMPLEX(func) - -#define DECLARE_PGMATH_ALL(func) \ - DECLARE_PGMATH_REAL(func) \ - DECLARE_PGMATH_COMPLEX(func) - -// Macros to declare fast/relaxed/precise libpgmath variants with two arguments. -#define DECLARE_PGMATH_FAST_REAL2(func) \ - extern "C" float __fs_##func##_1(float, float); \ - extern "C" double __fd_##func##_1(double, double); \ - template <> constexpr auto Sym{__fs_##func##_1}; \ - template <> constexpr auto Sym{__fd_##func##_1}; - -#define DECLARE_PGMATH_FAST_COMPLEX2(func) \ - extern "C" float _Complex __fc_##func##_1(float _Complex, float _Complex); \ - extern "C" double _Complex __fz_##func##_1( \ - double _Complex, double _Complex); \ - template <> \ - constexpr auto Sym>{__fc_##func##_1}; \ - template <> \ - constexpr auto Sym>{__fz_##func##_1}; - -#define DECLARE_PGMATH_FAST_ALL_FP2(func) \ - DECLARE_PGMATH_FAST_REAL2(func) \ - DECLARE_PGMATH_FAST_COMPLEX2(func) - -#define DECLARE_PGMATH_PRECISE_REAL2(func) \ - extern "C" float __ps_##func##_1(float, float); \ - extern "C" double __pd_##func##_1(double, double); \ - template <> constexpr auto Sym{__ps_##func##_1}; \ - template <> constexpr auto Sym{__pd_##func##_1}; - -#define DECLARE_PGMATH_PRECISE_COMPLEX2(func) \ - extern "C" float _Complex __pc_##func##_1(float _Complex, float _Complex); \ - extern "C" double _Complex __pz_##func##_1( \ - double _Complex, double _Complex); \ - template <> \ - constexpr auto Sym>{__pc_##func##_1}; \ - template <> \ - constexpr auto Sym>{__pz_##func##_1}; - -#define DECLARE_PGMATH_PRECISE_ALL_FP2(func) \ - DECLARE_PGMATH_PRECISE_REAL2(func) \ - DECLARE_PGMATH_PRECISE_COMPLEX2(func) - -#define DECLARE_PGMATH_RELAXED_REAL2(func) \ - extern "C" float __rs_##func##_1(float, float); \ - extern "C" double __rd_##func##_1(double, double); \ - template <> constexpr auto Sym{__rs_##func##_1}; \ - template <> constexpr auto Sym{__rd_##func##_1}; - -#define DECLARE_PGMATH_RELAXED_COMPLEX2(func) \ - extern "C" float _Complex __rc_##func##_1(float _Complex, float _Complex); \ - extern "C" double _Complex __rz_##func##_1( \ - double _Complex, double _Complex); \ - template <> \ - constexpr auto Sym>{__rc_##func##_1}; \ - template <> \ - constexpr auto Sym>{__rz_##func##_1}; - -#define DECLARE_PGMATH_RELAXED_ALL_FP2(func) \ - DECLARE_PGMATH_RELAXED_REAL2(func) \ - DECLARE_PGMATH_RELAXED_COMPLEX2(func) - -#define DECLARE_PGMATH_REAL2(func) \ - DECLARE_PGMATH_FAST_REAL2(func) \ - DECLARE_PGMATH_PRECISE_REAL2(func) \ - DECLARE_PGMATH_RELAXED_REAL2(func) - -#define DECLARE_PGMATH_COMPLEX2(func) \ - DECLARE_PGMATH_FAST_COMPLEX2(func) \ - DECLARE_PGMATH_PRECISE_COMPLEX2(func) \ - DECLARE_PGMATH_RELAXED_COMPLEX2(func) - -#define DECLARE_PGMATH_ALL2(func) \ - DECLARE_PGMATH_REAL2(func) \ - DECLARE_PGMATH_COMPLEX2(func) - -// Marcos to declare __mth_i libpgmath variants -#define DECLARE_PGMATH_MTH_VERSION_REAL(func) \ - extern "C" float __mth_i_##func(float); \ - extern "C" double __mth_i_d##func(double); \ - template <> constexpr auto Sym{__mth_i_##func}; \ - template <> constexpr auto Sym{__mth_i_d##func}; \ - template <> constexpr auto Sym{__mth_i_##func}; \ - template <> constexpr auto Sym{__mth_i_d##func}; \ - template <> constexpr auto Sym{__mth_i_##func}; \ - template <> constexpr auto Sym{__mth_i_d##func}; - -// Actual libpgmath declarations -DECLARE_PGMATH_ALL(acos) -DECLARE_PGMATH_MTH_VERSION_REAL(acosh) -DECLARE_PGMATH_ALL(asin) -DECLARE_PGMATH_MTH_VERSION_REAL(asinh) -DECLARE_PGMATH_ALL(atan) -DECLARE_PGMATH_REAL2(atan2) -DECLARE_PGMATH_MTH_VERSION_REAL(atanh) -DECLARE_PGMATH_MTH_VERSION_REAL(bessel_j0) -DECLARE_PGMATH_MTH_VERSION_REAL(bessel_j1) -DECLARE_PGMATH_MTH_VERSION_REAL(bessel_y0) -DECLARE_PGMATH_MTH_VERSION_REAL(bessel_y1) -// bessel_jn and bessel_yn takes an int as first arg -extern "C" float __mth_i_bessel_jn(int, float); -extern "C" double __mth_i_dbessel_jn(int, double); -template <> constexpr auto Sym{__mth_i_bessel_jn}; -template <> constexpr auto Sym{__mth_i_dbessel_jn}; -template <> constexpr auto Sym{__mth_i_bessel_jn}; -template <> constexpr auto Sym{__mth_i_dbessel_jn}; -template <> constexpr auto Sym{__mth_i_bessel_jn}; -template <> constexpr auto Sym{__mth_i_dbessel_jn}; -extern "C" float __mth_i_bessel_yn(int, float); -extern "C" double __mth_i_dbessel_yn(int, double); -template <> constexpr auto Sym{__mth_i_bessel_yn}; -template <> constexpr auto Sym{__mth_i_dbessel_yn}; -template <> constexpr auto Sym{__mth_i_bessel_yn}; -template <> constexpr auto Sym{__mth_i_dbessel_yn}; -template <> constexpr auto Sym{__mth_i_bessel_yn}; -template <> constexpr auto Sym{__mth_i_dbessel_yn}; -DECLARE_PGMATH_ALL(cos) -DECLARE_PGMATH_ALL(cosh) -DECLARE_PGMATH_MTH_VERSION_REAL(erf) -DECLARE_PGMATH_MTH_VERSION_REAL(erfc) -DECLARE_PGMATH_MTH_VERSION_REAL(erfc_scaled) -DECLARE_PGMATH_ALL(exp) -DECLARE_PGMATH_MTH_VERSION_REAL(gamma) -extern "C" float __mth_i_hypot(float, float); -extern "C" double __mth_i_dhypot(double, double); -template <> constexpr auto Sym{__mth_i_hypot}; -template <> constexpr auto Sym{__mth_i_dhypot}; -template <> constexpr auto Sym{__mth_i_hypot}; -template <> constexpr auto Sym{__mth_i_dhypot}; -template <> constexpr auto Sym{__mth_i_hypot}; -template <> constexpr auto Sym{__mth_i_dhypot}; -DECLARE_PGMATH_ALL(log) -DECLARE_PGMATH_REAL(log10) -DECLARE_PGMATH_MTH_VERSION_REAL(log_gamma) -// no function for modulo in libpgmath -extern "C" float __fs_mod_1(float, float); -extern "C" double __fd_mod_1(double, double); -template <> constexpr auto Sym{__fs_mod_1}; -template <> constexpr auto Sym{__fd_mod_1}; -template <> constexpr auto Sym{__fs_mod_1}; -template <> constexpr auto Sym{__fd_mod_1}; -template <> constexpr auto Sym{__fs_mod_1}; -template <> constexpr auto Sym{__fd_mod_1}; -DECLARE_PGMATH_ALL2(pow) -DECLARE_PGMATH_ALL(sin) -DECLARE_PGMATH_ALL(sinh) -DECLARE_PGMATH_MTH_VERSION_REAL(sqrt) -DECLARE_PGMATH_COMPLEX(sqrt) // real versions are __mth_i... -DECLARE_PGMATH_ALL(tan) -DECLARE_PGMATH_ALL(tanh) - // Fill the function map used for folding with libpgmath symbols -template -static void AddLibpgmathRealHostProcedures( +template +static void AddLibpgmathFloatHostProcedures( HostIntrinsicProceduresLibrary &hostIntrinsicLibrary) { - static_assert(std::is_same_v || std::is_same_v); - HostRuntimeIntrinsicProcedure pgmathSymbols[]{ - {"acos", Sym, true}, - {"acosh", Sym, true}, - {"asin", Sym, true}, - {"asinh", Sym, true}, - {"atan", Sym, true}, - {"atan", Sym, - true}, // atan is also the generic name for atan2 - {"atanh", Sym, true}, - {"bessel_j0", Sym, true}, - {"bessel_j1", Sym, true}, - {"bessel_jn", Sym, true}, - {"bessel_y0", Sym, true}, - {"bessel_y1", Sym, true}, - {"bessel_yn", Sym, true}, - {"cos", Sym, true}, - {"cosh", Sym, true}, - {"erf", Sym, true}, - {"erfc", Sym, true}, - {"erfc_scaled", Sym, true}, - {"exp", Sym, true}, - {"gamma", Sym, true}, - {"hypot", Sym, true}, - {"log", Sym, true}, - {"log10", Sym, true}, - {"log_gamma", Sym, true}, - {"mod", Sym, true}, - {"pow", Sym, true}, - {"sin", Sym, true}, - {"sinh", Sym, true}, - {"sqrt", Sym, true}, - {"tan", Sym, true}, - {"tanh", Sym, true}, - }; + if constexpr (Lib == L::F) { + HostRuntimeIntrinsicProcedure pgmathSymbols[]{ +#define PGMATH_FAST +#define PGMATH_USE_S(name, function) {#name, function, true}, +#include "../runtime/pgmath.h.inc" + }; + for (auto sym : pgmathSymbols) { + hostIntrinsicLibrary.AddProcedure(std::move(sym)); + } + } else if constexpr (Lib == L::R) { + HostRuntimeIntrinsicProcedure pgmathSymbols[]{ +#define PGMATH_RELAXED +#define PGMATH_USE_S(name, function) {#name, function, true}, +#include "../runtime/pgmath.h.inc" + }; + for (auto sym : pgmathSymbols) { + hostIntrinsicLibrary.AddProcedure(std::move(sym)); + } + } else { + static_assert(Lib == L::P && "unexpected libpgmath version"); + HostRuntimeIntrinsicProcedure pgmathSymbols[]{ +#define PGMATH_PRECISE +#define PGMATH_USE_S(name, function) {#name, function, true}, +#include "../runtime/pgmath.h.inc" + }; + for (auto sym : pgmathSymbols) { + hostIntrinsicLibrary.AddProcedure(std::move(sym)); + } + } +} - for (auto sym : pgmathSymbols) { - hostIntrinsicLibrary.AddProcedure(std::move(sym)); +template +static void AddLibpgmathDoubleHostProcedures( + HostIntrinsicProceduresLibrary &hostIntrinsicLibrary) { + if constexpr (Lib == L::F) { + HostRuntimeIntrinsicProcedure pgmathSymbols[]{ +#define PGMATH_FAST +#define PGMATH_USE_D(name, function) {#name, function, true}, +#include "../runtime/pgmath.h.inc" + }; + for (auto sym : pgmathSymbols) { + hostIntrinsicLibrary.AddProcedure(std::move(sym)); + } + } else if constexpr (Lib == L::R) { + HostRuntimeIntrinsicProcedure pgmathSymbols[]{ +#define PGMATH_RELAXED +#define PGMATH_USE_D(name, function) {#name, function, true}, +#include "../runtime/pgmath.h.inc" + }; + for (auto sym : pgmathSymbols) { + hostIntrinsicLibrary.AddProcedure(std::move(sym)); + } + } else { + static_assert(Lib == L::P && "unexpected libpgmath version"); + HostRuntimeIntrinsicProcedure pgmathSymbols[]{ +#define PGMATH_PRECISE +#define PGMATH_USE_D(name, function) {#name, function, true}, +#include "../runtime/pgmath.h.inc" + }; + for (auto sym : pgmathSymbols) { + hostIntrinsicLibrary.AddProcedure(std::move(sym)); + } } } -// Note: std::complex and _complex are layout compatible but are not guaranteed +// Note: Lipgmath uses _Complex but the front-end use std::complex for folding. +// std::complex and _Complex are layout compatible but are not guaranteed // to be linkage compatible. For instance, on i386, float _Complex is returned // by a pair of register but std::complex is returned by structure // address. To fix the issue, wrapper around C _Complex functions are defined // below. -template func> -static std::complex ComplexCFuncWrapper(std::complex &arg) { - float _Complex res{func(*reinterpret_cast(&arg))}; - return *reinterpret_cast *>(&res); -} -template func> -static std::complex ComplexCFuncWrapper(std::complex &arg) { - double _Complex res{func(*reinterpret_cast(&arg))}; - return *reinterpret_cast *>(&res); -} - -template func> -static std::complex ComplexCFuncWrapper( - std::complex &arg1, std::complex &arg2) { - float _Complex res{func(*reinterpret_cast(&arg1), - *reinterpret_cast(&arg2))}; - return *reinterpret_cast *>(&res); -} +template struct ToStdComplex { + using Type = T; + using AType = Type; +}; -template func> -static std::complex ComplexCFuncWrapper( - std::complex &arg1, std::complex &arg2) { - double _Complex res{func(*reinterpret_cast(&arg1), - *reinterpret_cast(&arg2))}; - return *reinterpret_cast *>(&res); -} +template struct CComplexFunc {}; +template func> +struct CComplexFunc, func> { + static typename ToStdComplex::Type wrapper( + typename ToStdComplex::AType... args) { + R res{func(*reinterpret_cast(&args)...)}; + return *reinterpret_cast::Type *>(&res); + } +}; -template +template static void AddLibpgmathComplexHostProcedures( HostIntrinsicProceduresLibrary &hostIntrinsicLibrary) { - static_assert(std::is_same_v || std::is_same_v); - using CHostT = std::complex; + if constexpr (Lib == L::F) { + HostRuntimeIntrinsicProcedure pgmathSymbols[]{ +#define PGMATH_FAST +#define PGMATH_USE_C(name, function) \ + {#name, CComplexFunc::wrapper, true}, +#include "../runtime/pgmath.h.inc" + }; + for (auto sym : pgmathSymbols) { + hostIntrinsicLibrary.AddProcedure(std::move(sym)); + } + } else if constexpr (Lib == L::R) { + HostRuntimeIntrinsicProcedure pgmathSymbols[]{ +#define PGMATH_RELAXED +#define PGMATH_USE_C(name, function) \ + {#name, CComplexFunc::wrapper, true}, +#include "../runtime/pgmath.h.inc" + }; + for (auto sym : pgmathSymbols) { + hostIntrinsicLibrary.AddProcedure(std::move(sym)); + } + } else { + static_assert(Lib == L::P && "unexpected libpgmath version"); + HostRuntimeIntrinsicProcedure pgmathSymbols[]{ +#define PGMATH_PRECISE +#define PGMATH_USE_C(name, function) \ + {#name, CComplexFunc::wrapper, true}, +#include "../runtime/pgmath.h.inc" + }; + for (auto sym : pgmathSymbols) { + hostIntrinsicLibrary.AddProcedure(std::move(sym)); + } + } + // cmath is used to complement pgmath when symbols are not available + using HostT = float; + using CHostT = std::complex; using CmathF = FuncPointer; - HostRuntimeIntrinsicProcedure pgmathSymbols[]{ - {"abs", FuncPointer{std::abs}, true}, - {"acos", ComplexCFuncWrapper>, true}, - {"acosh", CmathF{std::acosh}, true}, - {"asin", ComplexCFuncWrapper>, true}, - {"asinh", CmathF{std::asinh}, true}, - {"atan", ComplexCFuncWrapper>, true}, - {"atanh", CmathF{std::atanh}, true}, - {"cos", ComplexCFuncWrapper>, true}, - {"cosh", ComplexCFuncWrapper>, true}, - {"exp", ComplexCFuncWrapper>, true}, - {"log", ComplexCFuncWrapper>, true}, - {"pow", ComplexCFuncWrapper>, true}, - {"sin", ComplexCFuncWrapper>, true}, - {"sinh", ComplexCFuncWrapper>, true}, - {"sqrt", ComplexCFuncWrapper>, true}, - {"tan", ComplexCFuncWrapper>, true}, - {"tanh", ComplexCFuncWrapper>, true}, - }; + hostIntrinsicLibrary.AddProcedure( + {"abs", FuncPointer{std::abs}, true}); + hostIntrinsicLibrary.AddProcedure({"acosh", CmathF{std::acosh}, true}); + hostIntrinsicLibrary.AddProcedure({"asinh", CmathF{std::asinh}, true}); + hostIntrinsicLibrary.AddProcedure({"atanh", CmathF{std::atanh}, true}); +} - for (auto sym : pgmathSymbols) { - hostIntrinsicLibrary.AddProcedure(std::move(sym)); +template +static void AddLibpgmathDoubleComplexHostProcedures( + HostIntrinsicProceduresLibrary &hostIntrinsicLibrary) { + if constexpr (Lib == L::F) { + HostRuntimeIntrinsicProcedure pgmathSymbols[]{ +#define PGMATH_FAST +#define PGMATH_USE_Z(name, function) \ + {#name, CComplexFunc::wrapper, true}, +#include "../runtime/pgmath.h.inc" + }; + for (auto sym : pgmathSymbols) { + hostIntrinsicLibrary.AddProcedure(std::move(sym)); + } + } else if constexpr (Lib == L::R) { + HostRuntimeIntrinsicProcedure pgmathSymbols[]{ +#define PGMATH_RELAXED +#define PGMATH_USE_Z(name, function) \ + {#name, CComplexFunc::wrapper, true}, +#include "../runtime/pgmath.h.inc" + }; + for (auto sym : pgmathSymbols) { + hostIntrinsicLibrary.AddProcedure(std::move(sym)); + } + } else { + static_assert(Lib == L::P && "unexpected libpgmath version"); + HostRuntimeIntrinsicProcedure pgmathSymbols[]{ +#define PGMATH_PRECISE +#define PGMATH_USE_Z(name, function) \ + {#name, CComplexFunc::wrapper, true}, +#include "../runtime/pgmath.h.inc" + }; + for (auto sym : pgmathSymbols) { + hostIntrinsicLibrary.AddProcedure(std::move(sym)); + } } + + // cmath is used to complement pgmath when symbols are not available + using HostT = double; + using CHostT = std::complex; + using CmathF = FuncPointer; + hostIntrinsicLibrary.AddProcedure( + {"abs", FuncPointer{std::abs}, true}); + hostIntrinsicLibrary.AddProcedure({"acosh", CmathF{std::acosh}, true}); + hostIntrinsicLibrary.AddProcedure({"asinh", CmathF{std::asinh}, true}); + hostIntrinsicLibrary.AddProcedure({"atanh", CmathF{std::atanh}, true}); } template static void InitHostIntrinsicLibraryWithLibpgmath( HostIntrinsicProceduresLibrary &lib) { if constexpr (host::FortranTypeExists()) { - AddLibpgmathRealHostProcedures(lib); + AddLibpgmathFloatHostProcedures(lib); } if constexpr (host::FortranTypeExists()) { - AddLibpgmathRealHostProcedures(lib); + AddLibpgmathDoubleHostProcedures(lib); } if constexpr (host::FortranTypeExists>()) { - AddLibpgmathComplexHostProcedures(lib); + AddLibpgmathComplexHostProcedures(lib); } if constexpr (host::FortranTypeExists>()) { - AddLibpgmathComplexHostProcedures(lib); + AddLibpgmathDoubleComplexHostProcedures(lib); } // No long double functions in libpgmath if constexpr (host::FortranTypeExists()) { @@ -558,7 +375,6 @@ static void InitHostIntrinsicLibraryWithLibpgmath( AddLibmComplexHostProcedures(lib); } } -} // namespace pgmath #endif // LINK_WITH_LIBPGMATH // Define which host runtime functions will be used for folding @@ -571,11 +387,11 @@ HostIntrinsicProceduresLibrary::HostIntrinsicProceduresLibrary() { // to silence clang warnings on unused symbols if all declared pgmath // symbols are not used somewhere. if (true) { - pgmath::InitHostIntrinsicLibraryWithLibpgmath(*this); + InitHostIntrinsicLibraryWithLibpgmath(*this); } else if (false) { - pgmath::InitHostIntrinsicLibraryWithLibpgmath(*this); + InitHostIntrinsicLibraryWithLibpgmath(*this); } else { - pgmath::InitHostIntrinsicLibraryWithLibpgmath(*this); + InitHostIntrinsicLibraryWithLibpgmath(*this); } #else InitHostIntrinsicLibraryWithLibm(*this); diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp index 0f92dd8e7f505..6237499d12ef7 100644 --- a/flang/lib/Evaluate/intrinsics.cpp +++ b/flang/lib/Evaluate/intrinsics.cpp @@ -496,28 +496,28 @@ static const IntrinsicInterface genericIntrinsicFunction[]{ {"logical", {{"l", AnyLogical}, DefaultingKIND}, KINDLogical}, {"log_gamma", {{"x", SameReal}}, SameReal}, {"matmul", - {{"array_a", AnyLogical, Rank::vector}, - {"array_b", AnyLogical, Rank::matrix}}, + {{"matrix_a", AnyLogical, Rank::vector}, + {"matrix_b", AnyLogical, Rank::matrix}}, ResultLogical, Rank::vector, IntrinsicClass::transformationalFunction}, {"matmul", - {{"array_a", AnyLogical, Rank::matrix}, - {"array_b", AnyLogical, Rank::vector}}, + {{"matrix_a", AnyLogical, Rank::matrix}, + {"matrix_b", AnyLogical, Rank::vector}}, ResultLogical, Rank::vector, IntrinsicClass::transformationalFunction}, {"matmul", - {{"array_a", AnyLogical, Rank::matrix}, - {"array_b", AnyLogical, Rank::matrix}}, + {{"matrix_a", AnyLogical, Rank::matrix}, + {"matrix_b", AnyLogical, Rank::matrix}}, ResultLogical, Rank::matrix, IntrinsicClass::transformationalFunction}, {"matmul", - {{"array_a", AnyNumeric, Rank::vector}, - {"array_b", AnyNumeric, Rank::matrix}}, + {{"matrix_a", AnyNumeric, Rank::vector}, + {"matrix_b", AnyNumeric, Rank::matrix}}, ResultNumeric, Rank::vector, IntrinsicClass::transformationalFunction}, {"matmul", - {{"array_a", AnyNumeric, Rank::matrix}, - {"array_b", AnyNumeric, Rank::vector}}, + {{"matrix_a", AnyNumeric, Rank::matrix}, + {"matrix_b", AnyNumeric, Rank::vector}}, ResultNumeric, Rank::vector, IntrinsicClass::transformationalFunction}, {"matmul", - {{"array_a", AnyNumeric, Rank::matrix}, - {"array_b", AnyNumeric, Rank::matrix}}, + {{"matrix_a", AnyNumeric, Rank::matrix}, + {"matrix_b", AnyNumeric, Rank::matrix}}, ResultNumeric, Rank::matrix, IntrinsicClass::transformationalFunction}, {"maskl", {{"i", AnyInt}, DefaultingKIND}, KINDInt}, {"maskr", {{"i", AnyInt}, DefaultingKIND}, KINDInt}, @@ -581,6 +581,10 @@ static const IntrinsicInterface genericIntrinsicFunction[]{ Rank::dimReduced, IntrinsicClass::transformationalFunction}, {"not", {{"i", SameInt}}, SameInt}, // NULL() is a special case handled in Probe() below + {"num_images", {}, DefaultInt, Rank::scalar, + IntrinsicClass::transformationalFunction}, + {"num_images", {{"team_number", AnyInt, Rank::scalar}}, DefaultInt, + Rank::scalar, IntrinsicClass::transformationalFunction}, {"out_of_range", {{"x", AnyIntOrReal}, {"mold", AnyIntOrReal, Rank::scalar}}, DefaultLogical}, @@ -724,7 +728,7 @@ static const IntrinsicInterface genericIntrinsicFunction[]{ // TODO: Coarray intrinsic functions // LCOBOUND, UCOBOUND, FAILED_IMAGES, GET_TEAM, IMAGE_INDEX, -// NUM_IMAGES, STOPPED_IMAGES, TEAM_NUMBER, THIS_IMAGE, +// STOPPED_IMAGES, TEAM_NUMBER, THIS_IMAGE, // COSHAPE // TODO: Non-standard intrinsic functions // AND, OR, XOR, LSHIFT, RSHIFT, SHIFT, ZEXT, IZEXT, @@ -1904,7 +1908,6 @@ std::optional IntrinsicProcTable::Implementation::Probe( } if (call.isSubroutineCall) { - parser::Messages buffer; auto subrRange{subroutines_.equal_range(call.name)}; for (auto iter{subrRange.first}; iter != subrRange.second; ++iter) { if (auto specificCall{ diff --git a/flang/lib/Evaluate/shape.cpp b/flang/lib/Evaluate/shape.cpp index 507de428b54a9..90d864466e2dc 100644 --- a/flang/lib/Evaluate/shape.cpp +++ b/flang/lib/Evaluate/shape.cpp @@ -205,7 +205,7 @@ auto GetLowerBoundHelper::operator()(const Symbol &symbol0) -> Result { if (j++ == dimension_) { if (const auto &bound{shapeSpec.lbound().GetExplicit()}) { return Fold(context_, common::Clone(*bound)); - } else if (semantics::IsDescriptor(symbol)) { + } else if (IsDescriptor(symbol)) { return ExtentExpr{DescriptorInquiry{NamedEntity{symbol0}, DescriptorInquiry::Field::LowerBound, dimension_}}; } else { @@ -230,7 +230,7 @@ auto GetLowerBoundHelper::operator()(const Component &component) -> Result { if (j++ == dimension_) { if (const auto &bound{shapeSpec.lbound().GetExplicit()}) { return Fold(context_, common::Clone(*bound)); - } else if (semantics::IsDescriptor(symbol)) { + } else if (IsDescriptor(symbol)) { return ExtentExpr{ DescriptorInquiry{NamedEntity{common::Clone(component)}, DescriptorInquiry::Field::LowerBound, dimension_}}; @@ -545,6 +545,23 @@ auto GetShapeHelper::operator()(const ProcedureRef &call) const -> Result { if (!call.arguments().empty()) { return (*this)(call.arguments()[0]); } + } else if (intrinsic->name == "matmul") { + if (call.arguments().size() == 2) { + if (auto ashape{(*this)(call.arguments()[0])}) { + if (auto bshape{(*this)(call.arguments()[1])}) { + if (ashape->size() == 1 && bshape->size() == 2) { + bshape->erase(bshape->begin()); + return std::move(*bshape); // matmul(vector, matrix) + } else if (ashape->size() == 2 && bshape->size() == 1) { + ashape->pop_back(); + return std::move(*ashape); // matmul(matrix, vector) + } else if (ashape->size() == 2 && bshape->size() == 2) { + (*ashape)[1] = std::move((*bshape)[1]); + return std::move(*ashape); // matmul(matrix, matrix) + } + } + } + } } else if (intrinsic->name == "reshape") { if (call.arguments().size() >= 2 && call.arguments().at(1)) { // SHAPE(RESHAPE(array,shape)) -> shape diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp index 3538cd587f970..677b263408b39 100644 --- a/flang/lib/Evaluate/tools.cpp +++ b/flang/lib/Evaluate/tools.cpp @@ -1003,7 +1003,7 @@ bool IsSaved(const Symbol &original) { } else if (const Symbol * block{FindCommonBlockContaining(symbol)}; block && block->attrs().test(Attr::SAVE)) { return true; - } else if (IsDummy(symbol)) { + } else if (IsDummy(symbol) || IsFunctionResult(symbol)) { return false; } else { for (; !scope->IsGlobal(); scope = &scope->parent()) { @@ -1026,6 +1026,13 @@ bool IsDummy(const Symbol &symbol) { symbol.details()); } +bool IsFunctionResult(const Symbol &symbol) { + return (symbol.has() && + symbol.get().isFuncResult()) || + (symbol.has() && + symbol.get().isFuncResult()); +} + int CountLenParameters(const DerivedTypeSpec &type) { return std::count_if(type.parameters().begin(), type.parameters().end(), [](const auto &pair) { return pair.second.isLen(); }); diff --git a/flang/lib/Evaluate/type.cpp b/flang/lib/Evaluate/type.cpp index 0a823cd20398f..293cd18648148 100644 --- a/flang/lib/Evaluate/type.cpp +++ b/flang/lib/Evaluate/type.cpp @@ -22,17 +22,21 @@ // IsDescriptor() predicate: true when a symbol is implemented // at runtime with a descriptor. -// TODO there's probably a better place for this predicate than here namespace Fortran::semantics { -static bool IsDescriptor(const ObjectEntityDetails &details) { - if (const auto *type{details.type()}) { +static bool IsDescriptor(const DeclTypeSpec *type) { + if (type) { if (auto dynamicType{evaluate::DynamicType::From(*type)}) { - if (dynamicType->RequiresDescriptor()) { - return true; - } + return dynamicType->RequiresDescriptor(); } } + return false; +} + +static bool IsDescriptor(const ObjectEntityDetails &details) { + if (IsDescriptor(details.type())) { + return true; + } // TODO: Automatic (adjustable) arrays - are they descriptors? for (const ShapeSpec &shapeSpec : details.shape()) { const auto &lb{shapeSpec.lbound().GetExplicit()}; @@ -62,6 +66,7 @@ bool IsDescriptor(const Symbol &symbol) { symbol.attrs().test(Attr::EXTERNAL)) && IsDescriptor(d); }, + [&](const EntityDetails &d) { return IsDescriptor(d.type()); }, [](const AssocEntityDetails &d) { if (const auto &expr{d.expr()}) { if (expr->Rank() > 0) { @@ -149,7 +154,7 @@ bool DynamicType::IsAssumedLengthCharacter() const { charLength_->isAssumed(); } -bool DynamicType::IsUnknownLengthCharacter() const { +bool DynamicType::IsNonConstantLengthCharacter() const { if (category_ != TypeCategory::Character) { return false; } else if (!charLength_) { @@ -471,7 +476,7 @@ DynamicType DynamicType::ResultTypeForMultiply(const DynamicType &that) const { } bool DynamicType::RequiresDescriptor() const { - return IsPolymorphic() || IsUnknownLengthCharacter() || + return IsPolymorphic() || IsNonConstantLengthCharacter() || (derived_ && CountNonConstantLenParameters(*derived_) > 0); } diff --git a/flang/lib/Evaluate/variable.cpp b/flang/lib/Evaluate/variable.cpp index 3a6cf560384c8..8c9bd18285af4 100644 --- a/flang/lib/Evaluate/variable.cpp +++ b/flang/lib/Evaluate/variable.cpp @@ -8,6 +8,7 @@ #include "flang/Evaluate/variable.h" #include "flang/Common/idioms.h" +#include "flang/Evaluate/check-expression.h" #include "flang/Evaluate/fold.h" #include "flang/Evaluate/tools.h" #include "flang/Parser/char-block.h" @@ -259,16 +260,13 @@ static std::optional> SymbolLEN(const Symbol &sym) { if (const semantics::ParamValue * len{dyType->charLength()}) { if (len->isExplicit()) { if (auto intExpr{len->GetExplicit()}) { - return ConvertToType(*std::move(intExpr)); - } else { - // There was an error constructing this symbol's type. It should - // have a length expression, but we couldn't retrieve it - return std::nullopt; + if (IsConstantExpr(*intExpr)) { + return ConvertToType(*std::move(intExpr)); + } } - } else { - return Expr{ - DescriptorInquiry{NamedEntity{sym}, DescriptorInquiry::Field::Len}}; } + return Expr{ + DescriptorInquiry{NamedEntity{sym}, DescriptorInquiry::Field::Len}}; } } return std::nullopt; diff --git a/flang/lib/Lower/.clang-tidy b/flang/lib/Lower/.clang-tidy new file mode 100644 index 0000000000000..87ec2ff53af6e --- /dev/null +++ b/flang/lib/Lower/.clang-tidy @@ -0,0 +1,19 @@ +# Almost identical to the top-level .clang-tidy, except that {Member,Parameter,Variable}Case use camelBack. +Checks: '-*,clang-diagnostic-*,llvm-*,misc-*,-misc-unused-parameters,-misc-non-private-member-variables-in-classes,readability-identifier-naming' +CheckOptions: + - key: readability-identifier-naming.ClassCase + value: CamelCase + - key: readability-identifier-naming.EnumCase + value: CamelCase + - key: readability-identifier-naming.FunctionCase + value: camelBack + - key: readability-identifier-naming.MemberCase + value: camelBack + - key: readability-identifier-naming.ParameterCase + value: camelBack + - key: readability-identifier-naming.UnionCase + value: CamelCase + - key: readability-identifier-naming.VariableCase + value: camelBack + - key: readability-identifier-naming.IgnoreMainLikeFunctions + value: 1 diff --git a/flang/lib/Lower/CMakeLists.txt b/flang/lib/Lower/CMakeLists.txt index 8602c23cc578e..3cd71c007a00a 100644 --- a/flang/lib/Lower/CMakeLists.txt +++ b/flang/lib/Lower/CMakeLists.txt @@ -2,9 +2,15 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error -Wno-unused-parameter") get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) add_flang_library(FortranLower + CharacterExpr.cpp + CharacterRuntime.cpp + Coarray.cpp ComplexExpr.cpp ConvertType.cpp DoLoopHelper.cpp + FIRBuilder.cpp + IntrinsicCall.cpp + IO.cpp Mangler.cpp OpenMP.cpp PFTBuilder.cpp @@ -16,6 +22,10 @@ add_flang_library(FortranLower LINK_LIBS FIROptimizer ${dialect_libs} + FortranCommon + FortranParser + FortranEvaluate + FortranSemantics MLIRAffineToStandard MLIRLLVMIR MLIRSCFToStandard diff --git a/flang/lib/Lower/CharacterExpr.cpp b/flang/lib/Lower/CharacterExpr.cpp new file mode 100644 index 0000000000000..eadf934019394 --- /dev/null +++ b/flang/lib/Lower/CharacterExpr.cpp @@ -0,0 +1,486 @@ +//===-- CharacterExpr.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 "flang/Lower/CharacterExpr.h" +#include "flang/Lower/ConvertType.h" +#include "flang/Lower/DoLoopHelper.h" +#include "flang/Lower/IntrinsicCall.h" + +//===----------------------------------------------------------------------===// +// CharacterExprHelper implementation +//===----------------------------------------------------------------------===// + +/// Get fir.char type with the same kind as inside str. +static fir::CharacterType getCharacterType(mlir::Type type) { + if (auto boxType = type.dyn_cast()) + return boxType.getEleTy(); + if (auto refType = type.dyn_cast()) + type = refType.getEleTy(); + if (auto seqType = type.dyn_cast()) { + assert(seqType.getShape().size() == 1 && "rank must be 1"); + type = seqType.getEleTy(); + } + if (auto charType = type.dyn_cast()) + return charType; + llvm_unreachable("Invalid character value type"); +} + +static fir::CharacterType getCharacterType(const fir::CharBoxValue &box) { + return getCharacterType(box.getBuffer().getType()); +} + +static bool needToMaterialize(const fir::CharBoxValue &box) { + return box.getBuffer().getType().isa() || + box.getBuffer().getType().isa(); +} + +static std::optional +getCompileTimeLength(const fir::CharBoxValue &box) { + // FIXME: should this just return box.getLen() ?? + auto type = box.getBuffer().getType(); + if (type.isa()) + return 1; + if (auto refType = type.dyn_cast()) + type = refType.getEleTy(); + if (auto seqType = type.dyn_cast()) { + auto shape = seqType.getShape(); + assert(shape.size() == 1 && "only scalar character supported"); + if (shape[0] != fir::SequenceType::getUnknownExtent()) + return shape[0]; + } + return {}; +} + +fir::CharBoxValue Fortran::lower::CharacterExprHelper::materializeValue( + const fir::CharBoxValue &str) { + if (!needToMaterialize(str)) + return str; + auto variable = builder.create(loc, str.getBuffer().getType()); + builder.create(loc, str.getBuffer(), variable); + return {variable, str.getLen()}; +} + +fir::CharBoxValue +Fortran::lower::CharacterExprHelper::toDataLengthPair(mlir::Value character) { + // TODO: get rid of toDataLengthPair when adding support for arrays + auto charBox = toExtendedValue(character).getCharBox(); + assert(charBox && "Array unsupported in character lowering helper"); + return *charBox; +} + +fir::ExtendedValue +Fortran::lower::CharacterExprHelper::toExtendedValue(mlir::Value character, + mlir::Value len) { + auto lenType = getLengthType(); + auto type = character.getType(); + auto base = character; + mlir::Value resultLen = len; + llvm::SmallVector extents; + + if (auto refType = type.dyn_cast()) + type = refType.getEleTy(); + + if (auto arrayType = type.dyn_cast()) { + type = arrayType.getEleTy(); + auto shape = arrayType.getShape(); + auto cstLen = shape[0]; + if (!resultLen && cstLen != fir::SequenceType::getUnknownExtent()) + resultLen = builder.createIntegerConstant(loc, lenType, cstLen); + // FIXME: only allow `?` in last dimension ? + auto typeExtents = + llvm::ArrayRef{shape}.drop_front(); + auto indexType = builder.getIndexType(); + for (auto extent : typeExtents) { + if (extent == fir::SequenceType::getUnknownExtent()) + break; + extents.emplace_back( + builder.createIntegerConstant(loc, indexType, extent)); + } + // Last extent might be missing in case of assumed-size. If more extents + // could not be deduced from type, that's an error (a fir.box should + // have been used in the interface). + if (extents.size() + 1 < typeExtents.size()) + mlir::emitError(loc, "cannot retrieve array extents from type"); + } else if (type.isa()) { + if (!resultLen) + resultLen = builder.createIntegerConstant(loc, lenType, 1); + } else if (auto boxCharType = type.dyn_cast()) { + auto refType = builder.getRefType(boxCharType.getEleTy()); + auto unboxed = + builder.create(loc, refType, lenType, character); + base = unboxed.getResult(0); + if (!resultLen) + resultLen = unboxed.getResult(1); + } else if (type.isa()) { + mlir::emitError(loc, "descriptor or derived type not yet handled"); + } else { + llvm_unreachable("Cannot translate mlir::Value to character ExtendedValue"); + } + + if (!resultLen) + mlir::emitError(loc, "no dynamic length found for character"); + if (!extents.empty()) + return fir::CharArrayBoxValue{base, resultLen, extents}; + return fir::CharBoxValue{base, resultLen}; +} + +/// Get fir.ref> type. +mlir::Type Fortran::lower::CharacterExprHelper::getReferenceType( + const fir::CharBoxValue &box) const { + return builder.getRefType(getCharacterType(box)); +} + +mlir::Value +Fortran::lower::CharacterExprHelper::createEmbox(const fir::CharBoxValue &box) { + // BoxChar require a reference. + auto str = box; + if (needToMaterialize(box)) + str = materializeValue(box); + auto kind = getCharacterType(str).getFKind(); + auto boxCharType = fir::BoxCharType::get(builder.getContext(), kind); + auto refType = getReferenceType(str); + // So far, fir.emboxChar fails lowering to llvm when it is given + // fir.ref>> types, so convert to + // fir.ref> if needed. + auto buff = str.getBuffer(); + buff = builder.createConvert(loc, refType, buff); + // Convert in case the provided length is not of the integer type that must + // be used in boxchar. + auto lenType = getLengthType(); + auto len = str.getLen(); + len = builder.createConvert(loc, lenType, len); + return builder.create(loc, boxCharType, buff, len); +} + +mlir::Value Fortran::lower::CharacterExprHelper::createLoadCharAt( + const fir::CharBoxValue &str, mlir::Value index) { + // In case this is addressing a length one character scalar simply return + // the single character. + if (str.getBuffer().getType().isa()) + return str.getBuffer(); + auto addr = builder.create(loc, getReferenceType(str), + str.getBuffer(), index); + return builder.create(loc, addr); +} + +void Fortran::lower::CharacterExprHelper::createStoreCharAt( + const fir::CharBoxValue &str, mlir::Value index, mlir::Value c) { + assert(!needToMaterialize(str) && "not in memory"); + auto addr = builder.create(loc, getReferenceType(str), + str.getBuffer(), index); + builder.create(loc, c, addr); +} + +void Fortran::lower::CharacterExprHelper::createCopy( + const fir::CharBoxValue &dest, const fir::CharBoxValue &src, + mlir::Value count) { + Fortran::lower::DoLoopHelper{builder, loc}.createLoop( + count, [&](Fortran::lower::FirOpBuilder &, mlir::Value index) { + auto charVal = createLoadCharAt(src, index); + createStoreCharAt(dest, index, charVal); + }); +} + +void Fortran::lower::CharacterExprHelper::createPadding( + const fir::CharBoxValue &str, mlir::Value lower, mlir::Value upper) { + auto blank = createBlankConstant(getCharacterType(str)); + // Always create the loop, if upper < lower, no iteration will be + // executed. + Fortran::lower::DoLoopHelper{builder, loc}.createLoop( + lower, upper, [&](Fortran::lower::FirOpBuilder &, mlir::Value index) { + createStoreCharAt(str, index, blank); + }); +} + +fir::CharBoxValue +Fortran::lower::CharacterExprHelper::createTemp(mlir::Type type, + mlir::Value len) { + assert(type.isa() && "expected fir character type"); + llvm::SmallVector sizes{len}; + auto ref = builder.allocateLocal(loc, type, llvm::StringRef{}, sizes); + return {ref, len}; +} + +// Simple length one character assignment without loops. +void Fortran::lower::CharacterExprHelper::createLengthOneAssign( + const fir::CharBoxValue &lhs, const fir::CharBoxValue &rhs) { + auto addr = lhs.getBuffer(); + auto val = rhs.getBuffer(); + // If rhs value resides in memory, load it. + if (!needToMaterialize(rhs)) + val = builder.create(loc, val); + auto valTy = val.getType(); + // Precondition is rhs is size 1, but it may be wrapped in a fir.array. + if (auto seqTy = valTy.dyn_cast()) { + auto zero = builder.createIntegerConstant(loc, builder.getIndexType(), 0); + valTy = seqTy.getEleTy(); + val = builder.create(loc, valTy, val, zero); + } + auto addrTy = fir::ReferenceType::get(valTy); + addr = builder.createConvert(loc, addrTy, addr); + assert(fir::dyn_cast_ptrEleTy(addr.getType()) == val.getType()); + builder.create(loc, val, addr); +} + +void Fortran::lower::CharacterExprHelper::createAssign( + const fir::CharBoxValue &lhs, const fir::CharBoxValue &rhs) { + auto rhsCstLen = getCompileTimeLength(rhs); + auto lhsCstLen = getCompileTimeLength(lhs); + bool compileTimeSameLength = + lhsCstLen && rhsCstLen && *lhsCstLen == *rhsCstLen; + + if (compileTimeSameLength && *lhsCstLen == 1) { + createLengthOneAssign(lhs, rhs); + return; + } + + // Copy the minimum of the lhs and rhs lengths and pad the lhs remainder + // if needed. + mlir::Value copyCount = lhs.getLen(); + if (!compileTimeSameLength) + copyCount = + Fortran::lower::genMin(builder, loc, {lhs.getLen(), rhs.getLen()}); + + fir::CharBoxValue safeRhs = rhs; + if (needToMaterialize(rhs)) { + // TODO: revisit now that character constant handling changed. + // Need to materialize the constant to get its elements. + // (No equivalent of fir.coordinate_of for array value). + safeRhs = materializeValue(rhs); + } else { + // If rhs is in memory, always assumes rhs might overlap with lhs + // in a way that require a temp for the copy. That can be optimize later. + // Only create a temp of copyCount size because we do not need more from + // rhs. + auto temp = createTemp(getCharacterType(rhs), copyCount); + createCopy(temp, rhs, copyCount); + safeRhs = temp; + } + + // Actual copy + createCopy(lhs, safeRhs, copyCount); + + // Pad if needed. + if (!compileTimeSameLength) { + auto one = builder.createIntegerConstant(loc, lhs.getLen().getType(), 1); + auto maxPadding = builder.create(loc, lhs.getLen(), one); + createPadding(lhs, copyCount, maxPadding); + } +} + +fir::CharBoxValue Fortran::lower::CharacterExprHelper::createConcatenate( + const fir::CharBoxValue &lhs, const fir::CharBoxValue &rhs) { + mlir::Value len = + builder.create(loc, lhs.getLen(), rhs.getLen()); + auto temp = createTemp(getCharacterType(rhs), len); + createCopy(temp, lhs, lhs.getLen()); + auto one = builder.createIntegerConstant(loc, len.getType(), 1); + auto upperBound = builder.create(loc, len, one); + auto lhsLen = + builder.createConvert(loc, builder.getIndexType(), lhs.getLen()); + Fortran::lower::DoLoopHelper{builder, loc}.createLoop( + lhs.getLen(), upperBound, one, + [&](Fortran::lower::FirOpBuilder &bldr, mlir::Value index) { + auto rhsIndex = bldr.create(loc, index, lhsLen); + auto charVal = createLoadCharAt(rhs, rhsIndex); + createStoreCharAt(temp, index, charVal); + }); + return temp; +} + +fir::CharBoxValue Fortran::lower::CharacterExprHelper::createSubstring( + const fir::CharBoxValue &box, llvm::ArrayRef bounds) { + // Constant need to be materialize in memory to use fir.coordinate_of. + auto str = box; + if (needToMaterialize(box)) + str = materializeValue(box); + + auto nbounds{bounds.size()}; + if (nbounds < 1 || nbounds > 2) { + mlir::emitError(loc, "Incorrect number of bounds in substring"); + return {mlir::Value{}, mlir::Value{}}; + } + mlir::SmallVector castBounds; + // Convert bounds to length type to do safe arithmetic on it. + for (auto bound : bounds) + castBounds.push_back(builder.createConvert(loc, getLengthType(), bound)); + auto lowerBound = castBounds[0]; + // FIR CoordinateOp is zero based but Fortran substring are one based. + auto one = builder.createIntegerConstant(loc, lowerBound.getType(), 1); + auto offset = builder.create(loc, lowerBound, one).getResult(); + auto idxType = builder.getIndexType(); + if (offset.getType() != idxType) + offset = builder.createConvert(loc, idxType, offset); + auto substringRef = builder.create( + loc, getReferenceType(str), str.getBuffer(), offset); + + // Compute the length. + mlir::Value substringLen{}; + if (nbounds < 2) { + substringLen = + builder.create(loc, str.getLen(), castBounds[0]); + } else { + substringLen = + builder.create(loc, castBounds[1], castBounds[0]); + } + substringLen = builder.create(loc, substringLen, one); + + // Set length to zero if bounds were reversed (Fortran 2018 9.4.1) + auto zero = builder.createIntegerConstant(loc, substringLen.getType(), 0); + auto cdt = builder.create(loc, mlir::CmpIPredicate::slt, + substringLen, zero); + substringLen = builder.create(loc, cdt, zero, substringLen); + + return {substringRef, substringLen}; +} + +mlir::Value Fortran::lower::CharacterExprHelper::createLenTrim( + const fir::CharBoxValue &str) { + // Note: Runtime for LEN_TRIM should also be available at some + // point. For now use an inlined implementation. + auto indexType = builder.getIndexType(); + auto len = builder.createConvert(loc, indexType, str.getLen()); + auto one = builder.createIntegerConstant(loc, indexType, 1); + auto minusOne = builder.createIntegerConstant(loc, indexType, -1); + auto zero = builder.createIntegerConstant(loc, indexType, 0); + auto trueVal = builder.createIntegerConstant(loc, builder.getI1Type(), 1); + auto blank = createBlankConstantCode(getCharacterType(str)); + mlir::Value lastChar = builder.create(loc, len, one); + + auto iterWhile = builder.create( + loc, lastChar, zero, minusOne, trueVal, lastChar); + auto insPt = builder.saveInsertionPoint(); + builder.setInsertionPointToStart(iterWhile.getBody()); + auto index = iterWhile.getInductionVar(); + // Look for first non-blank from the right of the character. + auto c = createLoadCharAt(str, index); + c = builder.createConvert(loc, blank.getType(), c); + auto isBlank = + builder.create(loc, mlir::CmpIPredicate::eq, blank, c); + llvm::SmallVector results = {isBlank, index}; + builder.create(loc, results); + builder.restoreInsertionPoint(insPt); + // Compute length after iteration (zero if all blanks) + mlir::Value newLen = + builder.create(loc, iterWhile.getResult(1), one); + auto result = + builder.create(loc, iterWhile.getResult(0), zero, newLen); + return builder.createConvert(loc, getLengthType(), result); +} + +mlir::Value Fortran::lower::CharacterExprHelper::createTemp(mlir::Type type, + int len) { + assert(type.isa() && "expected fir character type"); + assert(len >= 0 && "expected positive length"); + fir::SequenceType::Shape shape{len}; + auto seqType = fir::SequenceType::get(shape, type); + return builder.create(loc, seqType); +} + +// Returns integer with code for blank. The integer has the same +// size as the character. Blank has ascii space code for all kinds. +mlir::Value Fortran::lower::CharacterExprHelper::createBlankConstantCode( + fir::CharacterType type) { + auto bits = builder.getKindMap().getCharacterBitsize(type.getFKind()); + auto intType = builder.getIntegerType(bits); + return builder.createIntegerConstant(loc, intType, ' '); +} + +mlir::Value Fortran::lower::CharacterExprHelper::createBlankConstant( + fir::CharacterType type) { + return builder.createConvert(loc, type, createBlankConstantCode(type)); +} + +void Fortran::lower::CharacterExprHelper::createCopy(mlir::Value dest, + mlir::Value src, + mlir::Value count) { + createCopy(toDataLengthPair(dest), toDataLengthPair(src), count); +} + +void Fortran::lower::CharacterExprHelper::createPadding(mlir::Value str, + mlir::Value lower, + mlir::Value upper) { + createPadding(toDataLengthPair(str), lower, upper); +} + +mlir::Value Fortran::lower::CharacterExprHelper::createSubstring( + mlir::Value str, llvm::ArrayRef bounds) { + return createEmbox(createSubstring(toDataLengthPair(str), bounds)); +} + +void Fortran::lower::CharacterExprHelper::createAssign(mlir::Value lhs, + mlir::Value rhs) { + createAssign(toDataLengthPair(lhs), toDataLengthPair(rhs)); +} + +mlir::Value +Fortran::lower::CharacterExprHelper::createLenTrim(mlir::Value str) { + return createLenTrim(toDataLengthPair(str)); +} + +void Fortran::lower::CharacterExprHelper::createAssign(mlir::Value lptr, + mlir::Value llen, + mlir::Value rptr, + mlir::Value rlen) { + createAssign(fir::CharBoxValue{lptr, llen}, fir::CharBoxValue{rptr, rlen}); +} + +mlir::Value +Fortran::lower::CharacterExprHelper::createConcatenate(mlir::Value lhs, + mlir::Value rhs) { + return createEmbox( + createConcatenate(toDataLengthPair(lhs), toDataLengthPair(rhs))); +} + +mlir::Value +Fortran::lower::CharacterExprHelper::createEmboxChar(mlir::Value addr, + mlir::Value len) { + return createEmbox(fir::CharBoxValue{addr, len}); +} + +std::pair +Fortran::lower::CharacterExprHelper::createUnboxChar(mlir::Value boxChar) { + auto box = toDataLengthPair(boxChar); + return {box.getBuffer(), box.getLen()}; +} + +mlir::Value +Fortran::lower::CharacterExprHelper::createCharacterTemp(mlir::Type type, + mlir::Value len) { + return createEmbox(createTemp(type, len)); +} + +std::pair +Fortran::lower::CharacterExprHelper::materializeCharacter(mlir::Value str) { + auto box = toDataLengthPair(str); + if (needToMaterialize(box)) + box = materializeValue(box); + return {box.getBuffer(), box.getLen()}; +} + +bool Fortran::lower::CharacterExprHelper::isCharacterLiteral(mlir::Type type) { + if (auto seqType = type.dyn_cast()) + return (seqType.getShape().size() == 1) && + seqType.getEleTy().isa(); + return false; +} + +bool Fortran::lower::CharacterExprHelper::isCharacter(mlir::Type type) { + if (type.isa()) + return true; + if (auto refType = type.dyn_cast()) + type = refType.getEleTy(); + if (auto seqType = type.dyn_cast()) + if (seqType.getShape().size() == 1) + type = seqType.getEleTy(); + return type.isa(); +} + +int Fortran::lower::CharacterExprHelper::getCharacterKind(mlir::Type type) { + return getCharacterType(type).getFKind(); +} diff --git a/flang/lib/Lower/CharacterRuntime.cpp b/flang/lib/Lower/CharacterRuntime.cpp new file mode 100644 index 0000000000000..af95885f985d2 --- /dev/null +++ b/flang/lib/Lower/CharacterRuntime.cpp @@ -0,0 +1,129 @@ +//===-- CharacterRuntime.cpp -- runtime for CHARACTER type entities -------===// +// +// 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 "flang/Lower/CharacterRuntime.h" +#include "../../runtime/character.h" +#include "RTBuilder.h" +#include "flang/Lower/Bridge.h" +#include "flang/Lower/CharacterExpr.h" +#include "flang/Lower/FIRBuilder.h" +#include "mlir/Dialect/StandardOps/IR/Ops.h" + +using namespace Fortran::runtime; + +#define NAMIFY_HELPER(X) #X +#define NAMIFY(X) NAMIFY_HELPER(IONAME(X)) +#define mkRTKey(X) mkKey(RTNAME(X)) + +namespace Fortran::lower { +/// Static table of CHARACTER runtime calls +/// +/// This logical map contains the name and type builder function for each +/// runtime function listed in the tuple. This table is fully constructed at +/// compile-time. Use the `mkRTKey` macro to access the table. +static constexpr std::tuple< + mkRTKey(CharacterCompareScalar), mkRTKey(CharacterCompareScalar1), + mkRTKey(CharacterCompareScalar2), mkRTKey(CharacterCompareScalar4), + mkRTKey(CharacterCompare)> + newCharRTTable; +} // namespace Fortran::lower + +using namespace Fortran::lower; + +/// Helper function to retrieve the name of the IO function given the key `A` +template +static constexpr const char *getName() { + return std::get(newCharRTTable).name; +} + +/// Helper function to retrieve the type model signature builder of the IO +/// function as defined by the key `A` +template +static constexpr FuncTypeBuilderFunc getTypeModel() { + return std::get(newCharRTTable).getTypeModel(); +} + +inline int64_t getLength(mlir::Type argTy) { + return argTy.cast().getShape()[0]; +} + +/// Get (or generate) the MLIR FuncOp for a given runtime function. +template +static mlir::FuncOp getRuntimeFunc(mlir::Location loc, + Fortran::lower::FirOpBuilder &builder) { + auto name = getName(); + auto func = builder.getNamedFunction(name); + if (func) + return func; + auto funTy = getTypeModel()(builder.getContext()); + func = builder.createFunction(loc, name, funTy); + func.setAttr("fir.runtime", builder.getUnitAttr()); + return func; +} + +/// Helper function to recover the KIND from the FIR type. +static int discoverKind(mlir::Type ty) { + if (auto charTy = ty.dyn_cast()) + return charTy.getFKind(); + if (auto eleTy = fir::dyn_cast_ptrEleTy(ty)) + return discoverKind(eleTy); + if (auto arrTy = ty.dyn_cast()) + return discoverKind(arrTy.getEleTy()); + if (auto boxTy = ty.dyn_cast()) + return discoverKind(boxTy.getEleTy()); + if (auto boxTy = ty.dyn_cast()) + return discoverKind(boxTy.getEleTy()); + llvm_unreachable("unexpected character type"); +} + +//===----------------------------------------------------------------------===// +// Lower character operations +//===----------------------------------------------------------------------===// + +mlir::Value +Fortran::lower::genRawCharCompare(Fortran::lower::AbstractConverter &converter, + mlir::Location loc, mlir::CmpIPredicate cmp, + mlir::Value lhsBuff, mlir::Value lhsLen, + mlir::Value rhsBuff, mlir::Value rhsLen) { + auto &builder = converter.getFirOpBuilder(); + mlir::FuncOp beginFunc; + switch (discoverKind(lhsBuff.getType())) { + case 1: + beginFunc = getRuntimeFunc(loc, builder); + break; + case 2: + beginFunc = getRuntimeFunc(loc, builder); + break; + case 4: + beginFunc = getRuntimeFunc(loc, builder); + break; + default: + llvm_unreachable("runtime does not support CHARACTER KIND"); + } + auto fTy = beginFunc.getType(); + auto lptr = builder.createConvert(loc, fTy.getInput(0), lhsBuff); + auto llen = builder.createConvert(loc, fTy.getInput(2), lhsLen); + auto rptr = builder.createConvert(loc, fTy.getInput(1), rhsBuff); + auto rlen = builder.createConvert(loc, fTy.getInput(3), rhsLen); + llvm::SmallVector args = {lptr, rptr, llen, rlen}; + auto tri = builder.create(loc, beginFunc, args).getResult(0); + auto zero = builder.createIntegerConstant(loc, tri.getType(), 0); + return builder.create(loc, cmp, tri, zero); +} + +mlir::Value +Fortran::lower::genBoxCharCompare(Fortran::lower::AbstractConverter &converter, + mlir::Location loc, mlir::CmpIPredicate cmp, + mlir::Value lhs, mlir::Value rhs) { + auto &builder = converter.getFirOpBuilder(); + Fortran::lower::CharacterExprHelper helper{builder, loc}; + auto lhsPair = helper.materializeCharacter(lhs); + auto rhsPair = helper.materializeCharacter(rhs); + return genRawCharCompare(converter, loc, cmp, lhsPair.first, lhsPair.second, + rhsPair.first, rhsPair.second); +} diff --git a/flang/lib/Lower/Coarray.cpp b/flang/lib/Lower/Coarray.cpp new file mode 100644 index 0000000000000..d73acbe17ce20 --- /dev/null +++ b/flang/lib/Lower/Coarray.cpp @@ -0,0 +1,73 @@ +//===-- Coarray.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 +// +//===----------------------------------------------------------------------===// +/// +/// Implementation of the lowering of image related constructs and expressions. +/// Fortran images can form teams, communicate via coarrays, etc. +/// +//===----------------------------------------------------------------------===// + +#include "flang/Lower/Coarray.h" +#include "SymbolMap.h" +#include "flang/Lower/AbstractConverter.h" +#include "flang/Lower/FIRBuilder.h" +#include "flang/Parser/parse-tree.h" +#include "flang/Semantics/expression.h" + +#undef TODO +#define TODO(MSG) \ + { \ + mlir::emitError(converter.getCurrentLocation(), "not yet implemented") \ + << MSG; \ + exit(1); \ + } + +//===----------------------------------------------------------------------===// +// TEAM statements and constructs +//===----------------------------------------------------------------------===// + +void Fortran::lower::genChangeTeamConstruct( + Fortran::lower::AbstractConverter &converter, + Fortran::lower::pft::Evaluation &, + const Fortran::parser::ChangeTeamConstruct &) { + TODO("CHANGE TEAM construct"); +} + +void Fortran::lower::genChangeTeamStmt( + Fortran::lower::AbstractConverter &converter, + Fortran::lower::pft::Evaluation &, + const Fortran::parser::ChangeTeamStmt &) { + TODO("CHANGE TEAM stmt"); +} + +void Fortran::lower::genEndChangeTeamStmt( + Fortran::lower::AbstractConverter &converter, + Fortran::lower::pft::Evaluation &, + const Fortran::parser::EndChangeTeamStmt &) { + TODO("END CHANGE TEAM"); +} + +void Fortran::lower::genFormTeamStatement( + Fortran::lower::AbstractConverter &converter, + Fortran::lower::pft::Evaluation &, const Fortran::parser::FormTeamStmt &) { + TODO("FORM TEAM"); +} + +//===----------------------------------------------------------------------===// +// COARRAY expressions +//===----------------------------------------------------------------------===// + +fir::ExtendedValue Fortran::lower::CoarrayExprHelper::genAddr( + const Fortran::evaluate::CoarrayRef &expr) { + (void)symMap; + TODO("co-array address"); +} + +fir::ExtendedValue Fortran::lower::CoarrayExprHelper::genValue( + const Fortran::evaluate::CoarrayRef &expr) { + TODO("co-array value"); +} diff --git a/flang/lib/Lower/ConvertType.cpp b/flang/lib/Lower/ConvertType.cpp index 54792a51b4ebc..276df03d6288d 100644 --- a/flang/lib/Lower/ConvertType.cpp +++ b/flang/lib/Lower/ConvertType.cpp @@ -177,18 +177,16 @@ namespace { /// mlir::Type. The type returned may be an MLIR standard or FIR type. class TypeBuilder { public: - /// Constructor. explicit TypeBuilder( mlir::MLIRContext *context, const Fortran::common::IntrinsicTypeDefaultKinds &defaults) : context{context}, defaults{defaults} {} - //===--------------------------------------------------------------------===// // Generate type entry points //===--------------------------------------------------------------------===// - + template
458 C++11 Hiding of member template parameters by other membersNoClang 11
459