llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: circl (circl-lastname) <details> <summary>Changes</summary> Fixes #<!-- -->107869 Due to the other FIXMEs in `#embed` code, this doesn't yet handle offsets, prefixes, and if_empty, however I feel it's a good start, and preferable to crashing. ![Screenshot_20241126_192631](https://github.com/user-attachments/assets/77e1ba7a-a7ec-41a1-a7fe-29b43a27adfd) I've used `StringRef` to store the filename inside `EmbedExpr`, and `std::string` to store the filename inside the `annot_embed` token. Hopefully this prevents the memory leak fixed in #<!-- -->95802, but this assumes the token array exists while the AST does, if this is a false assumption I can try changing how the storage works. --- Full diff: https://github.com/llvm/llvm-project/pull/117770.diff 9 Files Affected: - (modified) clang/include/clang/AST/Expr.h (+7-2) - (modified) clang/include/clang/Lex/Preprocessor.h (+4-1) - (modified) clang/include/clang/Sema/Sema.h (+2-2) - (modified) clang/lib/AST/Expr.cpp (+4-4) - (modified) clang/lib/AST/StmtPrinter.cpp (+13-1) - (modified) clang/lib/Lex/PPDirectives.cpp (+6-3) - (modified) clang/lib/Parse/ParseInit.cpp (+2-1) - (modified) clang/lib/Sema/SemaExpr.cpp (+3-2) - (modified) clang/lib/Sema/SemaInit.cpp (+3-3) ``````````diff diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 708c8656decbe0..95d341957c59a2 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -4917,19 +4917,24 @@ class EmbedExpr final : public Expr { SourceLocation EmbedKeywordLoc; IntegerLiteral *FakeChildNode = nullptr; const ASTContext *Ctx = nullptr; + StringRef Filename; + bool IsAngled; EmbedDataStorage *Data; unsigned Begin = 0; unsigned NumOfElements; public: - EmbedExpr(const ASTContext &Ctx, SourceLocation Loc, EmbedDataStorage *Data, - unsigned Begin, unsigned NumOfElements); + EmbedExpr(const ASTContext &Ctx, SourceLocation Loc, StringRef Filename, + bool IsAngled, EmbedDataStorage *Data, unsigned Begin, + unsigned NumOfElements); explicit EmbedExpr(EmptyShell Empty) : Expr(SourceLocExprClass, Empty) {} SourceLocation getLocation() const { return EmbedKeywordLoc; } SourceLocation getBeginLoc() const { return EmbedKeywordLoc; } SourceLocation getEndLoc() const { return EmbedKeywordLoc; } + StringRef getFilename() const { return Filename; } + bool getIsAngled() const { return IsAngled; } StringLiteral *getDataStringLiteral() const { return Data->BinaryData; } EmbedDataStorage *getData() const { return Data; } diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 3312d4ed1d798d..0a4ca35224497c 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -2761,7 +2761,8 @@ class Preprocessor { // Binary data inclusion void HandleEmbedDirective(SourceLocation HashLoc, Token &Tok, const FileEntry *LookupFromFile = nullptr); - void HandleEmbedDirectiveImpl(SourceLocation HashLoc, + void HandleEmbedDirectiveImpl(SourceLocation HashLoc, StringRef Filename, + bool IsAngled, const LexEmbedParametersResult &Params, StringRef BinaryContents); @@ -3066,6 +3067,8 @@ class EmptylineHandler { /// Helper class to shuttle information about #embed directives from the /// preprocessor to the parser through an annotation token. struct EmbedAnnotationData { + std::string Filename; + bool IsAngled; StringRef BinaryData; }; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 24abd5d95dd844..435bc4d4807bc4 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -7086,8 +7086,8 @@ class Sema final : public SemaBase { SourceLocation RPLoc); // #embed - ExprResult ActOnEmbedExpr(SourceLocation EmbedKeywordLoc, - StringLiteral *BinaryData); + ExprResult ActOnEmbedExpr(SourceLocation EmbedKeywordLoc, StringRef Filename, + bool IsAngled, StringLiteral *BinaryData); // Build a potentially resolved SourceLocExpr. ExprResult BuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy, diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index a4fb4d5a1f2ec4..eeea6da07d304f 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -2383,11 +2383,11 @@ APValue SourceLocExpr::EvaluateInContext(const ASTContext &Ctx, } EmbedExpr::EmbedExpr(const ASTContext &Ctx, SourceLocation Loc, - EmbedDataStorage *Data, unsigned Begin, - unsigned NumOfElements) + StringRef Filename, bool IsAngled, EmbedDataStorage *Data, + unsigned Begin, unsigned NumOfElements) : Expr(EmbedExprClass, Ctx.IntTy, VK_PRValue, OK_Ordinary), - EmbedKeywordLoc(Loc), Ctx(&Ctx), Data(Data), Begin(Begin), - NumOfElements(NumOfElements) { + EmbedKeywordLoc(Loc), Ctx(&Ctx), Filename(Filename), IsAngled(IsAngled), + Data(Data), Begin(Begin), NumOfElements(NumOfElements) { setDependence(ExprDependence::None); FakeChildNode = IntegerLiteral::Create( Ctx, llvm::APInt::getZero(Ctx.getTypeSize(getType())), getType(), Loc); diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index c8677d11b64e8d..da6b4cb5f66955 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -1202,7 +1202,19 @@ void StmtPrinter::VisitSourceLocExpr(SourceLocExpr *Node) { } void StmtPrinter::VisitEmbedExpr(EmbedExpr *Node) { - llvm::report_fatal_error("Not implemented"); + // FIXME: This doesn't handle offsets, prefixes, and if_empty yet + OS << NL << "#embed"; + if (Node->getIsAngled()) { + OS << "<"; + } else { + OS << "\""; + } + OS << Node->getFilename(); + if (Node->getIsAngled()) { + OS << ">" << NL; + } else { + OS << "\"" << NL; + } } void StmtPrinter::VisitConstantExpr(ConstantExpr *Node) { diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index a23ad40884f249..62eda8401636c4 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -3871,8 +3871,8 @@ Preprocessor::LexEmbedParameters(Token &CurTok, bool ForHasEmbed) { } void Preprocessor::HandleEmbedDirectiveImpl( - SourceLocation HashLoc, const LexEmbedParametersResult &Params, - StringRef BinaryContents) { + SourceLocation HashLoc, StringRef Filename, bool IsAngled, + const LexEmbedParametersResult &Params, StringRef BinaryContents) { if (BinaryContents.empty()) { // If we have no binary contents, the only thing we need to emit are the // if_empty tokens, if any. @@ -3902,6 +3902,8 @@ void Preprocessor::HandleEmbedDirectiveImpl( } EmbedAnnotationData *Data = new (BP) EmbedAnnotationData; + Data->Filename = Filename; + Data->IsAngled = IsAngled; Data->BinaryData = BinaryContents; Toks[CurIdx].startToken(); @@ -4006,5 +4008,6 @@ void Preprocessor::HandleEmbedDirective(SourceLocation HashLoc, Token &EmbedTok, if (Callbacks) Callbacks->EmbedDirective(HashLoc, Filename, isAngled, MaybeFileRef, *Params); - HandleEmbedDirectiveImpl(HashLoc, *Params, BinaryContents); + HandleEmbedDirectiveImpl(HashLoc, Filename, isAngled, *Params, + BinaryContents); } diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp index 63b1d7bd9db53e..06ced273a65e92 100644 --- a/clang/lib/Parse/ParseInit.cpp +++ b/clang/lib/Parse/ParseInit.cpp @@ -451,7 +451,8 @@ ExprResult Parser::createEmbedExpr() { StringLiteral *BinaryDataArg = CreateStringLiteralFromStringRef( Data->BinaryData, Context.UnsignedCharTy); - Res = Actions.ActOnEmbedExpr(StartLoc, BinaryDataArg); + Res = Actions.ActOnEmbedExpr(StartLoc, Data->Filename, Data->IsAngled, + BinaryDataArg); } return Res; } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index c9d7444d5865a5..f5deacf709d606 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -16770,12 +16770,13 @@ ExprResult Sema::BuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy, } ExprResult Sema::ActOnEmbedExpr(SourceLocation EmbedKeywordLoc, + StringRef Filename, bool IsAngled, StringLiteral *BinaryData) { EmbedDataStorage *Data = new (Context) EmbedDataStorage; Data->BinaryData = BinaryData; return new (Context) - EmbedExpr(Context, EmbedKeywordLoc, Data, /*NumOfElements=*/0, - Data->getDataElementCount()); + EmbedExpr(Context, EmbedKeywordLoc, Filename, IsAngled, Data, + /*NumOfElements=*/0, Data->getDataElementCount()); } static bool maybeDiagnoseAssignmentToFunction(Sema &S, QualType DstType, diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 7c03a12e812809..609ca34a8c1d20 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -525,9 +525,9 @@ class InitListChecker { } } - Result = new (SemaRef.Context) - EmbedExpr(SemaRef.Context, Embed->getLocation(), Embed->getData(), - CurEmbedIndex, ElsCount); + Result = new (SemaRef.Context) EmbedExpr( + SemaRef.Context, Embed->getLocation(), Embed->getFilename(), + Embed->getIsAngled(), Embed->getData(), CurEmbedIndex, ElsCount); CurEmbedIndex += ElsCount; if (CurEmbedIndex >= Embed->getDataElementCount()) { CurEmbed = nullptr; `````````` </details> https://github.com/llvm/llvm-project/pull/117770 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits