[clang] clang: __builtin_VARIABLE_NAME (PR #86756)
@@ -2305,6 +2308,36 @@ APValue SourceLocExpr::EvaluateInContext(const ASTContext , }; switch (getIdentKind()) { + case SourceLocIdentKind::VariableName: { +// __builtin_VARIABLE_NAME() is a Clang-specific extension that expands to +// the name of the variable being defined in a CXXDefaultArgExpr. + +// FIXME: The AST doesn't have upward edges, so we can't easily traverse up +// from the CXXDefaultArgExpr to find it. Unfortunately, this means we need +// to do a linear scan of (up to) the entire FunctionDecl. +struct FindVarDecl : public RecursiveASTVisitor { + const Expr *ToFind; + const VarDecl *Found = nullptr; + bool TraverseVarDecl(VarDecl *D) { +if (const auto *CE = dyn_cast_or_null(D->getInit())) { jroelofs wrote: Need to strip casts, conversions, parens, etc. https://github.com/llvm/llvm-project/pull/86756 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] clang: __builtin_VARIABLE_NAME (PR #86756)
jroelofs wrote: Here's an example of the awkward lengths Halide has to go through to do this without compiler support: https://github.com/halide/Halide/blob/a132246ced07adc59c7b3631009464e5a14e0abb/src/Introspection.h#L19-L23 https://github.com/llvm/llvm-project/pull/86756 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] clang: __builtin_VARIABLE_NAME (PR #86756)
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 1949f7d6c9bd59172c01c7933e1c558797c47eac dc4a313b793b4215c8a68bea0b4b8e70f8a7806b -- clang/test/CodeGenCXX/variable-name.cpp clang/include/clang/AST/Expr.h clang/lib/AST/Expr.cpp clang/lib/Parse/ParseExpr.cpp clang/lib/Sema/SemaExpr.cpp clang/test/SemaCXX/source_location.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 1d0e741ddc..d3e496b642 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -4731,7 +4731,8 @@ enum class SourceLocIdentKind { /// Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), /// __builtin_FUNCTION(), __builtin_FUNCSIG(), __builtin_FILE(), -/// __builtin_FILE_NAME(), __builtin_source_location() or __builtin_VARIABLE_NAME(). +/// __builtin_FILE_NAME(), __builtin_source_location() or +/// __builtin_VARIABLE_NAME(). class SourceLocExpr final : public Expr { SourceLocation BuiltinLoc, RParenLoc; DeclContext *ParentContext; diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 96954df5a9..1f03fe75e9 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -2332,7 +2332,7 @@ APValue SourceLocExpr::EvaluateInContext(const ASTContext , if (isa(Context)) { FindVarDecl FVD; FVD.ToFind = DefaultExpr; - FVD.TraverseDecl(const_cast(cast(Context))); + FVD.TraverseDecl(const_cast(cast(Context))); if (FVD.Found) return MakeStringLiteral(FVD.Found->getQualifiedNameAsString()); } diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index bca64d8540..a1a4c8fbe2 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -828,20 +828,18 @@ class CastExpressionIdValidator final : public CorrectionCandidateCallback { /// [OBJC] '\@encode' '(' type-name ')' /// [OBJC] objc-string-literal /// [C++] simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3] -/// [C++11] simple-type-specifier braced-init-list [C++11 5.2.3] -/// [C++] typename-specifier '(' expression-list[opt] ')' [C++ 5.2.3] -/// [C++11] typename-specifier braced-init-list [C++11 5.2.3] -/// [C++] 'const_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] -/// [C++] 'dynamic_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] -/// [C++] 'reinterpret_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] -/// [C++] 'static_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] -/// [C++] 'typeid' '(' expression ')' [C++ 5.2p1] -/// [C++] 'typeid' '(' type-id ')'[C++ 5.2p1] -/// [C++] 'this' [C++ 9.3.2] -/// [G++] unary-type-trait '(' type-id ')' -/// [G++] binary-type-trait '(' type-id ',' type-id ')' [TODO] -/// [EMBT] array-type-trait '(' type-id ',' integer ')' -/// [clang] '^' block-literal +/// [C++11] simple-type-specifier braced-init-list [C++11 5.2.3] [C++] +/// typename-specifier '(' expression-list[opt] ')' [C++ 5.2.3] [C++11] +/// typename-specifier braced-init-list [C++11 5.2.3] [C++] +/// 'const_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] [C++] +/// 'dynamic_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] [C++] +/// 'reinterpret_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] [C++] +/// 'static_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1] [C++] +/// 'typeid' '(' expression ')' [C++ 5.2p1] [C++] +/// 'typeid' '(' type-id ')'[C++ 5.2p1] [C++] +/// 'this' [C++ 9.3.2] [G++] unary-type-trait '(' type-id ')' [G++] +/// binary-type-trait '(' type-id ',' type-id ')' [TODO] [EMBT] +/// array-type-trait '(' type-id ',' integer ')' [clang] '^' block-literal /// /// constant: [C99 6.4.4] /// integer-constant `` https://github.com/llvm/llvm-project/pull/86756 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] clang: __builtin_VARIABLE_NAME (PR #86756)
@@ -2305,6 +2308,36 @@ APValue SourceLocExpr::EvaluateInContext(const ASTContext , }; switch (getIdentKind()) { + case SourceLocIdentKind::VariableName: { +// __builtin_VARIABLE_NAME() is a Clang-specific extension that expands to +// the name of the variable being defined in a CXXDefaultArgExpr. + +// FIXME: The AST doesn't have upward edges, so we can't easily traverse up +// from the CXXDefaultArgExpr to find it. Unfortunately, this means we need +// to do a linear scan of (up to) the entire FunctionDecl. jroelofs wrote: I could use some help here. Using the visitor to walk back up the AST feels wrong / slow. https://github.com/llvm/llvm-project/pull/86756 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] clang: __builtin_VARIABLE_NAME (PR #86756)
https://github.com/jroelofs created https://github.com/llvm/llvm-project/pull/86756 Some C++ Embedded DSLs make use of `std::source_location` as a form of crude reflection. Until now, they didn't have a great way to reflect variable names into their IRs. With `__buitlin_SOURCE_LOCATION()`, that is as simple as adding a default argument expression to a constructor: ``` struct Variable { const char *Name; Variable(const char *Name = __builtin_SOURCE_LOCATION()) : Name(Name) {} }; Variable foo; // foo.Name == "foo" ``` >From dc4a313b793b4215c8a68bea0b4b8e70f8a7806b Mon Sep 17 00:00:00 2001 From: Jon Roelofs Date: Tue, 26 Mar 2024 16:54:12 -0700 Subject: [PATCH] clang: __builtin_VARIABLE_NAME Some C++ Embedded DSLs make use of std::source_location as a form of crude reflection. Until now, they didn't have a great way to reflect variable names into their IRs. With __buitlin_SOURCE_LOCATION(), that is as simple as adding a default argument expression to a constructor. struct Variable { const char *Name; Variable(const char *Name = __builtin_SOURCE_LOCATION()) : Name(Name) {} }; Variable foo; // foo.Name == "foo" --- clang/include/clang/AST/Expr.h | 7 ++- clang/include/clang/Basic/TokenKinds.def | 1 + clang/lib/AST/Expr.cpp | 33 +++ clang/lib/Parse/ParseExpr.cpp| 6 ++ clang/lib/Sema/SemaExpr.cpp | 1 + clang/test/CodeGenCXX/variable-name.cpp | 75 clang/test/SemaCXX/source_location.cpp | 39 7 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 clang/test/CodeGenCXX/variable-name.cpp diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 6e153ebe024b42..1d0e741ddc983b 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -4725,12 +4725,13 @@ enum class SourceLocIdentKind { FileName, Line, Column, - SourceLocStruct + SourceLocStruct, + VariableName, }; /// Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), /// __builtin_FUNCTION(), __builtin_FUNCSIG(), __builtin_FILE(), -/// __builtin_FILE_NAME() or __builtin_source_location(). +/// __builtin_FILE_NAME(), __builtin_source_location() or __builtin_VARIABLE_NAME(). class SourceLocExpr final : public Expr { SourceLocation BuiltinLoc, RParenLoc; DeclContext *ParentContext; @@ -4762,6 +4763,7 @@ class SourceLocExpr final : public Expr { case SourceLocIdentKind::Function: case SourceLocIdentKind::FuncSig: case SourceLocIdentKind::SourceLocStruct: +case SourceLocIdentKind::VariableName: return false; case SourceLocIdentKind::Line: case SourceLocIdentKind::Column: @@ -4796,6 +4798,7 @@ class SourceLocExpr final : public Expr { case SourceLocIdentKind::Function: case SourceLocIdentKind::FuncSig: case SourceLocIdentKind::SourceLocStruct: +case SourceLocIdentKind::VariableName: return true; default: return false; diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index 3a96f8a4d22bd1..23e617e1640886 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -448,6 +448,7 @@ KEYWORD(__builtin_FUNCSIG , KEYMS) KEYWORD(__builtin_LINE , KEYALL) KEYWORD(__builtin_COLUMN, KEYALL) KEYWORD(__builtin_source_location , KEYCXX) +KEYWORD(__builtin_VARIABLE_NAME , KEYCXX) // __builtin_types_compatible_p is a GNU C extension that we handle like a C++ // type trait. diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 6221ebd5c9b4e9..96954df5a9817b 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -24,6 +24,7 @@ #include "clang/AST/IgnoreExpr.h" #include "clang/AST/Mangle.h" #include "clang/AST/RecordLayout.h" +#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/StmtVisitor.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/CharInfo.h" @@ -2262,6 +2263,8 @@ StringRef SourceLocExpr::getBuiltinStr() const { return "__builtin_FILE"; case SourceLocIdentKind::FileName: return "__builtin_FILE_NAME"; + case SourceLocIdentKind::VariableName: +return "__builtin_VARIABLE_NAME"; case SourceLocIdentKind::Function: return "__builtin_FUNCTION"; case SourceLocIdentKind::FuncSig: @@ -2305,6 +2308,36 @@ APValue SourceLocExpr::EvaluateInContext(const ASTContext , }; switch (getIdentKind()) { + case SourceLocIdentKind::VariableName: { +// __builtin_VARIABLE_NAME() is a Clang-specific extension that expands to +// the name of the variable being defined in a CXXDefaultArgExpr. + +// FIXME: The AST doesn't have upward edges, so we can't easily traverse up +// from the CXXDefaultArgExpr to find it. Unfortunately, this means we need +// to do a linear scan of (up to) the entire FunctionDecl. +struct FindVarDecl : public