|
@@ -4938,7 +4938,6 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|
|
|
|
|
TypeSourceInfo *ReturnTypeInfo = nullptr;
|
|
TypeSourceInfo *ReturnTypeInfo = nullptr;
|
|
QualType T = GetDeclSpecTypeForDeclarator(state, ReturnTypeInfo);
|
|
QualType T = GetDeclSpecTypeForDeclarator(state, ReturnTypeInfo);
|
|
-
|
|
|
|
if (D.isPrototypeContext() && getLangOpts().ObjCAutoRefCount)
|
|
if (D.isPrototypeContext() && getLangOpts().ObjCAutoRefCount)
|
|
inferARCWriteback(state, T);
|
|
inferARCWriteback(state, T);
|
|
|
|
|
|
@@ -5752,9 +5751,10 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type,
|
|
ASIdx = LangAS::opencl_constant; break;
|
|
ASIdx = LangAS::opencl_constant; break;
|
|
case AttributeList::AT_OpenCLGenericAddressSpace:
|
|
case AttributeList::AT_OpenCLGenericAddressSpace:
|
|
ASIdx = LangAS::opencl_generic; break;
|
|
ASIdx = LangAS::opencl_generic; break;
|
|
|
|
+ case AttributeList::AT_OpenCLPrivateAddressSpace:
|
|
|
|
+ ASIdx = LangAS::opencl_private; break;
|
|
default:
|
|
default:
|
|
- assert(Attr.getKind() == AttributeList::AT_OpenCLPrivateAddressSpace);
|
|
|
|
- ASIdx = 0; break;
|
|
|
|
|
|
+ llvm_unreachable("Invalid address space");
|
|
}
|
|
}
|
|
|
|
|
|
Type = S.Context.getAddrSpaceQualType(Type, ASIdx);
|
|
Type = S.Context.getAddrSpaceQualType(Type, ASIdx);
|
|
@@ -6986,6 +6986,92 @@ static void HandleOpenCLAccessAttr(QualType &CurType, const AttributeList &Attr,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void deduceOpenCLImplicitAddrSpace(TypeProcessingState &State,
|
|
|
|
+ QualType &T, TypeAttrLocation TAL) {
|
|
|
|
+ Declarator &D = State.getDeclarator();
|
|
|
|
+
|
|
|
|
+ // Handle the cases where address space should not be deduced.
|
|
|
|
+ //
|
|
|
|
+ // The pointee type of a pointer type is alwasy deduced since a pointer always
|
|
|
|
+ // points to some memory location which should has an address space.
|
|
|
|
+ //
|
|
|
|
+ // There are situations that at the point of certain declarations, the address
|
|
|
|
+ // space may be unknown and better to be left as default. For example, when
|
|
|
|
+ // definining a typedef or struct type, they are not associated with any
|
|
|
|
+ // specific address space. Later on, they may be used with any address space
|
|
|
|
+ // to declare a variable.
|
|
|
|
+ //
|
|
|
|
+ // The return value of a function is r-value, therefore should not have
|
|
|
|
+ // address space.
|
|
|
|
+ //
|
|
|
|
+ // The void type does not occupy memory, therefore should not have address
|
|
|
|
+ // space, except when it is used as a pointee type.
|
|
|
|
+ //
|
|
|
|
+ // Since LLVM assumes function type is in default address space, it should not
|
|
|
|
+ // have address space.
|
|
|
|
+ auto ChunkIndex = State.getCurrentChunkIndex();
|
|
|
|
+ bool IsPointee =
|
|
|
|
+ ChunkIndex > 0 &&
|
|
|
|
+ (D.getTypeObject(ChunkIndex - 1).Kind == DeclaratorChunk::Pointer ||
|
|
|
|
+ D.getTypeObject(ChunkIndex - 1).Kind == DeclaratorChunk::BlockPointer);
|
|
|
|
+ bool IsFuncReturnType =
|
|
|
|
+ ChunkIndex > 0 &&
|
|
|
|
+ D.getTypeObject(ChunkIndex - 1).Kind == DeclaratorChunk::Function;
|
|
|
|
+ bool IsFuncType =
|
|
|
|
+ ChunkIndex < D.getNumTypeObjects() &&
|
|
|
|
+ D.getTypeObject(ChunkIndex).Kind == DeclaratorChunk::Function;
|
|
|
|
+ if ( // Do not deduce addr space for function return type and function type,
|
|
|
|
+ // otherwise it will fail some sema check.
|
|
|
|
+ IsFuncReturnType || IsFuncType ||
|
|
|
|
+ // Do not deduce addr space for member types of struct, except the pointee
|
|
|
|
+ // type of a pointer member type.
|
|
|
|
+ (D.getContext() == Declarator::MemberContext && !IsPointee) ||
|
|
|
|
+ // Do not deduce addr space for types used to define a typedef and the
|
|
|
|
+ // typedef itself, except the pointee type of a pointer type which is used
|
|
|
|
+ // to define the typedef.
|
|
|
|
+ (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef &&
|
|
|
|
+ !IsPointee) ||
|
|
|
|
+ // Do not deduce addr space of the void type, e.g. in f(void), otherwise
|
|
|
|
+ // it will fail some sema check.
|
|
|
|
+ (T->isVoidType() && !IsPointee))
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ unsigned ImpAddr;
|
|
|
|
+ // Put OpenCL automatic variable in private address space.
|
|
|
|
+ // OpenCL v1.2 s6.5:
|
|
|
|
+ // The default address space name for arguments to a function in a
|
|
|
|
+ // program, or local variables of a function is __private. All function
|
|
|
|
+ // arguments shall be in the __private address space.
|
|
|
|
+ if (State.getSema().getLangOpts().OpenCLVersion <= 120) {
|
|
|
|
+ ImpAddr = LangAS::opencl_private;
|
|
|
|
+ } else {
|
|
|
|
+ // If address space is not set, OpenCL 2.0 defines non private default
|
|
|
|
+ // address spaces for some cases:
|
|
|
|
+ // OpenCL 2.0, section 6.5:
|
|
|
|
+ // The address space for a variable at program scope or a static variable
|
|
|
|
+ // inside a function can either be __global or __constant, but defaults to
|
|
|
|
+ // __global if not specified.
|
|
|
|
+ // (...)
|
|
|
|
+ // Pointers that are declared without pointing to a named address space
|
|
|
|
+ // point to the generic address space.
|
|
|
|
+ if (IsPointee) {
|
|
|
|
+ ImpAddr = LangAS::opencl_generic;
|
|
|
|
+ } else {
|
|
|
|
+ if (D.getContext() == Declarator::FileContext) {
|
|
|
|
+ ImpAddr = LangAS::opencl_global;
|
|
|
|
+ } else {
|
|
|
|
+ if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static ||
|
|
|
|
+ D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_extern) {
|
|
|
|
+ ImpAddr = LangAS::opencl_global;
|
|
|
|
+ } else {
|
|
|
|
+ ImpAddr = LangAS::opencl_private;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ T = State.getSema().Context.getAddrSpaceQualType(T, ImpAddr);
|
|
|
|
+}
|
|
|
|
+
|
|
static void processTypeAttrs(TypeProcessingState &state, QualType &type,
|
|
static void processTypeAttrs(TypeProcessingState &state, QualType &type,
|
|
TypeAttrLocation TAL, AttributeList *attrs) {
|
|
TypeAttrLocation TAL, AttributeList *attrs) {
|
|
// Scan through and apply attributes to this type where it makes sense. Some
|
|
// Scan through and apply attributes to this type where it makes sense. Some
|
|
@@ -7157,39 +7243,11 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- // If address space is not set, OpenCL 2.0 defines non private default
|
|
|
|
- // address spaces for some cases:
|
|
|
|
- // OpenCL 2.0, section 6.5:
|
|
|
|
- // The address space for a variable at program scope or a static variable
|
|
|
|
- // inside a function can either be __global or __constant, but defaults to
|
|
|
|
- // __global if not specified.
|
|
|
|
- // (...)
|
|
|
|
- // Pointers that are declared without pointing to a named address space point
|
|
|
|
- // to the generic address space.
|
|
|
|
- if (state.getSema().getLangOpts().OpenCLVersion >= 200 &&
|
|
|
|
- !hasOpenCLAddressSpace && type.getAddressSpace() == 0 &&
|
|
|
|
- (TAL == TAL_DeclSpec || TAL == TAL_DeclChunk)) {
|
|
|
|
- Declarator &D = state.getDeclarator();
|
|
|
|
- if (state.getCurrentChunkIndex() > 0 &&
|
|
|
|
- (D.getTypeObject(state.getCurrentChunkIndex() - 1).Kind ==
|
|
|
|
- DeclaratorChunk::Pointer ||
|
|
|
|
- D.getTypeObject(state.getCurrentChunkIndex() - 1).Kind ==
|
|
|
|
- DeclaratorChunk::BlockPointer)) {
|
|
|
|
- type = state.getSema().Context.getAddrSpaceQualType(
|
|
|
|
- type, LangAS::opencl_generic);
|
|
|
|
- } else if (state.getCurrentChunkIndex() == 0 &&
|
|
|
|
- D.getContext() == Declarator::FileContext &&
|
|
|
|
- !D.isFunctionDeclarator() && !D.isFunctionDefinition() &&
|
|
|
|
- D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef &&
|
|
|
|
- !type->isSamplerT())
|
|
|
|
- type = state.getSema().Context.getAddrSpaceQualType(
|
|
|
|
- type, LangAS::opencl_global);
|
|
|
|
- else if (state.getCurrentChunkIndex() == 0 &&
|
|
|
|
- D.getContext() == Declarator::BlockContext &&
|
|
|
|
- D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static)
|
|
|
|
- type = state.getSema().Context.getAddrSpaceQualType(
|
|
|
|
- type, LangAS::opencl_global);
|
|
|
|
- }
|
|
|
|
|
|
+ if (!state.getSema().getLangOpts().OpenCL ||
|
|
|
|
+ type.getAddressSpace() != LangAS::Default)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ deduceOpenCLImplicitAddrSpace(state, type, TAL);
|
|
}
|
|
}
|
|
|
|
|
|
void Sema::completeExprArrayBound(Expr *E) {
|
|
void Sema::completeExprArrayBound(Expr *E) {
|