llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-codegen

Author: Nhat Nguyen  (changkhothuychung)

<details>
<summary>Changes</summary>

This PR introduces std::meta::info type for reflection on primitive types, as 
parsing right now only supports primitive types. This implementation is based 
on the fork of @<!-- -->katzdm 

For constant evaluation of std::meta::info, a new kind `Reflection` is 
introduced in APValue::ValueKind.

---

Patch is 28.39 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/190356.diff


23 Files Affected:

- (modified) clang/include/clang/AST/APValue.h (+35-2) 
- (modified) clang/include/clang/AST/ASTContext.h (+1) 
- (modified) clang/include/clang/AST/BuiltinTypes.def (+3) 
- (modified) clang/include/clang/AST/ExprCXX.h (+13-7) 
- (added) clang/include/clang/AST/Reflection.h (+25) 
- (modified) clang/include/clang/AST/TypeBase.h (+5) 
- (modified) clang/include/clang/Basic/TargetInfo.h (+5) 
- (modified) clang/lib/AST/APValue.cpp (+22) 
- (modified) clang/lib/AST/ASTContext.cpp (+7) 
- (modified) clang/lib/AST/ExprCXX.cpp (+5-4) 
- (modified) clang/lib/AST/ExprConstant.cpp (+63) 
- (modified) clang/lib/AST/Type.cpp (+10) 
- (modified) clang/lib/Basic/TargetInfo.cpp (+2) 
- (modified) clang/lib/CodeGen/CodeGenModule.cpp (+3) 
- (modified) clang/lib/CodeGen/CodeGenTypes.cpp (+4) 
- (modified) clang/lib/CodeGen/ItaniumCXXABI.cpp (+1) 
- (modified) clang/lib/Sema/SemaExpr.cpp (+7) 
- (modified) clang/lib/Sema/SemaOverload.cpp (+16) 
- (modified) clang/lib/Sema/TreeTransform.h (+4-1) 
- (modified) clang/test/CodeGenCXX/reflection-mangle-itanium.cpp (+4) 
- (modified) clang/test/CodeGenCXX/reflection-mangle-ms.cpp (+3) 
- (added) clang/test/Parser/reflection-meta-info.fail.cpp (+21) 
- (added) clang/test/Parser/reflection-meta-info.pass.cpp (+39) 


``````````diff
diff --git a/clang/include/clang/AST/APValue.h 
b/clang/include/clang/AST/APValue.h
index 8a2d6d434792a..efd293914ff32 100644
--- a/clang/include/clang/AST/APValue.h
+++ b/clang/include/clang/AST/APValue.h
@@ -13,6 +13,7 @@
 #ifndef LLVM_CLANG_AST_APVALUE_H
 #define LLVM_CLANG_AST_APVALUE_H
 
+#include "clang/AST/Reflection.h"
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/APFixedPoint.h"
 #include "llvm/ADT/APFloat.h"
@@ -140,7 +141,8 @@ class APValue {
     Struct,
     Union,
     MemberPointer,
-    AddrLabelDiff
+    AddrLabelDiff,
+    Reflection
   };
 
   class alignas(uint64_t) LValueBase {
@@ -304,12 +306,16 @@ class APValue {
     const AddrLabelExpr* LHSExpr;
     const AddrLabelExpr* RHSExpr;
   };
+  struct ReflectionData {
+    const ReflectionKind OperandKind;
+    const void *Operand;
+  };
   struct MemberPointerData;
 
   // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
   typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt,
                                       ComplexAPFloat, Vec, Arr, StructData,
-                                      UnionData, AddrLabelDiffData> DataType;
+                                      UnionData, AddrLabelDiffData, 
ReflectionData> DataType;
   static const size_t DataSize = sizeof(DataType);
 
   DataType Data;
@@ -396,6 +402,15 @@ class APValue {
       : Kind(None), AllowConstexprUnknown(false) {
     MakeArray(InitElts, Size);
   }
+
+  /// Creates a new Reflection APValue.
+  /// \param OperandKind The kind of reflection.
+  /// \param Operand The entity being reflected.
+  APValue(ReflectionKind OperandKind, const void *Operand)
+      : Kind(None) {
+    MakeReflection(OperandKind, Operand);
+  }
+
   /// Creates a new struct APValue.
   /// \param UninitStruct Marker. Pass an empty UninitStruct.
   /// \param NumBases Number of bases.
@@ -476,6 +491,7 @@ class APValue {
   bool isUnion() const { return Kind == Union; }
   bool isMemberPointer() const { return Kind == MemberPointer; }
   bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
+  bool isReflection() const { return Kind == Reflection; }
 
   void dump() const;
   void dump(raw_ostream &OS, const ASTContext &Context) const;
@@ -651,6 +667,16 @@ class APValue {
     return ((const AddrLabelDiffData *)(const char *)&Data)->RHSExpr;
   }
 
+  const ReflectionKind getReflectionOperandKind() const {
+    assert(isReflection() && "Invalid accessor");
+    return ((const ReflectionData *)(const char *)&Data)->OperandKind;
+  }
+
+  const void* getOpaqueReflectionOperand() const {
+    assert(isReflection() && "Invalid accessor");
+    return ((const ReflectionData *)(const char *)&Data)->Operand;
+  }
+
   void setInt(APSInt I) {
     assert(isInt() && "Invalid accessor");
     *(APSInt *)(char *)&Data = std::move(I);
@@ -696,6 +722,13 @@ class APValue {
 
 private:
   void DestroyDataAndMakeUninit();
+  void MakeReflection(ReflectionKind OperandKind,
+                      const void *Operand) {
+    assert(isAbsent() && "Bad state change");
+    new ((void *)(char *)Data.buffer) ReflectionData(
+            OperandKind, Operand);
+    Kind = Reflection;
+  }
   void MakeInt() {
     assert(isAbsent() && "Bad state change");
     new ((void *)&Data) APSInt(1);
diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index 05302c30d18d1..0f96ce9fc7f7b 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1315,6 +1315,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
   CanQualType BFloat16Ty;
   CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3
   CanQualType VoidPtrTy, NullPtrTy;
+  CanQualType MetaInfoTy;
   CanQualType DependentTy, OverloadTy, BoundMemberTy, UnresolvedTemplateTy,
       UnknownAnyTy;
   CanQualType BuiltinFnTy;
diff --git a/clang/include/clang/AST/BuiltinTypes.def 
b/clang/include/clang/AST/BuiltinTypes.def
index 444be4311a743..87a376a839cda 100644
--- a/clang/include/clang/AST/BuiltinTypes.def
+++ b/clang/include/clang/AST/BuiltinTypes.def
@@ -226,6 +226,9 @@ FLOATING_TYPE(Ibm128, Ibm128Ty)
 // This is the type of C++0x 'nullptr'.
 BUILTIN_TYPE(NullPtr, NullPtrTy)
 
+// 'std::meta::info' in C++
+BUILTIN_TYPE(MetaInfo, MetaInfoTy)
+
 // The primitive Objective C 'id' type.  The user-visible 'id'
 // type is a typedef of an ObjCObjectPointerType to an
 // ObjCObjectType with this as its base.  In fact, this only ever
diff --git a/clang/include/clang/AST/ExprCXX.h 
b/clang/include/clang/AST/ExprCXX.h
index c40cd929b7408..824d96cb9dae1 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -25,6 +25,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/OperationKinds.h"
+#include "clang/AST/Reflection.h"
 #include "clang/AST/Stmt.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/TemplateBase.h"
@@ -5508,15 +5509,18 @@ class BuiltinBitCastExpr final
 ///  - an id-expression.
 class CXXReflectExpr : public Expr {
 
-  // TODO(Reflection): add support for TemplateReference, NamespaceReference 
and
-  // DeclRefExpr
-  using operand_type = llvm::PointerUnion<const TypeSourceInfo *>;
 
-  SourceLocation CaretCaretLoc;
-  operand_type Operand;
+  private:
+    // TODO(Reflection): add support for TemplateReference, NamespaceReference 
and
+    // DeclRefExpr
+    using operand_type = llvm::PointerUnion<const TypeSourceInfo *>;
 
-  CXXReflectExpr(SourceLocation CaretCaretLoc, const TypeSourceInfo *TSI);
-  CXXReflectExpr(EmptyShell Empty);
+    SourceLocation CaretCaretLoc;
+    ReflectionKind Kind;
+    operand_type Operand;
+
+    CXXReflectExpr(ASTContext &C, SourceLocation CaretCaretLoc, const 
TypeSourceInfo *TSI);
+    CXXReflectExpr(EmptyShell Empty);
 
 public:
   static CXXReflectExpr *Create(ASTContext &C, SourceLocation OperatorLoc,
@@ -5538,6 +5542,8 @@ class CXXReflectExpr : public Expr {
 
   /// Returns location of the '^^'-operator.
   SourceLocation getOperatorLoc() const { return CaretCaretLoc; }
+  ReflectionKind getKind() const { return Kind; }
+  const void* getOpaqueValue() const { return Operand.getOpaqueValue(); }
 
   child_range children() {
     // TODO(Reflection)
diff --git a/clang/include/clang/AST/Reflection.h 
b/clang/include/clang/AST/Reflection.h
new file mode 100644
index 0000000000000..140f48af6efe3
--- /dev/null
+++ b/clang/include/clang/AST/Reflection.h
@@ -0,0 +1,25 @@
+//===--- Reflection.h - Kind of reflection operands ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the kinds of reflection operands.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_CLANG_AST_REFLECTION_H
+#define LLVM_CLANG_AST_REFLECTION_H
+namespace clang {
+
+// TODO(Reflection): Add support for Template, Namespace and DeclRefExpr.
+enum class ReflectionKind {
+  Type
+};
+
+}
+
+#endif
diff --git a/clang/include/clang/AST/TypeBase.h 
b/clang/include/clang/AST/TypeBase.h
index 9402469f5e12b..bdbca5b8d9dae 100644
--- a/clang/include/clang/AST/TypeBase.h
+++ b/clang/include/clang/AST/TypeBase.h
@@ -2634,6 +2634,7 @@ class alignas(TypeAlignment) Type : public 
ExtQualsTypeCommonBase {
   bool isRecordType() const;
   bool isClassType() const;
   bool isStructureType() const;
+  bool isMetaInfoType() const;
   bool isStructureTypeWithFlexibleArrayMember() const;
   bool isObjCBoxableRecordType() const;
   bool isInterfaceType() const;
@@ -8953,6 +8954,10 @@ inline bool Type::isVoidType() const {
   return isSpecificBuiltinType(BuiltinType::Void);
 }
 
+inline bool Type::isMetaInfoType() const {
+  return isSpecificBuiltinType(BuiltinType::MetaInfo);
+}
+
 inline bool Type::isHalfType() const {
   // FIXME: Should we allow complex __fp16? Probably not.
   return isSpecificBuiltinType(BuiltinType::Half);
diff --git a/clang/include/clang/Basic/TargetInfo.h 
b/clang/include/clang/Basic/TargetInfo.h
index ec6cd2be7c3c5..a830d165de98c 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -96,6 +96,7 @@ struct TransferrableTargetInfo {
   unsigned char FloatWidth, FloatAlign;
   unsigned char DoubleWidth, DoubleAlign;
   unsigned char LongDoubleWidth, LongDoubleAlign, Float128Align, Ibm128Align;
+  unsigned char MetaInfoWidth, MetaInfoAlign;
   unsigned char LargeArrayMinWidth, LargeArrayAlign;
   unsigned char LongWidth, LongAlign;
   unsigned char LongLongWidth, LongLongAlign;
@@ -824,6 +825,10 @@ class TargetInfo : public TransferrableTargetInfo,
   unsigned getIbm128Align() const { return Ibm128Align; }
   const llvm::fltSemantics &getIbm128Format() const { return *Ibm128Format; }
 
+  /// getMetaInfoWidth/Align - Returns the size/align of std::meta::info.
+  unsigned getMetaInfoWidth() const { return MetaInfoWidth; }
+  unsigned getMetaInfoAlign() const { return MetaInfoAlign; }
+
   /// Return the mangled code of long double.
   virtual const char *getLongDoubleMangling() const { return "e"; }
 
diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp
index 2e1c8eb3726cf..803c54d4f1c07 100644
--- a/clang/lib/AST/APValue.cpp
+++ b/clang/lib/AST/APValue.cpp
@@ -377,6 +377,9 @@ APValue::APValue(const APValue &RHS)
     MakeAddrLabelDiff();
     setAddrLabelDiff(RHS.getAddrLabelDiffLHS(), RHS.getAddrLabelDiffRHS());
     break;
+  case Reflection:
+    MakeReflection(RHS.getReflectionOperandKind(), 
RHS.getOpaqueReflectionOperand());
+    break;
   }
 }
 
@@ -430,6 +433,8 @@ void APValue::DestroyDataAndMakeUninit() {
     ((MemberPointerData *)(char *)&Data)->~MemberPointerData();
   else if (Kind == AddrLabelDiff)
     ((AddrLabelDiffData *)(char *)&Data)->~AddrLabelDiffData();
+  else if (Kind == Reflection)
+    ((ReflectionData *)(char *)&Data)->~ReflectionData();
   Kind = None;
   AllowConstexprUnknown = false;
 }
@@ -439,6 +444,7 @@ bool APValue::needsCleanup() const {
   case None:
   case Indeterminate:
   case AddrLabelDiff:
+  case Reflection:
     return false;
   case Struct:
   case Union:
@@ -486,6 +492,18 @@ static void profileIntValue(llvm::FoldingSetNodeID &ID, 
const llvm::APInt &V) {
     ID.AddInteger((uint32_t)V.extractBitsAsZExtValue(std::min(32u, N - I), I));
 }
 
+static void profileReflection(llvm::FoldingSetNodeID &ID, APValue V) {
+  ID.AddInteger(static_cast<int>(V.getReflectionOperandKind()));
+  switch (V.getReflectionOperandKind()) {
+    case ReflectionKind::Type: {
+      const TypeSourceInfo* info = static_cast<const 
TypeSourceInfo*>(V.getOpaqueReflectionOperand());
+      ID.AddPointer((info->getType().getCanonicalType().getAsOpaquePtr()));
+      return;
+    }
+    assert(false && "unknown or unimplemented reflection entities");
+  }
+}
+
 void APValue::Profile(llvm::FoldingSetNodeID &ID) const {
   // Note that our profiling assumes that only APValues of the same type are
   // ever compared. As a result, we don't consider collisions that could only
@@ -624,6 +642,9 @@ void APValue::Profile(llvm::FoldingSetNodeID &ID) const {
     for (const CXXRecordDecl *D : getMemberPointerPath())
       ID.AddPointer(D);
     return;
+  case Reflection:
+    profileReflection(ID, *this);
+    return;
   }
 
   llvm_unreachable("Unknown APValue kind!");
@@ -1139,6 +1160,7 @@ LinkageInfo LinkageComputer::getLVForValue(const APValue 
&V,
   case APValue::ComplexInt:
   case APValue::ComplexFloat:
   case APValue::Vector:
+  case APValue::Reflection:
     break;
 
   case APValue::AddrLabelDiff:
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index b74766dab38f8..937bcb17da44f 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1452,6 +1452,9 @@ void ASTContext::InitBuiltinTypes(const TargetInfo 
&Target,
   // nullptr type (C++0x 2.14.7)
   InitBuiltinType(NullPtrTy,           BuiltinType::NullPtr);
 
+  // std::meta::info type (C++26 21.4.1)
+  InitBuiltinType(MetaInfoTy, BuiltinType::MetaInfo);
+
   // half type (OpenCL 6.1.1.1) / ARM NEON __fp16
   InitBuiltinType(HalfTy, BuiltinType::Half);
 
@@ -2280,6 +2283,10 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) 
const {
       Width = Target->getPointerWidth(LangAS::Default);
       Align = Target->getPointerAlign(LangAS::Default);
       break;
+    case BuiltinType::MetaInfo:
+      Width = Target->getMetaInfoWidth();
+      Align = Target->getMetaInfoAlign();
+      break;
     case BuiltinType::ObjCId:
     case BuiltinType::ObjCClass:
     case BuiltinType::ObjCSel:
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index bcc481fc8399f..489ad54b1509c 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -24,6 +24,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/LambdaCapture.h"
 #include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/Reflection.h"
 #include "clang/AST/TemplateBase.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/TypeLoc.h"
@@ -1942,15 +1943,15 @@ TypeTraitExpr *TypeTraitExpr::CreateDeserialized(const 
ASTContext &C,
 CXXReflectExpr::CXXReflectExpr(EmptyShell Empty)
     : Expr(CXXReflectExprClass, Empty) {}
 
-CXXReflectExpr::CXXReflectExpr(SourceLocation CaretCaretLoc,
+CXXReflectExpr::CXXReflectExpr(ASTContext &C, SourceLocation CaretCaretLoc,
                                const TypeSourceInfo *TSI)
-    : Expr(CXXReflectExprClass, TSI->getType(), VK_PRValue, OK_Ordinary),
-      CaretCaretLoc(CaretCaretLoc), Operand(TSI) {}
+    : Expr(CXXReflectExprClass, C.MetaInfoTy, VK_PRValue, OK_Ordinary),
+      CaretCaretLoc(CaretCaretLoc), Kind(ReflectionKind::Type), Operand(TSI) {}
 
 CXXReflectExpr *CXXReflectExpr::Create(ASTContext &C,
                                        SourceLocation CaretCaretLoc,
                                        TypeSourceInfo *TSI) {
-  return new (C) CXXReflectExpr(CaretCaretLoc, TSI);
+  return new (C) CXXReflectExpr(C, CaretCaretLoc, TSI);
 }
 
 CXXReflectExpr *CXXReflectExpr::CreateEmpty(ASTContext &C) {
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 5973315406aed..069c9b9116af6 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -51,6 +51,7 @@
 #include "clang/AST/StmtVisitor.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/TypeLoc.h"
+#include "clang/AST/Reflection.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/DiagnosticSema.h"
 #include "clang/Basic/TargetBuiltins.h"
@@ -2469,6 +2470,8 @@ static bool 
CheckEvaluationResult(CheckEvaluationResultKind CERK,
         Value.getUnionValue(), Kind, Value.getUnionField(), CheckedTemps);
   }
   if (Value.isStruct()) {
+    if (Type->isMetaInfoType())
+        return true;
     auto *RD = Type->castAsRecordDecl();
     if (const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
       unsigned BaseIndex = 0;
@@ -10895,6 +10898,46 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const 
CXXNewExpr *E) {
 
   return true;
 }
+
+//===----------------------------------------------------------------------===//
+// Reflection expression evaluation
+//===----------------------------------------------------------------------===//
+
+namespace {
+class ReflectionEvaluator
+  : public ExprEvaluatorBase<ReflectionEvaluator> {
+
+  using BaseType = ExprEvaluatorBase<ReflectionEvaluator>;
+
+  APValue &Result;
+public:
+  ReflectionEvaluator(EvalInfo &E, APValue &Result)
+    : ExprEvaluatorBaseTy(E), Result(Result) {}
+
+  bool Success(const APValue &V, const Expr *E) {
+    Result = V;
+    return true;
+  }
+
+  bool VisitCXXReflectExpr(const CXXReflectExpr *E);
+};
+
+bool ReflectionEvaluator::VisitCXXReflectExpr(const CXXReflectExpr *E) {
+  switch (E->getKind()) {
+    case ReflectionKind::Type: {
+      APValue Result(ReflectionKind::Type, E->getOpaqueValue());
+      return Success(Result, E);
+    }
+  }
+  llvm_unreachable("invalid reflection");
+}
+}  // end anonymous namespace
+
+static bool EvaluateReflection(const Expr *E, APValue &Result, EvalInfo &Info) 
{
+  assert(E->isPRValue() && E->getType()->isMetaInfoType());
+  return ReflectionEvaluator(Info, Result).Visit(E);
+}
+
 
//===----------------------------------------------------------------------===//
 // Member Pointer Evaluation
 
//===----------------------------------------------------------------------===//
@@ -18277,6 +18320,23 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const 
BinaryOperator *E,
     return Success(CmpResult::Equal, E);
   }
 
+  if (LHSTy->isMetaInfoType() && RHSTy->isMetaInfoType()) {
+    APValue LHSValue, RHSValue;
+    llvm::FoldingSetNodeID LID, RID;
+    if (!Evaluate(LHSValue, Info, E->getLHS()))
+      return false;
+    LHSValue.Profile(LID);
+
+    if (!Evaluate(RHSValue, Info, E->getRHS()))
+      return false;
+    RHSValue.Profile(RID);
+
+    if (LID == RID)
+      return Success(CmpResult::Equal, E);
+    else
+      return Success(CmpResult::Unequal, E);
+  }
+
   return DoAfter();
 }
 
@@ -20432,6 +20492,9 @@ static bool Evaluate(APValue &Result, EvalInfo &Info, 
const Expr *E) {
   } else if (T->isIntegralOrEnumerationType()) {
     if (!IntExprEvaluator(Info, Result).Visit(E))
       return false;
+  } else if (T->isMetaInfoType()) {
+    if(!EvaluateReflection(E, Result, Info))
+      return false;
   } else if (T->hasPointerRepresentation()) {
     LValue LV;
     if (!EvaluatePointer(E, LV, Info))
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index a85f08753a132..eebea6811b5c6 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -3105,6 +3105,13 @@ bool Type::isLiteralType(const ASTContext &Ctx) const {
     return true;
   }
 
+  // C++26 [basic.types]p9:
+  // -- std::meta::info is a scalar type
+  // C++26 [basic.types]p10:
+  // -- a scalar type is a literal type
+  if(isMetaInfoType())
+    return true;
+
   // We treat _Atomic T as a literal type if T is a literal type.
   if (const auto *AT = BaseTy->getAs<AtomicType>())
     return AT->getValueType()->isLiteralType(Ctx);
@@ -3480,6 +3487,8 @@ StringRef BuiltinType::getName(const PrintingPolicy 
&Policy) const {
     return "unsigned _Accum";
   case ULongAccum:
     return "unsigned long _Accum";
+  case BuiltinType::MetaInfo:
+    return "meta::info";
   case BuiltinType::ShortFract:
     return "short _Fract";
   case BuiltinType::Fract:
@@ -5194,6 +5203,7 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const 
{
 #include "clang/Basic/HLSLIntangibleTypes.def"
     case BuiltinType::BuiltinFn:
     case BuiltinType::NullPtr:
+    case BuiltinType::MetaInfo:
     case BuiltinType::IncompleteMatrixIdx:
     case BuiltinType::ArraySection:
     case BuiltinType::OMPArrayShaping:
diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp
index 794621c4b3e1f..3943347947d5c 100644
--- a/clang/lib/Basic/TargetInfo.cpp
+++ b/clang/lib/Basic/TargetInfo.cpp
@@ -125,6 +125,8 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) {
   LongDoubleAlign = 64;
   Float128Align = 128;
   Ibm128Align = 128;
+  MetaInfoWidth = 64;
+  MetaInfoAlign = 64;
   LargeArrayMinWidth = 0;
   LargeArrayAlign = 0;
   MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0;
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 35ee108cdc4fc..fb341ba9615dc 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -6085,6 +6085,9 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl 
*D,
   if (getLangOpts().OpenCL && ASTTy->isSamplerT())
     return;
 
+  if (getLangOpts().Reflection && ASTTy->isMetaInfoType())
+    return;
+
   // HLSL default buffer constants will be emitted during HLSLBufferDecl 
codegen
   if (getLangOpts().HLSL &&
       D->getType().getAddressSpace() == LangAS::hlsl_constant)
diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp 
b/clang/lib/CodeGen/CodeGenTypes.cpp
index 6bd79056e599a..b17d38e659450 100644
--- a/clang/lib/CodeGen/CodeGenTypes.cpp
+++ b/clang/lib/CodeGen/CodeGenTypes.cpp
@@ -515,6 +515,10 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
       ResultType = llvm::PointerType::getUnqual(getLLVMContext());
       break;
 
+    case BuiltinType::MetaInfo:
+      ResultType = ll...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/190356
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to