Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/include/clang/AST/ComputeDependence.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class MatrixSubscriptExpr;
class CompoundLiteralExpr;
class ImplicitCastExpr;
class ExplicitCastExpr;
class ConstantTemplateParamCastExpr;
class BinaryOperator;
class ConditionalOperator;
class BinaryConditionalOperator;
Expand Down Expand Up @@ -121,6 +122,7 @@ ExprDependence computeDependence(MatrixSubscriptExpr *E);
ExprDependence computeDependence(CompoundLiteralExpr *E);
ExprDependence computeDependence(ImplicitCastExpr *E);
ExprDependence computeDependence(ExplicitCastExpr *E);
ExprDependence computeDependence(ConstantTemplateParamCastExpr *E);
ExprDependence computeDependence(BinaryOperator *E);
ExprDependence computeDependence(ConditionalOperator *E);
ExprDependence computeDependence(BinaryConditionalOperator *E);
Expand Down
8 changes: 4 additions & 4 deletions clang/include/clang/AST/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -3624,7 +3624,7 @@ class CastExpr : public Expr {
Expr *op, unsigned BasePathSize, bool HasFPFeatures)
: Expr(SC, ty, VK, OK_Ordinary), Op(op) {
CastExprBits.Kind = kind;
CastExprBits.PartOfExplicitCast = false;
CastExprBits.ExtraData = false;
CastExprBits.BasePathSize = BasePathSize;
assert((CastExprBits.BasePathSize == BasePathSize) &&
"BasePathSize overflow!");
Expand All @@ -3636,7 +3636,7 @@ class CastExpr : public Expr {
CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize,
bool HasFPFeatures)
: Expr(SC, Empty) {
CastExprBits.PartOfExplicitCast = false;
CastExprBits.ExtraData = false;
CastExprBits.BasePathSize = BasePathSize;
CastExprBits.HasFPFeatures = HasFPFeatures;
assert((CastExprBits.BasePathSize == BasePathSize) &&
Expand Down Expand Up @@ -3815,9 +3815,9 @@ class ImplicitCastExpr final
*getTrailingFPFeatures() = FPO;
}

bool isPartOfExplicitCast() const { return CastExprBits.PartOfExplicitCast; }
bool isPartOfExplicitCast() const { return CastExprBits.ExtraData; }
void setIsPartOfExplicitCast(bool PartOfExplicitCast) {
CastExprBits.PartOfExplicitCast = PartOfExplicitCast;
CastExprBits.ExtraData = PartOfExplicitCast;
}

static ImplicitCastExpr *Create(const ASTContext &Context, QualType T,
Expand Down
56 changes: 56 additions & 0 deletions clang/include/clang/AST/ExprCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -4653,6 +4653,62 @@ class PackIndexingExpr final
}
};

/// ImplicitCastExpr - Allows us to explicitly represent implicit type
/// conversions, which have no direct representation in the original
/// source code. For example: converting T[]->T*, void f()->void
/// (*f)(), float->double, short->int, etc.
class ConstantTemplateParamCastExpr final : public CastExpr {

NonTypeTemplateParmDecl *Param;

ConstantTemplateParamCastExpr(NonTypeTemplateParmDecl *Param, QualType ty,
Expr *op, ExprValueKind VK, bool IsDeduced)
: CastExpr(ConstantTemplateParamCastExprClass, ty, VK,
CastKind::CK_Dependent, op,
/*BasePathSize=*/0,
/*HasFPFeatures=*/false),
Param(Param) {
CastExprBits.ExtraData = IsDeduced;
setDependence(computeDependence(this));
}

explicit ConstantTemplateParamCastExpr(EmptyShell Shell)
: CastExpr(ConstantTemplateParamCastExprClass, Shell, /*BasePathSize=*/0,
/*HasFPFeatures=*/false) {}

template <class T> T *getTrailingObjectsNonStrict() { return nullptr; }

public:
static ConstantTemplateParamCastExpr *Create(const ASTContext &Context,
NonTypeTemplateParmDecl *Param,
QualType ParamType,
Expr *Operand, bool IsDeduced);

static ConstantTemplateParamCastExpr *CreateEmpty(const ASTContext &Context) {
return new (Context) ConstantTemplateParamCastExpr(EmptyShell());
}

NonTypeTemplateParmDecl *getParam() const { return Param; }

QualType getParamType(const ASTContext &Context) const;

bool isDeduced() const { return CastExprBits.ExtraData; }

SourceLocation getBeginLoc() const LLVM_READONLY {
return getSubExpr()->getBeginLoc();
}
SourceLocation getEndLoc() const LLVM_READONLY {
return getSubExpr()->getEndLoc();
}

static bool classof(const Stmt *T) {
return T->getStmtClass() == ConstantTemplateParamCastExprClass;
}

friend class CastExpr;
friend class ASTStmtReader;
};

/// Represents a reference to a non-type template parameter
/// that has been substituted with a template argument.
class SubstNonTypeTemplateParmExpr : public Expr {
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/AST/JSONNodeDumper.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,8 @@ class JSONNodeDumper
void VisitCXXThisExpr(const CXXThisExpr *TE);
void VisitCastExpr(const CastExpr *CE);
void VisitImplicitCastExpr(const ImplicitCastExpr *ICE);
void
VisitConstantTemplateParamCastExpr(const ConstantTemplateParamCastExpr *CE);
void VisitCallExpr(const CallExpr *CE);
void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *TTE);
void VisitSizeOfPackExpr(const SizeOfPackExpr *SOPE);
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/AST/RecursiveASTVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -2628,6 +2628,12 @@ DEF_TRAVERSE_STMT(MemberExpr, {
S->getNumTemplateArgs()));
})

DEF_TRAVERSE_STMT(ConstantTemplateParamCastExpr,
{
// We don't traverse the cast type, as it's not written in
// the source code.
})

DEF_TRAVERSE_STMT(
ImplicitCastExpr,
{// We don't traverse the cast type, as it's not written in the
Expand Down
5 changes: 4 additions & 1 deletion clang/include/clang/AST/Stmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -616,14 +616,17 @@ class alignas(void *) Stmt {
class CastExprBitfields {
friend class CastExpr;
friend class ImplicitCastExpr;
friend class ConstantTemplateParamCastExpr;

LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;

LLVM_PREFERRED_TYPE(CastKind)
unsigned Kind : 7;

// Used by ImplicitCastExpr and ConstantTemplateParamCastExpr.
LLVM_PREFERRED_TYPE(bool)
unsigned PartOfExplicitCast : 1; // Only set for ImplicitCastExpr.
unsigned ExtraData : 1;

/// True if the call expression has some floating-point features.
LLVM_PREFERRED_TYPE(bool)
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/AST/TextNodeDumper.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,8 @@ class TextNodeDumper
void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *Node);
void VisitCastExpr(const CastExpr *Node);
void VisitImplicitCastExpr(const ImplicitCastExpr *Node);
void
VisitConstantTemplateParamCastExpr(const ConstantTemplateParamCastExpr *Node);
void VisitDeclRefExpr(const DeclRefExpr *Node);
void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *Node);
void VisitSYCLUniqueStableNameExpr(const SYCLUniqueStableNameExpr *Node);
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -5774,6 +5774,9 @@ def note_template_class_explicit_specialization_was_here : Note<
"class template %0 was explicitly specialized here">;
def note_template_class_instantiation_here : Note<
"in instantiation of template class %q0 requested here">;
def note_non_type_template_parameter_instantiation_here
: Note<
"in instantiation of non-type template parameter %q0 requested here">;
def note_template_member_class_here : Note<
"in instantiation of member class %q0 requested here">;
def note_template_member_function_here : Note<
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/StmtNodes.td
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ def AbstractConditionalOperator : StmtNode<Expr, 1>;
def ConditionalOperator : StmtNode<AbstractConditionalOperator>;
def BinaryConditionalOperator : StmtNode<AbstractConditionalOperator>;
def ImplicitCastExpr : StmtNode<CastExpr>;
def ConstantTemplateParamCastExpr : StmtNode<CastExpr>;
def ExplicitCastExpr : StmtNode<CastExpr, 1>;
def CStyleCastExpr : StmtNode<ExplicitCastExpr>;
def OMPArrayShapingExpr : StmtNode<Expr>;
Expand Down
6 changes: 3 additions & 3 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -12683,11 +12683,11 @@ class Sema final : public SemaBase {
QualType Replacement);

// Substitute auto in TypeWithAuto for a Dependent auto type
QualType SubstAutoTypeDependent(QualType TypeWithAuto);
QualType SubstAutoTypeDependent(QualType TypeWithAuto, bool IsPack = false);

// Substitute auto in TypeWithAuto for a Dependent auto type
TypeSourceInfo *
SubstAutoTypeSourceInfoDependent(TypeSourceInfo *TypeWithAuto);
TypeSourceInfo *SubstAutoTypeSourceInfoDependent(TypeSourceInfo *TypeWithAuto,
bool IsPack = false);

/// Completely replace the \c auto in \p TypeWithAuto by
/// \p Replacement. This does not retain any \c auto type sugar.
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -1684,6 +1684,9 @@ enum StmtCode {
/// An ImplicitCastExpr record.
EXPR_IMPLICIT_CAST,

/// An ConstantTemplateParamCastExpr record.
EXPR_CONSTANT_TEMPLATE_PARAM_CAST,

/// A CStyleCastExpr record.
EXPR_CSTYLE_CAST,

Expand Down
11 changes: 11 additions & 0 deletions clang/lib/AST/ComputeDependence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,17 @@ ExprDependence clang::computeDependence(ExplicitCastExpr *E) {
return D;
}

ExprDependence clang::computeDependence(ConstantTemplateParamCastExpr *E) {
// We model implicit conversions as combining the dependence of their
// subexpression, apart from its type, with the semantic portion of the
// target type.
ExprDependence D =
toExprDependenceForImpliedType(E->getType()->getDependence());
if (auto *S = E->getSubExpr())
D |= S->getDependence() & ~ExprDependence::Type;
return D;
}

ExprDependence clang::computeDependence(BinaryOperator *E) {
return E->getLHS()->getDependence() | E->getRHS()->getDependence();
}
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/Expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3858,6 +3858,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
return true;
}
[[fallthrough]];
case ConstantTemplateParamCastExprClass:
case ImplicitCastExprClass:
case CStyleCastExprClass:
case CXXStaticCastExprClass:
Expand Down
24 changes: 24 additions & 0 deletions clang/lib/AST/ExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1765,6 +1765,30 @@ PackIndexingExpr::CreateDeserialized(ASTContext &Context,
return new (Storage) PackIndexingExpr(EmptyShell{});
}

ConstantTemplateParamCastExpr *ConstantTemplateParamCastExpr::Create(
const ASTContext &C, NonTypeTemplateParmDecl *Param, QualType ParamType,
Expr *Operand, bool IsDeduced) {
return new (C) ConstantTemplateParamCastExpr(
Param, ParamType.getNonLValueExprType(C), Operand,
ParamType->isLValueReferenceType() ? VK_LValue
: ParamType->isRValueReferenceType() ? VK_XValue
: VK_PRValue,
IsDeduced);
}

QualType
ConstantTemplateParamCastExpr::getParamType(const ASTContext &C) const {
switch (getValueKind()) {
case VK_LValue:
return C.getLValueReferenceType(getType());
case VK_XValue:
return C.getRValueReferenceType(getType());
case VK_PRValue:
return getType();
}
llvm_unreachable("unhandled value kind");
}

QualType SubstNonTypeTemplateParmExpr::getParameterType(
const ASTContext &Context) const {
// Note that, for a class type NTTP, we will have an lvalue of type 'const
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/ExprClassification.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {

// Implicit casts are lvalues if they're lvalue casts. Other than that, we
// only specifically record class temporaries.
case Expr::ConstantTemplateParamCastExprClass:
case Expr::ImplicitCastExprClass:
return ClassifyExprValueKind(Lang, E, E->getValueKind());

Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18341,6 +18341,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
}
llvm_unreachable("invalid binary operator kind");
}
case Expr::ConstantTemplateParamCastExprClass:
case Expr::ImplicitCastExprClass:
case Expr::CStyleCastExprClass:
case Expr::CXXFunctionalCastExprClass:
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/AST/ItaniumMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5527,9 +5527,10 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity,
break;
}

case Expr::ConstantTemplateParamCastExprClass:
case Expr::ImplicitCastExprClass: {
ImplicitlyConvertedToType = E->getType();
E = cast<ImplicitCastExpr>(E)->getSubExpr();
E = cast<CastExpr>(E)->getSubExpr();
goto recurse;
}

Expand Down
6 changes: 6 additions & 0 deletions clang/lib/AST/JSONNodeDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1459,6 +1459,12 @@ void JSONNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *ICE) {
attributeOnlyIfTrue("isPartOfExplicitCast", ICE->isPartOfExplicitCast());
}

void JSONNodeDumper::VisitConstantTemplateParamCastExpr(
const ConstantTemplateParamCastExpr *CE) {
VisitCastExpr(CE);
JOS.attribute("param", createBareDeclRef(CE->getParam()));
}

void JSONNodeDumper::VisitCallExpr(const CallExpr *CE) {
attributeOnlyIfTrue("adl", CE->usesADL());
}
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/AST/StmtPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1822,6 +1822,12 @@ void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
PrintExpr(Node->getInitializer());
}

void StmtPrinter::VisitConstantTemplateParamCastExpr(
ConstantTemplateParamCastExpr *Node) {
// No need to print anything, simply forward to the subexpression.
PrintExpr(Node->getSubExpr());
}

void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
// No need to print anything, simply forward to the subexpression.
PrintExpr(Node->getSubExpr());
Expand Down
10 changes: 10 additions & 0 deletions clang/lib/AST/StmtProfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1519,6 +1519,16 @@ void StmtProfiler::VisitCastExpr(const CastExpr *S) {
VisitExpr(S);
}

void StmtProfiler::VisitConstantTemplateParamCastExpr(
const ConstantTemplateParamCastExpr *S) {
if (S->isDeduced()) {
Visit(S->getSubExpr());
} else {
VisitCastExpr(S);
VisitDecl(S->getParam());
}
}

void StmtProfiler::VisitImplicitCastExpr(const ImplicitCastExpr *S) {
VisitCastExpr(S);
ID.AddInteger(S->getValueKind());
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/AST/TextNodeDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1534,6 +1534,14 @@ void TextNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) {
OS << " part_of_explicit_cast";
}

void TextNodeDumper::VisitConstantTemplateParamCastExpr(
const ConstantTemplateParamCastExpr *Node) {
VisitCastExpr(Node);
if (Node->isDeduced())
OS << " is_deduced";
dumpDeclRef(Node->getParam());
}

void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
OS << " ";
dumpBareDeclRef(Node->getDecl());
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Sema/SemaExceptionSpec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1312,6 +1312,7 @@ CanThrowResult Sema::canThrow(const Stmt *S) {
case Expr::CStyleCastExprClass:
case Expr::CXXStaticCastExprClass:
case Expr::CXXFunctionalCastExprClass:
case Expr::ConstantTemplateParamCastExprClass:
case Expr::ImplicitCastExprClass:
case Expr::MaterializeTemporaryExprClass:
case Expr::UnaryOperatorClass: {
Expand Down
5 changes: 4 additions & 1 deletion clang/lib/Sema/SemaOverload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14744,10 +14744,13 @@ static ExprResult FinishOverloadedCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
SemaRef.FixOverloadedFunctionReference(Fn, (*Best)->FoundDecl, FDecl);
if (Res.isInvalid())
return ExprError();
return SemaRef.BuildResolvedCallExpr(
Res = SemaRef.BuildResolvedCallExpr(
Res.get(), FDecl, LParenLoc, Args, RParenLoc, ExecConfig,
/*IsExecConfig=*/false,
static_cast<CallExpr::ADLCallKind>((*Best)->IsADLCandidate));
if (Res.isInvalid())
return ExprError();
Fn = Res.get();
}
}

Expand Down
Loading
Loading