std::string getAsString() const;
std::string getAsString(const PrintingPolicy &Policy) const;
+ static std::string getAddrSpaceAsString(LangAS AS);
+
bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const;
void print(raw_ostream &OS, const PrintingPolicy &Policy,
bool appendSpaceIfNonEmpty = false) const;
return type->getBaseElementTypeUnsafe();
return type;
}
+/// Insertion operator for diagnostics. This allows sending address spaces into
+/// a diagnostic with <<.
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ LangAS AS) {
+ DB.AddTaggedVal(static_cast<std::underlying_type_t<LangAS>>(AS),
+ DiagnosticsEngine::ArgumentKind::ak_addrspace);
+ return DB;
+}
+
+/// Insertion operator for partial diagnostics. This allows sending adress
+/// spaces into a diagnostic with <<.
+inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+ LangAS AS) {
+ PD.AddTaggedVal(static_cast<std::underlying_type_t<LangAS>>(AS),
+ DiagnosticsEngine::ArgumentKind::ak_addrspace);
+ return PD;
+}
/// Insertion operator for diagnostics. This allows sending Qualifiers into a
/// diagnostic with <<.
/// IdentifierInfo
ak_identifierinfo,
+ /// address space
+ ak_addrspace,
+
/// Qualifiers
ak_qual,
"%select{%ordinal4 argument|object argument}3">;
def note_ovl_candidate_bad_addrspace : Note<
"candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
- "address space mismatch in %select{%ordinal6|'this'}5 argument (%3), "
- "parameter type must be %4">;
+ "cannot %select{pass pointer to|bind reference in}5 %3 "
+ "%select{as a pointer to|to object in}5 %4 in %ordinal6 "
+ "argument">;
+def note_ovl_candidate_bad_addrspace_this : Note<
+ "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
+ "'this' object is in %3, but method expects object in %4">;
def note_ovl_candidate_bad_gc : Note<
"candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
"%select{%ordinal7|'this'}6 argument (%3) has %select{no|__weak|__strong}4 "
switch (Kind) {
default: llvm_unreachable("unknown ArgumentKind");
+ case DiagnosticsEngine::ak_addrspace: {
+ assert(Modifier.empty() && Argument.empty() &&
+ "Invalid modifier for Qualfiers argument");
+
+ auto S = Qualifiers::getAddrSpaceAsString(static_cast<LangAS>(Val));
+ if (S.empty()) {
+ OS << (Context.getLangOpts().OpenCL ? "default" : "generic");
+ OS << " address space";
+ } else {
+ OS << "address space";
+ OS << " '" << S << "'";
+ }
+ NeedQuotes = false;
+ break;
+ }
case DiagnosticsEngine::ak_qual: {
assert(Modifier.empty() && Argument.empty() &&
"Invalid modifier for Qualfiers argument");
OS << "unqualified";
NeedQuotes = false;
} else {
- OS << Q.getAsString();
+ OS << S;
}
break;
}
return true;
}
+std::string Qualifiers::getAddrSpaceAsString(LangAS AS) {
+ switch (AS) {
+ case LangAS::Default:
+ return "";
+ case LangAS::opencl_global:
+ return "__global";
+ case LangAS::opencl_local:
+ return "__local";
+ case LangAS::opencl_private:
+ return "";
+ case LangAS::opencl_constant:
+ return "__constant";
+ case LangAS::opencl_generic:
+ return "__generic";
+ case LangAS::cuda_device:
+ return "__device__";
+ case LangAS::cuda_constant:
+ return "__constant__";
+ case LangAS::cuda_shared:
+ return "__shared__";
+ default:
+ return std::to_string(toTargetAddressSpace(AS));
+ }
+}
+
// Appends qualifiers to the given string, separated by spaces. Will
// prefix a space if the string is non-empty. Will not append a final
// space.
OS << "__unaligned";
addSpace = true;
}
- LangAS addrspace = getAddressSpace();
- if (addrspace != LangAS::Default) {
- if (addrspace != LangAS::opencl_private) {
- if (addSpace)
- OS << ' ';
- addSpace = true;
- switch (addrspace) {
- case LangAS::opencl_global:
- OS << "__global";
- break;
- case LangAS::opencl_local:
- OS << "__local";
- break;
- case LangAS::opencl_private:
- break;
- case LangAS::opencl_constant:
- OS << "__constant";
- break;
- case LangAS::opencl_generic:
- OS << "__generic";
- break;
- case LangAS::cuda_device:
- OS << "__device__";
- break;
- case LangAS::cuda_constant:
- OS << "__constant__";
- break;
- case LangAS::cuda_shared:
- OS << "__shared__";
- break;
- default:
- OS << "__attribute__((address_space(";
- OS << toTargetAddressSpace(addrspace);
- OS << ")))";
- }
- }
+ auto ASStr = getAddrSpaceAsString(getAddressSpace());
+ if (!ASStr.empty()) {
+ if (addSpace)
+ OS << ' ';
+ addSpace = true;
+ // Wrap target address space into an attribute syntax
+ if (isTargetAddressSpace(getAddressSpace()))
+ OS << "__attribute__((address_space(" << ASStr << ")))";
+ else
+ OS << ASStr;
}
+
if (Qualifiers::GC gc = getObjCGCAttr()) {
if (addSpace)
OS << ' ';
llvm::raw_svector_ostream(OutStr) << '\'' << II->getName() << '\'';
break;
}
+ case DiagnosticsEngine::ak_addrspace:
case DiagnosticsEngine::ak_qual:
case DiagnosticsEngine::ak_qualtype:
case DiagnosticsEngine::ak_declarationname:
Qualifiers ToQs = CToTy.getQualifiers();
if (FromQs.getAddressSpace() != ToQs.getAddressSpace()) {
- S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_addrspace)
- << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc
- << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy
- << ToTy << (unsigned)isObjectArgument << I + 1;
+ if (isObjectArgument)
+ S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_addrspace_this)
+ << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second
+ << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
+ << FromQs.getAddressSpace() << ToQs.getAddressSpace();
+ else
+ S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_addrspace)
+ << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second
+ << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
+ << FromQs.getAddressSpace() << ToQs.getAddressSpace()
+ << ToTy->isReferenceType() << I + 1;
MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl);
return;
}
typedef int __attribute__((address_space(1))) int_1;
typedef int __attribute__((address_space(2))) int_2;
-void f0(int_1 &); // expected-note{{candidate function not viable: address space mismatch in 1st argument ('int'), parameter type must be 'int_1 &' (aka '__attribute__((address_space(1))) int &')}} \
-// expected-note{{candidate function not viable: address space mismatch in 1st argument ('int_2' (aka '__attribute__((address_space(2))) int')), parameter type must be 'int_1 &' (aka '__attribute__((address_space(1))) int &')}}
-void f0(const int_1 &); // expected-note{{candidate function not viable: address space mismatch in 1st argument ('int'), parameter type must be 'const int_1 &' (aka 'const __attribute__((address_space(1))) int &')}} \
-// expected-note{{candidate function not viable: address space mismatch in 1st argument ('int_2' (aka '__attribute__((address_space(2))) int')), parameter type must be 'const int_1 &' (aka 'const __attribute__((address_space(1))) int &')}}
+void f0(int_1 &); // expected-note{{candidate function not viable: cannot bind reference in generic address space to object in address space '1' in 1st argument}} \
+// expected-note{{candidate function not viable: cannot bind reference in address space '2' to object in address space '1' in 1st argument}}
+void f0(const int_1 &); // expected-note{{candidate function not viable: cannot bind reference in generic address space to object in address space '1' in 1st argument}} \
+// expected-note{{candidate function not viable: cannot bind reference in address space '2' to object in address space '1' in 1st argument}}
void test_f0() {
int i;
#if !__OPENCL_CPP_VERSION__
// expected-note@-3{{passing argument to parameter 'arg_glob' here}}
#else
-// expected-note-re@-5{{candidate function not viable: address space mismatch in 1st argument ('__{{generic|constant}} int *'), parameter type must be '__global int *'}}
+// expected-note-re@-5{{candidate function not viable: cannot pass pointer to address space '__{{generic|constant}}' as a pointer to address space '__global' in 1st argument}}
#endif
#endif
#if !__OPENCL_CPP_VERSION__
// expected-note@-2{{passing argument to parameter 'arg_loc' here}}
#else
-// expected-note-re@-4{{candidate function not viable: address space mismatch in 1st argument ('__{{global|generic|constant}} int *'), parameter type must be '__local int *'}}
+// expected-note-re@-4{{candidate function not viable: cannot pass pointer to address space '__{{global|generic|constant}}' as a pointer to address space '__local' in 1st argument}}
#endif
void f_const(__constant int *arg_const) {}
#if !__OPENCL_CPP_VERSION__
// expected-note@-3{{passing argument to parameter 'arg_const' here}}
#else
-// expected-note-re@-5{{candidate function not viable: address space mismatch in 1st argument ('__{{global|generic}} int *'), parameter type must be '__constant int *'}}
+// expected-note-re@-5{{candidate function not viable: cannot pass pointer to address space '__{{global|generic}}' as a pointer to address space '__constant' in 1st argument}}
#endif
#endif
#if !__OPENCL_CPP_VERSION__
// expected-note@-2{{passing argument to parameter 'arg_priv' here}}
#else
-// expected-note-re@-4{{candidate function not viable: address space mismatch in 1st argument ('__{{global|generic|constant}} int *'), parameter type must be 'int *'}}
+// expected-note-re@-4{{candidate function not viable: cannot pass pointer to address space '__{{global|generic|constant}}' as a pointer to default address space in 1st argument}}
#endif
void f_gen(__generic int *arg_gen) {}
#if !__OPENCL_CPP_VERSION__
// expected-note@-3{{passing argument to parameter 'arg_gen' here}}
#else
-// expected-note@-5{{candidate function not viable: address space mismatch in 1st argument ('__constant int *'), parameter type must be '__generic int *'}}
+// expected-note@-5{{candidate function not viable: cannot pass pointer to address space '__constant' as a pointer to address space '__generic' in 1st argument}}
#endif
#endif
// Test lambda with default parameters
//CHECK: CXXMethodDecl {{.*}} constexpr operator() 'void () const __generic'
[&] {i++;} ();
- __constant auto err = [&]() {}; //expected-note-re{{candidate function not viable: address space mismatch in 'this' argument ('__constant (lambda at {{.*}})'), parameter type must be 'const __generic (lambda at {{.*}})'}}
+ __constant auto err = [&]() {}; //expected-note{{candidate function not viable: 'this' object is in address space '__constant', but method expects object in address space '__generic'}}
err(); //expected-error-re{{no matching function for call to object of type '__constant (lambda at {{.*}})'}}
// FIXME: There is very limited addr space functionality
// we can test when taking lambda type from the object.
//CHECK: |-CXXMethodDecl {{.*}} constexpr operator() 'void () const __generic'
auto priv2 = []() __generic {};
priv2();
- auto priv3 = []() __global {}; //expected-note-re{{candidate function not viable: address space mismatch in 'this' argument ('(lambda at {{.*}})'), parameter type must be 'const __global (lambda at {{.*}})'}} //expected-note{{conversion candidate of type 'void (*)()'}}
+ auto priv3 = []() __global {}; //expected-note{{candidate function not viable: 'this' object is in default address space, but method expects object in address space '__global'}} //expected-note{{conversion candidate of type 'void (*)()'}}
priv3(); //expected-error{{no matching function for call to object of type}}
- __constant auto const1 = []() __private{}; //expected-note-re{{candidate function not viable: address space mismatch in 'this' argument ('__constant (lambda at {{.*}})'), parameter type must be 'const (lambda at {{.*}}'}} //expected-note{{conversion candidate of type 'void (*)()'}}
+ __constant auto const1 = []() __private{}; //expected-note{{candidate function not viable: 'this' object is in address space '__constant', but method expects object in default address space}} //expected-note{{conversion candidate of type 'void (*)()'}}
const1(); //expected-error{{no matching function for call to object of type '__constant (lambda at}}
- __constant auto const2 = []() __generic{}; //expected-note-re{{candidate function not viable: address space mismatch in 'this' argument ('__constant (lambda at {{.*}})'), parameter type must be 'const __generic (lambda at {{.*}}'}} //expected-note{{conversion candidate of type 'void (*)()'}}
+ __constant auto const2 = []() __generic{}; //expected-note{{candidate function not viable: 'this' object is in address space '__constant', but method expects object in address space '__generic'}} //expected-note{{conversion candidate of type 'void (*)()'}}
const2(); //expected-error{{no matching function for call to object of type '__constant (lambda at}}
//CHECK: |-CXXMethodDecl {{.*}} constexpr operator() 'void () const __constant'
__constant auto const3 = []() __constant{};
const3();
- [&] () __global {} (); //expected-error{{no matching function for call to object of type '(lambda at}} expected-note-re{{candidate function not viable: address space mismatch in 'this' argument ('(lambda at {{.*}})'), parameter type must be 'const __global (lambda at {{.*}})'}}
- [&] () __private {} (); //expected-error{{no matching function for call to object of type '(lambda at}} expected-note-re{{candidate function not viable: address space mismatch in 'this' argument ('(lambda at {{.*}})'), parameter type must be 'const (lambda at {{.*}})'}}
+ [&] () __global {} (); //expected-error{{no matching function for call to object of type '(lambda at}} expected-note{{candidate function not viable: 'this' object is in default address space, but method expects object in address space '__global'}}
+ [&] () __private {} (); //expected-error{{no matching function for call to object of type '(lambda at}} expected-note{{candidate function not viable: 'this' object is in default address space, but method expects object in default address space}}
[&] __private {} (); //expected-error{{lambda requires '()' before attribute specifier}} expected-error{{expected body of lambda expression}}
};
void bar(__local C*);
-// expected-note@-1{{candidate function not viable: address space mismatch in 1st argument ('decltype(this)' (aka '__global C *')), parameter type must be '__local C *'}}
-// expected-note@-2{{candidate function not viable: address space mismatch in 1st argument ('decltype(this)' (aka 'C *')), parameter type must be '__local C *'}}
+// expected-note@-1{{candidate function not viable: cannot pass pointer to address space '__global' as a pointer to address space '__local' in 1st argument}}
+// expected-note@-2{{candidate function not viable: cannot pass pointer to default address space as a pointer to address space '__local' in 1st argument}}
__global C Glob;
void foo(){