aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Parse/Parser.cpp
diff options
context:
space:
mode:
authorcor3ntin <corentinjabot@gmail.com>2025-03-17 20:10:46 +0100
committerGitHub <noreply@github.com>2025-03-17 20:10:46 +0100
commit911b200ce339ace2d55cd2827bb10ed6a494faae (patch)
tree7e6360734a4fcef3407b8fb8e3047288a270e690 /clang/lib/Parse/Parser.cpp
parent2443fe537f8bf7620c26586034b12a977d14e366 (diff)
downloadllvm-911b200ce339ace2d55cd2827bb10ed6a494faae.zip
llvm-911b200ce339ace2d55cd2827bb10ed6a494faae.tar.gz
llvm-911b200ce339ace2d55cd2827bb10ed6a494faae.tar.bz2
[Clang] Constant Expressions inside of GCC' asm strings (#131003)
Implements GCC's constexpr string ASM extension https://gcc.gnu.org/onlinedocs/gcc/Asm-constexprs.html
Diffstat (limited to 'clang/lib/Parse/Parser.cpp')
-rw-r--r--clang/lib/Parse/Parser.cpp41
1 files changed, 27 insertions, 14 deletions
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 0710542..83dd7b1 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -19,6 +19,7 @@
#include "clang/Basic/FileManager.h"
#include "clang/Parse/RAIIObjectsForParser.h"
#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/EnterExpressionEvaluationContext.h"
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaCodeCompletion.h"
@@ -1668,28 +1669,40 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) {
/// string-literal
///
ExprResult Parser::ParseAsmStringLiteral(bool ForAsmLabel) {
- if (!isTokenStringLiteral()) {
- Diag(Tok, diag::err_expected_string_literal)
- << /*Source='in...'*/0 << "'asm'";
- return ExprError();
- }
- ExprResult AsmString(ParseStringLiteralExpression());
- if (!AsmString.isInvalid()) {
+ ExprResult AsmString;
+ if (isTokenStringLiteral()) {
+ AsmString = ParseStringLiteralExpression();
+ if (AsmString.isInvalid())
+ return AsmString;
+
const auto *SL = cast<StringLiteral>(AsmString.get());
if (!SL->isOrdinary()) {
Diag(Tok, diag::err_asm_operand_wide_string_literal)
- << SL->isWide()
- << SL->getSourceRange();
+ << SL->isWide() << SL->getSourceRange();
return ExprError();
}
- if (ForAsmLabel && SL->getString().empty()) {
- Diag(Tok, diag::err_asm_operand_wide_string_literal)
- << 2 /* an empty */ << SL->getSourceRange();
+ } else if (!ForAsmLabel && getLangOpts().CPlusPlus11 &&
+ Tok.is(tok::l_paren)) {
+ ParenParseOption ExprType = SimpleExpr;
+ SourceLocation RParenLoc;
+ ParsedType CastTy;
+
+ EnterExpressionEvaluationContext ConstantEvaluated(
+ Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
+ AsmString = ParseParenExpression(ExprType, true /*stopIfCastExpr*/, false,
+ CastTy, RParenLoc);
+ if (!AsmString.isInvalid())
+ AsmString = Actions.ActOnConstantExpression(AsmString);
+
+ if (AsmString.isInvalid())
return ExprError();
- }
+ } else {
+ Diag(Tok, diag::err_asm_expected_string) << /*and expression=*/(
+ (getLangOpts().CPlusPlus11 && !ForAsmLabel) ? 0 : 1);
}
- return AsmString;
+
+ return Actions.ActOnGCCAsmStmtString(AsmString.get(), ForAsmLabel);
}
/// ParseSimpleAsm