Revert "[SYCL] Implement __builtin_unique_stable_name."

This reverts commit b5a034e771.

This feature was added without following the proper process.
This commit is contained in:
John McCall 2020-10-12 01:09:25 -04:00
parent cddb49bcc0
commit cec49a5836
14 changed files with 14 additions and 495 deletions

View File

@ -2218,30 +2218,6 @@ argument.
int *pb =__builtin_preserve_access_index(&v->c[3].b);
__builtin_preserve_access_index(v->j);
``__builtin_unique_stable_name``
--------------------------------
``__builtin_unique_stable_name()`` is a builtin that takes a type or expression and
produces a string literal containing a unique name for the type (or type of the
expression) that is stable across split compilations.
In cases where the split compilation needs to share a unique token for a type
across the boundary (such as in an offloading situation), this name can be used
for lookup purposes.
This builtin is superior to RTTI for this purpose for two reasons. First, this
value is computed entirely at compile time, so it can be used in constant
expressions. Second, this value encodes lambda functions based on line-number
rather than the order in which it appears in a function. This is valuable
because it is stable in cases where an unrelated lambda is introduced
conditionally in the same function.
The current implementation of this builtin uses a slightly modified Itanium
Mangler to produce the unique name. The lambda ordinal is replaced with one or
more line/column pairs in the format ``LINE->COL``, separated with a ``~``
character. Typically, only one pair will be included, however in the case of
macro expansions the entire macro expansion stack is expressed.
Multiprecision Arithmetic Builtins
----------------------------------

View File

@ -1930,17 +1930,13 @@ public:
/// [C99 6.4.2.2] - A predefined identifier such as __func__.
class PredefinedExpr final
: public Expr,
private llvm::TrailingObjects<PredefinedExpr, Stmt *, Expr *,
TypeSourceInfo *> {
private llvm::TrailingObjects<PredefinedExpr, Stmt *> {
friend class ASTStmtReader;
friend TrailingObjects;
// PredefinedExpr is optionally followed by a single trailing
// "Stmt *" for the predefined identifier. It is present if and only if
// hasFunctionName() is true and is always a "StringLiteral *".
// It can also be followed by a Expr* in the case of a
// __builtin_unique_stable_name with an expression, or TypeSourceInfo * if
// __builtin_unique_stable_name with a type.
public:
enum IdentKind {
@ -1953,18 +1949,12 @@ public:
PrettyFunction,
/// The same as PrettyFunction, except that the
/// 'virtual' keyword is omitted for virtual member functions.
PrettyFunctionNoVirtual,
UniqueStableNameType,
UniqueStableNameExpr,
PrettyFunctionNoVirtual
};
private:
PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK,
StringLiteral *SL);
PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK,
TypeSourceInfo *Info);
PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK,
Expr *E);
explicit PredefinedExpr(EmptyShell Empty, bool HasFunctionName);
@ -1977,39 +1967,10 @@ private:
*getTrailingObjects<Stmt *>() = SL;
}
void setTypeSourceInfo(TypeSourceInfo *Info) {
assert(!hasFunctionName() && getIdentKind() == UniqueStableNameType &&
"TypeSourceInfo only valid for UniqueStableName of a Type");
*getTrailingObjects<TypeSourceInfo *>() = Info;
}
void setExpr(Expr *E) {
assert(!hasFunctionName() && getIdentKind() == UniqueStableNameExpr &&
"TypeSourceInfo only valid for UniqueStableName of n Expression.");
*getTrailingObjects<Expr *>() = E;
}
size_t numTrailingObjects(OverloadToken<Stmt *>) const {
return hasFunctionName();
}
size_t numTrailingObjects(OverloadToken<TypeSourceInfo *>) const {
return getIdentKind() == UniqueStableNameType && !hasFunctionName();
}
size_t numTrailingObjects(OverloadToken<Expr *>) const {
return getIdentKind() == UniqueStableNameExpr && !hasFunctionName();
}
public:
/// Create a PredefinedExpr.
static PredefinedExpr *Create(const ASTContext &Ctx, SourceLocation L,
QualType FNTy, IdentKind IK, StringLiteral *SL);
static PredefinedExpr *Create(const ASTContext &Ctx, SourceLocation L,
QualType FNTy, IdentKind IK, StringLiteral *SL,
TypeSourceInfo *Info);
static PredefinedExpr *Create(const ASTContext &Ctx, SourceLocation L,
QualType FNTy, IdentKind IK, StringLiteral *SL,
Expr *E);
/// Create an empty PredefinedExpr.
static PredefinedExpr *CreateEmpty(const ASTContext &Ctx,
@ -2034,34 +1995,8 @@ public:
: nullptr;
}
TypeSourceInfo *getTypeSourceInfo() {
assert(!hasFunctionName() && getIdentKind() == UniqueStableNameType &&
"TypeSourceInfo only valid for UniqueStableName of a Type");
return *getTrailingObjects<TypeSourceInfo *>();
}
const TypeSourceInfo *getTypeSourceInfo() const {
assert(!hasFunctionName() && getIdentKind() == UniqueStableNameType &&
"TypeSourceInfo only valid for UniqueStableName of a Type");
return *getTrailingObjects<TypeSourceInfo *>();
}
Expr *getExpr() {
assert(!hasFunctionName() && getIdentKind() == UniqueStableNameExpr &&
"TypeSourceInfo only valid for UniqueStableName of n Expression.");
return *getTrailingObjects<Expr *>();
}
const Expr *getExpr() const {
assert(!hasFunctionName() && getIdentKind() == UniqueStableNameExpr &&
"TypeSourceInfo only valid for UniqueStableName of n Expression.");
return *getTrailingObjects<Expr *>();
}
static StringRef getIdentKindName(IdentKind IK);
static std::string ComputeName(IdentKind IK, const Decl *CurrentDecl);
static std::string ComputeName(ASTContext &Context, IdentKind IK,
const QualType Ty);
SourceLocation getBeginLoc() const { return getLocation(); }
SourceLocation getEndLoc() const { return getLocation(); }

View File

@ -152,14 +152,9 @@ public:
};
class ItaniumMangleContext : public MangleContext {
bool IsUniqueNameMangler = false;
public:
explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D)
: MangleContext(C, D, MK_Itanium) {}
explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D,
bool IsUniqueNameMangler)
: MangleContext(C, D, MK_Itanium),
IsUniqueNameMangler(IsUniqueNameMangler) {}
virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
@ -180,15 +175,12 @@ public:
virtual void mangleDynamicStermFinalizer(const VarDecl *D, raw_ostream &) = 0;
bool isUniqueNameMangler() { return IsUniqueNameMangler; }
static bool classof(const MangleContext *C) {
return C->getKind() == MK_Itanium;
}
static ItaniumMangleContext *create(ASTContext &Context,
DiagnosticsEngine &Diags,
bool IsUniqueNameMangler = false);
DiagnosticsEngine &Diags);
};
class MicrosoftMangleContext : public MangleContext {

View File

@ -698,7 +698,6 @@ ALIAS("__char16_t" , char16_t , KEYCXX)
ALIAS("__char32_t" , char32_t , KEYCXX)
KEYWORD(__builtin_bit_cast , KEYALL)
KEYWORD(__builtin_available , KEYALL)
KEYWORD(__builtin_unique_stable_name, KEYALL)
// Clang-specific keywords enabled only in testing.
TESTING_KEYWORD(__unknown_anytype , KEYALL)

View File

@ -1824,7 +1824,6 @@ private:
ExprResult ParsePostfixExpressionSuffix(ExprResult LHS);
ExprResult ParseUnaryExprOrTypeTraitExpression();
ExprResult ParseBuiltinPrimaryExpression();
ExprResult ParseUniqueStableNameExpression();
ExprResult ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
bool &isCastExpr,

View File

@ -4919,15 +4919,6 @@ public:
ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind);
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val);
ExprResult BuildUniqueStableName(SourceLocation Loc, TypeSourceInfo *Operand);
ExprResult BuildUniqueStableName(SourceLocation Loc, Expr *E);
ExprResult ActOnUniqueStableNameExpr(SourceLocation OpLoc,
SourceLocation LParen,
SourceLocation RParen, ParsedType Ty);
ExprResult ActOnUniqueStableNameExpr(SourceLocation OpLoc,
SourceLocation LParen,
SourceLocation RParen, Expr *E);
bool CheckLoopHintExpr(Expr *E, SourceLocation Loc);
ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope = nullptr);

View File

@ -510,34 +510,6 @@ PredefinedExpr::PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK,
setDependence(computeDependence(this));
}
PredefinedExpr::PredefinedExpr(SourceLocation L, QualType FnTy, IdentKind IK,
TypeSourceInfo *Info)
: Expr(PredefinedExprClass, FnTy, VK_LValue, OK_Ordinary) {
PredefinedExprBits.Kind = IK;
assert((getIdentKind() == IK) &&
"IdentKind do not fit in PredefinedExprBitFields!");
assert(IK == UniqueStableNameType &&
"Constructor only valid with UniqueStableNameType");
PredefinedExprBits.HasFunctionName = false;
PredefinedExprBits.Loc = L;
setTypeSourceInfo(Info);
setDependence(computeDependence(this));
}
PredefinedExpr::PredefinedExpr(SourceLocation L, QualType FnTy, IdentKind IK,
Expr *E)
: Expr(PredefinedExprClass, FnTy, VK_LValue, OK_Ordinary) {
PredefinedExprBits.Kind = IK;
assert((getIdentKind() == IK) &&
"IdentKind do not fit in PredefinedExprBitFields!");
assert(IK == UniqueStableNameExpr &&
"Constructor only valid with UniqueStableNameExpr");
PredefinedExprBits.HasFunctionName = false;
PredefinedExprBits.Loc = L;
setExpr(E);
setDependence(computeDependence(this));
}
PredefinedExpr::PredefinedExpr(EmptyShell Empty, bool HasFunctionName)
: Expr(PredefinedExprClass, Empty) {
PredefinedExprBits.HasFunctionName = HasFunctionName;
@ -547,44 +519,15 @@ PredefinedExpr *PredefinedExpr::Create(const ASTContext &Ctx, SourceLocation L,
QualType FNTy, IdentKind IK,
StringLiteral *SL) {
bool HasFunctionName = SL != nullptr;
void *Mem = Ctx.Allocate(
totalSizeToAlloc<Stmt *, Expr *, TypeSourceInfo *>(HasFunctionName, 0, 0),
alignof(PredefinedExpr));
void *Mem = Ctx.Allocate(totalSizeToAlloc<Stmt *>(HasFunctionName),
alignof(PredefinedExpr));
return new (Mem) PredefinedExpr(L, FNTy, IK, SL);
}
PredefinedExpr *PredefinedExpr::Create(const ASTContext &Ctx, SourceLocation L,
QualType FNTy, IdentKind IK,
StringLiteral *SL,
TypeSourceInfo *Info) {
assert(IK == UniqueStableNameType && "Only valid with UniqueStableNameType");
bool HasFunctionName = SL != nullptr;
void *Mem = Ctx.Allocate(totalSizeToAlloc<Stmt *, Expr *, TypeSourceInfo *>(
HasFunctionName, 0, !HasFunctionName),
alignof(PredefinedExpr));
if (HasFunctionName)
return new (Mem) PredefinedExpr(L, FNTy, IK, SL);
return new (Mem) PredefinedExpr(L, FNTy, IK, Info);
}
PredefinedExpr *PredefinedExpr::Create(const ASTContext &Ctx, SourceLocation L,
QualType FNTy, IdentKind IK,
StringLiteral *SL, Expr *E) {
assert(IK == UniqueStableNameExpr && "Only valid with UniqueStableNameExpr");
bool HasFunctionName = SL != nullptr;
void *Mem = Ctx.Allocate(totalSizeToAlloc<Stmt *, Expr *, TypeSourceInfo *>(
HasFunctionName, !HasFunctionName, 0),
alignof(PredefinedExpr));
if (HasFunctionName)
return new (Mem) PredefinedExpr(L, FNTy, IK, SL);
return new (Mem) PredefinedExpr(L, FNTy, IK, E);
}
PredefinedExpr *PredefinedExpr::CreateEmpty(const ASTContext &Ctx,
bool HasFunctionName) {
void *Mem = Ctx.Allocate(
totalSizeToAlloc<Stmt *, Expr *, TypeSourceInfo *>(HasFunctionName, 0, 0),
alignof(PredefinedExpr));
void *Mem = Ctx.Allocate(totalSizeToAlloc<Stmt *>(HasFunctionName),
alignof(PredefinedExpr));
return new (Mem) PredefinedExpr(EmptyShell(), HasFunctionName);
}
@ -604,28 +547,12 @@ StringRef PredefinedExpr::getIdentKindName(PredefinedExpr::IdentKind IK) {
return "__FUNCSIG__";
case LFuncSig:
return "L__FUNCSIG__";
case UniqueStableNameType:
case UniqueStableNameExpr:
return "__builtin_unique_stable_name";
case PrettyFunctionNoVirtual:
break;
}
llvm_unreachable("Unknown ident kind for PredefinedExpr");
}
std::string PredefinedExpr::ComputeName(ASTContext &Context, IdentKind IK,
QualType Ty) {
std::unique_ptr<MangleContext> Ctx{ItaniumMangleContext::create(
Context, Context.getDiagnostics(), /*IsUniqueNameMangler*/ true)};
Ty = Ty.getCanonicalType();
SmallString<256> Buffer;
llvm::raw_svector_ostream Out(Buffer);
Ctx->mangleTypeName(Ty, Out);
return std::string(Buffer.str());
}
// FIXME: Maybe this should use DeclPrinter with a special "print predefined
// expr" policy instead.
std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) {

View File

@ -127,9 +127,8 @@ class ItaniumMangleContextImpl : public ItaniumMangleContext {
public:
explicit ItaniumMangleContextImpl(ASTContext &Context,
DiagnosticsEngine &Diags,
bool IsUniqueNameMangler)
: ItaniumMangleContext(Context, Diags, IsUniqueNameMangler) {}
DiagnosticsEngine &Diags)
: ItaniumMangleContext(Context, Diags) {}
/// @name Mangler Entry Points
/// @{
@ -1413,8 +1412,7 @@ void CXXNameMangler::mangleUnqualifiedName(GlobalDecl GD,
// <lambda-sig> ::= <template-param-decl>* <parameter-type>+
// # Parameter types or 'v' for 'void'.
if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(TD)) {
if (Record->isLambda() && (Record->getLambdaManglingNumber() ||
Context.isUniqueNameMangler())) {
if (Record->isLambda() && Record->getLambdaManglingNumber()) {
assert(!AdditionalAbiTags &&
"Lambda type cannot have additional abi tags");
mangleLambda(Record);
@ -1789,37 +1787,6 @@ void CXXNameMangler::mangleTemplateParamDecl(const NamedDecl *Decl) {
}
}
// Handles the __builtin_unique_stable_name feature for lambdas. Instead of the
// ordinal of the lambda in its mangling, this does line/column to uniquely and
// reliably identify the lambda. Additionally, macro expansions are expressed
// as well to prevent macros causing duplicates.
static void mangleUniqueNameLambda(CXXNameMangler &Mangler, SourceManager &SM,
raw_ostream &Out,
const CXXRecordDecl *Lambda) {
SourceLocation Loc = Lambda->getLocation();
PresumedLoc PLoc = SM.getPresumedLoc(Loc);
Mangler.mangleNumber(PLoc.getLine());
Out << "_";
Mangler.mangleNumber(PLoc.getColumn());
while(Loc.isMacroID()) {
SourceLocation SLToPrint = Loc;
if (SM.isMacroArgExpansion(Loc))
SLToPrint = SM.getImmediateExpansionRange(Loc).getBegin();
PLoc = SM.getPresumedLoc(SM.getSpellingLoc(SLToPrint));
Out << "m";
Mangler.mangleNumber(PLoc.getLine());
Out << "_";
Mangler.mangleNumber(PLoc.getColumn());
Loc = SM.getImmediateMacroCallerLoc(Loc);
if (Loc.isFileID())
Loc = SM.getImmediateMacroCallerLoc(SLToPrint);
}
}
void CXXNameMangler::mangleLambda(const CXXRecordDecl *Lambda) {
// If the context of a closure type is an initializer for a class member
// (static or nonstatic), it is encoded in a qualified name with a final
@ -1850,12 +1817,6 @@ void CXXNameMangler::mangleLambda(const CXXRecordDecl *Lambda) {
mangleLambdaSig(Lambda);
Out << "E";
if (Context.isUniqueNameMangler()) {
mangleUniqueNameLambda(
*this, Context.getASTContext().getSourceManager(), Out, Lambda);
return;
}
// The number is omitted for the first closure type with a given
// <lambda-sig> in a given context; it is n-2 for the nth closure type
// (in lexical order) with that same <lambda-sig> and context.
@ -5483,8 +5444,7 @@ void ItaniumMangleContextImpl::mangleLambdaSig(const CXXRecordDecl *Lambda,
Mangler.mangleLambdaSig(Lambda);
}
ItaniumMangleContext *ItaniumMangleContext::create(ASTContext &Context,
DiagnosticsEngine &Diags,
bool IsUniqueNameMangler) {
return new ItaniumMangleContextImpl(Context, Diags, IsUniqueNameMangler);
ItaniumMangleContext *
ItaniumMangleContext::create(ASTContext &Context, DiagnosticsEngine &Diags) {
return new ItaniumMangleContextImpl(Context, Diags);
}

View File

@ -1469,9 +1469,7 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
case tok::kw_this:
Res = ParseCXXThis();
break;
case tok::kw___builtin_unique_stable_name:
Res = ParseUniqueStableNameExpression();
break;
case tok::annot_typename:
if (isStartOfObjCClassMessageMissingOpenBracket()) {
TypeResult Type = getTypeAnnotation(Tok);
@ -2320,43 +2318,6 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
}
ExprResult Parser::ParseUniqueStableNameExpression() {
assert(Tok.is(tok::kw___builtin_unique_stable_name) &&
"Not __bulitin_unique_stable_name");
SourceLocation OpLoc = ConsumeToken();
BalancedDelimiterTracker T(*this, tok::l_paren);
// typeid expressions are always parenthesized.
if (T.expectAndConsume(diag::err_expected_lparen_after,
"__builtin_unique_stable_name"))
return ExprError();
if (isTypeIdInParens()) {
TypeResult Ty = ParseTypeName();
T.consumeClose();
if (Ty.isInvalid())
return ExprError();
return Actions.ActOnUniqueStableNameExpr(OpLoc, T.getOpenLocation(),
T.getCloseLocation(), Ty.get());
}
EnterExpressionEvaluationContext Unevaluated(
Actions, Sema::ExpressionEvaluationContext::Unevaluated);
ExprResult Result = ParseExpression();
if (Result.isInvalid()) {
SkipUntil(tok::r_paren, StopAtSemi);
return Result;
}
T.consumeClose();
return Actions.ActOnUniqueStableNameExpr(OpLoc, T.getOpenLocation(),
T.getCloseLocation(), Result.get());
}
/// Parse a sizeof or alignof expression.
///
/// \verbatim

View File

@ -3421,70 +3421,6 @@ ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc,
return PredefinedExpr::Create(Context, Loc, ResTy, IK, SL);
}
static std::pair<QualType, StringLiteral *>
GetUniqueStableNameInfo(ASTContext &Context, QualType OpType,
SourceLocation OpLoc, PredefinedExpr::IdentKind K) {
std::pair<QualType, StringLiteral*> Result{{}, nullptr};
if (OpType->isDependentType()) {
Result.first = Context.DependentTy;
return Result;
}
std::string Str = PredefinedExpr::ComputeName(Context, K, OpType);
llvm::APInt Length(32, Str.length() + 1);
Result.first =
Context.adjustStringLiteralBaseType(Context.CharTy.withConst());
Result.first = Context.getConstantArrayType(
Result.first, Length, nullptr, ArrayType::Normal, /*IndexTypeQuals*/ 0);
Result.second = StringLiteral::Create(Context, Str, StringLiteral::Ascii,
/*Pascal*/ false, Result.first, OpLoc);
return Result;
}
ExprResult Sema::BuildUniqueStableName(SourceLocation OpLoc,
TypeSourceInfo *Operand) {
QualType ResultTy;
StringLiteral *SL;
std::tie(ResultTy, SL) = GetUniqueStableNameInfo(
Context, Operand->getType(), OpLoc, PredefinedExpr::UniqueStableNameType);
return PredefinedExpr::Create(Context, OpLoc, ResultTy,
PredefinedExpr::UniqueStableNameType, SL,
Operand);
}
ExprResult Sema::BuildUniqueStableName(SourceLocation OpLoc,
Expr *E) {
QualType ResultTy;
StringLiteral *SL;
std::tie(ResultTy, SL) = GetUniqueStableNameInfo(
Context, E->getType(), OpLoc, PredefinedExpr::UniqueStableNameExpr);
return PredefinedExpr::Create(Context, OpLoc, ResultTy,
PredefinedExpr::UniqueStableNameExpr, SL, E);
}
ExprResult Sema::ActOnUniqueStableNameExpr(SourceLocation OpLoc,
SourceLocation L, SourceLocation R,
ParsedType Ty) {
TypeSourceInfo *TInfo = nullptr;
QualType T = GetTypeFromParser(Ty, &TInfo);
if (T.isNull())
return ExprError();
if (!TInfo)
TInfo = Context.getTrivialTypeSourceInfo(T, OpLoc);
return BuildUniqueStableName(OpLoc, TInfo);
}
ExprResult Sema::ActOnUniqueStableNameExpr(SourceLocation OpLoc,
SourceLocation L, SourceLocation R,
Expr *E) {
return BuildUniqueStableName(OpLoc, E);
}
ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) {
PredefinedExpr::IdentKind IK;

View File

@ -1414,47 +1414,11 @@ TemplateName TemplateInstantiator::TransformTemplateName(
AllowInjectedClassName);
}
static ExprResult TransformUniqueStableName(TemplateInstantiator &TI,
PredefinedExpr *E) {
if (E->getIdentKind() == PredefinedExpr::UniqueStableNameType) {
TypeSourceInfo *Info =
TI.getDerived().TransformType(E->getTypeSourceInfo());
if (!Info)
return ExprError();
if (!TI.getDerived().AlwaysRebuild() && Info == E->getTypeSourceInfo())
return E;
return TI.getSema().BuildUniqueStableName(E->getLocation(), Info);
}
if (E->getIdentKind() == PredefinedExpr::UniqueStableNameExpr) {
EnterExpressionEvaluationContext Unevaluated(
TI.getSema(), Sema::ExpressionEvaluationContext::Unevaluated);
ExprResult SubExpr = TI.getDerived().TransformExpr(E->getExpr());
if (SubExpr.isInvalid())
return ExprError();
if (!TI.getDerived().AlwaysRebuild() && SubExpr.get() == E->getExpr())
return E;
return TI.getSema().BuildUniqueStableName(E->getLocation(), SubExpr.get());
}
llvm_unreachable("Only valid for UniqueStableNameType/Expr");
}
ExprResult
TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) {
if (!E->isTypeDependent())
return E;
if (E->getIdentKind() == PredefinedExpr::UniqueStableNameType ||
E->getIdentKind() == PredefinedExpr::UniqueStableNameExpr)
return TransformUniqueStableName(*this, E);
return getSema().BuildPredefinedExpr(E->getLocation(), E->getIdentKind());
}

View File

@ -7,12 +7,6 @@ template <typename T>
void clang_analyzer_dump(const T *);
void clang_analyzer_warnIfReached();
void builtin_unique_stable_name_of_lambda() {
auto y = [] {};
clang_analyzer_dump(__builtin_unique_stable_name(y));
// expected-warning@-1 {{&Element{"_ZTSZ36builtin_unique_stable_name_of_lambdavEUlvE11_12",0 S64b,char}}}
}
template <typename T, auto Value, typename U>
void func(U param) {
clang_analyzer_dump(__func__);
@ -56,11 +50,6 @@ void foo() {
func<struct Class, 42ull>('b'); // instantiate template
}
void test_builtin_unique_stable_name(int a) {
clang_analyzer_dump(__builtin_unique_stable_name(a));
// expected-warning@-1 {{&Element{"_ZTSi",0 S64b,char}}}
}
struct A {
A() {
clang_analyzer_dump(__func__);

View File

@ -1,77 +0,0 @@
// RUN: %clang_cc1 -triple spir64-unknown-unknown-sycldevice -fsycl -fsycl-is-device -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s
// CHECK: @[[INT:[^\w]+]] = private unnamed_addr constant [[INT_SIZE:\[[0-9]+ x i8\]]] c"_ZTSi\00"
// CHECK: @[[LAMBDA_X:[^\w]+]] = private unnamed_addr constant [[LAMBDA_X_SIZE:\[[0-9]+ x i8\]]] c"_ZTSZZ4mainENKUlvE42_5clEvEUlvE46_16\00"
// CHECK: @[[MACRO_X:[^\w]+]] = private unnamed_addr constant [[MACRO_SIZE:\[[0-9]+ x i8\]]] c"_ZTSZZ4mainENKUlvE42_5clEvEUlvE52_7m28_18\00"
// CHECK: @[[MACRO_Y:[^\w]+]] = private unnamed_addr constant [[MACRO_SIZE]] c"_ZTSZZ4mainENKUlvE42_5clEvEUlvE52_7m28_41\00"
// CHECK: @[[MACRO_MACRO_X:[^\w]+]] = private unnamed_addr constant [[MACRO_MACRO_SIZE:\[[0-9]+ x i8\]]] c"_ZTSZZ4mainENKUlvE42_5clEvEUlvE55_7m28_18m33_4\00"
// CHECK: @[[MACRO_MACRO_Y:[^\w]+]] = private unnamed_addr constant [[MACRO_MACRO_SIZE]] c"_ZTSZZ4mainENKUlvE42_5clEvEUlvE55_7m28_41m33_4\00"
// CHECK: @[[LAMBDA_IN_DEP_INT:[^\w]+]] = private unnamed_addr constant [[DEP_INT_SIZE:\[[0-9]+ x i8\]]] c"_ZTSZ28lambda_in_dependent_functionIiEvvEUlvE23_12\00",
// CHECK: @[[LAMBDA_IN_DEP_X:[^\w]+]] = private unnamed_addr constant [[DEP_LAMBDA_SIZE:\[[0-9]+ x i8\]]] c"_ZTSZ28lambda_in_dependent_functionIZZ4mainENKUlvE42_5clEvEUlvE46_16EvvEUlvE23_12\00",
extern "C" void printf(const char *) {}
template <typename T>
void template_param() {
printf(__builtin_unique_stable_name(T));
}
template <typename T>
T getT() { return T{}; }
template <typename T>
void lambda_in_dependent_function() {
auto y = [] {};
printf(__builtin_unique_stable_name(y));
}
#define DEF_IN_MACRO() \
auto MACRO_X = []() {};auto MACRO_Y = []() {}; \
printf(__builtin_unique_stable_name(MACRO_X)); \
printf(__builtin_unique_stable_name(MACRO_Y));
#define MACRO_CALLS_MACRO() \
{DEF_IN_MACRO();}{DEF_IN_MACRO();}
template <typename KernelName, typename KernelType>
[[clang::sycl_kernel]] void kernel_single_task(KernelType kernelFunc) {
kernelFunc();
}
int main() {
kernel_single_task<class kernel>(
[]() {
printf(__builtin_unique_stable_name(int));
// CHECK: call spir_func void @printf(i8* getelementptr inbounds ([[INT_SIZE]], [[INT_SIZE]]* @[[INT]]
auto x = [](){};
printf(__builtin_unique_stable_name(x));
printf(__builtin_unique_stable_name(decltype(x)));
// CHECK: call spir_func void @printf(i8* getelementptr inbounds ([[LAMBDA_X_SIZE]], [[LAMBDA_X_SIZE]]* @[[LAMBDA_X]]
// CHECK: call spir_func void @printf(i8* getelementptr inbounds ([[LAMBDA_X_SIZE]], [[LAMBDA_X_SIZE]]* @[[LAMBDA_X]]
DEF_IN_MACRO();
// CHECK: call spir_func void @printf(i8* getelementptr inbounds ([[MACRO_SIZE]], [[MACRO_SIZE]]* @[[MACRO_X]]
// CHECK: call spir_func void @printf(i8* getelementptr inbounds ([[MACRO_SIZE]], [[MACRO_SIZE]]* @[[MACRO_Y]]
MACRO_CALLS_MACRO();
// CHECK: call spir_func void @printf(i8* getelementptr inbounds ([[MACRO_MACRO_SIZE]], [[MACRO_MACRO_SIZE]]* @[[MACRO_MACRO_X]]
// CHECK: call spir_func void @printf(i8* getelementptr inbounds ([[MACRO_MACRO_SIZE]], [[MACRO_MACRO_SIZE]]* @[[MACRO_MACRO_Y]]
template_param<int>();
// CHECK: define linkonce_odr spir_func void @_Z14template_paramIiEvv
// CHECK: call spir_func void @printf(i8* getelementptr inbounds ([[INT_SIZE]], [[INT_SIZE]]* @[[INT]]
template_param<decltype(x)>();
// CHECK: define internal spir_func void @"_Z14template_paramIZZ4mainENK3
// CHECK: call spir_func void @printf(i8* getelementptr inbounds ([[LAMBDA_X_SIZE]], [[LAMBDA_X_SIZE]]* @[[LAMBDA_X]]
lambda_in_dependent_function<int>();
// CHECK: define linkonce_odr spir_func void @_Z28lambda_in_dependent_functionIiEvv
// CHECK: call spir_func void @printf(i8* getelementptr inbounds ([[DEP_INT_SIZE]], [[DEP_INT_SIZE]]* @[[LAMBDA_IN_DEP_INT]]
lambda_in_dependent_function<decltype(x)>();
// CHECK: define internal spir_func void @"_Z28lambda_in_dependent_functionIZZ4mainENK3$_0clEvEUlvE_Evv
// CHECK: call spir_func void @printf(i8* getelementptr inbounds ([[DEP_LAMBDA_SIZE]], [[DEP_LAMBDA_SIZE]]* @[[LAMBDA_IN_DEP_X]]
});
}

View File

@ -1,33 +0,0 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-unused %s
namespace NS{};
void f(int var) {
// expected-error@+1{{expected '(' after '__builtin_unique_stable_name'}}
__builtin_unique_stable_name int;
// expected-error@+1{{expected '(' after '__builtin_unique_stable_name'}}
__builtin_unique_stable_name {int};
__builtin_unique_stable_name(var);
// expected-error@+1{{use of undeclared identifier 'bad_var'}}
__builtin_unique_stable_name(bad_var);
// expected-error@+1{{use of undeclared identifier 'bad'}}
__builtin_unique_stable_name(bad::type);
// expected-error@+1{{no member named 'still_bad' in namespace 'NS'}}
__builtin_unique_stable_name(NS::still_bad);
}
template <typename T>
void f2() {
// expected-error@+1{{no member named 'bad_val' in 'S'}}
__builtin_unique_stable_name(T::bad_val);
// expected-error@+1{{no type named 'bad_type' in 'S'}}
__builtin_unique_stable_name(typename T::bad_type);
}
struct S{};
void use() {
// expected-note@+1{{in instantiation of}}
f2<S>();
}