aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST')
-rw-r--r--clang/lib/AST/Expr.cpp12
-rw-r--r--clang/lib/AST/ExprClassification.cpp5
-rw-r--r--clang/lib/AST/ExprConstant.cpp63
-rw-r--r--clang/lib/AST/Interp/ByteCodeExprGen.cpp20
-rw-r--r--clang/lib/AST/Interp/ByteCodeExprGen.h1
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp1
-rw-r--r--clang/lib/AST/StmtPrinter.cpp4
-rw-r--r--clang/lib/AST/StmtProfile.cpp2
-rw-r--r--clang/lib/AST/TextNodeDumper.cpp5
9 files changed, 105 insertions, 8 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 7e55568..04b331a 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -2373,6 +2373,17 @@ APValue SourceLocExpr::EvaluateInContext(const ASTContext &Ctx,
llvm_unreachable("unhandled case");
}
+EmbedExpr::EmbedExpr(const ASTContext &Ctx, SourceLocation Loc,
+ EmbedDataStorage *Data, unsigned Begin,
+ unsigned NumOfElements)
+ : Expr(EmbedExprClass, Ctx.UnsignedCharTy, VK_PRValue, OK_Ordinary),
+ EmbedKeywordLoc(Loc), Ctx(&Ctx), Data(Data), Begin(Begin),
+ NumOfElements(NumOfElements) {
+ setDependence(ExprDependence::None);
+ FakeChildNode = IntegerLiteral::Create(
+ Ctx, llvm::APInt::getZero(Ctx.getTypeSize(getType())), getType(), Loc);
+}
+
InitListExpr::InitListExpr(const ASTContext &C, SourceLocation lbraceloc,
ArrayRef<Expr *> initExprs, SourceLocation rbraceloc)
: Expr(InitListExprClass, QualType(), VK_PRValue, OK_Ordinary),
@@ -3615,6 +3626,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
case CXXUuidofExprClass:
case OpaqueValueExprClass:
case SourceLocExprClass:
+ case EmbedExprClass:
case ConceptSpecializationExprClass:
case RequiresExprClass:
case SYCLUniqueStableNameExprClass:
diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp
index 390000e3..6482cb6 100644
--- a/clang/lib/AST/ExprClassification.cpp
+++ b/clang/lib/AST/ExprClassification.cpp
@@ -204,6 +204,11 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
case Expr::RequiresExprClass:
return Cl::CL_PRValue;
+ case Expr::EmbedExprClass:
+ // Nominally, this just goes through as a PRValue until we actually expand
+ // it and check it.
+ return Cl::CL_PRValue;
+
// Make HLSL this reference-like
case Expr::CXXThisExprClass:
return Lang.HLSL ? Cl::CL_LValue : Cl::CL_PRValue;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index d505745..af1f18a 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -7727,6 +7727,11 @@ public:
return Error(E);
}
+ bool VisitEmbedExpr(const EmbedExpr *E) {
+ const auto It = E->begin();
+ return StmtVisitorTy::Visit(*It);
+ }
+
bool VisitPredefinedExpr(const PredefinedExpr *E) {
return StmtVisitorTy::Visit(E->getFunctionName());
}
@@ -9145,6 +9150,11 @@ public:
return true;
}
+ bool VisitEmbedExpr(const EmbedExpr *E) {
+ llvm_unreachable("Not yet implemented for ExprConstant.cpp");
+ return true;
+ }
+
bool VisitSYCLUniqueStableNameExpr(const SYCLUniqueStableNameExpr *E) {
std::string ResultStr = E->ComputeName(Info.Ctx);
@@ -11249,8 +11259,17 @@ bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
// If the initializer might depend on the array index, run it for each
// array element.
- if (NumEltsToInit != NumElts && MaybeElementDependentArrayFiller(ArrayFiller))
+ if (NumEltsToInit != NumElts &&
+ MaybeElementDependentArrayFiller(ArrayFiller)) {
NumEltsToInit = NumElts;
+ } else {
+ for (auto *Init : Args) {
+ if (auto *EmbedS = dyn_cast<EmbedExpr>(Init->IgnoreParenImpCasts()))
+ NumEltsToInit += EmbedS->getDataElementCount() - 1;
+ }
+ if (NumEltsToInit > NumElts)
+ NumEltsToInit = NumElts;
+ }
LLVM_DEBUG(llvm::dbgs() << "The number of elements to initialize: "
<< NumEltsToInit << ".\n");
@@ -11268,16 +11287,49 @@ bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
LValue Subobject = This;
Subobject.addArray(Info, ExprToVisit, CAT);
- for (unsigned Index = 0; Index != NumEltsToInit; ++Index) {
- const Expr *Init = Index < Args.size() ? Args[Index] : ArrayFiller;
- if (!EvaluateInPlace(Result.getArrayInitializedElt(Index),
- Info, Subobject, Init) ||
+ auto Eval = [&](const Expr *Init, unsigned ArrayIndex) {
+ if (!EvaluateInPlace(Result.getArrayInitializedElt(ArrayIndex), Info,
+ Subobject, Init) ||
!HandleLValueArrayAdjustment(Info, Init, Subobject,
CAT->getElementType(), 1)) {
if (!Info.noteFailure())
return false;
Success = false;
}
+ return true;
+ };
+ unsigned ArrayIndex = 0;
+ QualType DestTy = CAT->getElementType();
+ APSInt Value(Info.Ctx.getTypeSize(DestTy), DestTy->isUnsignedIntegerType());
+ for (unsigned Index = 0; Index != NumEltsToInit; ++Index) {
+ const Expr *Init = Index < Args.size() ? Args[Index] : ArrayFiller;
+ if (ArrayIndex >= NumEltsToInit)
+ break;
+ if (auto *EmbedS = dyn_cast<EmbedExpr>(Init->IgnoreParenImpCasts())) {
+ StringLiteral *SL = EmbedS->getDataStringLiteral();
+ for (unsigned I = EmbedS->getStartingElementPos(),
+ N = EmbedS->getDataElementCount();
+ I != EmbedS->getStartingElementPos() + N; ++I) {
+ Value = SL->getCodeUnit(I);
+ if (DestTy->isIntegerType()) {
+ Result.getArrayInitializedElt(ArrayIndex) = APValue(Value);
+ } else {
+ assert(DestTy->isFloatingType() && "unexpected type");
+ const FPOptions FPO =
+ Init->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
+ APFloat FValue(0.0);
+ if (!HandleIntToFloatCast(Info, Init, FPO, EmbedS->getType(), Value,
+ DestTy, FValue))
+ return false;
+ Result.getArrayInitializedElt(ArrayIndex) = APValue(FValue);
+ }
+ ArrayIndex++;
+ }
+ } else {
+ if (!Eval(Init, ArrayIndex))
+ return false;
+ ++ArrayIndex;
+ }
}
if (!Result.hasArrayFiller())
@@ -16363,6 +16415,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
case Expr::SizeOfPackExprClass:
case Expr::GNUNullExprClass:
case Expr::SourceLocExprClass:
+ case Expr::EmbedExprClass:
return NoDiag();
case Expr::PackIndexingExprClass:
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 1393ef1..e766558 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1201,11 +1201,19 @@ bool ByteCodeExprGen<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
}
if (T->isArrayType()) {
+ auto Eval = [&](Expr *Init, unsigned ElemIndex) {
+ return visitArrayElemInit(ElemIndex, Init);
+ };
unsigned ElementIndex = 0;
for (const Expr *Init : Inits) {
- if (!this->visitArrayElemInit(ElementIndex, Init))
- return false;
- ++ElementIndex;
+ if (auto *EmbedS = dyn_cast<EmbedExpr>(Init->IgnoreParenImpCasts())) {
+ if (!EmbedS->doForEachDataElement(Eval, ElementIndex))
+ return false;
+ } else {
+ if (!this->visitArrayElemInit(ElementIndex, Init))
+ return false;
+ ++ElementIndex;
+ }
}
// Expand the filler expression.
@@ -1351,6 +1359,12 @@ bool ByteCodeExprGen<Emitter>::VisitConstantExpr(const ConstantExpr *E) {
return this->delegate(E->getSubExpr());
}
+template <class Emitter>
+bool ByteCodeExprGen<Emitter>::VisitEmbedExpr(const EmbedExpr *E) {
+ auto It = E->begin();
+ return this->visit(*It);
+}
+
static CharUnits AlignOfType(QualType T, const ASTContext &ASTCtx,
UnaryExprOrTypeTrait Kind) {
bool AlignOfReturnsPreferred =
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 295cfef..f9f508e 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -115,6 +115,7 @@ public:
bool VisitSizeOfPackExpr(const SizeOfPackExpr *E);
bool VisitGenericSelectionExpr(const GenericSelectionExpr *E);
bool VisitChooseExpr(const ChooseExpr *E);
+ bool VisitEmbedExpr(const EmbedExpr *E);
bool VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E);
bool VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E);
bool VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index ed9e6eeb..eac1801 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -4760,6 +4760,7 @@ recurse:
case Expr::PseudoObjectExprClass:
case Expr::AtomicExprClass:
case Expr::SourceLocExprClass:
+ case Expr::EmbedExprClass:
case Expr::BuiltinBitCastExprClass:
{
NotPrimaryExpr();
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 8f51d16..2d223a9 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -1177,6 +1177,10 @@ void StmtPrinter::VisitSourceLocExpr(SourceLocExpr *Node) {
OS << Node->getBuiltinStr() << "()";
}
+void StmtPrinter::VisitEmbedExpr(EmbedExpr *Node) {
+ assert(false && "not yet implemented");
+}
+
void StmtPrinter::VisitConstantExpr(ConstantExpr *Node) {
PrintExpr(Node->getSubExpr());
}
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index d165590..1add5ca 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -2313,6 +2313,8 @@ void StmtProfiler::VisitSourceLocExpr(const SourceLocExpr *E) {
VisitExpr(E);
}
+void StmtProfiler::VisitEmbedExpr(const EmbedExpr *E) { VisitExpr(E); }
+
void StmtProfiler::VisitRecoveryExpr(const RecoveryExpr *E) { VisitExpr(E); }
void StmtProfiler::VisitObjCStringLiteral(const ObjCStringLiteral *S) {
diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index 1076dcd..e1a2709 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -2884,3 +2884,8 @@ void TextNodeDumper::VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *S) {
else
OS << " parent: " << S->getParentComputeConstruct();
}
+
+void TextNodeDumper::VisitEmbedExpr(const EmbedExpr *S) {
+ AddChild("begin", [=] { OS << S->getStartingElementPos(); });
+ AddChild("number of elements", [=] { OS << S->getDataElementCount(); });
+}