diff options
author | Andrew Savonichev <andrew.savonichev@intel.com> | 2018-10-11 13:35:34 +0000 |
---|---|---|
committer | Andrew Savonichev <andrew.savonichev@intel.com> | 2018-10-11 13:35:34 +0000 |
commit | 16f1699ddaf1a1ee4731cd06eb5ba76a21d7183a (patch) | |
tree | b1c4596cd05d3841fce7e6355745b15a8b471ec4 | |
parent | 0f80d9f27dc1e8c232dc7dec486475d67c50df9e (diff) | |
download | bcm5719-llvm-16f1699ddaf1a1ee4731cd06eb5ba76a21d7183a.tar.gz bcm5719-llvm-16f1699ddaf1a1ee4731cd06eb5ba76a21d7183a.zip |
[Sema][OpenCL] Improve diagnostics for not viable overloadable function candidates
Summary:
Allowed extension name (that ought to be disabled) printing in the note message.
This diagnostic was proposed here: https://reviews.llvm.org/D51341
Reviewers: Anastasia, yaxunl
Reviewed By: Anastasia
Subscribers: cfe-commits, asavonic, bader
Differential Revision: https://reviews.llvm.org/D52292
llvm-svn: 344246
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 | ||||
-rw-r--r-- | clang/include/clang/Sema/Sema.h | 15 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.cpp | 28 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 3 | ||||
-rw-r--r-- | clang/test/SemaOpenCL/extension-begin.cl | 2 |
5 files changed, 47 insertions, 3 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 86b43e37bb4..aeaff242f72 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3674,7 +3674,7 @@ def warn_diagnose_if_succeeded : Warning<"%0">, InGroup<UserDefinedWarnings>, def note_ovl_candidate_disabled_by_function_cond_attr : Note< "candidate disabled: %0">; def note_ovl_candidate_disabled_by_extension : Note< - "candidate disabled due to OpenCL extension">; + "candidate unavailable as it requires OpenCL extension '%0' to be disabled">; def err_addrof_function_disabled_by_enable_if_attr : Error< "cannot take address of function %0 because it has one or more " "non-tautological enable_if conditions">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index e1e6dae3ad8..703c64624e5 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -8576,6 +8576,21 @@ public: llvm::StringRef getCurrentOpenCLExtension() const { return CurrOpenCLExtension; } + + /// Check if a function declaration \p FD associates with any + /// extensions present in OpenCLDeclExtMap and if so return the + /// extension(s) name(s). + std::string getOpenCLExtensionsFromDeclExtMap(FunctionDecl *FD); + + /// Check if a function type \p FT associates with any + /// extensions present in OpenCLTypeExtMap and if so return the + /// extension(s) name(s). + std::string getOpenCLExtensionsFromTypeExtMap(FunctionType *FT); + + /// Find an extension in an appropriate extension map and return its name + template<typename T, typename MapT> + std::string getOpenCLExtensionsFromExtMap(T* FT, MapT &Map); + void setCurrentOpenCLExtension(llvm::StringRef Ext) { CurrOpenCLExtension = Ext; } diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index a9c5f7d58bf..916f23c1caa 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -1914,6 +1914,34 @@ void Sema::setCurrentOpenCLExtensionForDecl(Decl *D) { setOpenCLExtensionForDecl(D, CurrOpenCLExtension); } +std::string Sema::getOpenCLExtensionsFromDeclExtMap(FunctionDecl *FD) { + if (!OpenCLDeclExtMap.empty()) + return getOpenCLExtensionsFromExtMap(FD, OpenCLDeclExtMap); + + return ""; +} + +std::string Sema::getOpenCLExtensionsFromTypeExtMap(FunctionType *FT) { + if (!OpenCLTypeExtMap.empty()) + return getOpenCLExtensionsFromExtMap(FT, OpenCLTypeExtMap); + + return ""; +} + +template <typename T, typename MapT> +std::string Sema::getOpenCLExtensionsFromExtMap(T *FDT, MapT &Map) { + std::string ExtensionNames = ""; + auto Loc = Map.find(FDT); + + for (auto const& I : Loc->second) { + ExtensionNames += I; + ExtensionNames += " "; + } + ExtensionNames.pop_back(); + + return ExtensionNames; +} + bool Sema::isOpenCLDisabledDecl(Decl *FD) { auto Loc = OpenCLDeclExtMap.find(FD); if (Loc == OpenCLDeclExtMap.end()) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index a5a51d54830..a8d69ea7fba 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -10242,7 +10242,8 @@ static void DiagnoseOpenCLExtensionDisabled(Sema &S, OverloadCandidate *Cand) { FunctionDecl *Callee = Cand->Function; S.Diag(Callee->getLocation(), - diag::note_ovl_candidate_disabled_by_extension); + diag::note_ovl_candidate_disabled_by_extension) + << S.getOpenCLExtensionsFromDeclExtMap(Callee); } /// Generates a 'note' diagnostic for an overload candidate. We've diff --git a/clang/test/SemaOpenCL/extension-begin.cl b/clang/test/SemaOpenCL/extension-begin.cl index 92ea8814323..440e72cbba4 100644 --- a/clang/test/SemaOpenCL/extension-begin.cl +++ b/clang/test/SemaOpenCL/extension-begin.cl @@ -48,7 +48,7 @@ void test_f2(void) { PointerOfA test_A_pointer; // expected-error {{use of type 'PointerOfA' (aka 'const struct A *') requires my_ext extension to be enabled}} f(); // expected-error {{use of declaration 'f' requires my_ext extension to be enabled}} g(0); // expected-error {{no matching function for call to 'g'}} - // expected-note@-26 {{candidate disabled due to OpenCL extension}} + // expected-note@-26 {{candidate unavailable as it requires OpenCL extension 'my_ext' to be disabled}} // expected-note@-22 {{candidate function not viable: requires 0 arguments, but 1 was provided}} } |