[clang] [clang] Implement statement printer for EmbedExpr (PR #117770)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 27 04:41:09 PST 2024
https://github.com/circl-lastname updated https://github.com/llvm/llvm-project/pull/117770
>From 184359e8be9eab570ef01810d5d3a6ba4a48afe9 Mon Sep 17 00:00:00 2001
From: circl <circl.lastname at gmail.com>
Date: Tue, 26 Nov 2024 18:52:19 +0100
Subject: [PATCH 1/2] [clang] Store filename in EmbedExpr
---
clang/include/clang/AST/Expr.h | 9 +++++++--
clang/include/clang/Lex/Preprocessor.h | 5 ++++-
clang/include/clang/Sema/Sema.h | 4 ++--
clang/lib/AST/Expr.cpp | 8 ++++----
clang/lib/Lex/PPDirectives.cpp | 9 ++++++---
clang/lib/Parse/ParseInit.cpp | 3 ++-
clang/lib/Sema/SemaExpr.cpp | 5 +++--
clang/lib/Sema/SemaInit.cpp | 6 +++---
8 files changed, 31 insertions(+), 18 deletions(-)
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/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;
>From c175f5ca83bd5e6a4c676ce7d36e2c8bdc73b701 Mon Sep 17 00:00:00 2001
From: circl <circl.lastname at gmail.com>
Date: Tue, 26 Nov 2024 19:44:27 +0100
Subject: [PATCH 2/2] [clang] Implement statement printer for EmbedExpr
---
clang/docs/ReleaseNotes.rst | 1 +
clang/lib/AST/StmtPrinter.cpp | 6 +++++-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 6c40e48e2f49b3..95ae2b52d80598 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -334,6 +334,7 @@ C23 Feature Support
- Clang now officially supports `N3030 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3030.htm>`_ Enhancements to Enumerations. Clang already supported it as an extension, so there were no changes to compiler behavior.
- Fixed the value of ``BOOL_WIDTH`` in ``<limits.h>`` to return ``1``
explicitly, as mandated by the standard. Fixes #GH117348
+- Initial support for pretty printing ``#embed`` directives, which no longer crash clangd when hovered.
Non-comprehensive list of changes in this release
-------------------------------------------------
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index c8677d11b64e8d..2ab9e9a1df4819 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -1202,7 +1202,11 @@ 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 ";
+ OS << (Node->getIsAngled() ? '<' : '"');
+ OS << Node->getFilename();
+ OS << (Node->getIsAngled() ? '>' : '"') << NL;
}
void StmtPrinter::VisitConstantExpr(ConstantExpr *Node) {
More information about the cfe-commits
mailing list