https://github.com/cor3ntin updated https://github.com/llvm/llvm-project/pull/143268
>From e50565a0e4850eb66ba718be08324a9b5af73d5a Mon Sep 17 00:00:00 2001 From: Corentin Jabot <corentinja...@gmail.com> Date: Sat, 7 Jun 2025 16:23:38 +0200 Subject: [PATCH] [Clang] Support constexpr asm at global scope. I previously failed to realize this feature existed... Fixes #137459 Fixes #143242 --- clang/include/clang/AST/ASTNodeTraverser.h | 2 +- clang/include/clang/AST/Decl.h | 20 ++++++++++--------- clang/include/clang/AST/RecursiveASTVisitor.h | 2 +- clang/lib/AST/Decl.cpp | 7 +++++-- clang/lib/AST/DeclPrinter.cpp | 4 ++-- clang/lib/CodeGen/CodeGenModule.cpp | 2 +- clang/lib/Sema/SemaDecl.cpp | 9 +++------ clang/lib/Serialization/ASTWriterDecl.cpp | 2 +- clang/test/CodeGenCXX/gnu-asm-constexpr.cpp | 8 +++++++- 9 files changed, 32 insertions(+), 24 deletions(-) diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h index 01bc12ce33eff..8d02a50e2e8a5 100644 --- a/clang/include/clang/AST/ASTNodeTraverser.h +++ b/clang/include/clang/AST/ASTNodeTraverser.h @@ -605,7 +605,7 @@ class ASTNodeTraverser } void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) { - Visit(D->getAsmString()); + Visit(D->getAsmStringExpr()); } void VisitTopLevelStmtDecl(const TopLevelStmtDecl *D) { Visit(D->getStmt()); } diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 69ad18f4c0581..05aac15b30cd6 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -4490,18 +4490,18 @@ class RecordDecl : public TagDecl { }; class FileScopeAsmDecl : public Decl { - StringLiteral *AsmString; + Expr *AsmString; SourceLocation RParenLoc; - FileScopeAsmDecl(DeclContext *DC, StringLiteral *asmstring, - SourceLocation StartL, SourceLocation EndL) - : Decl(FileScopeAsm, DC, StartL), AsmString(asmstring), RParenLoc(EndL) {} + FileScopeAsmDecl(DeclContext *DC, Expr *asmstring, SourceLocation StartL, + SourceLocation EndL) + : Decl(FileScopeAsm, DC, StartL), AsmString(asmstring), RParenLoc(EndL) {} virtual void anchor(); public: - static FileScopeAsmDecl *Create(ASTContext &C, DeclContext *DC, - StringLiteral *Str, SourceLocation AsmLoc, + static FileScopeAsmDecl *Create(ASTContext &C, DeclContext *DC, Expr *Str, + SourceLocation AsmLoc, SourceLocation RParenLoc); static FileScopeAsmDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); @@ -4513,9 +4513,11 @@ class FileScopeAsmDecl : public Decl { return SourceRange(getAsmLoc(), getRParenLoc()); } - const StringLiteral *getAsmString() const { return AsmString; } - StringLiteral *getAsmString() { return AsmString; } - void setAsmString(StringLiteral *Asm) { AsmString = Asm; } + const Expr *getAsmStringExpr() const { return AsmString; } + Expr *getAsmStringExpr() { return AsmString; } + void setAsmString(Expr *Asm) { AsmString = Asm; } + + std::string getAsmString() const; static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == FileScopeAsm; } diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index a11157c006f92..b0f8ae621cf6d 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -1617,7 +1617,7 @@ DEF_TRAVERSE_DECL(LifetimeExtendedTemporaryDecl, { }) DEF_TRAVERSE_DECL(FileScopeAsmDecl, - { TRY_TO(TraverseStmt(D->getAsmString())); }) + { TRY_TO(TraverseStmt(D->getAsmStringExpr())); }) DEF_TRAVERSE_DECL(TopLevelStmtDecl, { TRY_TO(TraverseStmt(D->getStmt())); }) diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index aad2d82401111..860968939b4ae 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -5713,8 +5713,7 @@ SourceRange TypeAliasDecl::getSourceRange() const { void FileScopeAsmDecl::anchor() {} FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC, - StringLiteral *Str, - SourceLocation AsmLoc, + Expr *Str, SourceLocation AsmLoc, SourceLocation RParenLoc) { return new (C, DC) FileScopeAsmDecl(DC, Str, AsmLoc, RParenLoc); } @@ -5725,6 +5724,10 @@ FileScopeAsmDecl *FileScopeAsmDecl::CreateDeserialized(ASTContext &C, SourceLocation()); } +std::string FileScopeAsmDecl::getAsmString() const { + return GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(getAsmStringExpr()); +} + void TopLevelStmtDecl::anchor() {} TopLevelStmtDecl *TopLevelStmtDecl::Create(ASTContext &C, Stmt *Statement) { diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index 3616419dce4ec..9443857443346 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -1042,8 +1042,8 @@ void DeclPrinter::VisitParmVarDecl(ParmVarDecl *D) { void DeclPrinter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) { Out << "__asm ("; - D->getAsmString()->printPretty(Out, nullptr, Policy, Indentation, "\n", - &Context); + D->getAsmStringExpr()->printPretty(Out, nullptr, Policy, Indentation, "\n", + &Context); Out << ")"; } diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index c005d3322ed7a..16e49aab4fe61 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -7271,7 +7271,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { if (LangOpts.SYCLIsDevice) break; auto *AD = cast<FileScopeAsmDecl>(D); - getModule().appendModuleInlineAsm(AD->getAsmString()->getString()); + getModule().appendModuleInlineAsm(AD->getAsmString()); break; } diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 60e911b9fecc0..bbd63372c168b 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -20514,14 +20514,11 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, CheckAlignasUnderalignment(Enum); } -Decl *Sema::ActOnFileScopeAsmDecl(Expr *expr, - SourceLocation StartLoc, +Decl *Sema::ActOnFileScopeAsmDecl(Expr *expr, SourceLocation StartLoc, SourceLocation EndLoc) { - StringLiteral *AsmString = cast<StringLiteral>(expr); - FileScopeAsmDecl *New = FileScopeAsmDecl::Create(Context, CurContext, - AsmString, StartLoc, - EndLoc); + FileScopeAsmDecl *New = + FileScopeAsmDecl::Create(Context, CurContext, expr, StartLoc, EndLoc); CurContext->addDecl(New); return New; } diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index b16026c4ba898..8f82324a27535 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -1389,7 +1389,7 @@ void ASTDeclWriter::VisitBindingDecl(BindingDecl *D) { void ASTDeclWriter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) { VisitDecl(D); - Record.AddStmt(D->getAsmString()); + Record.AddStmt(D->getAsmStringExpr()); Record.AddSourceLocation(D->getRParenLoc()); Code = serialization::DECL_FILE_SCOPE_ASM; } diff --git a/clang/test/CodeGenCXX/gnu-asm-constexpr.cpp b/clang/test/CodeGenCXX/gnu-asm-constexpr.cpp index d9c633ea69283..175a3b7bc588c 100644 --- a/clang/test/CodeGenCXX/gnu-asm-constexpr.cpp +++ b/clang/test/CodeGenCXX/gnu-asm-constexpr.cpp @@ -16,6 +16,12 @@ struct string_view { } }; +namespace GH143242 { + constexpr string_view code2 = R"(nop; nop; nop; nop)"; + asm((code2)); + // CHECK: module asm "nop; nop; nop; nop" +} + int func() {return 0;}; void f() { @@ -49,4 +55,4 @@ void test_srcloc() { foobar)o") ) ::(string_view("r"))(func())); - } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits