@@ -4799,166 +4799,6 @@ class SourceLocExpr final : public Expr {
4799
4799
friend class ASTStmtReader ;
4800
4800
};
4801
4801
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
-
4962
4802
// / Describes an C or C++ initializer list.
4963
4803
// /
4964
4804
// / InitListExpr describes an initializer list, which can be used to
0 commit comments