summaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
authorAnastasia Stulova <anastasia.stulova@arm.com>2019-01-14 11:44:22 +0000
committerAnastasia Stulova <anastasia.stulova@arm.com>2019-01-14 11:44:22 +0000
commit5c85c8c7fb3f03288d288b51c2fcf5fdc4647aaa (patch)
tree91b02ed9fe397d8a2b12df4b14aa6dc2ede8a6ae /lib/Sema
parent765aed95548bbd215d97f8418f43815823e79905 (diff)
downloadclang-5c85c8c7fb3f03288d288b51c2fcf5fdc4647aaa.tar.gz
[OpenCL] Set generic addr space of 'this' in special class members.
Set address spaces of 'this' param correctly for implicit special class members. This also changes initialization conversion sequence to separate address space conversion from other qualifiers in case of binding reference to a temporary. In this case address space conversion should happen after the binding (unlike for other quals). This is needed to materialize it correctly in the alloca address space. Initial patch by Mikael Nilssoni! Differential Revision: https://reviews.llvm.org/D56066 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@351053 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/SemaDecl.cpp7
-rw-r--r--lib/Sema/SemaDeclCXX.cpp66
-rw-r--r--lib/Sema/SemaInit.cpp11
-rw-r--r--lib/Sema/SemaType.cpp5
4 files changed, 53 insertions, 36 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 0fb4ba60bf..e853180d76 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -3192,12 +3192,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD,
if (RequiresAdjustment) {
const FunctionType *AdjustedType = New->getType()->getAs<FunctionType>();
AdjustedType = Context.adjustFunctionType(AdjustedType, NewTypeInfo);
-
- QualType AdjustedQT = QualType(AdjustedType, 0);
- LangAS AS = Old->getType().getAddressSpace();
- AdjustedQT = Context.getAddrSpaceQualType(AdjustedQT, AS);
-
- New->setType(AdjustedQT);
+ New->setType(QualType(AdjustedType, 0));
NewQType = Context.getCanonicalType(New->getType());
NewType = cast<FunctionType>(NewQType);
}
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index c2fa87a079..43b289d8d0 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -6551,8 +6551,11 @@ void Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD) {
if (CSM == CXXCopyAssignment || CSM == CXXMoveAssignment) {
// Check for return type matching.
ReturnType = Type->getReturnType();
- QualType ExpectedReturnType =
- Context.getLValueReferenceType(Context.getTypeDeclType(RD));
+
+ QualType DeclType = Context.getTypeDeclType(RD);
+ DeclType = Context.getAddrSpaceQualType(DeclType, MD->getTypeQualifiers().getAddressSpace());
+ QualType ExpectedReturnType = Context.getLValueReferenceType(DeclType);
+
if (!Context.hasSameType(ReturnType, ExpectedReturnType)) {
Diag(MD->getLocation(), diag::err_defaulted_special_member_return_type)
<< (CSM == CXXMoveAssignment) << ExpectedReturnType;
@@ -6560,7 +6563,7 @@ void Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD) {
}
// A defaulted special member cannot have cv-qualifiers.
- if (Type->getTypeQuals()) {
+ if (Type->getTypeQuals().hasConst() || Type->getTypeQuals().hasVolatile()) {
if (DeleteOnTypeMismatch)
ShouldDeleteForTypeMismatch = true;
else {
@@ -10910,6 +10913,22 @@ void Sema::CheckImplicitSpecialMemberDeclaration(Scope *S, FunctionDecl *FD) {
CheckFunctionDeclaration(S, FD, R, /*IsMemberSpecialization*/false);
}
+void Sema::setupImplicitSpecialMemberType(CXXMethodDecl *SpecialMem,
+ QualType ResultTy,
+ ArrayRef<QualType> Args) {
+ // Build an exception specification pointing back at this constructor.
+ FunctionProtoType::ExtProtoInfo EPI = getImplicitMethodEPI(*this, SpecialMem);
+
+ if (getLangOpts().OpenCLCPlusPlus) {
+ // OpenCL: Implicitly defaulted special member are of the generic address
+ // space.
+ EPI.TypeQuals.addAddressSpace(LangAS::opencl_generic);
+ }
+
+ auto QT = Context.getFunctionType(ResultTy, Args, EPI);
+ SpecialMem->setType(QT);
+}
+
CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor(
CXXRecordDecl *ClassDecl) {
// C++ [class.ctor]p5:
@@ -10950,9 +10969,7 @@ CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor(
/* Diagnose */ false);
}
- // Build an exception specification pointing back at this constructor.
- FunctionProtoType::ExtProtoInfo EPI = getImplicitMethodEPI(*this, DefaultCon);
- DefaultCon->setType(Context.getFunctionType(Context.VoidTy, None, EPI));
+ setupImplicitSpecialMemberType(DefaultCon, Context.VoidTy, None);
// We don't need to use SpecialMemberIsTrivial here; triviality for default
// constructors is easy to compute.
@@ -11223,9 +11240,7 @@ CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) {
/* Diagnose */ false);
}
- // Build an exception specification pointing back at this destructor.
- FunctionProtoType::ExtProtoInfo EPI = getImplicitMethodEPI(*this, Destructor);
- Destructor->setType(Context.getFunctionType(Context.VoidTy, None, EPI));
+ setupImplicitSpecialMemberType(Destructor, Context.VoidTy, None);
// We don't need to use SpecialMemberIsTrivial here; triviality for
// destructors is easy to compute.
@@ -11799,6 +11814,10 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) {
bool Const = ClassDecl->implicitCopyAssignmentHasConstParam();
if (Const)
ArgType = ArgType.withConst();
+
+ if (Context.getLangOpts().OpenCLCPlusPlus)
+ ArgType = Context.getAddrSpaceQualType(ArgType, LangAS::opencl_generic);
+
ArgType = Context.getLValueReferenceType(ArgType);
bool Constexpr = defaultedSpecialMemberIsConstexpr(*this, ClassDecl,
@@ -11825,10 +11844,7 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) {
/* Diagnose */ false);
}
- // Build an exception specification pointing back at this member.
- FunctionProtoType::ExtProtoInfo EPI =
- getImplicitMethodEPI(*this, CopyAssignment);
- CopyAssignment->setType(Context.getFunctionType(RetType, ArgType, EPI));
+ setupImplicitSpecialMemberType(CopyAssignment, RetType, ArgType);
// Add the parameter to the operator.
ParmVarDecl *FromParam = ParmVarDecl::Create(Context, CopyAssignment,
@@ -12312,8 +12328,6 @@ void Sema::DefineImplicitMoveAssignment(SourceLocation CurrentLocation,
ParmVarDecl *Other = MoveAssignOperator->getParamDecl(0);
QualType OtherRefType = Other->getType()->
getAs<RValueReferenceType>()->getPointeeType();
- assert(!OtherRefType.getQualifiers() &&
- "Bad argument type of defaulted move assignment");
// Our location for everything implicitly-generated.
SourceLocation Loc = MoveAssignOperator->getEndLoc().isValid()
@@ -12495,6 +12509,10 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
bool Const = ClassDecl->implicitCopyConstructorHasConstParam();
if (Const)
ArgType = ArgType.withConst();
+
+ if (Context.getLangOpts().OpenCLCPlusPlus)
+ ArgType = Context.getAddrSpaceQualType(ArgType, LangAS::opencl_generic);
+
ArgType = Context.getLValueReferenceType(ArgType);
bool Constexpr = defaultedSpecialMemberIsConstexpr(*this, ClassDecl,
@@ -12523,11 +12541,7 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
/* Diagnose */ false);
}
- // Build an exception specification pointing back at this member.
- FunctionProtoType::ExtProtoInfo EPI =
- getImplicitMethodEPI(*this, CopyConstructor);
- CopyConstructor->setType(
- Context.getFunctionType(Context.VoidTy, ArgType, EPI));
+ setupImplicitSpecialMemberType(CopyConstructor, Context.VoidTy, ArgType);
// Add the parameter to the constructor.
ParmVarDecl *FromParam = ParmVarDecl::Create(Context, CopyConstructor,
@@ -12624,7 +12638,11 @@ CXXConstructorDecl *Sema::DeclareImplicitMoveConstructor(
return nullptr;
QualType ClassType = Context.getTypeDeclType(ClassDecl);
- QualType ArgType = Context.getRValueReferenceType(ClassType);
+
+ QualType ArgType = ClassType;
+ if (Context.getLangOpts().OpenCLCPlusPlus)
+ ArgType = Context.getAddrSpaceQualType(ClassType, LangAS::opencl_generic);
+ ArgType = Context.getRValueReferenceType(ArgType);
bool Constexpr = defaultedSpecialMemberIsConstexpr(*this, ClassDecl,
CXXMoveConstructor,
@@ -12653,11 +12671,7 @@ CXXConstructorDecl *Sema::DeclareImplicitMoveConstructor(
/* Diagnose */ false);
}
- // Build an exception specification pointing back at this member.
- FunctionProtoType::ExtProtoInfo EPI =
- getImplicitMethodEPI(*this, MoveConstructor);
- MoveConstructor->setType(
- Context.getFunctionType(Context.VoidTy, ArgType, EPI));
+ setupImplicitSpecialMemberType(MoveConstructor, Context.VoidTy, ArgType);
// Add the parameter to the constructor.
ParmVarDecl *FromParam = ParmVarDecl::Create(Context, MoveConstructor,
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 80cc4617eb..10c0c6bf33 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -4669,11 +4669,22 @@ static void TryReferenceInitializationCore(Sema &S,
// If the converted initializer is a prvalue, its type T4 is adjusted
// to type "cv1 T4" and the temporary materialization conversion is
// applied.
+ // Postpone address space conversions to after the temporary materialization
+ // conversion to allow creating temporaries in the alloca address space.
+ auto AS1 = T1Quals.getAddressSpace();
+ auto AS2 = T2Quals.getAddressSpace();
+ T1Quals.removeAddressSpace();
+ T2Quals.removeAddressSpace();
QualType cv1T4 = S.Context.getQualifiedType(cv2T2, T1Quals);
if (T1Quals != T2Quals)
Sequence.AddQualificationConversionStep(cv1T4, ValueKind);
Sequence.AddReferenceBindingStep(cv1T4, ValueKind == VK_RValue);
ValueKind = isLValueRef ? VK_LValue : VK_XValue;
+ if (AS1 != AS2) {
+ T1Quals.addAddressSpace(AS1);
+ QualType cv1AST4 = S.Context.getQualifiedType(cv2T2, T1Quals);
+ Sequence.AddQualificationConversionStep(cv1AST4, ValueKind);
+ }
// In any case, the reference is bound to the resulting glvalue (or to
// an appropriate base class subobject).
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index bf1b9c66a7..b4c075e9c4 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -4836,11 +4836,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
LangAS AS =
(CurAS == LangAS::Default ? LangAS::opencl_generic : CurAS);
EPI.TypeQuals.addAddressSpace(AS);
- T = Context.getFunctionType(T, ParamTys, EPI);
- T = state.getSema().Context.getAddrSpaceQualType(T, AS);
- } else {
- T = Context.getFunctionType(T, ParamTys, EPI);
}
+ T = Context.getFunctionType(T, ParamTys, EPI);
}
break;
}