[Clang] Support constexpr asm at global scope. (#143268)
I previously failed to realize this feature existed... Fixes #137459 Fixes #143242
This commit is contained in:
@@ -605,7 +605,7 @@ public:
|
||||
}
|
||||
|
||||
void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) {
|
||||
Visit(D->getAsmString());
|
||||
Visit(D->getAsmStringExpr());
|
||||
}
|
||||
|
||||
void VisitTopLevelStmtDecl(const TopLevelStmtDecl *D) { Visit(D->getStmt()); }
|
||||
|
||||
@@ -4490,18 +4490,18 @@ private:
|
||||
};
|
||||
|
||||
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 @@ public:
|
||||
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; }
|
||||
|
||||
@@ -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())); })
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 << ")";
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user