@@ -4799,166 +4799,6 @@ class SourceLocExpr final : public Expr {
47994799 friend class ASTStmtReader ;
48004800};
48014801
4802- // / Stores data related to a single #embed directive.
4803- struct EmbedDataStorage {
4804- StringLiteral *Filename;
4805- StringLiteral *BinaryData;
4806- size_t getDataElementCount () const { return BinaryData->getByteLength (); }
4807- };
4808-
4809- // / Represents a reference to #emded data. By default, this references the whole
4810- // / range. Otherwise it represents a subrange of data imported by #embed
4811- // / directive. Needed to handle nested initializer lists with #embed directives.
4812- // / Example:
4813- // / struct S {
4814- // / int x, y;
4815- // / };
4816- // /
4817- // / struct T {
4818- // / int x[2];
4819- // / struct S s
4820- // / };
4821- // /
4822- // / struct T t[] = {
4823- // / #embed "data" // data contains 10 elements;
4824- // / };
4825- // /
4826- // / The resulting semantic form of initializer list will contain (EE stands
4827- // / for EmbedExpr):
4828- // / { {EE(first two data elements), {EE(3rd element), EE(4th element) }},
4829- // / { {EE(5th and 6th element), {EE(7th element), EE(8th element) }},
4830- // / { {EE(9th and 10th element), { zeroinitializer }}}
4831- // /
4832- // / EmbedExpr inside of a semantic initializer list and referencing more than
4833- // / one element can only appear for arrays of scalars.
4834- class EmbedExpr final : public Expr {
4835- SourceLocation EmbedKeywordLoc;
4836- IntegerLiteral *FakeChildNode = nullptr ;
4837- const ASTContext *Ctx = nullptr ;
4838- EmbedDataStorage *Data;
4839- unsigned Begin = 0 ;
4840- unsigned NumOfElements;
4841-
4842- public:
4843- EmbedExpr (const ASTContext &Ctx, SourceLocation Loc, EmbedDataStorage *Data,
4844- unsigned Begin, unsigned NumOfElements);
4845- explicit EmbedExpr (EmptyShell Empty) : Expr(SourceLocExprClass, Empty) {}
4846-
4847- SourceLocation getLocation () const { return EmbedKeywordLoc; }
4848- SourceLocation getBeginLoc () const { return EmbedKeywordLoc; }
4849- SourceLocation getEndLoc () const { return EmbedKeywordLoc; }
4850-
4851- StringLiteral *getFilenameStringLiteral () const { return Data->Filename ; }
4852- StringLiteral *getDataStringLiteral () const { return Data->BinaryData ; }
4853- EmbedDataStorage *getData () const { return Data; }
4854-
4855- unsigned getStartingElementPos () const { return Begin; }
4856- size_t getDataElementCount () const { return NumOfElements; }
4857-
4858- // Allows accessing every byte of EmbedExpr data and iterating over it.
4859- // An Iterator knows the EmbedExpr that it refers to, and an offset value
4860- // within the data.
4861- // Dereferencing an Iterator results in construction of IntegerLiteral AST
4862- // node filled with byte of data of the corresponding EmbedExpr within offset
4863- // that the Iterator currently has.
4864- template <bool Const>
4865- class ChildElementIter
4866- : public llvm::iterator_facade_base<
4867- ChildElementIter<Const>, std::random_access_iterator_tag,
4868- std::conditional_t <Const, const IntegerLiteral *,
4869- IntegerLiteral *>> {
4870- friend class EmbedExpr ;
4871-
4872- EmbedExpr *EExpr = nullptr ;
4873- unsigned long long CurOffset = ULLONG_MAX;
4874- using BaseTy = typename ChildElementIter::iterator_facade_base;
4875-
4876- ChildElementIter (EmbedExpr *E) : EExpr(E) {
4877- if (E)
4878- CurOffset = E->getStartingElementPos ();
4879- }
4880-
4881- public:
4882- ChildElementIter () : CurOffset(ULLONG_MAX) {}
4883- typename BaseTy::reference operator *() const {
4884- assert (EExpr && CurOffset != ULLONG_MAX &&
4885- " trying to dereference an invalid iterator" );
4886- IntegerLiteral *N = EExpr->FakeChildNode ;
4887- StringRef DataRef = EExpr->Data ->BinaryData ->getBytes ();
4888- N->setValue (*EExpr->Ctx ,
4889- llvm::APInt (N->getValue ().getBitWidth (), DataRef[CurOffset],
4890- N->getType ()->isSignedIntegerType ()));
4891- // We want to return a reference to the fake child node in the
4892- // EmbedExpr, not the local variable N.
4893- return const_cast <typename BaseTy::reference>(EExpr->FakeChildNode );
4894- }
4895- typename BaseTy::pointer operator ->() const { return **this ; }
4896- using BaseTy::operator ++;
4897- ChildElementIter &operator ++() {
4898- assert (EExpr && " trying to increment an invalid iterator" );
4899- assert (CurOffset != ULLONG_MAX &&
4900- " Already at the end of what we can iterate over" );
4901- if (++CurOffset >=
4902- EExpr->getDataElementCount () + EExpr->getStartingElementPos ()) {
4903- CurOffset = ULLONG_MAX;
4904- EExpr = nullptr ;
4905- }
4906- return *this ;
4907- }
4908- bool operator ==(ChildElementIter Other) const {
4909- return (EExpr == Other.EExpr && CurOffset == Other.CurOffset );
4910- }
4911- }; // class ChildElementIter
4912-
4913- public:
4914- using fake_child_range = llvm::iterator_range<ChildElementIter<false >>;
4915- using const_fake_child_range = llvm::iterator_range<ChildElementIter<true >>;
4916-
4917- fake_child_range underlying_data_elements () {
4918- return fake_child_range (ChildElementIter<false >(this ),
4919- ChildElementIter<false >());
4920- }
4921-
4922- const_fake_child_range underlying_data_elements () const {
4923- return const_fake_child_range (
4924- ChildElementIter<true >(const_cast <EmbedExpr *>(this )),
4925- ChildElementIter<true >());
4926- }
4927-
4928- child_range children () {
4929- return child_range (child_iterator (), child_iterator ());
4930- }
4931-
4932- const_child_range children () const {
4933- return const_child_range (const_child_iterator (), const_child_iterator ());
4934- }
4935-
4936- static bool classof (const Stmt *T) {
4937- return T->getStmtClass () == EmbedExprClass;
4938- }
4939-
4940- ChildElementIter<false > begin () { return ChildElementIter<false >(this ); }
4941-
4942- ChildElementIter<true > begin () const {
4943- return ChildElementIter<true >(const_cast <EmbedExpr *>(this ));
4944- }
4945-
4946- template <typename Call, typename ... Targs>
4947- bool doForEachDataElement (Call &&C, unsigned &StartingIndexInArray,
4948- Targs &&...Fargs) const {
4949- for (auto It : underlying_data_elements ()) {
4950- if (!std::invoke (std::forward<Call>(C), const_cast <IntegerLiteral *>(It),
4951- StartingIndexInArray, std::forward<Targs>(Fargs)...))
4952- return false ;
4953- StartingIndexInArray++;
4954- }
4955- return true ;
4956- }
4957-
4958- private:
4959- friend class ASTStmtReader ;
4960- };
4961-
49624802// / Describes an C or C++ initializer list.
49634803// /
49644804// / InitListExpr describes an initializer list, which can be used to
0 commit comments