forked from OSchip/llvm-project
[OpenCL] Add constant address space to __func__ in AST.
Added string literal helper function to obtain the type attributed by a constant address space. Also fixed predefind __func__ expr to use the helper to constract the string literal correctly. Differential Revision: https://reviews.llvm.org/D46049 llvm-svn: 331877
This commit is contained in:
parent
d20289b31a
commit
59055b94af
|
@ -1348,6 +1348,8 @@ public:
|
||||||
return getFunctionTypeInternal(ResultTy, Args, EPI, false);
|
return getFunctionTypeInternal(ResultTy, Args, EPI, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QualType adjustStringLiteralBaseType(QualType StrLTy) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Return a normal function type with a typed argument list.
|
/// Return a normal function type with a typed argument list.
|
||||||
QualType getFunctionTypeInternal(QualType ResultTy, ArrayRef<QualType> Args,
|
QualType getFunctionTypeInternal(QualType ResultTy, ArrayRef<QualType> Args,
|
||||||
|
|
|
@ -3621,6 +3621,12 @@ QualType ASTContext::getPipeType(QualType T, bool ReadOnly) const {
|
||||||
return QualType(New, 0);
|
return QualType(New, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QualType ASTContext::adjustStringLiteralBaseType(QualType Ty) const {
|
||||||
|
// OpenCL v1.1 s6.5.3: a string literal is in the constant address space.
|
||||||
|
return LangOpts.OpenCL ? getAddrSpaceQualType(Ty, LangAS::opencl_constant)
|
||||||
|
: Ty;
|
||||||
|
}
|
||||||
|
|
||||||
QualType ASTContext::getReadPipeType(QualType T) const {
|
QualType ASTContext::getReadPipeType(QualType T) const {
|
||||||
return getPipeType(T, true);
|
return getPipeType(T, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -881,7 +881,8 @@ StringLiteral *StringLiteral::CreateEmpty(const ASTContext &C,
|
||||||
void *Mem =
|
void *Mem =
|
||||||
C.Allocate(sizeof(StringLiteral) + sizeof(SourceLocation) * (NumStrs - 1),
|
C.Allocate(sizeof(StringLiteral) + sizeof(SourceLocation) * (NumStrs - 1),
|
||||||
alignof(StringLiteral));
|
alignof(StringLiteral));
|
||||||
StringLiteral *SL = new (Mem) StringLiteral(QualType());
|
StringLiteral *SL =
|
||||||
|
new (Mem) StringLiteral(C.adjustStringLiteralBaseType(QualType()));
|
||||||
SL->CharByteWidth = 0;
|
SL->CharByteWidth = 0;
|
||||||
SL->Length = 0;
|
SL->Length = 0;
|
||||||
SL->NumConcatenated = NumStrs;
|
SL->NumConcatenated = NumStrs;
|
||||||
|
|
|
@ -1554,18 +1554,15 @@ Sema::ActOnStringLiteral(ArrayRef<Token> StringToks, Scope *UDLScope) {
|
||||||
if (getLangOpts().CPlusPlus || getLangOpts().ConstStrings)
|
if (getLangOpts().CPlusPlus || getLangOpts().ConstStrings)
|
||||||
CharTyConst.addConst();
|
CharTyConst.addConst();
|
||||||
|
|
||||||
|
CharTyConst = Context.adjustStringLiteralBaseType(CharTyConst);
|
||||||
|
|
||||||
// Get an array type for the string, according to C99 6.4.5. This includes
|
// Get an array type for the string, according to C99 6.4.5. This includes
|
||||||
// the nul terminator character as well as the string length for pascal
|
// the nul terminator character as well as the string length for pascal
|
||||||
// strings.
|
// strings.
|
||||||
QualType StrTy = Context.getConstantArrayType(CharTyConst,
|
QualType StrTy = Context.getConstantArrayType(
|
||||||
llvm::APInt(32, Literal.GetNumStringChars()+1),
|
CharTyConst, llvm::APInt(32, Literal.GetNumStringChars() + 1),
|
||||||
ArrayType::Normal, 0);
|
ArrayType::Normal, 0);
|
||||||
|
|
||||||
// OpenCL v1.1 s6.5.3: a string literal is in the constant address space.
|
|
||||||
if (getLangOpts().OpenCL) {
|
|
||||||
StrTy = Context.getAddrSpaceQualType(StrTy, LangAS::opencl_constant);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pass &StringTokLocs[0], StringTokLocs.size() to factory!
|
// Pass &StringTokLocs[0], StringTokLocs.size() to factory!
|
||||||
StringLiteral *Lit = StringLiteral::Create(Context, Literal.GetString(),
|
StringLiteral *Lit = StringLiteral::Create(Context, Literal.GetString(),
|
||||||
Kind, Literal.Pascal, StrTy,
|
Kind, Literal.Pascal, StrTy,
|
||||||
|
@ -3046,7 +3043,8 @@ ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc,
|
||||||
|
|
||||||
llvm::APInt LengthI(32, Length + 1);
|
llvm::APInt LengthI(32, Length + 1);
|
||||||
if (IT == PredefinedExpr::LFunction) {
|
if (IT == PredefinedExpr::LFunction) {
|
||||||
ResTy = Context.WideCharTy.withConst();
|
ResTy =
|
||||||
|
Context.adjustStringLiteralBaseType(Context.WideCharTy.withConst());
|
||||||
SmallString<32> RawChars;
|
SmallString<32> RawChars;
|
||||||
ConvertUTF8ToWideString(Context.getTypeSizeInChars(ResTy).getQuantity(),
|
ConvertUTF8ToWideString(Context.getTypeSizeInChars(ResTy).getQuantity(),
|
||||||
Str, RawChars);
|
Str, RawChars);
|
||||||
|
@ -3055,7 +3053,7 @@ ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc,
|
||||||
SL = StringLiteral::Create(Context, RawChars, StringLiteral::Wide,
|
SL = StringLiteral::Create(Context, RawChars, StringLiteral::Wide,
|
||||||
/*Pascal*/ false, ResTy, Loc);
|
/*Pascal*/ false, ResTy, Loc);
|
||||||
} else {
|
} else {
|
||||||
ResTy = Context.CharTy.withConst();
|
ResTy = Context.adjustStringLiteralBaseType(Context.CharTy.withConst());
|
||||||
ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal,
|
ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal,
|
||||||
/*IndexTypeQuals*/ 0);
|
/*IndexTypeQuals*/ 0);
|
||||||
SL = StringLiteral::Create(Context, Str, StringLiteral::Ascii,
|
SL = StringLiteral::Create(Context, Str, StringLiteral::Ascii,
|
||||||
|
@ -3294,8 +3292,8 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
|
||||||
// operator "" X ("n")
|
// operator "" X ("n")
|
||||||
unsigned Length = Literal.getUDSuffixOffset();
|
unsigned Length = Literal.getUDSuffixOffset();
|
||||||
QualType StrTy = Context.getConstantArrayType(
|
QualType StrTy = Context.getConstantArrayType(
|
||||||
Context.CharTy.withConst(), llvm::APInt(32, Length + 1),
|
Context.adjustStringLiteralBaseType(Context.CharTy.withConst()),
|
||||||
ArrayType::Normal, 0);
|
llvm::APInt(32, Length + 1), ArrayType::Normal, 0);
|
||||||
Expr *Lit = StringLiteral::Create(
|
Expr *Lit = StringLiteral::Create(
|
||||||
Context, StringRef(TokSpelling.data(), Length), StringLiteral::Ascii,
|
Context, StringRef(TokSpelling.data(), Length), StringLiteral::Ascii,
|
||||||
/*Pascal*/false, StrTy, &TokLoc, 1);
|
/*Pascal*/false, StrTy, &TokLoc, 1);
|
||||||
|
@ -13675,7 +13673,6 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
|
||||||
DiagKind = diag::err_typecheck_incompatible_address_space;
|
DiagKind = diag::err_typecheck_incompatible_address_space;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
} else if (lhq.getObjCLifetime() != rhq.getObjCLifetime()) {
|
} else if (lhq.getObjCLifetime() != rhq.getObjCLifetime()) {
|
||||||
DiagKind = diag::err_typecheck_incompatible_ownership;
|
DiagKind = diag::err_typecheck_incompatible_ownership;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -3,7 +3,13 @@
|
||||||
__constant char *__constant x = "hello world";
|
__constant char *__constant x = "hello world";
|
||||||
__constant char *__constant y = "hello world";
|
__constant char *__constant y = "hello world";
|
||||||
|
|
||||||
// CHECK: unnamed_addr addrspace(2) constant
|
// CHECK: unnamed_addr addrspace(2) constant{{.*}}"hello world\00"
|
||||||
// CHECK-NOT: addrspace(2) unnamed_addr constant
|
// CHECK-NOT: addrspace(2) unnamed_addr constant
|
||||||
// CHECK: @x = {{(dso_local )?}}addrspace(2) constant i8 addrspace(2)*
|
// CHECK: @x = {{(dso_local )?}}addrspace(2) constant i8 addrspace(2)*
|
||||||
// CHECK: @y = {{(dso_local )?}}addrspace(2) constant i8 addrspace(2)*
|
// CHECK: @y = {{(dso_local )?}}addrspace(2) constant i8 addrspace(2)*
|
||||||
|
// CHECK: unnamed_addr addrspace(2) constant{{.*}}"f\00"
|
||||||
|
|
||||||
|
void f() {
|
||||||
|
//CHECK: store i8 addrspace(2)* {{.*}}, i8 addrspace(2)**
|
||||||
|
constant const char *f3 = __func__;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
// RUN: %clang_cc1 %s -verify
|
||||||
|
// RUN: %clang_cc1 %s -verify -cl-std=CL2.0
|
||||||
|
|
||||||
|
void f() {
|
||||||
|
char *f1 = __func__; //expected-error-re{{initializing '{{__generic char|char}} *' with an expression of type 'const __constant char *' changes address space of pointer}}
|
||||||
|
constant char *f2 = __func__; //expected-warning{{initializing '__constant char *' with an expression of type 'const __constant char [2]' discards qualifiers}}
|
||||||
|
constant const char *f3 = __func__;
|
||||||
|
}
|
Loading…
Reference in New Issue