[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
@@ -2586,10 +2586,11 @@ static void UpdateAsmCallInst(llvm::CallBase &Result,
bool HasSideEffect,
// Slap the source location of the inline asm into a !srcloc metadata on the
// call.
- if (const auto *gccAsmStmt = dyn_cast(&S))
-Result.setMetadata("srcloc",
- getAsmSrcLocInfo(gccAsmStmt->getAsmString(), CGF));
- else {
+ if (const auto *gccAsmStmt = dyn_cast(&S)) {
+if (const StringLiteral *SL =
+dyn_cast(gccAsmStmt->getAsmStringExpr()))
+ Result.setMetadata("srcloc", getAsmSrcLocInfo(SL, CGF));
efriedma-quic wrote:
What do the diagnostics look like if you get a parse failure inside the inline
asm?
https://github.com/llvm/llvm-project/pull/131003
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
@@ -17261,33 +17261,50 @@ void Sema::DiagnoseStaticAssertDetails(const Expr *E)
{
}
}
-bool Sema::EvaluateStaticAssertMessageAsString(Expr *Message,
- std::string &Result,
- ASTContext &Ctx,
- bool ErrorOnInvalidMessage) {
+template
+static bool EvaluateAsStringImpl(Sema &SemaRef, Expr *Message,
+ ResultType &Result, ASTContext &Ctx,
+ Sema::StringEvaluationContext EvalContext,
+ bool ErrorOnInvalidMessage) {
+
assert(Message);
assert(!Message->isTypeDependent() && !Message->isValueDependent() &&
"can't evaluate a dependant static assert message");
if (const auto *SL = dyn_cast(Message)) {
assert(SL->isUnevaluated() && "expected an unevaluated string");
-Result.assign(SL->getString().begin(), SL->getString().end());
+if constexpr (std::is_same_v) {
+ Result =
+ APValue(APValue::UninitArray{}, SL->getLength(), SL->getLength());
+ const ConstantArrayType *CAT =
+ SemaRef.getASTContext().getAsConstantArrayType(SL->getType());
+ assert(CAT && "string literal isn't an array");
+ QualType CharType = CAT->getElementType();
+ llvm::APSInt Value(SemaRef.getASTContext().getTypeSize(CharType),
+ CharType->isUnsignedIntegerType());
+ for (unsigned I = 0; I < SL->getLength(); I++) {
+Value = SL->getCodeUnit(I);
+Result.getArrayInitializedElt(I) = APValue(Value);
+ }
+} else {
+ Result.assign(SL->getString().begin(), SL->getString().end());
+}
return true;
}
SourceLocation Loc = Message->getBeginLoc();
QualType T = Message->getType().getNonReferenceType();
auto *RD = T->getAsCXXRecordDecl();
if (!RD) {
-Diag(Loc, diag::err_static_assert_invalid_message);
+SemaRef.Diag(Loc, diag::err_user_defined_msg_invalid) << EvalContext;
return false;
}
auto FindMember = [&](StringRef Member, bool &Empty,
bool Diag = false) -> std::optional {
cor3ntin wrote:
It is preexisting, but there was a lot of nonsense here; thanks!
https://github.com/llvm/llvm-project/pull/131003
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
@@ -17261,33 +17261,50 @@ void Sema::DiagnoseStaticAssertDetails(const Expr *E)
{
}
}
-bool Sema::EvaluateStaticAssertMessageAsString(Expr *Message,
- std::string &Result,
- ASTContext &Ctx,
- bool ErrorOnInvalidMessage) {
+template
+static bool EvaluateAsStringImpl(Sema &SemaRef, Expr *Message,
+ ResultType &Result, ASTContext &Ctx,
+ Sema::StringEvaluationContext EvalContext,
+ bool ErrorOnInvalidMessage) {
+
assert(Message);
assert(!Message->isTypeDependent() && !Message->isValueDependent() &&
"can't evaluate a dependant static assert message");
if (const auto *SL = dyn_cast(Message)) {
assert(SL->isUnevaluated() && "expected an unevaluated string");
-Result.assign(SL->getString().begin(), SL->getString().end());
+if constexpr (std::is_same_v) {
+ Result =
+ APValue(APValue::UninitArray{}, SL->getLength(), SL->getLength());
+ const ConstantArrayType *CAT =
+ SemaRef.getASTContext().getAsConstantArrayType(SL->getType());
+ assert(CAT && "string literal isn't an array");
+ QualType CharType = CAT->getElementType();
+ llvm::APSInt Value(SemaRef.getASTContext().getTypeSize(CharType),
+ CharType->isUnsignedIntegerType());
+ for (unsigned I = 0; I < SL->getLength(); I++) {
+Value = SL->getCodeUnit(I);
+Result.getArrayInitializedElt(I) = APValue(Value);
+ }
+} else {
+ Result.assign(SL->getString().begin(), SL->getString().end());
+}
return true;
}
SourceLocation Loc = Message->getBeginLoc();
QualType T = Message->getType().getNonReferenceType();
auto *RD = T->getAsCXXRecordDecl();
if (!RD) {
-Diag(Loc, diag::err_static_assert_invalid_message);
+SemaRef.Diag(Loc, diag::err_user_defined_msg_invalid) << EvalContext;
return false;
}
auto FindMember = [&](StringRef Member, bool &Empty,
bool Diag = false) -> std::optional {
erichkeane wrote:
`Diag` isn't actually used at all!
https://github.com/llvm/llvm-project/pull/131003
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
@@ -609,9 +632,10 @@ int GCCAsmStmt::getNamedOperand(StringRef SymbolicName)
const {
/// true, otherwise return false.
unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl&Pieces,
const ASTContext &C, unsigned &DiagOffs) const
{
- StringRef Str = getAsmString()->getString();
- const char *StrStart = Str.begin();
- const char *StrEnd = Str.end();
+
+ std::string Str = getAsmString();
+ const char *StrStart = Str.data();
cor3ntin wrote:
begin/end are iterators, and some of the arithmetic in this function we do
requires pointers
https://github.com/llvm/llvm-project/pull/131003
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
llvmbot wrote:
@llvm/pr-subscribers-clang
Author: cor3ntin (cor3ntin)
Changes
Implements GCC's constexpr string ASM extension
https://gcc.gnu.org/onlinedocs/gcc/Asm-constexprs.html
---
Patch is 77.41 KiB, truncated to 20.00 KiB below, full version:
https://github.com/llvm/llvm-project/pull/131003.diff
25 Files Affected:
- (modified) clang/docs/LanguageExtensions.rst (+18)
- (modified) clang/docs/ReleaseNotes.rst (+9)
- (modified) clang/include/clang/AST/Expr.h (+4)
- (modified) clang/include/clang/AST/RecursiveASTVisitor.h (+4-4)
- (modified) clang/include/clang/AST/Stmt.h (+28-32)
- (modified) clang/include/clang/Basic/DiagnosticParseKinds.td (+4-1)
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+23-13)
- (modified) clang/include/clang/Basic/Features.def (+1)
- (modified) clang/include/clang/Sema/Sema.h (+17-3)
- (modified) clang/lib/AST/ASTImporter.cpp (+6-6)
- (modified) clang/lib/AST/ExprConstant.cpp (+40-11)
- (modified) clang/lib/AST/Stmt.cpp (+78-48)
- (modified) clang/lib/AST/StmtPrinter.cpp (+4-4)
- (modified) clang/lib/AST/StmtProfile.cpp (+4-4)
- (modified) clang/lib/CodeGen/CGStmt.cpp (+9-8)
- (modified) clang/lib/Parse/ParseStmtAsm.cpp (+3-3)
- (modified) clang/lib/Parse/Parser.cpp (+27-14)
- (modified) clang/lib/Sema/SemaDeclCXX.cpp (+72-34)
- (modified) clang/lib/Sema/SemaStmtAsm.cpp (+107-65)
- (modified) clang/lib/Sema/TreeTransform.h (+36-13)
- (modified) clang/lib/Serialization/ASTReaderStmt.cpp (+5-5)
- (modified) clang/lib/Serialization/ASTWriterStmt.cpp (+4-4)
- (added) clang/test/CodeGenCXX/gnu-asm-constexpr.cpp (+38)
- (modified) clang/test/Parser/asm.cpp (+45)
- (added) clang/test/Sema/gnu-asm-constexpr.cpp (+127)
``diff
diff --git a/clang/docs/LanguageExtensions.rst
b/clang/docs/LanguageExtensions.rst
index f8d1bc9fe2624..a990eefc8eeac 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -1958,6 +1958,24 @@ references can be used instead of numeric references.
return -1;
}
+
+Constexpr strings in GNU ASM statememts
+===
+
+In C++11 mode (and greater), Clang supports specifying the template,
+constraints, and clobber strings with a parenthesized constant expression
+producing an object with ``data`` and ``size`` member functions,
+such as ``std::string``.
+
+Query for this feature with ``__has_extension(gnu_asm_constexpr_strings)``.
+
+.. code-block:: c++
+
+ int foo() {
+ asm((std::string_view("nop")) ::: (std::string_view("memory")));
+ }
+
+
Objective-C Features
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 48da5558b3f38..c438b9a997ad8 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -74,6 +74,15 @@ What's New in Clang |release|?
C++ Language Changes
+- Similarly to GCC, Clang now supports constant expressions in
+ the strings of a GNU ``asm`` statement.
+
+ .. code-block:: c++
+
+int foo() {
+ asm((std::string_view("nop")) ::: (std::string_view("memory")));
+}
+
C++2c Feature Support
^
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index cfe49acf20b77..28437b5629b00 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -787,6 +787,10 @@ class Expr : public ValueStmt {
const Expr *PtrExpression, ASTContext &Ctx,
EvalResult &Status) const;
+ bool EvaluateCharRangeAsString(APValue &Result, const Expr *SizeExpression,
+ const Expr *PtrExpression, ASTContext &Ctx,
+ EvalResult &Status) const;
+
/// If the current Expr can be evaluated to a pointer to a null-terminated
/// constant string, return the constant string (without the terminating
/// null).
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h
b/clang/include/clang/AST/RecursiveASTVisitor.h
index fac4c10987157..87a6c22b35ee8 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -2410,15 +2410,15 @@ DEF_TRAVERSE_DECL(ImplicitConceptSpecializationDecl, {
}
DEF_TRAVERSE_STMT(GCCAsmStmt, {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAsmString());
+ TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAsmStringExpr());
for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
-TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInputConstraintLiteral(I));
+TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInputConstraintExpr(I));
}
for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
-TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOutputConstraintLiteral(I));
+TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOutputConstraintExpr(I));
}
for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
-TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getClobberStringLiteral(I));
+TRY_TO_TRAV
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
llvmbot wrote:
@llvm/pr-subscribers-clang-modules
Author: cor3ntin (cor3ntin)
Changes
Implements GCC's constexpr string ASM extension
https://gcc.gnu.org/onlinedocs/gcc/Asm-constexprs.html
---
Patch is 77.41 KiB, truncated to 20.00 KiB below, full version:
https://github.com/llvm/llvm-project/pull/131003.diff
25 Files Affected:
- (modified) clang/docs/LanguageExtensions.rst (+18)
- (modified) clang/docs/ReleaseNotes.rst (+9)
- (modified) clang/include/clang/AST/Expr.h (+4)
- (modified) clang/include/clang/AST/RecursiveASTVisitor.h (+4-4)
- (modified) clang/include/clang/AST/Stmt.h (+28-32)
- (modified) clang/include/clang/Basic/DiagnosticParseKinds.td (+4-1)
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+23-13)
- (modified) clang/include/clang/Basic/Features.def (+1)
- (modified) clang/include/clang/Sema/Sema.h (+17-3)
- (modified) clang/lib/AST/ASTImporter.cpp (+6-6)
- (modified) clang/lib/AST/ExprConstant.cpp (+40-11)
- (modified) clang/lib/AST/Stmt.cpp (+78-48)
- (modified) clang/lib/AST/StmtPrinter.cpp (+4-4)
- (modified) clang/lib/AST/StmtProfile.cpp (+4-4)
- (modified) clang/lib/CodeGen/CGStmt.cpp (+9-8)
- (modified) clang/lib/Parse/ParseStmtAsm.cpp (+3-3)
- (modified) clang/lib/Parse/Parser.cpp (+27-14)
- (modified) clang/lib/Sema/SemaDeclCXX.cpp (+72-34)
- (modified) clang/lib/Sema/SemaStmtAsm.cpp (+107-65)
- (modified) clang/lib/Sema/TreeTransform.h (+36-13)
- (modified) clang/lib/Serialization/ASTReaderStmt.cpp (+5-5)
- (modified) clang/lib/Serialization/ASTWriterStmt.cpp (+4-4)
- (added) clang/test/CodeGenCXX/gnu-asm-constexpr.cpp (+38)
- (modified) clang/test/Parser/asm.cpp (+45)
- (added) clang/test/Sema/gnu-asm-constexpr.cpp (+127)
``diff
diff --git a/clang/docs/LanguageExtensions.rst
b/clang/docs/LanguageExtensions.rst
index f8d1bc9fe2624..a990eefc8eeac 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -1958,6 +1958,24 @@ references can be used instead of numeric references.
return -1;
}
+
+Constexpr strings in GNU ASM statememts
+===
+
+In C++11 mode (and greater), Clang supports specifying the template,
+constraints, and clobber strings with a parenthesized constant expression
+producing an object with ``data`` and ``size`` member functions,
+such as ``std::string``.
+
+Query for this feature with ``__has_extension(gnu_asm_constexpr_strings)``.
+
+.. code-block:: c++
+
+ int foo() {
+ asm((std::string_view("nop")) ::: (std::string_view("memory")));
+ }
+
+
Objective-C Features
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 48da5558b3f38..c438b9a997ad8 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -74,6 +74,15 @@ What's New in Clang |release|?
C++ Language Changes
+- Similarly to GCC, Clang now supports constant expressions in
+ the strings of a GNU ``asm`` statement.
+
+ .. code-block:: c++
+
+int foo() {
+ asm((std::string_view("nop")) ::: (std::string_view("memory")));
+}
+
C++2c Feature Support
^
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index cfe49acf20b77..28437b5629b00 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -787,6 +787,10 @@ class Expr : public ValueStmt {
const Expr *PtrExpression, ASTContext &Ctx,
EvalResult &Status) const;
+ bool EvaluateCharRangeAsString(APValue &Result, const Expr *SizeExpression,
+ const Expr *PtrExpression, ASTContext &Ctx,
+ EvalResult &Status) const;
+
/// If the current Expr can be evaluated to a pointer to a null-terminated
/// constant string, return the constant string (without the terminating
/// null).
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h
b/clang/include/clang/AST/RecursiveASTVisitor.h
index fac4c10987157..87a6c22b35ee8 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -2410,15 +2410,15 @@ DEF_TRAVERSE_DECL(ImplicitConceptSpecializationDecl, {
}
DEF_TRAVERSE_STMT(GCCAsmStmt, {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAsmString());
+ TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAsmStringExpr());
for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
-TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInputConstraintLiteral(I));
+TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInputConstraintExpr(I));
}
for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
-TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOutputConstraintLiteral(I));
+TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOutputConstraintExpr(I));
}
for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
-TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getClobberStringLiteral(I));
+TRY
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
llvmbot wrote:
@llvm/pr-subscribers-clang-codegen
Author: cor3ntin (cor3ntin)
Changes
Implements GCC's constexpr string ASM extension
https://gcc.gnu.org/onlinedocs/gcc/Asm-constexprs.html
---
Patch is 77.41 KiB, truncated to 20.00 KiB below, full version:
https://github.com/llvm/llvm-project/pull/131003.diff
25 Files Affected:
- (modified) clang/docs/LanguageExtensions.rst (+18)
- (modified) clang/docs/ReleaseNotes.rst (+9)
- (modified) clang/include/clang/AST/Expr.h (+4)
- (modified) clang/include/clang/AST/RecursiveASTVisitor.h (+4-4)
- (modified) clang/include/clang/AST/Stmt.h (+28-32)
- (modified) clang/include/clang/Basic/DiagnosticParseKinds.td (+4-1)
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+23-13)
- (modified) clang/include/clang/Basic/Features.def (+1)
- (modified) clang/include/clang/Sema/Sema.h (+17-3)
- (modified) clang/lib/AST/ASTImporter.cpp (+6-6)
- (modified) clang/lib/AST/ExprConstant.cpp (+40-11)
- (modified) clang/lib/AST/Stmt.cpp (+78-48)
- (modified) clang/lib/AST/StmtPrinter.cpp (+4-4)
- (modified) clang/lib/AST/StmtProfile.cpp (+4-4)
- (modified) clang/lib/CodeGen/CGStmt.cpp (+9-8)
- (modified) clang/lib/Parse/ParseStmtAsm.cpp (+3-3)
- (modified) clang/lib/Parse/Parser.cpp (+27-14)
- (modified) clang/lib/Sema/SemaDeclCXX.cpp (+72-34)
- (modified) clang/lib/Sema/SemaStmtAsm.cpp (+107-65)
- (modified) clang/lib/Sema/TreeTransform.h (+36-13)
- (modified) clang/lib/Serialization/ASTReaderStmt.cpp (+5-5)
- (modified) clang/lib/Serialization/ASTWriterStmt.cpp (+4-4)
- (added) clang/test/CodeGenCXX/gnu-asm-constexpr.cpp (+38)
- (modified) clang/test/Parser/asm.cpp (+45)
- (added) clang/test/Sema/gnu-asm-constexpr.cpp (+127)
``diff
diff --git a/clang/docs/LanguageExtensions.rst
b/clang/docs/LanguageExtensions.rst
index f8d1bc9fe2624..a990eefc8eeac 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -1958,6 +1958,24 @@ references can be used instead of numeric references.
return -1;
}
+
+Constexpr strings in GNU ASM statememts
+===
+
+In C++11 mode (and greater), Clang supports specifying the template,
+constraints, and clobber strings with a parenthesized constant expression
+producing an object with ``data`` and ``size`` member functions,
+such as ``std::string``.
+
+Query for this feature with ``__has_extension(gnu_asm_constexpr_strings)``.
+
+.. code-block:: c++
+
+ int foo() {
+ asm((std::string_view("nop")) ::: (std::string_view("memory")));
+ }
+
+
Objective-C Features
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 48da5558b3f38..c438b9a997ad8 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -74,6 +74,15 @@ What's New in Clang |release|?
C++ Language Changes
+- Similarly to GCC, Clang now supports constant expressions in
+ the strings of a GNU ``asm`` statement.
+
+ .. code-block:: c++
+
+int foo() {
+ asm((std::string_view("nop")) ::: (std::string_view("memory")));
+}
+
C++2c Feature Support
^
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index cfe49acf20b77..28437b5629b00 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -787,6 +787,10 @@ class Expr : public ValueStmt {
const Expr *PtrExpression, ASTContext &Ctx,
EvalResult &Status) const;
+ bool EvaluateCharRangeAsString(APValue &Result, const Expr *SizeExpression,
+ const Expr *PtrExpression, ASTContext &Ctx,
+ EvalResult &Status) const;
+
/// If the current Expr can be evaluated to a pointer to a null-terminated
/// constant string, return the constant string (without the terminating
/// null).
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h
b/clang/include/clang/AST/RecursiveASTVisitor.h
index fac4c10987157..87a6c22b35ee8 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -2410,15 +2410,15 @@ DEF_TRAVERSE_DECL(ImplicitConceptSpecializationDecl, {
}
DEF_TRAVERSE_STMT(GCCAsmStmt, {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAsmString());
+ TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAsmStringExpr());
for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
-TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInputConstraintLiteral(I));
+TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInputConstraintExpr(I));
}
for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
-TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOutputConstraintLiteral(I));
+TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOutputConstraintExpr(I));
}
for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
-TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getClobberStringLiteral(I));
+TRY
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
https://github.com/cor3ntin ready_for_review https://github.com/llvm/llvm-project/pull/131003 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
@@ -17300,7 +17317,8 @@ bool Sema::EvaluateStaticAssertMessageAsString(Expr
*Message,
std::optional SizeMember = FindMember("size", SizeNotFound);
std::optional DataMember = FindMember("data", DataNotFound);
if (SizeNotFound || DataNotFound) {
erichkeane wrote:
Should probably just check the optional.
https://github.com/llvm/llvm-project/pull/131003
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
@@ -17261,33 +17261,50 @@ void Sema::DiagnoseStaticAssertDetails(const Expr *E)
{
}
}
-bool Sema::EvaluateStaticAssertMessageAsString(Expr *Message,
- std::string &Result,
- ASTContext &Ctx,
- bool ErrorOnInvalidMessage) {
+template
+static bool EvaluateAsStringImpl(Sema &SemaRef, Expr *Message,
+ ResultType &Result, ASTContext &Ctx,
+ Sema::StringEvaluationContext EvalContext,
+ bool ErrorOnInvalidMessage) {
+
assert(Message);
assert(!Message->isTypeDependent() && !Message->isValueDependent() &&
"can't evaluate a dependant static assert message");
if (const auto *SL = dyn_cast(Message)) {
assert(SL->isUnevaluated() && "expected an unevaluated string");
-Result.assign(SL->getString().begin(), SL->getString().end());
+if constexpr (std::is_same_v) {
+ Result =
+ APValue(APValue::UninitArray{}, SL->getLength(), SL->getLength());
+ const ConstantArrayType *CAT =
+ SemaRef.getASTContext().getAsConstantArrayType(SL->getType());
+ assert(CAT && "string literal isn't an array");
+ QualType CharType = CAT->getElementType();
+ llvm::APSInt Value(SemaRef.getASTContext().getTypeSize(CharType),
+ CharType->isUnsignedIntegerType());
+ for (unsigned I = 0; I < SL->getLength(); I++) {
+Value = SL->getCodeUnit(I);
+Result.getArrayInitializedElt(I) = APValue(Value);
+ }
+} else {
+ Result.assign(SL->getString().begin(), SL->getString().end());
+}
return true;
}
SourceLocation Loc = Message->getBeginLoc();
QualType T = Message->getType().getNonReferenceType();
auto *RD = T->getAsCXXRecordDecl();
if (!RD) {
-Diag(Loc, diag::err_static_assert_invalid_message);
+SemaRef.Diag(Loc, diag::err_user_defined_msg_invalid) << EvalContext;
return false;
}
auto FindMember = [&](StringRef Member, bool &Empty,
bool Diag = false) -> std::optional {
-DeclarationName DN = PP.getIdentifierInfo(Member);
-LookupResult MemberLookup(*this, DN, Loc, Sema::LookupMemberName);
-LookupQualifiedName(MemberLookup, RD);
+DeclarationName DN = SemaRef.PP.getIdentifierInfo(Member);
+LookupResult MemberLookup(SemaRef, DN, Loc, Sema::LookupMemberName);
+SemaRef.LookupQualifiedName(MemberLookup, RD);
Empty = MemberLookup.empty();
erichkeane wrote:
Whats hte point of `Empty` if we are returning an optional?
https://github.com/llvm/llvm-project/pull/131003
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
@@ -15328,6 +15338,15 @@ void
Sema::PragmaStack::Act(SourceLocation PragmaLocation,
PragmaMsStackAction Action,
llvm::StringRef
StackSlotLabel,
AlignPackInfo Value);
+
+inline
+const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
+Sema::StringEvaluationContext Ctx) {
+ DB << llvm::to_underlying(Ctx);
cor3ntin wrote:
As discussed offline, this is just to pass a number for `%select{}`
https://github.com/llvm/llvm-project/pull/131003
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
@@ -609,9 +632,10 @@ int GCCAsmStmt::getNamedOperand(StringRef SymbolicName)
const {
/// true, otherwise return false.
unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl&Pieces,
const ASTContext &C, unsigned &DiagOffs) const
{
- StringRef Str = getAsmString()->getString();
- const char *StrStart = Str.begin();
- const char *StrEnd = Str.end();
+
+ std::string Str = getAsmString();
+ const char *StrStart = Str.data();
cor3ntin wrote:
not necessarily depending on your standard library! (for example
`__gnu_cxx::__normal_iterator`)
https://github.com/llvm/llvm-project/pull/131003
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
@@ -3193,7 +3193,7 @@ class AsmStmt : public Stmt {
/// getOutputConstraint - Return the constraint string for the specified
/// output operand. All output constraints are known to be non-empty (either
/// '=' or '+').
- StringRef getOutputConstraint(unsigned i) const;
+ std::string getOutputConstraint(unsigned i) const;
cor3ntin wrote:
As discussed offline, std::string is better at interface boundaries
https://llvm.org/docs/ProgrammersManual.html#string-like-containers
https://github.com/llvm/llvm-project/pull/131003
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
@@ -17928,43 +17928,70 @@ std::optional
Expr::tryEvaluateString(ASTContext &Ctx) const {
return {};
}
-bool Expr::EvaluateCharRangeAsString(std::string &Result,
- const Expr *SizeExpression,
- const Expr *PtrExpression, ASTContext
&Ctx,
- EvalResult &Status) const {
- LValue String;
- EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
- Info.InConstantContext = true;
+template
+static bool EvaluateCharRangeAsStringImpl(const Expr*, T& Result,
+ const Expr *SizeExpression,
+ const Expr *PtrExpression,
ASTContext &Ctx,
+ Expr::EvalResult &Status) {
+LValue String;
+EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
+Info.InConstantContext = true;
- FullExpressionRAII Scope(Info);
- APSInt SizeValue;
- if (!::EvaluateInteger(SizeExpression, SizeValue, Info))
-return false;
+FullExpressionRAII Scope(Info);
cor3ntin wrote:
fixed
https://github.com/llvm/llvm-project/pull/131003
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
@@ -328,20 +328,20 @@ void StmtProfiler::VisitGCCAsmStmt(const GCCAsmStmt *S) {
VisitStmt(S);
ID.AddBoolean(S->isVolatile());
ID.AddBoolean(S->isSimple());
- VisitStringLiteral(S->getAsmString());
+ VisitExpr(S->getAsmStringExpr());
cor3ntin wrote:
I was able to revert!
https://github.com/llvm/llvm-project/pull/131003
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
@@ -609,9 +632,10 @@ int GCCAsmStmt::getNamedOperand(StringRef SymbolicName)
const {
/// true, otherwise return false.
unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl&Pieces,
const ASTContext &C, unsigned &DiagOffs) const
{
- StringRef Str = getAsmString()->getString();
- const char *StrStart = Str.begin();
- const char *StrEnd = Str.end();
+
+ std::string Str = getAsmString();
+ const char *StrStart = Str.data();
erichkeane wrote:
Isn't the type of the iterators `const char*`?
https://github.com/llvm/llvm-project/pull/131003
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
@@ -328,20 +328,20 @@ void StmtProfiler::VisitGCCAsmStmt(const GCCAsmStmt *S) {
VisitStmt(S);
ID.AddBoolean(S->isVolatile());
ID.AddBoolean(S->isSimple());
- VisitStringLiteral(S->getAsmString());
+ VisitExpr(S->getAsmStringExpr());
erichkeane wrote:
Are these necessary? I would expect the `children` definition of the statement
should instead print these. It'll change how the ast-dump works, but for the
better IMO. Though perhaps we like how these look...
https://github.com/llvm/llvm-project/pull/131003
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
cor3ntin wrote: @ojhunt @erichkeane @AaronBallman I'm looking for early feedback at this point. Obviously this has no tests yes This - Generalize our ability to evaluate string expression outside of static assert (which will be otherwise useful for https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3423r1.html ) - Implement GCC's constexpr string in ASM - Once strings are evaluated, they are cached in a ConstantExpr (but we still need to go from APValue -> std::string everytime, which seems reasonable - Because the strings can be arbitrary expressions they can be dependent. If any string is a dependent expression all of sema is skipped until instantiation. It's a slightly big hammer but honestly I'm not sure that we can improve or that it would be worth it. - [ ] Tests - [ ] Doc / Changelog - [ ] cxx_features https://github.com/llvm/llvm-project/pull/131003 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
@@ -17928,43 +17928,70 @@ std::optional
Expr::tryEvaluateString(ASTContext &Ctx) const {
return {};
}
-bool Expr::EvaluateCharRangeAsString(std::string &Result,
- const Expr *SizeExpression,
- const Expr *PtrExpression, ASTContext
&Ctx,
- EvalResult &Status) const {
- LValue String;
- EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
- Info.InConstantContext = true;
+template
+static bool EvaluateCharRangeAsStringImpl(const Expr*, T& Result,
+ const Expr *SizeExpression,
+ const Expr *PtrExpression,
ASTContext &Ctx,
+ Expr::EvalResult &Status) {
+LValue String;
+EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
+Info.InConstantContext = true;
- FullExpressionRAII Scope(Info);
- APSInt SizeValue;
- if (!::EvaluateInteger(SizeExpression, SizeValue, Info))
-return false;
+FullExpressionRAII Scope(Info);
erichkeane wrote:
What weirdness is going on with the formatting here?
https://github.com/llvm/llvm-project/pull/131003
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
@@ -17928,43 +17928,70 @@ std::optional
Expr::tryEvaluateString(ASTContext &Ctx) const {
return {};
}
-bool Expr::EvaluateCharRangeAsString(std::string &Result,
- const Expr *SizeExpression,
- const Expr *PtrExpression, ASTContext
&Ctx,
- EvalResult &Status) const {
- LValue String;
- EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
- Info.InConstantContext = true;
+template
+static bool EvaluateCharRangeAsStringImpl(const Expr*, T& Result,
+ const Expr *SizeExpression,
+ const Expr *PtrExpression,
ASTContext &Ctx,
+ Expr::EvalResult &Status) {
+LValue String;
+EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
+Info.InConstantContext = true;
- FullExpressionRAII Scope(Info);
- APSInt SizeValue;
- if (!::EvaluateInteger(SizeExpression, SizeValue, Info))
-return false;
+FullExpressionRAII Scope(Info);
+APSInt SizeValue;
+if (!::EvaluateInteger(SizeExpression, SizeValue, Info))
+ return false;
- uint64_t Size = SizeValue.getZExtValue();
+uint64_t Size = SizeValue.getZExtValue();
- if (!::EvaluatePointer(PtrExpression, String, Info))
-return false;
+if constexpr(std::is_same_v)
+Result = APValue(APValue::UninitArray{}, Size, Size);
+//else
+//Result.reserve(Size);
- QualType CharTy = PtrExpression->getType()->getPointeeType();
- for (uint64_t I = 0; I < Size; ++I) {
-APValue Char;
-if (!handleLValueToRValueConversion(Info, PtrExpression, CharTy, String,
-Char))
+if (!::EvaluatePointer(PtrExpression, String, Info))
+ return false;
+
+QualType CharTy = PtrExpression->getType()->getPointeeType();
+for (uint64_t I = 0; I < Size; ++I) {
+ APValue Char;
+ if (!handleLValueToRValueConversion(Info, PtrExpression, CharTy, String,
+ Char))
+return false;
+
+ if constexpr(std::is_same_v) {
+ Result.getArrayInitializedElt(I) = std::move(Char);
+ }
+ else {
+ APSInt C = Char.getInt();
+ Result.push_back(static_cast(C.getExtValue()));
+ }
+
+ if (!HandleLValueArrayAdjustment(Info, PtrExpression, String, CharTy, 1))
+return false;
+}
+if (!Scope.destroy())
return false;
-APSInt C = Char.getInt();
-Result.push_back(static_cast(C.getExtValue()));
-if (!HandleLValueArrayAdjustment(Info, PtrExpression, String, CharTy, 1))
+if (!CheckMemoryLeaks(Info))
erichkeane wrote:
This looks like a `if (!X) return false; return true;` here :)
https://github.com/llvm/llvm-project/pull/131003
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
@@ -497,6 +497,19 @@ void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
if (Policy.IncludeNewlines) OS << NL;
}
+static void PrintGCCAsmString(raw_ostream &OS, Expr*E) {
+ if(E->getDependence()) {
+OS << "<>";
+return;
+ }
+
+ std::string Str = GCCAsmStmt::ExtractStringFromGCCAsmStmtComponent(E);
erichkeane wrote:
Do we really want to do this instead of printing the expression? Seems weird
that `-ast-print` would be changing the value here.
https://github.com/llvm/llvm-project/pull/131003
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
@@ -17928,43 +17928,70 @@ std::optional
Expr::tryEvaluateString(ASTContext &Ctx) const {
return {};
}
-bool Expr::EvaluateCharRangeAsString(std::string &Result,
- const Expr *SizeExpression,
- const Expr *PtrExpression, ASTContext
&Ctx,
- EvalResult &Status) const {
- LValue String;
- EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
- Info.InConstantContext = true;
+template
+static bool EvaluateCharRangeAsStringImpl(const Expr*, T& Result,
+ const Expr *SizeExpression,
+ const Expr *PtrExpression,
ASTContext &Ctx,
+ Expr::EvalResult &Status) {
+LValue String;
+EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
+Info.InConstantContext = true;
- FullExpressionRAII Scope(Info);
- APSInt SizeValue;
- if (!::EvaluateInteger(SizeExpression, SizeValue, Info))
-return false;
+FullExpressionRAII Scope(Info);
+APSInt SizeValue;
+if (!::EvaluateInteger(SizeExpression, SizeValue, Info))
+ return false;
- uint64_t Size = SizeValue.getZExtValue();
+uint64_t Size = SizeValue.getZExtValue();
- if (!::EvaluatePointer(PtrExpression, String, Info))
-return false;
+if constexpr(std::is_same_v)
+Result = APValue(APValue::UninitArray{}, Size, Size);
+//else
+//Result.reserve(Size);
- QualType CharTy = PtrExpression->getType()->getPointeeType();
- for (uint64_t I = 0; I < Size; ++I) {
-APValue Char;
-if (!handleLValueToRValueConversion(Info, PtrExpression, CharTy, String,
-Char))
+if (!::EvaluatePointer(PtrExpression, String, Info))
+ return false;
+
+QualType CharTy = PtrExpression->getType()->getPointeeType();
+for (uint64_t I = 0; I < Size; ++I) {
+ APValue Char;
+ if (!handleLValueToRValueConversion(Info, PtrExpression, CharTy, String,
+ Char))
+return false;
+
+ if constexpr(std::is_same_v) {
+ Result.getArrayInitializedElt(I) = std::move(Char);
+ }
+ else {
+ APSInt C = Char.getInt();
+ Result.push_back(static_cast(C.getExtValue()));
erichkeane wrote:
Should we do some range checking before the cast? I would expect based on
`CharTy` that we could expect `C` here to have a bitwidth of 8, right?
https://github.com/llvm/llvm-project/pull/131003
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
@@ -17928,43 +17928,70 @@ std::optional
Expr::tryEvaluateString(ASTContext &Ctx) const {
return {};
}
-bool Expr::EvaluateCharRangeAsString(std::string &Result,
- const Expr *SizeExpression,
- const Expr *PtrExpression, ASTContext
&Ctx,
- EvalResult &Status) const {
- LValue String;
- EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
- Info.InConstantContext = true;
+template
+static bool EvaluateCharRangeAsStringImpl(const Expr*, T& Result,
+ const Expr *SizeExpression,
+ const Expr *PtrExpression,
ASTContext &Ctx,
+ Expr::EvalResult &Status) {
+LValue String;
+EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
+Info.InConstantContext = true;
- FullExpressionRAII Scope(Info);
- APSInt SizeValue;
- if (!::EvaluateInteger(SizeExpression, SizeValue, Info))
-return false;
+FullExpressionRAII Scope(Info);
+APSInt SizeValue;
+if (!::EvaluateInteger(SizeExpression, SizeValue, Info))
+ return false;
- uint64_t Size = SizeValue.getZExtValue();
+uint64_t Size = SizeValue.getZExtValue();
- if (!::EvaluatePointer(PtrExpression, String, Info))
-return false;
+if constexpr(std::is_same_v)
+Result = APValue(APValue::UninitArray{}, Size, Size);
+//else
erichkeane wrote:
Eh?
https://github.com/llvm/llvm-project/pull/131003
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
@@ -8552,25 +8552,39 @@ template
StmtResult
TreeTransform::TransformGCCAsmStmt(GCCAsmStmt *S) {
+
SmallVector Constraints;
SmallVector Exprs;
SmallVector Names;
- ExprResult AsmString;
SmallVector Clobbers;
bool ExprsChanged = false;
+ auto RebuildString = [&] (Expr* E) {
+ ExprResult Result = getDerived().TransformExpr(E);
+ if (Result.isInvalid())
erichkeane wrote:
```suggestion
if (!Result.isUsable())
```
https://github.com/llvm/llvm-project/pull/131003
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
@@ -3193,7 +3193,7 @@ class AsmStmt : public Stmt {
/// getOutputConstraint - Return the constraint string for the specified
/// output operand. All output constraints are known to be non-empty (either
/// '=' or '+').
- StringRef getOutputConstraint(unsigned i) const;
+ std::string getOutputConstraint(unsigned i) const;
erichkeane wrote:
should these be llvm::SmallString?
https://github.com/llvm/llvm-project/pull/131003
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
@@ -609,9 +632,10 @@ int GCCAsmStmt::getNamedOperand(StringRef SymbolicName)
const {
/// true, otherwise return false.
unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl&Pieces,
const ASTContext &C, unsigned &DiagOffs) const
{
- StringRef Str = getAsmString()->getString();
- const char *StrStart = Str.begin();
- const char *StrEnd = Str.end();
+
+ std::string Str = getAsmString();
+ const char *StrStart = Str.data();
erichkeane wrote:
Curious why data/data+size instead of just begin/end?
https://github.com/llvm/llvm-project/pull/131003
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
@@ -8552,25 +8552,39 @@ template
StmtResult
TreeTransform::TransformGCCAsmStmt(GCCAsmStmt *S) {
+
SmallVector Constraints;
SmallVector Exprs;
SmallVector Names;
- ExprResult AsmString;
SmallVector Clobbers;
bool ExprsChanged = false;
+ auto RebuildString = [&] (Expr* E) {
+ ExprResult Result = getDerived().TransformExpr(E);
+ if (Result.isInvalid())
+return Result;
+ if(!Result.isInvalid() && Result.get() != E) {
erichkeane wrote:
```suggestion
if(Result.get() != E) {
```
https://github.com/llvm/llvm-project/pull/131003
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
@@ -15328,6 +15338,15 @@ void
Sema::PragmaStack::Act(SourceLocation PragmaLocation,
PragmaMsStackAction Action,
llvm::StringRef
StackSlotLabel,
AlignPackInfo Value);
+
+inline
+const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
+Sema::StringEvaluationContext Ctx) {
+ DB << llvm::to_underlying(Ctx);
erichkeane wrote:
This is a shame... an-inverse-string-switch here would be nice.
https://github.com/llvm/llvm-project/pull/131003
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
https://github.com/cor3ntin updated
https://github.com/llvm/llvm-project/pull/131003
>From 84508166a9784701dad659881bf75f9764e53f54 Mon Sep 17 00:00:00 2001
From: Corentin Jabot
Date: Wed, 12 Mar 2025 12:23:14 +0100
Subject: [PATCH 1/2] [Clang][WIP] Constant Expressions inside of gcc'asm
strings
Implements GCC's constexpr string ASM extension
https://gcc.gnu.org/onlinedocs/gcc/Asm-constexprs.html
---
clang/include/clang/AST/Expr.h| 5 +
clang/include/clang/AST/RecursiveASTVisitor.h | 8 +-
clang/include/clang/AST/Stmt.h| 50 +++---
.../clang/Basic/DiagnosticParseKinds.td | 5 +-
.../clang/Basic/DiagnosticSemaKinds.td| 36 +++--
clang/include/clang/Sema/Sema.h | 25 ++-
clang/lib/AST/ASTImporter.cpp | 12 +-
clang/lib/AST/ExprConstant.cpp| 83 ++
clang/lib/AST/Stmt.cpp| 103
clang/lib/AST/StmtPrinter.cpp | 21 ++-
clang/lib/AST/StmtProfile.cpp | 8 +-
clang/lib/CodeGen/CGStmt.cpp | 16 +-
clang/lib/Parse/ParseStmtAsm.cpp | 2 +-
clang/lib/Parse/Parser.cpp| 37 +++--
clang/lib/Sema/SemaDeclCXX.cpp| 99
clang/lib/Sema/SemaStmtAsm.cpp| 147 +++---
clang/lib/Sema/TreeTransform.h| 50 --
clang/lib/Serialization/ASTReaderStmt.cpp | 10 +-
clang/lib/Serialization/ASTWriterStmt.cpp | 8 +-
19 files changed, 473 insertions(+), 252 deletions(-)
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index cfe49acf20b77..7f9e50dfe78bd 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -787,6 +787,11 @@ class Expr : public ValueStmt {
const Expr *PtrExpression, ASTContext &Ctx,
EvalResult &Status) const;
+ bool EvaluateCharRangeAsString(APValue &Result,
+ const Expr *SizeExpression,
+ const Expr *PtrExpression, ASTContext &Ctx,
+ EvalResult &Status) const;
+
/// If the current Expr can be evaluated to a pointer to a null-terminated
/// constant string, return the constant string (without the terminating
/// null).
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h
b/clang/include/clang/AST/RecursiveASTVisitor.h
index fac4c10987157..87a6c22b35ee8 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -2410,15 +2410,15 @@ DEF_TRAVERSE_DECL(ImplicitConceptSpecializationDecl, {
}
DEF_TRAVERSE_STMT(GCCAsmStmt, {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAsmString());
+ TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAsmStringExpr());
for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
-TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInputConstraintLiteral(I));
+TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInputConstraintExpr(I));
}
for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
-TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOutputConstraintLiteral(I));
+TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOutputConstraintExpr(I));
}
for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
-TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getClobberStringLiteral(I));
+TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getClobberExpr(I));
}
// children() iterates over inputExpr and outputExpr.
})
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 604ac51d478cf..7bf0a6911c515 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -3193,7 +3193,7 @@ class AsmStmt : public Stmt {
/// getOutputConstraint - Return the constraint string for the specified
/// output operand. All output constraints are known to be non-empty (either
/// '=' or '+').
- StringRef getOutputConstraint(unsigned i) const;
+ std::string getOutputConstraint(unsigned i) const;
/// isOutputPlusConstraint - Return true if the specified output constraint
/// is a "+" constraint (which is both an input and an output) or false if it
@@ -3214,14 +3214,14 @@ class AsmStmt : public Stmt {
/// getInputConstraint - Return the specified input constraint. Unlike
output
/// constraints, these can be empty.
- StringRef getInputConstraint(unsigned i) const;
+ std::string getInputConstraint(unsigned i) const;
const Expr *getInputExpr(unsigned i) const;
//===--- Other ---===//
unsigned getNumClobbers() const { return NumClobbers; }
- StringRef getClobber(unsigned i) const;
+ std::string getClobber(unsigned i) const;
static bool classof(const Stmt *T) {
return T->getStmtClass() == GCCAsmStmtClass ||
@@ -3302,20 +3302,20 @@ class GCCAsmStmt : public AsmStmt {
friend class ASTStmtReader;
SourceLocation RParenLoc;
- StringLiteral *AsmStr
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
github-actions[bot] wrote:
:warning: C/C++ code formatter, clang-format found issues in your code.
:warning:
You can test this locally with the following command:
``bash
git-clang-format --diff 90a08fb4b7e79e79121a563ac9cd8138cfedeb3c
84508166a9784701dad659881bf75f9764e53f54 --extensions cpp,h --
clang/include/clang/AST/Expr.h clang/include/clang/AST/RecursiveASTVisitor.h
clang/include/clang/AST/Stmt.h clang/include/clang/Sema/Sema.h
clang/lib/AST/ASTImporter.cpp clang/lib/AST/ExprConstant.cpp
clang/lib/AST/Stmt.cpp clang/lib/AST/StmtPrinter.cpp
clang/lib/AST/StmtProfile.cpp clang/lib/CodeGen/CGStmt.cpp
clang/lib/Parse/ParseStmtAsm.cpp clang/lib/Parse/Parser.cpp
clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaStmtAsm.cpp
clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReaderStmt.cpp
clang/lib/Serialization/ASTWriterStmt.cpp
``
View the diff from clang-format here.
``diff
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 7f9e50dfe7..28437b5629 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -787,10 +787,9 @@ public:
const Expr *PtrExpression, ASTContext &Ctx,
EvalResult &Status) const;
- bool EvaluateCharRangeAsString(APValue &Result,
- const Expr *SizeExpression,
- const Expr *PtrExpression, ASTContext &Ctx,
- EvalResult &Status) const;
+ bool EvaluateCharRangeAsString(APValue &Result, const Expr *SizeExpression,
+ const Expr *PtrExpression, ASTContext &Ctx,
+ EvalResult &Status) const;
/// If the current Expr can be evaluated to a pointer to a null-terminated
/// constant string, return the constant string (without the terminating
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 7bf0a6911c..88ae3aeefa 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -3314,9 +3314,8 @@ public:
GCCAsmStmt(const ASTContext &C, SourceLocation asmloc, bool issimple,
bool isvolatile, unsigned numoutputs, unsigned numinputs,
IdentifierInfo **names, Expr **constraints, Expr **exprs,
- Expr *asmstr, unsigned numclobbers,
- Expr **clobbers, unsigned numlabels,
- SourceLocation rparenloc);
+ Expr *asmstr, unsigned numclobbers, Expr **clobbers,
+ unsigned numlabels, SourceLocation rparenloc);
/// Build an empty inline-assembly statement.
explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty) {}
@@ -3404,9 +3403,7 @@ public:
const Expr *getOutputConstraintExpr(unsigned i) const {
return Constraints[i];
}
- Expr *getOutputConstraintExpr(unsigned i) {
-return Constraints[i];
- }
+ Expr *getOutputConstraintExpr(unsigned i) { return Constraints[i]; }
Expr *getOutputExpr(unsigned i);
@@ -3443,7 +3440,7 @@ public:
return const_cast(this)->getInputExpr(i);
}
- static std::string ExtractStringFromGCCAsmStmtComponent(const Expr* E);
+ static std::string ExtractStringFromGCCAsmStmtComponent(const Expr *E);
//===--- Labels ---===//
@@ -3493,12 +3490,9 @@ public:
private:
void setOutputsAndInputsAndClobbers(const ASTContext &C,
IdentifierInfo **Names,
- Expr **Constraints,
- Stmt **Exprs,
- unsigned NumOutputs,
- unsigned NumInputs,
- unsigned NumLabels,
- Expr **Clobbers,
+ Expr **Constraints, Stmt **Exprs,
+ unsigned NumOutputs, unsigned NumInputs,
+ unsigned NumLabels, Expr **Clobbers,
unsigned NumClobbers);
public:
@@ -3512,9 +3506,7 @@ public:
std::string getClobber(unsigned i) const;
Expr *getClobberExpr(unsigned i) { return Clobbers[i]; }
- const Expr *getClobberExpr(unsigned i) const {
-return Clobbers[i];
- }
+ const Expr *getClobberExpr(unsigned i) const { return Clobbers[i]; }
SourceLocation getBeginLoc() const LLVM_READONLY { return AsmLoc; }
SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index e1b1083675..4043699912 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5585,10 +5585,7 @@ public:
void ActOnFinishDelayedCXXMethodDeclaration(Scope *S, Decl *Method);
void ActOnFinishDelayedMemberInitializers(Decl *Record);
- enum class StringEvaluationContext {
- Sta
[clang] [Clang][WIP] Constant Expressions inside of gcc'asm strings (PR #131003)
https://github.com/cor3ntin created
https://github.com/llvm/llvm-project/pull/131003
Implements GCC's constexpr string ASM extension
https://gcc.gnu.org/onlinedocs/gcc/Asm-constexprs.html
>From 84508166a9784701dad659881bf75f9764e53f54 Mon Sep 17 00:00:00 2001
From: Corentin Jabot
Date: Wed, 12 Mar 2025 12:23:14 +0100
Subject: [PATCH] [Clang][WIP] Constant Expressions inside of gcc'asm strings
Implements GCC's constexpr string ASM extension
https://gcc.gnu.org/onlinedocs/gcc/Asm-constexprs.html
---
clang/include/clang/AST/Expr.h| 5 +
clang/include/clang/AST/RecursiveASTVisitor.h | 8 +-
clang/include/clang/AST/Stmt.h| 50 +++---
.../clang/Basic/DiagnosticParseKinds.td | 5 +-
.../clang/Basic/DiagnosticSemaKinds.td| 36 +++--
clang/include/clang/Sema/Sema.h | 25 ++-
clang/lib/AST/ASTImporter.cpp | 12 +-
clang/lib/AST/ExprConstant.cpp| 83 ++
clang/lib/AST/Stmt.cpp| 103
clang/lib/AST/StmtPrinter.cpp | 21 ++-
clang/lib/AST/StmtProfile.cpp | 8 +-
clang/lib/CodeGen/CGStmt.cpp | 16 +-
clang/lib/Parse/ParseStmtAsm.cpp | 2 +-
clang/lib/Parse/Parser.cpp| 37 +++--
clang/lib/Sema/SemaDeclCXX.cpp| 99
clang/lib/Sema/SemaStmtAsm.cpp| 147 +++---
clang/lib/Sema/TreeTransform.h| 50 --
clang/lib/Serialization/ASTReaderStmt.cpp | 10 +-
clang/lib/Serialization/ASTWriterStmt.cpp | 8 +-
19 files changed, 473 insertions(+), 252 deletions(-)
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index cfe49acf20b77..7f9e50dfe78bd 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -787,6 +787,11 @@ class Expr : public ValueStmt {
const Expr *PtrExpression, ASTContext &Ctx,
EvalResult &Status) const;
+ bool EvaluateCharRangeAsString(APValue &Result,
+ const Expr *SizeExpression,
+ const Expr *PtrExpression, ASTContext &Ctx,
+ EvalResult &Status) const;
+
/// If the current Expr can be evaluated to a pointer to a null-terminated
/// constant string, return the constant string (without the terminating
/// null).
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h
b/clang/include/clang/AST/RecursiveASTVisitor.h
index fac4c10987157..87a6c22b35ee8 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -2410,15 +2410,15 @@ DEF_TRAVERSE_DECL(ImplicitConceptSpecializationDecl, {
}
DEF_TRAVERSE_STMT(GCCAsmStmt, {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAsmString());
+ TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAsmStringExpr());
for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
-TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInputConstraintLiteral(I));
+TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInputConstraintExpr(I));
}
for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
-TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOutputConstraintLiteral(I));
+TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOutputConstraintExpr(I));
}
for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
-TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getClobberStringLiteral(I));
+TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getClobberExpr(I));
}
// children() iterates over inputExpr and outputExpr.
})
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 604ac51d478cf..7bf0a6911c515 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -3193,7 +3193,7 @@ class AsmStmt : public Stmt {
/// getOutputConstraint - Return the constraint string for the specified
/// output operand. All output constraints are known to be non-empty (either
/// '=' or '+').
- StringRef getOutputConstraint(unsigned i) const;
+ std::string getOutputConstraint(unsigned i) const;
/// isOutputPlusConstraint - Return true if the specified output constraint
/// is a "+" constraint (which is both an input and an output) or false if it
@@ -3214,14 +3214,14 @@ class AsmStmt : public Stmt {
/// getInputConstraint - Return the specified input constraint. Unlike
output
/// constraints, these can be empty.
- StringRef getInputConstraint(unsigned i) const;
+ std::string getInputConstraint(unsigned i) const;
const Expr *getInputExpr(unsigned i) const;
//===--- Other ---===//
unsigned getNumClobbers() const { return NumClobbers; }
- StringRef getClobber(unsigned i) const;
+ std::string getClobber(unsigned i) const;
static bool classof(const Stmt *T) {
return T->getStmtClass() == GCCAsmStmtClass ||
@@ -3302,20 +3302,20 @@ class GCCAsmStmt : publ
