[clang] clang: __builtin_VARIABLE_NAME (PR #86756)

2024-03-27 Thread Jon Roelofs via cfe-commits


@@ -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)

2024-03-26 Thread Jon Roelofs via cfe-commits

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)

2024-03-26 Thread via cfe-commits

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)

2024-03-26 Thread Jon Roelofs via cfe-commits


@@ -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)

2024-03-26 Thread Jon Roelofs via cfe-commits

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