From 89930f711851073c1703ec4f08b14e54a3fc3aa5 Mon Sep 17 00:00:00 2001 From: Dan Katz Date: Thu, 1 Aug 2024 19:55:50 -0400 Subject: [PATCH 1/7] Refactor of reflection representation. Merge 'ReflectionValue' into 'APValue' entirely. Add a "reflection depth" counter to every APValue, such that if APValues V and RV are the same except that RV has a ReflectionDepth one higher than V, then RV represents a reflection of V. This permits the representation of reflections of values and objects without dynamically allocating any memory to store the reflected results. --- P2996.md | 44 +- clang/include/clang/AST/APValue.h | 197 +- clang/include/clang/AST/AbstractBasicReader.h | 4 - clang/include/clang/AST/ExprCXX.h | 12 +- clang/include/clang/AST/PropertiesBase.td | 83 +- clang/include/clang/AST/RecursiveASTVisitor.h | 29 +- clang/include/clang/AST/Reflection.h | 215 +- clang/include/clang/AST/Type.h | 4 +- .../clang/Serialization/ASTRecordWriter.h | 5 - clang/lib/AST/APValue.cpp | 431 +++- clang/lib/AST/ASTDiagnostic.cpp | 64 +- clang/lib/AST/ComputeDependence.cpp | 28 +- clang/lib/AST/ExprCXX.cpp | 12 +- clang/lib/AST/ExprConstant.cpp | 15 +- clang/lib/AST/ItaniumMangle.cpp | 48 +- clang/lib/AST/MicrosoftMangle.cpp | 27 +- clang/lib/AST/Reflection.cpp | 235 -- clang/lib/Sema/Metafunctions.cpp | 2223 ++++++++--------- clang/lib/Sema/SemaReflect.cpp | 166 +- clang/lib/Sema/SemaTemplate.cpp | 6 +- clang/lib/Sema/SemaTemplateInstantiate.cpp | 4 +- clang/lib/Sema/SemaTemplateVariadic.cpp | 14 +- clang/lib/Sema/TreeTransform.h | 44 +- clang/lib/Serialization/ASTWriterStmt.cpp | 2 +- libcxx/include/experimental/meta | 52 +- .../reflection/to-and-from-values.pass.cpp | 32 + 26 files changed, 1933 insertions(+), 2063 deletions(-) diff --git a/P2996.md b/P2996.md index 4be2dbb62bcf03..972b7151620056 100644 --- a/P2996.md +++ b/P2996.md @@ -59,15 +59,16 @@ Any implemented language or library extensions that are _not_ candidates for inc One sharp edge worth mentioning is that our current implementation of P2996 metafunctions is regrettably resistant to proper AST serialization. As such, this compiler cannot, in its current state, be safely used to build precompiled headers or C++20 modules that contain reflection features. This is a difficult problem that is discussed in greater detail below. We are very interested in identifying a design that can elegantly address this issue. ### Incomplete features -A few features and behavior from P2996 are not yet supported (e.g., template splicers). The [issue tracker](https://github.com/bloomberg/clang-p2996/issues) will be kept updated with all known bugs, noncomformant behaviors, and missing features. +Nearly all of P2996 is supported. We make an effort to keep the [issue tracker](https://github.com/bloomberg/clang-p2996/issues) updated with all known bugs, noncomformant behaviors, and missing features. -Our goal has been to provide a working compiler capable of building executables. It is currently a non-goal to support the full family of features and tools offered by `clang` (e.g., AST output, `clang-tidy`, etc). We have therefore taken several shortcuts when it comes to defining things like the formatting of a reflection in a text dump. We are open to pull requests implementing such things, but are otherwise content to wait until P2996 is further along in the WG21 process. +It has been our goal to provide a working compiler capable of building executables, but it has not been a non-goal to support the full family of features and tools offered by `clang` (e.g., AST output, `clang-tidy`, etc). Several shortcuts were therefore taken when it comes to defining things like the formatting of a reflection in a text dump. We are open to pull requests implementing such things, but are otherwise content to wait until P2996 is further along in the WG21 process. ### P2996 test cases A significant number of tests have been written for this project, covering both the reflection and splicing operators proposed for the core language and the various metafunctions proposed for the Standard Library (found [here](/clang/test/Reflection/) and [here](/libcxx/test/std/experimental/reflection/) respectively). Among these tests are many of the examples from the P2996 paper (e.g., "_Parsing Command-Line Options II_", "_Compile-Time Ticket Counter_", and "_Emulating Typeful Reflection_"). We expect for this body of tests to continue to grow, and hope that it may furthermore assist validation of future implementations of P2996. At this time, our test cases only verify correct uses of P2996 facilities; that is, we have not yet written tests to validate expected diagnostics for ill-formed programs. As such, this is probably an area having a nontrivial number of bugs and crashes waiting to be discovered. + ## License Following the example of the upstream LLVM project, new code developed for Clang/P2996 is licensed under Apache 2.0 with LLVM extensions ([LICENSE.TXT](/LICENSE.TXT)). @@ -80,42 +81,26 @@ The Clang/P2996 project has adopted a [Code of Conduct](https://github.com/bloom Below are some high level notes about our implementation of P2996, along with some thoughts regarding certain "sharp edges" of the proposal as it relates to `clang`. ## Representing reflections -A reflection is represented as a `ReflectionValue`: effectively a `void *` tagged with an enum value identifying the kind of entity reflected (i.e., very similar to `TemplateArgument`, `APValue`, and several other AST vocabulary types found in clang). A `ReflectionValue` is one of: +P2996 proposes a _value-based_ reflection model, whereby reflections are encoded as opaque scalar values usable during translation. The evaluation of an expression can compute a reflection, so it becomes important for an `APValue` to be capable of representing a reflection. A new `APValue::Reflection` kind is introduced for this purpose. + +Most reflections are internally represented as a `void *` tagged with an enum value identifying the kind of entity reflected (similar to e.g., `TemplateArgument`). The pointer identifies one of: * A type (represented by a `QualType`) -* A constant value (represented by an `ConstantExpr *`) * A declaration of an evaluatable entity (represented by a `ValueDecl *`) * A template (represented by a `TemplateName`) * A namespace (represented by a `Decl *`) * A base class specifier (represented by a `CXXBaseSpecifier *`) * A description of a hypothetical data member, for representing the result of a call to `std::meta::data_member_spec` (represented by a `TagDataMemberSpec *`). -This set of possible "kinds" is intended to be extensible. - -Since a constant expression can evaluate to a `ReflectionValue` scalar prvalue, `ReflectionValue` becomes a new possible kind of `APValue`. - -Since a reflection can only be spliced if it is a constant expression, the passing of reflections as template arguments is an important use case. However, the semantics of equality for reflection values do differ from those of, for example, integers. In part to implement this bespoke definition of equality, `ReflectionValue` also becomes a distinct kind of `TemplateArgument`. - +Representing all of these kinds of reflections is straightforward. Less straightforward is the representation of _values_ and _objects_, the natural representations of which are _also_ `APValue`s. The puzzling situation emerges in which an `APValue` must sometimes be able to hold a reflection, but a reflection must sometimes also be able to hold an `APValue`. -### Retrospective -This foundational design has worked well, but a few shortcomings are worth noting. +Our initial implementation of P2996 used a separate `ReflectionValue` class to model a reflection, and made `ReflectionValue` one of the several different "kinds" of structs that might be held by an `APValue`. When a reflection of a value or object was required, we stored the reflected result in a separate dynamically allocated `APValue`. -The use of a `ConstantExpr *` to represent a constant value was chosen as a convenient container for an `APValue`, but a smarter implementation might either use `APValue` directly. This does leave a somewhat odd cycle in which an `APValue` might hold a `ReflectionValue`, which itself might hold an `APValue`, but the use of a `ConstantExpr *`-node as a layer of indirection does nothing to make this any less weird. In fact, it necessitated several otherwise unnecessary changes to allow `ConstantExpr` to hold an `APValue` without an associated `SubExpr`. - -It's also a bit unfortunate that the "most specific" type that could be used to represent a namespace is a `Decl *`. This was chosen because a reflection of a namespace could be a `NamespaceDecl`, a `NamespaceAlias`, or a `TranslationUnitDecl` (representing the global namespace). Regrettably, the nearest common ancestor of these is `Decl` itself. +We eventually settled on a more efficient, if more invasive, change: We merged the `ReflectionValue` class into the `APValue` class, and added a `ReflectionDepth` "counter" to the representation of every `APValue`. This reduces the task of "taking a reflection of a value" to little more than incrementing its "reflection depth". The details are slightly more involved, but this model requires no dynamic allocations to represent any reflections. ## Reflect expressions -We generally found parsing reflect expressions (e.g., `^int`) to be an easier problem than parsing splices. An expression of the form `^E`, where `E` is a named entity or a constant expression, is parsed as a `CXXReflectExpr` with the operand represented by a `ReflectionValue` data member. - -Several different interpretations of `E` are tentatively parsed: -1. As a template -2. As a namespace -3. As a type -4. As an expression - -The first interpretation of these to succeed is selected; if none succeed, the reflect-expression is ill-formed. - +We generally found parsing reflect expressions (e.g., `^int`) to be an easier problem than parsing splices. An expression of the form `^E`, where `E` is a named entity or a constant expression, is parsed as a `CXXReflectExpr` with the operand represented by a `APValue` data member. ### Reflection contexts The operand of a reflect expression is unevaluated, but we found that parsing reflections follows slightly different rules from other unevaluated contexts. Examples here include allowing direct reference to class members without taking their address (e.g., `^S::fn`) and resolving a namespace to a `NamespaceAliasDecl` without dealiasing. @@ -128,22 +113,23 @@ While the act of reflecting over an entity always produces an expression, the ac * A type (i.e., `QualType`) * A reference to an entity or constant expression (e.g., `ConstantExpr *`) * A namespace +* A template name It thus becomes clear that a _splice_, without further context, can only be given a coherent definition at the grammatical level; its semantics are dependent on both the context and the evaluation of the spliced expression. If the operand of the splice can be evaluated at parse time, then this presents little difficulty. However, if the splice is value-dependent on a template parameter (e.g., the common use case of splicing a reflection received as a template argument), then it may not be possible to determine what the splice "is" until template substitution. P2996 addresses this in a familiar way, requiring that all such splices be preceded with e.g., a leading `typename` to disambiguate the class of entity; an expression is assumed in the absence of such a disambiguator. To help with such cases, we decompose a splice `[:R:]` into two objects: -1. A `CXXIndeterminateSpliceExpr` representing the expression whose evaluation will yield the `ReflectionValue` of the entity being spliced, and -2. An AST object holding a pointer to the `CXXIndeterminateSpliceExpr` (e.g., `ReflectionSpliceType` for types, `CXXExprSpliceExpr` for expressions). +1. A `CXXSpliceSpecifierExpr` representing the expression whose evaluation will yield the `APValue` of the entity being spliced, and +2. An AST object holding a pointer to the `CXXSpliceSpecifierExpr` (e.g., `ReflectionSpliceType` for types, `CXXExprSpliceExpr` for expressions). ### Parsing splices of expressions -Splices of expressions usually appear in the context of a _cast-expression_ (e.g., `[:R:] + 13`), but they can also appear on the right-hand side of a _member access expression_. The existing machinery in `SemaMemberExpr.cpp` assumes that the member being accessed has not yet been resolved and performs name lookup to find a `Decl`. However, in the case of an expression like `a.[:R:]`, we already have the `Decl` from a `ReflectionValue` obtained through evaluation of `R`. Therefore, we introduce overloads of functions like `Sema::ActOnMemberAccessExpr` to support the case where the right-hand of the member access is a splice. A special `CXXDependentMemberSpliceExpr` is introduced to cover cases when the reflection is dependent on a template parameter, in order to "hold" the underlying `CXXIndeterminateSpliceExpr` until template substitution. +Splices of expressions usually appear in the context of a _cast-expression_ (e.g., `[:R:] + 13`), but they can also appear on the right-hand side of a _member access expression_. The existing machinery in `SemaMemberExpr.cpp` assumes that the member being accessed has not yet been resolved and performs name lookup to find a `Decl`. However, in the case of an expression like `a.[:R:]`, we already have the `Decl` from a `APValue` obtained through evaluation of `R`. Therefore, we introduce overloads of functions like `Sema::ActOnMemberAccessExpr` to support the case where the right-hand of the member access is a splice. A special `CXXDependentMemberSpliceExpr` is introduced to cover cases when the reflection is dependent on a template parameter, in order to "hold" the underlying `CXXSpliceSpecifierExpr` until template substitution. ### Nested-name-specifiers containing splices -Splices of types and namespaces can appear as the (possibly dependent) leading component of a nested-name-specifier. This is interesting in cases such as `typename [:R:]::member`, for which the `typename` keyword clarifies that `member` will resolve to a type, but tells us nothing about what sort of entity `[:R:]` might be. We address this by adding a new `SpecifierKind::IndeterminateSplice` kind to `NestedNameSpecifier`, which holds a `CXXIndeterminateSpliceExpr` to be rebuilt thereafter into a namespace or type during template substitution. +Splices of types and namespaces can appear as the (possibly dependent) leading component of a nested-name-specifier. This is interesting in cases such as `typename [:R:]::member`, for which the `typename` keyword clarifies that `member` will resolve to a type, but tells us nothing about what sort of entity `[:R:]` might be. We address this by adding a new `SpecifierKind::IndeterminateSplice` kind to `NestedNameSpecifier`, which holds a `CXXSpliceSpecifierExpr` to be rebuilt thereafter into a namespace or type during template substitution. ### Splicing namespaces diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h index 464ac6acf0f827..e5fdf9d7c9c557 100644 --- a/clang/include/clang/AST/APValue.h +++ b/clang/include/clang/AST/APValue.h @@ -122,7 +122,8 @@ template<> struct PointerLikeTypeTraits { namespace clang { /// APValue - This class implements a discriminated union of [uninitialized] /// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset], -/// [Vector: N * APValue], [Array: N * APValue], [ReflectionValue] +/// [Vector: N * APValue], [Array: N * APValue], +/// [ReflectionKind + Ptr] class APValue { typedef llvm::APFixedPoint APFixedPoint; typedef llvm::APSInt APSInt; @@ -145,7 +146,7 @@ class APValue { Union, MemberPointer, AddrLabelDiff, - Reflection + Reflection, }; class LValueBase { @@ -308,76 +309,98 @@ class APValue { const AddrLabelExpr* LHSExpr; const AddrLabelExpr* RHSExpr; }; + struct ReflectionData { + ReflectionKind Kind; + const void *Data; + }; struct MemberPointerData; // We ensure elsewhere that Data is big enough for LV and MemberPointerData. typedef llvm::AlignedCharArrayUnion DataType; + ReflectionData> DataType; static const size_t DataSize = sizeof(DataType); DataType Data; + // A reflection can represent a value, but is also -itself- a value. + // + // When 'ReflectionDepth' is nonzero 'N', the APValue represents the otherwise + // described value with N "layers of reflection" over it. The otherwise + // equivalent APValue for which ReflectionDepth is zero is referred to as the + // "underlying value". Since two reflections of values are equivalent only if + // their types are the same, it becomes necessary to store the type of the + // underlying value ('UnderlyingTy'). + QualType UnderlyingTy; + uint8_t ReflectionDepth; + public: - APValue() : Kind(None) {} - explicit APValue(APSInt I) : Kind(None) { + APValue() : Kind(None), UnderlyingTy(), ReflectionDepth() {} + explicit APValue(APSInt I) : Kind(None), UnderlyingTy(), ReflectionDepth() { MakeInt(); setInt(std::move(I)); } - explicit APValue(APFloat F) : Kind(None) { + explicit APValue(APFloat F) : Kind(None), UnderlyingTy(), ReflectionDepth() { MakeFloat(); setFloat(std::move(F)); } - explicit APValue(APFixedPoint FX) : Kind(None) { + explicit APValue(APFixedPoint FX) + : Kind(None), UnderlyingTy(), ReflectionDepth() { MakeFixedPoint(std::move(FX)); } - explicit APValue(const APValue *E, unsigned N) : Kind(None) { + explicit APValue(const APValue *E, unsigned N) + : Kind(None), UnderlyingTy(), ReflectionDepth() { MakeVector(); setVector(E, N); } - APValue(APSInt R, APSInt I) : Kind(None) { + APValue(APSInt R, APSInt I) : Kind(None), UnderlyingTy(), ReflectionDepth() { MakeComplexInt(); setComplexInt(std::move(R), std::move(I)); } - APValue(APFloat R, APFloat I) : Kind(None) { + APValue(APFloat R, APFloat I) : Kind(None), UnderlyingTy(), ReflectionDepth() { MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I)); } APValue(const APValue &RHS); APValue(APValue &&RHS); APValue(LValueBase B, const CharUnits &O, NoLValuePath N, bool IsNullPtr = false) - : Kind(None) { + : Kind(None), UnderlyingTy(), ReflectionDepth() { MakeLValue(); setLValue(B, O, N, IsNullPtr); } APValue(LValueBase B, const CharUnits &O, ArrayRef Path, bool OnePastTheEnd, bool IsNullPtr = false) - : Kind(None) { + : Kind(None), UnderlyingTy(), ReflectionDepth() { MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr); } - APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(None) { + APValue(UninitArray, unsigned InitElts, unsigned Size) + : Kind(None), UnderlyingTy(), ReflectionDepth() { MakeArray(InitElts, Size); } - APValue(UninitStruct, unsigned B, unsigned M) : Kind(None) { + APValue(UninitStruct, unsigned B, unsigned M) + : Kind(None), UnderlyingTy(), ReflectionDepth() { MakeStruct(B, M); } explicit APValue(const FieldDecl *D, const APValue &V = APValue()) - : Kind(None) { + : Kind(None), UnderlyingTy(), ReflectionDepth() { MakeUnion(); setUnion(D, V); } APValue(const ValueDecl *Member, bool IsDerivedMember, - ArrayRef Path) : Kind(None) { + ArrayRef Path) + : Kind(None), UnderlyingTy(), ReflectionDepth() { MakeMemberPointer(Member, IsDerivedMember, Path); } APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr) - : Kind(None) { + : Kind(None), UnderlyingTy(), ReflectionDepth() { MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr); } - APValue(ReflectionValue RV) - : Kind(None) { - MakeReflection(RV); + APValue(ReflectionKind RK, const void *Data) + : Kind(None), UnderlyingTy(), ReflectionDepth() { + MakeReflection(); setReflection(RK, Data); } static APValue IndeterminateValue() { APValue Result; Result.Kind = Indeterminate; return Result; } + APValue Lift(QualType ResultType) const; + APValue Lower() const; APValue &operator=(const APValue &RHS); APValue &operator=(APValue &&RHS); @@ -402,25 +425,65 @@ class APValue { /// typically also be profiled if it's not implied by the context. void Profile(llvm::FoldingSetNodeID &ID) const; - ValueKind getKind() const { return Kind; } + ValueKind getKind() const { + return isReflection() ? Reflection : Kind; + } bool isAbsent() const { return Kind == None; } bool isIndeterminate() const { return Kind == Indeterminate; } bool hasValue() const { return Kind != None && Kind != Indeterminate; } - bool isInt() const { return Kind == Int; } - bool isFloat() const { return Kind == Float; } - bool isFixedPoint() const { return Kind == FixedPoint; } - bool isComplexInt() const { return Kind == ComplexInt; } - bool isComplexFloat() const { return Kind == ComplexFloat; } - bool isLValue() const { return Kind == LValue; } - bool isVector() const { return Kind == Vector; } - bool isArray() const { return Kind == Array; } - bool isStruct() const { return Kind == Struct; } - bool isUnion() const { return Kind == Union; } - bool isMemberPointer() const { return Kind == MemberPointer; } - bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; } - bool isReflection() const { return Kind == Reflection; } + bool isInt() const { return !isReflection() && Kind == Int; } + bool isFloat() const { return !isReflection() && Kind == Float; } + bool isFixedPoint() const { return !isReflection() && Kind == FixedPoint; } + bool isComplexInt() const { return !isReflection() && Kind == ComplexInt; } + bool isComplexFloat() const { + return !isReflection() && Kind == ComplexFloat; + } + bool isLValue() const { return !isReflection() && Kind == LValue; } + bool isVector() const { return !isReflection() && Kind == Vector; } + bool isArray() const { return !isReflection() && Kind == Array; } + bool isStruct() const { return !isReflection() && Kind == Struct; } + bool isUnion() const { return !isReflection() && Kind == Union; } + bool isMemberPointer() const { + return !isReflection() && Kind == MemberPointer; + } + bool isAddrLabelDiff() const { + return !isReflection() && Kind == AddrLabelDiff; + } + + bool isReflection() const { + return Kind == Reflection || getReflectionDepth() > 0; + } + bool isNullReflection() const { + return isReflection() && getReflectionKind() == ReflectionKind::Null; + } + bool isReflectedType() const { + return isReflection() && getReflectionKind() == ReflectionKind::Type; + } + bool isReflectedObject() const { + return isReflection() && getReflectionKind() == ReflectionKind::Object; + } + bool isReflectedValue() const { + return isReflection() && getReflectionKind() == ReflectionKind::Value; + } + bool isReflectedDecl() const { + return isReflection() && getReflectionKind() == ReflectionKind::Declaration; + } + bool isReflectedTemplate() const { + return isReflection() && getReflectionKind() == ReflectionKind::Template; + } + bool isReflectedNamespace() const { + return isReflection() && getReflectionKind() == ReflectionKind::Namespace; + } + bool isReflectedBaseSpecifier() const { + return isReflection() && + getReflectionKind() == ReflectionKind::BaseSpecifier; + } + bool isReflectedDataMemberSpec() const { + return isReflection() && + getReflectionKind() == ReflectionKind::DataMemberSpec; + } void dump() const; void dump(raw_ostream &OS, const ASTContext &Context) const; @@ -432,7 +495,7 @@ class APValue { std::string getAsString(const ASTContext &Ctx, QualType Ty) const; APSInt &getInt() { - assert(isInt() && "Invalid accessor"); + assert(Kind == Int && "Invalid accessor"); return *(APSInt *)(char *)&Data; } const APSInt &getInt() const { @@ -446,7 +509,7 @@ class APValue { const ASTContext &Ctx) const; APFloat &getFloat() { - assert(isFloat() && "Invalid accessor"); + assert(Kind == Float && "Invalid accessor"); return *(APFloat *)(char *)&Data; } const APFloat &getFloat() const { @@ -454,7 +517,7 @@ class APValue { } APFixedPoint &getFixedPoint() { - assert(isFixedPoint() && "Invalid accessor"); + assert(Kind == FixedPoint && "Invalid accessor"); return *(APFixedPoint *)(char *)&Data; } const APFixedPoint &getFixedPoint() const { @@ -462,7 +525,7 @@ class APValue { } APSInt &getComplexIntReal() { - assert(isComplexInt() && "Invalid accessor"); + assert(Kind == ComplexInt && "Invalid accessor"); return ((ComplexAPSInt *)(char *)&Data)->Real; } const APSInt &getComplexIntReal() const { @@ -470,7 +533,7 @@ class APValue { } APSInt &getComplexIntImag() { - assert(isComplexInt() && "Invalid accessor"); + assert(Kind == ComplexInt && "Invalid accessor"); return ((ComplexAPSInt *)(char *)&Data)->Imag; } const APSInt &getComplexIntImag() const { @@ -478,7 +541,7 @@ class APValue { } APFloat &getComplexFloatReal() { - assert(isComplexFloat() && "Invalid accessor"); + assert(Kind == ComplexFloat && "Invalid accessor"); return ((ComplexAPFloat *)(char *)&Data)->Real; } const APFloat &getComplexFloatReal() const { @@ -486,7 +549,7 @@ class APValue { } APFloat &getComplexFloatImag() { - assert(isComplexFloat() && "Invalid accessor"); + assert(Kind == ComplexFloat && "Invalid accessor"); return ((ComplexAPFloat *)(char *)&Data)->Imag; } const APFloat &getComplexFloatImag() const { @@ -506,7 +569,7 @@ class APValue { bool isNullPointer() const; APValue &getVectorElt(unsigned I) { - assert(isVector() && "Invalid accessor"); + assert(Kind == Vector && "Invalid accessor"); assert(I < getVectorLength() && "Index out of range"); return ((Vec *)(char *)&Data)->Elts[I]; } @@ -514,12 +577,12 @@ class APValue { return const_cast(this)->getVectorElt(I); } unsigned getVectorLength() const { - assert(isVector() && "Invalid accessor"); + assert(Kind == Vector && "Invalid accessor"); return ((const Vec *)(const void *)&Data)->NumElts; } APValue &getArrayInitializedElt(unsigned I) { - assert(isArray() && "Invalid accessor"); + assert(Kind == Array && "Invalid accessor"); assert(I < getArrayInitializedElts() && "Index out of range"); return ((Arr *)(char *)&Data)->Elts[I]; } @@ -530,7 +593,7 @@ class APValue { return getArrayInitializedElts() != getArraySize(); } APValue &getArrayFiller() { - assert(isArray() && "Invalid accessor"); + assert(Kind == Array && "Invalid accessor"); assert(hasArrayFiller() && "No array filler"); return ((Arr *)(char *)&Data)->Elts[getArrayInitializedElts()]; } @@ -538,29 +601,29 @@ class APValue { return const_cast(this)->getArrayFiller(); } unsigned getArrayInitializedElts() const { - assert(isArray() && "Invalid accessor"); + assert(Kind == Array && "Invalid accessor"); return ((const Arr *)(const void *)&Data)->NumElts; } unsigned getArraySize() const { - assert(isArray() && "Invalid accessor"); + assert(Kind == Array && "Invalid accessor"); return ((const Arr *)(const void *)&Data)->ArrSize; } unsigned getStructNumBases() const { - assert(isStruct() && "Invalid accessor"); + assert(Kind == Struct && "Invalid accessor"); return ((const StructData *)(const char *)&Data)->NumBases; } unsigned getStructNumFields() const { - assert(isStruct() && "Invalid accessor"); + assert(Kind == Struct && "Invalid accessor"); return ((const StructData *)(const char *)&Data)->NumFields; } APValue &getStructBase(unsigned i) { - assert(isStruct() && "Invalid accessor"); + assert(Kind == Struct && "Invalid accessor"); assert(i < getStructNumBases() && "base class index OOB"); return ((StructData *)(char *)&Data)->Elts[i]; } APValue &getStructField(unsigned i) { - assert(isStruct() && "Invalid accessor"); + assert(Kind == Struct && "Invalid accessor"); assert(i < getStructNumFields() && "field index OOB"); return ((StructData *)(char *)&Data)->Elts[getStructNumBases() + i]; } @@ -572,11 +635,11 @@ class APValue { } const FieldDecl *getUnionField() const { - assert(isUnion() && "Invalid accessor"); + assert(Kind == Union && "Invalid accessor"); return ((const UnionData *)(const char *)&Data)->Field; } APValue &getUnionValue() { - assert(isUnion() && "Invalid accessor"); + assert(Kind == Union && "Invalid accessor"); return *((UnionData *)(char *)&Data)->Value; } const APValue &getUnionValue() const { @@ -588,24 +651,23 @@ class APValue { ArrayRef getMemberPointerPath() const; const AddrLabelExpr* getAddrLabelDiffLHS() const { - assert(isAddrLabelDiff() && "Invalid accessor"); + assert(Kind == AddrLabelDiff && "Invalid accessor"); return ((const AddrLabelDiffData *)(const char *)&Data)->LHSExpr; } const AddrLabelExpr* getAddrLabelDiffRHS() const { - assert(isAddrLabelDiff() && "Invalid accessor"); + assert(Kind == AddrLabelDiff && "Invalid accessor"); return ((const AddrLabelDiffData *)(const char *)&Data)->RHSExpr; } - ReflectionValue &getReflection() { - assert(isReflection() && "Invalid accessor"); - return *(ReflectionValue *)(char *)&Data; - } - const ReflectionValue &getReflection() const { - return const_cast(this)->getReflection(); - } + unsigned getReflectionDepth() const { return ReflectionDepth; } + QualType getTypeOfReflectedResult(const ASTContext &Ctx) const; + + ReflectionKind getReflectionKind() const; + const void *getOpaqueReflectionData() const; + QualType getReflectedType() const; - const APValue &getReflectedObject() const; - const APValue &getReflectedValue() const; + APValue getReflectedObject() const; + APValue getReflectedValue() const; ValueDecl *getReflectedDecl() const; const TemplateName getReflectedTemplate() const; Decl *getReflectedNamespace() const; @@ -654,6 +716,7 @@ class APValue { ((AddrLabelDiffData *)(char *)&Data)->LHSExpr = LHSExpr; ((AddrLabelDiffData *)(char *)&Data)->RHSExpr = RHSExpr; } + void setReflection(ReflectionKind RK, const void *Data); private: void DestroyDataAndMakeUninit(); @@ -706,10 +769,10 @@ class APValue { new ((void *)(char *)&Data) AddrLabelDiffData(); Kind = AddrLabelDiff; } - void MakeReflection(ReflectionValue RV) { - assert(isAbsent() && "Bad state change"); - new ((void *)(char *)Data.buffer) ReflectionValue(RV); + void MakeReflection() { + assert(isAbsent() && "Bad state change"); + new ((void*)(char *)&Data) ReflectionData(); Kind = Reflection; } diff --git a/clang/include/clang/AST/AbstractBasicReader.h b/clang/include/clang/AST/AbstractBasicReader.h index 4e713b4c7fea9a..e7d8e698e41fc9 100644 --- a/clang/include/clang/AST/AbstractBasicReader.h +++ b/clang/include/clang/AST/AbstractBasicReader.h @@ -177,10 +177,6 @@ class DataStreamBasicReader : public BasicReaderBase { return llvm::APInt(bitWidth, numWords, &data[0]); } - ReflectionValue readReflectionValue() { - llvm_unreachable("unimplemented"); - } - llvm::FixedPointSemantics readFixedPointSemantics() { unsigned width = asImpl().readUInt32(); unsigned scale = asImpl().readUInt32(); diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 2957354425b6c5..bc707f562deaae 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -5328,26 +5328,28 @@ class CXXReflectExpr : public Expr { // The operand of the expression. OperandKind Kind; - llvm::AlignedCharArrayUnion Operand; + llvm::AlignedCharArrayUnion Operand; // Source locations. SourceLocation OperatorLoc; SourceRange OperandRange; - CXXReflectExpr(const ASTContext &C, QualType ExprTy, ReflectionValue RV); + CXXReflectExpr(const ASTContext &C, QualType ExprTy, APValue RV); CXXReflectExpr(const ASTContext &C, QualType ExprTy, Expr *DepSubExpr); public: static CXXReflectExpr *Create(ASTContext &C, SourceLocation OperatorLoc, - SourceRange OperandRange, ReflectionValue RV); + SourceRange OperandRange, APValue RV); static CXXReflectExpr *Create(ASTContext &C, SourceLocation OperatorLoc, Expr *DepSubExpr); /// Returns the operand of the reflection expression. - ReflectionValue getReflection() const { - return *(const ReflectionValue *)(const char *)&Operand; + APValue getReflection() const { + assert(Kind == OperandKind::Reflection); + return *(const APValue *)(const char *)&Operand; } Expr *getDependentSubExpr() const { + assert(Kind == OperandKind::DependentExpr); return *(Expr **)const_cast((const char *)&Operand); } bool hasDependentSubExpr() const { diff --git a/clang/include/clang/AST/PropertiesBase.td b/clang/include/clang/AST/PropertiesBase.td index a701f377aa43cd..e189a82f54f13c 100644 --- a/clang/include/clang/AST/PropertiesBase.td +++ b/clang/include/clang/AST/PropertiesBase.td @@ -136,8 +136,7 @@ def OverloadedOperatorKind : EnumPropertyType; def Qualifiers : PropertyType; def QualType : DefaultValuePropertyType; def RefQualifierKind : EnumPropertyType; -def ReflectionKind : EnumPropertyType<"ReflectionValue::ReflectionKind">; -def ReflectionValue : PropertyType { let PassByReference = 1; } +def ReflectionKind : EnumPropertyType<"ReflectionKind">; def Selector : PropertyType; def SourceLocation : PropertyType; def StmtRef : RefPropertyType<"Stmt"> { let ConstWhenWriting = 1; } @@ -264,86 +263,6 @@ class PropertyTypeCase : HasProperties { string Name = name; } -// Type cases for ReflectionValue. -def : PropertyTypeKind; -let Class = PropertyTypeCase in { - def : Creator<[{ - return ReflectionValue(); - }]>; -} -let Class = PropertyTypeCase in { - def : Property<"value", QualType> { - let Read = [{ node.getAsType() }]; - } - def : Creator<[{ - return ReflectionValue(ReflectionValue::RK_type, - value.getAsOpaquePtr()); - }]>; -} -let Class = PropertyTypeCase in { - def : Property<"value", APValue> { - let Read = [{ node.getAsObject() }]; - } - def : Creator<[{ - return ReflectionValue(ReflectionValue::RK_object, - new (ctx) APValue(value)); - }]>; -} -let Class = PropertyTypeCase in { - def : Property<"value", APValue> { - let Read = [{ node.getAsValue() }]; - } - def : Property<"type", QualType> { - let Read = [{ node.getResultType() }]; - } - def : Creator<[{ - return ReflectionValue(ReflectionValue::RK_value, - new (ctx) APValue(value), type); - }]>; -} -let Class = PropertyTypeCase in { - def : Property<"value", ValueDeclRef> { - let Read = [{ node.getAsDecl() }]; - } - def : Creator<[{ - return ReflectionValue(ReflectionValue::RK_declaration, value); - }]>; -} -let Class = PropertyTypeCase in { - def : Property<"value", TemplateName> { - let Read = [{ node.getAsTemplate() }]; - } - def : Creator<[{ - return ReflectionValue(ReflectionValue::RK_template, - value.getAsTemplateDecl()); - }]>; -} -let Class = PropertyTypeCase in { - def : Property<"value", DeclRef> { - let Read = [{ node.getAsNamespace() }]; - } - def : Creator<[{ - return ReflectionValue(ReflectionValue::RK_namespace, value); - }]>; -} -let Class = PropertyTypeCase in { - def : Property<"value", CXXBaseSpecifierRef> { - let Read = [{ node.getAsBaseSpecifier() }]; - } - def : Creator<[{ - return ReflectionValue(ReflectionValue::RK_base_specifier, value); - }]>; -} -let Class = PropertyTypeCase in { - def : Property<"value", TagDataMemberSpecRef> { - let Read = [{ node.getAsDataMemberSpec() }]; - } - def : Creator<[{ - return ReflectionValue(ReflectionValue::RK_data_member_spec, value); - }]>; -} - // Type cases for APValue. def : PropertyTypeKind; diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 6ede96421899f2..fcdd493c4a8f71 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2958,26 +2958,27 @@ DEF_TRAVERSE_STMT(CXXReflectExpr, { if (S->hasDependentSubExpr()) { TRY_TO(TraverseStmt(S->getDependentSubExpr())); } else { - ReflectionValue RV = S->getReflection(); - switch (RV.getKind()) { - case ReflectionValue::RK_type: { - TRY_TO(TraverseType(RV.getAsType())); + APValue RV = S->getReflection(); + assert(RV.isReflection()); + switch (RV.getReflectionKind()) { + case ReflectionKind::Type: { + TRY_TO(TraverseType(RV.getReflectedType())); break; } - case ReflectionValue::RK_declaration: { - TRY_TO(TraverseDecl(RV.getAsDecl())); + case ReflectionKind::Declaration: { + TRY_TO(TraverseDecl(RV.getReflectedDecl())); break; } - case ReflectionValue::RK_template: { - TRY_TO(TraverseTemplateName(RV.getAsTemplate())); + case ReflectionKind::Template: { + TRY_TO(TraverseTemplateName(RV.getReflectedTemplate())); break; } - case ReflectionValue::RK_null: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + case ReflectionKind::Null: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: break; } } diff --git a/clang/include/clang/AST/Reflection.h b/clang/include/clang/AST/Reflection.h index 621d60b0783535..98290a162b9277 100644 --- a/clang/include/clang/AST/Reflection.h +++ b/clang/include/clang/AST/Reflection.h @@ -31,153 +31,77 @@ class ValueDecl; struct TagDataMemberSpec; -/// \brief Representation of a reflection value holding an opaque pointer to one -/// or more entities. -class ReflectionValue { -public: - /// \brief The kind of construct reflected. - enum ReflectionKind { - /// \brief A null reflection. - /// - /// Corresponds to no object. - RK_null = 0, - - /// \brief A reflection of a type. - /// - /// Corresponds to a QualType. - RK_type, - - /// \brief A reflection of an object (i.e., the non-function result of an - /// lvalue). - /// - /// Corresponds to an APValue (plus a QualType). - RK_object, - - /// \brief A reflection of a value (i.e., the result of a prvalue). - /// - /// Corresponds to an APValue (plus a QualType). - RK_value, - - /// \brief A reflection of a language construct that has a declaration in - /// the Clang AST. - /// - /// Corresponds to a ValueDecl, which could be any of: - /// - a variable (i.e., VarDecl), - /// - a structured binding (i.e., BindingDecl), - /// - a function (i.e., FunctionDecl), - /// - an enumerator (i.e., EnumConstantDecl), - /// - a non-static data member or unnamed bit-field (i.e., FieldDecl), - RK_declaration, - - /// \brief A reflection of a template (e.g., class template, variable - /// template, function template, alias template, concept). - /// - /// Corresponds to a TemplateName. - RK_template, - - /// \brief A reflection of a namespace. - /// - /// Corresponds to a Decl, which could be any of: - /// - the global namespace (i.e., TranslationUnitDecl), - /// - a non-global namespace (i.e., NamespaceDecl), - /// - a namespace alias (i.e., NamespaceAliasDecl) - /// - /// Somewhat annoyingly, these classes have no nearer common ancestor than - /// the Decl class. - RK_namespace, - - /// \brief A reflection of a base class specifier. - /// - /// Corresponds to a CXXBaseSpecifier. - RK_base_specifier, - - /// \brief A reflection of a description of a hypothetical data member - /// (static or nonstatic) that might belong to a class or union. - /// - /// Corresponds to a TagDataMemberSpec. - /// - /// This is specifically used for the 'std::meta::data_member_spec' and - /// 'std::meta::define_class' metafunctions. If the surface area of - /// 'define_class' grows (i.e., supports additional types of "descriptions", - /// e.g., for member functions), it would be nice to find a more generic way - /// to do this. One idea is to allow a reflection of a type erased struct, - /// but the current design seems tolerable for now. - RK_data_member_spec, - }; - -private: - ReflectionKind Kind; - - void *Entity; - QualType ResultType; - -public: - ReflectionValue(); - ReflectionValue(ReflectionValue const&Rhs); - ReflectionValue(ReflectionKind ReflKind, void *Entity, - QualType ResultType = {}); - ReflectionValue &operator=(ReflectionValue const& Rhs); - - ReflectionKind getKind() const { - return Kind; - } - void *getOpaqueValue() const { - return Entity; - } - - /// Returns whether this is a null reflection. - bool isNull() const; - - /// Returns this as a type operand. - QualType getAsType() const; - - /// Returns this as an APValue having an lvalue designating an object. - const APValue &getAsObject() const; - - /// Returns this as an APValue representing a value. - const APValue &getAsValue() const; - - /// Returns the type of the object or value represented by the reflection. - QualType getResultType() const { - assert(getKind() == RK_value || getKind() == RK_object); - return ResultType; - } - - /// Returns this as a declaration that can hold a value. - ValueDecl *getAsDecl() const { - assert(getKind() == RK_declaration && "not a declaration reference"); - return reinterpret_cast(Entity); - } - - /// Returns this as a template name. - TemplateName getAsTemplate() const { - assert(getKind() == RK_template && "not a template"); - return TemplateName::getFromVoidPointer(const_cast(Entity)); - } - - /// Returns this as a namespace declaration. - Decl *getAsNamespace() const { - assert(getKind() == RK_namespace && "not a namespace"); - return reinterpret_cast(Entity); - } - - CXXBaseSpecifier *getAsBaseSpecifier() const { - assert(getKind() == RK_base_specifier && "not a base class specifier"); - return reinterpret_cast(Entity); - } - - /// Returns this as a struct describing a hypothetical data member. - TagDataMemberSpec *getAsDataMemberSpec() const { - assert(getKind() == RK_data_member_spec && "not a data member spec"); - return reinterpret_cast(Entity); - } - - void Profile(llvm::FoldingSetNodeID &ID) const; - - bool operator==(ReflectionValue const& Rhs) const; - bool operator!=(ReflectionValue const& Rhs) const; +/// \brief The kind of construct reflected. +enum class ReflectionKind { + /// \brief A null reflection. + /// + /// Corresponds to no object. + Null = 0, + + /// \brief A reflection of a type. + /// + /// Corresponds to a QualType. + Type, + + /// \brief A reflection of an object (i.e., the non-function result of an + /// lvalue). + /// + /// Corresponds to an APValue (plus a QualType). + Object, + + /// \brief A reflection of a value (i.e., the result of a prvalue). + /// + /// Corresponds to an APValue (plus a QualType). + Value, + + /// \brief A reflection of a language construct that has a declaration in + /// the Clang AST. + /// + /// Corresponds to a ValueDecl, which could be any of: + /// - a variable (i.e., VarDecl), + /// - a structured binding (i.e., BindingDecl), + /// - a function (i.e., FunctionDecl), + /// - an enumerator (i.e., EnumConstantDecl), + /// - a non-static data member or unnamed bit-field (i.e., FieldDecl), + Declaration, + + /// \brief A reflection of a template (e.g., class template, variable + /// template, function template, alias template, concept). + /// + /// Corresponds to a TemplateName. + Template, + + /// \brief A reflection of a namespace. + /// + /// Corresponds to a Decl, which could be any of: + /// - the global namespace (i.e., TranslationUnitDecl), + /// - a non-global namespace (i.e., NamespaceDecl), + /// - a namespace alias (i.e., NamespaceAliasDecl) + /// + /// Somewhat annoyingly, these classes have no nearer common ancestor than + /// the Decl class. + Namespace, + + /// \brief A reflection of a base class specifier. + /// + /// Corresponds to a CXXBaseSpecifier. + BaseSpecifier, + + /// \brief A reflection of a description of a hypothetical data member + /// (static or nonstatic) that might belong to a class or union. + /// + /// Corresponds to a TagDataMemberSpec. + /// + /// This is specifically used for the 'std::meta::data_member_spec' and + /// 'std::meta::define_class' metafunctions. If the surface area of + /// 'define_class' grows (i.e., supports additional types of "descriptions", + /// e.g., for member functions), it would be nice to find a more generic way + /// to do this. One idea is to allow a reflection of a type erased struct, + /// but the current design seems tolerable for now. + DataMemberSpec, }; + /// \brief Representation of a hypothetical data member, which could be used to /// complete an incomplete class definition using the 'std::meta::define_class' /// standard library function. @@ -192,7 +116,6 @@ struct TagDataMemberSpec { bool operator==(TagDataMemberSpec const& Rhs) const; bool operator!=(TagDataMemberSpec const& Rhs) const; }; - } // namespace clang #endif diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 0d1aa9fa392565..ea1eec7df76493 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -7054,8 +7054,8 @@ class PackExpansionType : public Type, public llvm::FoldingSetNode { /// Represents a type formed by evaluating a reflection splice (C++2c, P2996). /// /// A reflection splice wraps a potentially dependent constant expression whose -/// resulting APValue holds a ReflectionValue; this is expected to hold a type -/// in the context of a 'ReflectionSpliceType'. +/// resulting APValue is a reflection; this is expected to hold a type in the +/// context of a 'ReflectionSpliceType'. class ReflectionSpliceType : public Type { Expr *Operand; QualType UnderlyingTy; diff --git a/clang/include/clang/Serialization/ASTRecordWriter.h b/clang/include/clang/Serialization/ASTRecordWriter.h index 480859f70bb2d0..5e3954c0bc31ba 100644 --- a/clang/include/clang/Serialization/ASTRecordWriter.h +++ b/clang/include/clang/Serialization/ASTRecordWriter.h @@ -183,11 +183,6 @@ class ASTRecordWriter /// Emit an APvalue. void AddAPValue(const APValue &Value) { writeAPValue(Value); } - /// Emit a ReflectionValue. - void AddReflectionValue(const ReflectionValue &Value) { - writeReflectionValue(Value); - } - /// Emit a reference to an identifier. void AddIdentifierRef(const IdentifierInfo *II) { return Writer->AddIdentifierRef(II, *Record); diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp index 62e1906b0e77fa..3988a586881a8a 100644 --- a/clang/lib/AST/APValue.cpp +++ b/clang/lib/AST/APValue.cpp @@ -19,9 +19,11 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/LocInfoType.h" #include "clang/AST/Type.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" +#include using namespace clang; /// The identity of a type_info object depends on the canonical unqualified @@ -310,11 +312,12 @@ APValue::UnionData::~UnionData () { delete Value; } -APValue::APValue(const APValue &RHS) : Kind(None) { - switch (RHS.getKind()) { +APValue::APValue(const APValue &RHS) + : Kind(None), UnderlyingTy(), ReflectionDepth() { + switch (RHS.Kind) { case None: case Indeterminate: - Kind = RHS.getKind(); + Kind = RHS.Kind; break; case Int: MakeInt(); @@ -378,14 +381,19 @@ APValue::APValue(const APValue &RHS) : Kind(None) { MakeAddrLabelDiff(); setAddrLabelDiff(RHS.getAddrLabelDiffLHS(), RHS.getAddrLabelDiffRHS()); break; - case Reflection: { - MakeReflection(RHS.getReflection()); + case Reflection: + MakeReflection(); + setReflection(((const ReflectionData *)(const char *)&RHS.Data)->Kind, + RHS.getOpaqueReflectionData()); break; } - } + ReflectionDepth = RHS.ReflectionDepth; + UnderlyingTy = RHS.UnderlyingTy; } -APValue::APValue(APValue &&RHS) : Kind(RHS.Kind), Data(RHS.Data) { +APValue::APValue(APValue &&RHS) + : Kind(RHS.Kind), Data(RHS.Data), + UnderlyingTy(RHS.UnderlyingTy), ReflectionDepth(RHS.ReflectionDepth) { RHS.Kind = None; } @@ -401,6 +409,8 @@ APValue &APValue::operator=(APValue &&RHS) { DestroyDataAndMakeUninit(); Kind = RHS.Kind; Data = RHS.Data; + UnderlyingTy = RHS.UnderlyingTy; + ReflectionDepth = RHS.ReflectionDepth; RHS.Kind = None; } return *this; @@ -431,20 +441,22 @@ 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; } bool APValue::needsCleanup() const { - switch (getKind()) { + switch (Kind) { case None: case Indeterminate: case AddrLabelDiff: - case Reflection: return false; case Struct: case Union: case Array: case Vector: + case Reflection: return true; case Int: return getInt().needsCleanup(); @@ -475,6 +487,8 @@ bool APValue::needsCleanup() const { void APValue::swap(APValue &RHS) { std::swap(Kind, RHS.Kind); std::swap(Data, RHS.Data); + std::swap(UnderlyingTy, RHS.UnderlyingTy); + std::swap(ReflectionDepth, RHS.ReflectionDepth); } /// Profile the value of an APInt, excluding its bit-width. @@ -483,6 +497,78 @@ 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) { + while (V.getReflectionDepth() > 0) + V = V.Lower(); + + ID.AddInteger(static_cast(V.getReflectionKind())); + + switch (V.getReflectionKind()) { + case ReflectionKind::Null: + return; + case ReflectionKind::Type: { + QualType QT = V.getReflectedType(); + QT.getQualifiers().Profile(ID); + + if (auto *TST = dyn_cast(QT)) { + // Note: This sugar only kept for alias template specializations. + ID.AddInteger(Type::TemplateSpecialization); + ID.AddPointer(TST->getTemplateName().getAsTemplateDecl()); + if (auto *D = QT->getAsRecordDecl()) + ID.AddPointer(D->getCanonicalDecl()); + } else { + ID.AddInteger(0); + if (auto *TDT = dyn_cast(QT)) { + ID.AddBoolean(true); + ID.AddPointer(TDT->getDecl()); + } else { + ID.AddBoolean(false); + QT.getCanonicalType().Profile(ID); + } + } + return; + } + case ReflectionKind::Declaration: + if (auto *PVD = dyn_cast(V.getReflectedDecl())) { + auto *FD = cast(PVD->getDeclContext())->getFirstDecl(); + PVD = FD->getParamDecl(PVD->getFunctionScopeIndex()); + ID.AddPointer(PVD); + } else { + ID.AddPointer(V.getReflectedDecl()); + } + return; + case ReflectionKind::Template: { + TemplateDecl *TDecl = V.getReflectedTemplate().getAsTemplateDecl(); + if (auto *RTD = dyn_cast(TDecl)) + TDecl = RTD->getCanonicalDecl(); + ID.AddPointer(TDecl); + return; + } + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + ID.AddPointer(V.getOpaqueReflectionData()); + return; + case ReflectionKind::DataMemberSpec: { + TagDataMemberSpec *TDMS = V.getReflectedDataMemberSpec(); + TDMS->Ty.Profile(ID); + ID.AddBoolean(TDMS->Name.has_value()); + if (TDMS->Name) + ID.AddString(TDMS->Name.value()); + ID.AddBoolean(TDMS->Alignment.has_value()); + if (TDMS->Alignment) + ID.AddInteger(TDMS->Alignment.value()); + ID.AddBoolean(TDMS->BitWidth.has_value()); + if (TDMS->BitWidth) + ID.AddInteger(TDMS->BitWidth.value()); + return; + } + case ReflectionKind::Object: + case ReflectionKind::Value: + llvm_unreachable("lowered value should never represent a value or object"); + } + llvm_unreachable("unknown reflection kind"); +} + 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 @@ -491,6 +577,11 @@ void APValue::Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(Kind); + // Profile the reflection depth and underlying type (if any). + ID.AddInteger(ReflectionDepth); + if (isReflectedValue()) + UnderlyingTy.getCanonicalType().getUnqualifiedType().Profile(ID); + switch (Kind) { case None: case Indeterminate: @@ -622,43 +713,220 @@ void APValue::Profile(llvm::FoldingSetNodeID &ID) const { ID.AddPointer(D); return; case Reflection: - getReflection().Profile(ID); + profileReflection(ID, *this); return; } llvm_unreachable("Unknown APValue kind!"); } +QualType APValue::getTypeOfReflectedResult(const ASTContext &C) const { + assert((isReflectedValue() || isReflectedObject()) && + "not a reflection of a value or object"); + if (getReflectionDepth() == 1) + return UnderlyingTy; + return C.MetaInfoTy; +} + +ReflectionKind APValue::getReflectionKind() const { + assert(isReflection() && "not a reflection value"); + + switch (getReflectionDepth()) { + // In case '0', this is a reflection of something other than a value or an + // object. Its kind is stored in the Data of the APValue. + case 0: { + ReflectionKind RK = ((const ReflectionData *)(const char *)&Data)->Kind; + assert((RK != ReflectionKind::Value && RK != ReflectionKind::Object) && + "Value and Object should never be stored as Kind"); + + return RK; + } + + // In case '1', this is either a reflection of a value or of an object. + // A few cases need to be considered to determine which. + case 1: + // If no type was provided, then the type must be inferrable from the + // LValue. IT must be an object. + if (UnderlyingTy.isNull()) { + return ReflectionKind::Object; + + // Any APValue which is not an LValue is assumed to be a value. + } else if (Kind == LValue) { + + // Handle the odd nullptr_t corner case, which is a value. + if (getLValueBase().isNull()) + return ReflectionKind::Value; + + // The only other LValue-kind APValues that we consider values are those + // that are pointers. For anything else, consider it an object. + else if (!UnderlyingTy->isPointerType()) + return ReflectionKind::Object; + + // We were give a pointer type, and we'll need to do some work to + // disambiguate between a value and an object. + // + // - A pointer value will be an LValue whose "thing it is pointing to" + // has a different type than itself (e.g., int * vs int). + // - An object that happens to have pointer type will be an LValue whose + // (normalized) type is the same as its 'UnderlyingTy'. + const Type *LVTy = nullptr; + + // If we have an LValuePath, use the type of the back-most path element. + if (hasLValuePath() && getLValuePath().size() > 0) { + const LValuePathEntry &E = getLValuePath().back(); + if (const auto *D = E.getAsBaseOrMember().getPointer()) { + if (auto *FD = dyn_cast(D)) + LVTy = FD->getType()->getCanonicalTypeUnqualified().getTypePtr(); + else if (auto *TD = dyn_cast(D)) + LVTy = TD->getTypeForDecl() + ->getCanonicalTypeUnqualified().getTypePtr(); + } + } + + // Otherwise, use the type of the LValueBase. + if (!LVTy) { + if (auto *B = getLValueBase().dyn_cast()) { + LVTy = B->getType()->getCanonicalTypeUnqualified().getTypePtr(); + } else if (auto *B = getLValueBase().dyn_cast()) { + LVTy = B->getType()->getCanonicalTypeUnqualified().getTypePtr(); + } + } + assert(LVTy); + + // Equivalent types means it's an object; otherwise, assume a value. + if (LVTy == UnderlyingTy->getCanonicalTypeUnqualified().getTypePtr()) { + return ReflectionKind::Object; + } + } + return ReflectionKind::Value; + default: + // Any APValue whose reflection depth is higher than 1 is a reflection of + // a value; the type is 'std::meta::info'. + return ReflectionKind::Value; + } +} + +static QualType ComputeLValueType(const APValue &V) { + assert(V.isLValue()); + if (V.getLValueBase().isNull()) + return QualType {}; + + SplitQualType SQT = V.getLValueBase().getType().split(); + + for (auto p = V.getLValuePath().begin(); + p != V.getLValuePath().end(); ++p) { + const Decl *D = V.getLValuePath().back().getAsBaseOrMember().getPointer(); + if (D) { // base or member case + if (auto *VD = dyn_cast(D)) { + QualType QT = VD->getType(); + SQT.Ty = QT.getTypePtr(); + + if (QT.isConstQualified()) SQT.Quals.addConst(); + if (QT.isVolatileQualified()) SQT.Quals.addVolatile(); + + continue; + } else if (auto *TD = dyn_cast(D)) { + SQT.Ty = TD->getTypeForDecl(); + continue; + } + + llvm_unreachable("unknown lvalue path kind"); + } else { // array case + QualType QT = cast(SQT.Ty)->getElementType(); + SQT.Ty = QT.getTypePtr(); + if (QT.isConstQualified()) SQT.Quals.addConst(); + if (QT.isVolatileQualified()) SQT.Quals.addVolatile(); + } + } + return QualType(SQT.Ty, SQT.Quals.getAsOpaqueValue()); +} + +APValue APValue::Lift(QualType ResultType) const { + assert(ReflectionDepth < + std::numeric_limits::max()); + + // TODO: Special case for lvalues referring to functions? + // Should be "promoted" to a reflection of the function declaration. + + APValue Result(*this); + ++Result.ReflectionDepth; + + if (Result.ReflectionDepth == 1) { + Result.UnderlyingTy = ResultType; + + if (Result.isReflectedObject()) + Result.UnderlyingTy = ComputeLValueType(*this); + else + assert(Result.isReflectedValue() && "not a value or an object?"); + } + return Result; +} + +APValue APValue::Lower() const { + assert(getReflectionDepth() > 0 && "not a reflection"); + + APValue Result(*this); + --Result.ReflectionDepth; + return Result; +} + +const void *APValue::getOpaqueReflectionData() const { + assert(isReflection() && "not a reflection value"); + return ((const ReflectionData *)(const void *)&Data)->Data; +} + QualType APValue::getReflectedType() const { - return getReflection().getAsType(); + assert(getReflectionKind() == ReflectionKind::Type && + "not a reflection of a type"); + return QualType::getFromOpaquePtr(getOpaqueReflectionData()); } -const APValue &APValue::getReflectedObject() const { - return getReflection().getAsObject(); +APValue APValue::getReflectedObject() const { + assert(getReflectionKind() == ReflectionKind::Object && + "not a reflection of an object"); + assert(getReflectionKind() == ReflectionKind::Object); + return Lower(); } -const APValue &APValue::getReflectedValue() const { - return getReflection().getAsValue(); +APValue APValue::getReflectedValue() const { + assert(getReflectionKind() == ReflectionKind::Value && + "not a reflection of a value"); + return Lower(); } ValueDecl *APValue::getReflectedDecl() const { - return getReflection().getAsDecl(); + assert(getReflectionKind() == ReflectionKind::Declaration && + "not a reflection of a declaration"); + return reinterpret_cast( + const_cast(getOpaqueReflectionData())); } const TemplateName APValue::getReflectedTemplate() const { - return getReflection().getAsTemplate(); + assert(getReflectionKind() == ReflectionKind::Template && + "not a reflection of a template"); + return TemplateName::getFromVoidPointer( + const_cast(getOpaqueReflectionData())); } Decl *APValue::getReflectedNamespace() const { - return getReflection().getAsNamespace(); + assert(getReflectionKind() == ReflectionKind::Namespace && + "not a reflection of a namespace"); + return reinterpret_cast( + const_cast(getOpaqueReflectionData())); } CXXBaseSpecifier *APValue::getReflectedBaseSpecifier() const { - return getReflection().getAsBaseSpecifier(); + assert(getReflectionKind() == ReflectionKind::BaseSpecifier && + "not a reflection of a base specifier"); + return reinterpret_cast( + const_cast(getOpaqueReflectionData())); } TagDataMemberSpec *APValue::getReflectedDataMemberSpec() const { - return getReflection().getAsDataMemberSpec(); + assert(getReflectionKind() == ReflectionKind::DataMemberSpec && + "not a reflection of a description of a data member"); + return reinterpret_cast( + const_cast(getOpaqueReflectionData())); } static double GetApproxValue(const llvm::APFloat &F) { @@ -749,7 +1017,7 @@ void APValue::printPretty(raw_ostream &Out, const PrintingPolicy &Policy, if (const auto *AT = Ty->getAs()) Ty = AT->getValueType(); - switch (getKind()) { + switch (Kind) { case APValue::None: Out << ""; return; @@ -982,34 +1250,33 @@ void APValue::printPretty(raw_ostream &Out, const PrintingPolicy &Policy, Out << "&&" << getAddrLabelDiffRHS()->getLabel()->getName(); return; case APValue::Reflection: - const ReflectionValue& Refl = getReflection(); - std::string Repr("..."); - switch (Refl.getKind()) { - case ReflectionValue::RK_null: + std::string Repr("unknown-reflection"); + switch (getReflectionKind()) { + case ReflectionKind::Null: Repr = "null"; break; - case ReflectionValue::RK_type: + case ReflectionKind::Type: Repr = "type"; break; - case ReflectionValue::RK_object: + case ReflectionKind::Object: Repr = "object"; break; - case ReflectionValue::RK_value: + case ReflectionKind::Value: Repr = "value"; break; - case ReflectionValue::RK_declaration: + case ReflectionKind::Declaration: Repr = "declaration"; break; - case ReflectionValue::RK_template: + case ReflectionKind::Template: Repr = "template"; break; - case ReflectionValue::RK_namespace: + case ReflectionKind::Namespace: Repr = "namespace"; break; - case ReflectionValue::RK_base_specifier: + case ReflectionKind::BaseSpecifier: Repr = "base-specifier"; break; - case ReflectionValue::RK_data_member_spec: + case ReflectionKind::DataMemberSpec: Repr = "data-member-spec"; break; } @@ -1048,43 +1315,43 @@ bool APValue::toIntegralConstant(APSInt &Result, QualType SrcTy, } const APValue::LValueBase APValue::getLValueBase() const { - assert(isLValue() && "Invalid accessor"); + assert(Kind == LValue && "Invalid accessor"); return ((const LV *)(const void *)&Data)->Base; } bool APValue::isLValueOnePastTheEnd() const { - assert(isLValue() && "Invalid accessor"); + assert(Kind == LValue && "Invalid accessor"); return ((const LV *)(const void *)&Data)->IsOnePastTheEnd; } CharUnits &APValue::getLValueOffset() { - assert(isLValue() && "Invalid accessor"); + assert(Kind == LValue && "Invalid accessor"); return ((LV *)(void *)&Data)->Offset; } bool APValue::hasLValuePath() const { - assert(isLValue() && "Invalid accessor"); + assert(Kind == LValue && "Invalid accessor"); return ((const LV *)(const char *)&Data)->hasPath(); } ArrayRef APValue::getLValuePath() const { - assert(isLValue() && hasLValuePath() && "Invalid accessor"); + assert(Kind == LValue && hasLValuePath() && "Invalid accessor"); const LV &LVal = *((const LV *)(const char *)&Data); return llvm::ArrayRef(LVal.getPath(), LVal.PathLength); } unsigned APValue::getLValueCallIndex() const { - assert(isLValue() && "Invalid accessor"); + assert(Kind == LValue && "Invalid accessor"); return ((const LV *)(const char *)&Data)->Base.getCallIndex(); } unsigned APValue::getLValueVersion() const { - assert(isLValue() && "Invalid accessor"); + assert(Kind == LValue && "Invalid accessor"); return ((const LV *)(const char *)&Data)->Base.getVersion(); } bool APValue::isNullPointer() const { - assert(isLValue() && "Invalid usage"); + assert(Kind == LValue && "Invalid usage"); return ((const LV *)(const char *)&Data)->IsNullPtr; } @@ -1131,21 +1398,21 @@ void APValue::setUnion(const FieldDecl *Field, const APValue &Value) { } const ValueDecl *APValue::getMemberPointerDecl() const { - assert(isMemberPointer() && "Invalid accessor"); + assert(Kind == MemberPointer && "Invalid accessor"); const MemberPointerData &MPD = *((const MemberPointerData *)(const char *)&Data); return MPD.MemberAndIsDerivedMember.getPointer(); } bool APValue::isMemberPointerToDerivedMember() const { - assert(isMemberPointer() && "Invalid accessor"); + assert(Kind == MemberPointer && "Invalid accessor"); const MemberPointerData &MPD = *((const MemberPointerData *)(const char *)&Data); return MPD.MemberAndIsDerivedMember.getInt(); } ArrayRef APValue::getMemberPointerPath() const { - assert(isMemberPointer() && "Invalid accessor"); + assert(Kind == MemberPointer && "Invalid accessor"); const MemberPointerData &MPD = *((const MemberPointerData *)(const char *)&Data); return llvm::ArrayRef(MPD.getPath(), MPD.PathLength); @@ -1285,3 +1552,79 @@ LinkageInfo LinkageComputer::getLVForValue(const APValue &V, return LV; } + +static QualType unwrapReflectedType(QualType QT) { + bool UnwrapAliases = false; + bool IsConst = QT.isConstQualified(); + bool IsVolatile = QT.isVolatileQualified(); + + void *AsPtr; + do { + AsPtr = QT.getAsOpaquePtr(); + + if (const auto *LIT = dyn_cast(QT)) + QT = LIT->getType(); + if (const auto *ET = dyn_cast(QT)) { + QualType New = ET->getNamedType(); + New.setLocalFastQualifiers(QT.getLocalFastQualifiers()); + QT = New; + } + if (const auto *STTPT = dyn_cast(QT); + STTPT && !STTPT->isDependentType()) + QT = STTPT->getReplacementType(); + if (const auto *RST = dyn_cast(QT); + RST && !RST->isDependentType()) + QT = RST->getUnderlyingType(); + if (const auto *TST = dyn_cast(QT); + TST && !TST->isTypeAlias()) { + QT = TST->desugar(); + } + if (const auto *DTST = dyn_cast(QT)) + QT = DTST->getDeducedType(); + if (const auto *DTT = dyn_cast(QT)) { + QT = DTT->desugar(); + UnwrapAliases = true; + } + if (const auto *UT = dyn_cast(QT); + UT && UnwrapAliases) + QT = UT->desugar(); + if (const auto *TDT = dyn_cast(QT); + TDT && UnwrapAliases) + QT = TDT->desugar(); + } while (QT.getAsOpaquePtr() != AsPtr); + + if (IsConst) + QT = QT.withConst(); + if (IsVolatile) + QT = QT.withVolatile(); + + return QT; +} + +void APValue::setReflection(ReflectionKind RK, const void *Ptr) { + ReflectionData &SelfData = *((ReflectionData *)(char *)&Data); + switch (RK) { + case ReflectionKind::Null: + SelfData.Kind = RK; + return; + case ReflectionKind::Type: { + QualType QT = unwrapReflectedType(QualType::getFromOpaquePtr(Ptr)); + + SelfData.Kind = RK; + SelfData.Data = QT.getAsOpaquePtr(); + return; + } + case ReflectionKind::Declaration: + case ReflectionKind::Template: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: + SelfData.Kind = RK; + SelfData.Data = Ptr; + return; + case ReflectionKind::Object: + case ReflectionKind::Value: + return; + } + assert(RK == ReflectionKind::Null && "unknown reflection kind"); +} diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp index 7e810135a7596e..dfd7b52aff5697 100644 --- a/clang/lib/AST/ASTDiagnostic.cpp +++ b/clang/lib/AST/ASTDiagnostic.cpp @@ -577,8 +577,6 @@ class TemplateDiff { TemplateTemplate, /// Integer difference Integer, - /// Reflection difference - Reflection, /// Declaration difference, nullptr arguments are included here Declaration, /// One argument being integer and the other being declaration @@ -594,9 +592,7 @@ class TemplateDiff { QualType ArgType; Qualifiers Qual; llvm::APSInt Val; - ReflectionValue *Refl; bool IsValidInt = false; - bool IsValidRefl = false; Expr *ArgExpr = nullptr; TemplateDecl *TD = nullptr; ValueDecl *VD = nullptr; @@ -704,25 +700,6 @@ class TemplateDiff { SetDefault(FromDefault, ToDefault); } - void SetReflectionDiff(ReflectionValue *FromRefl, - ReflectionValue *ToRefl, - bool IsValidFromRefl, bool IsValidToRefl, - QualType MetaInfoType, - Expr *FromExpr, Expr *ToExpr, bool FromDefault, - bool ToDefault) { - assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty."); - FlatTree[CurrentNode].Kind = Reflection; - FlatTree[CurrentNode].FromArgInfo.Refl = FromRefl; - FlatTree[CurrentNode].ToArgInfo.Refl = ToRefl; - FlatTree[CurrentNode].FromArgInfo.IsValidRefl = IsValidFromRefl; - FlatTree[CurrentNode].ToArgInfo.IsValidRefl = IsValidToRefl; - FlatTree[CurrentNode].FromArgInfo.ArgType = MetaInfoType; - FlatTree[CurrentNode].ToArgInfo.ArgType = MetaInfoType; - FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr; - FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr; - SetDefault(FromDefault, ToDefault); - } - void SetDeclarationDiff(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl, bool FromAddressOf, bool ToAddressOf, bool FromNullPtr, bool ToNullPtr, Expr *FromExpr, @@ -1236,8 +1213,6 @@ class TemplateDiff { NonTypeTemplateParmDecl *Default, llvm::APSInt &Value, bool &HasInt, QualType &IntType, bool &IsNullPtr, - bool &HasReflection, - ReflectionValue *&ReflValue, Expr *&E, ValueDecl *&VD, bool &NeedAddressOf) { if (!Iter.isEnd()) { @@ -1331,26 +1306,21 @@ class TemplateDiff { Expr *FromExpr = nullptr, *ToExpr = nullptr; llvm::APSInt FromInt, ToInt; QualType FromIntType, ToIntType; - ReflectionValue *FromRefl, *ToRefl; ValueDecl *FromValueDecl = nullptr, *ToValueDecl = nullptr; bool HasFromInt = false, HasToInt = false, FromNullPtr = false, - ToNullPtr = false, NeedFromAddressOf = false, NeedToAddressOf = false, - HasFromRefl = false, HasToRefl = false; + ToNullPtr = false, NeedFromAddressOf = false, NeedToAddressOf = false; InitializeNonTypeDiffVariables( Context, FromIter, FromDefaultNonTypeDecl, FromInt, HasFromInt, - FromIntType, FromNullPtr, HasFromRefl, FromRefl, FromExpr, - FromValueDecl, NeedFromAddressOf); + FromIntType, FromNullPtr, FromExpr, FromValueDecl, NeedFromAddressOf); InitializeNonTypeDiffVariables(Context, ToIter, ToDefaultNonTypeDecl, ToInt, - HasToInt, ToIntType, ToNullPtr, HasToRefl, - ToRefl, ToExpr, ToValueDecl, - NeedToAddressOf); + HasToInt, ToIntType, ToNullPtr, ToExpr, + ToValueDecl, NeedToAddressOf); bool FromDefault = FromIter.isEnd() && (FromExpr || FromValueDecl || HasFromInt || - FromNullPtr || HasFromRefl); + FromNullPtr); bool ToDefault = ToIter.isEnd() && - (ToExpr || ToValueDecl || HasToInt || HasToRefl || - ToNullPtr); + (ToExpr || ToValueDecl || HasToInt || ToNullPtr); bool FromDeclaration = FromValueDecl || FromNullPtr; bool ToDeclaration = ToValueDecl || ToNullPtr; @@ -1382,24 +1352,6 @@ class TemplateDiff { return; } - if (FromDeclaration && HasToRefl) { - llvm_unreachable("unimplemented"); - } - - if (HasFromRefl && ToDeclaration) { - llvm_unreachable("unimplemented"); - } - - if (HasFromRefl || HasToRefl) { - Tree.SetReflectionDiff(FromRefl, ToRefl, HasFromRefl, HasToRefl, - Context.MetaInfoTy, FromExpr, ToExpr, - FromDefault, ToDefault); - if (HasFromRefl && HasToRefl) { - Tree.SetSame(FromRefl == ToRefl); - } - return; - } - if (FromDeclaration || ToDeclaration) { Tree.SetDeclarationDiff(FromValueDecl, ToValueDecl, NeedFromAddressOf, NeedToAddressOf, FromNullPtr, ToNullPtr, FromExpr, @@ -1609,10 +1561,6 @@ class TemplateDiff { Tree.ToDefault(), Tree.NodeIsSame()); return; } - case DiffTree::Reflection: { - llvm_unreachable("unimplemented"); - return; - } case DiffTree::Declaration: { ValueDecl *FromValueDecl, *ToValueDecl; bool FromAddressOf, ToAddressOf; diff --git a/clang/lib/AST/ComputeDependence.cpp b/clang/lib/AST/ComputeDependence.cpp index 0142e422334908..dfcf0201dd692d 100644 --- a/clang/lib/AST/ComputeDependence.cpp +++ b/clang/lib/AST/ComputeDependence.cpp @@ -945,11 +945,11 @@ ExprDependence clang::computeDependence(CXXReflectExpr *E, if (E->hasDependentSubExpr()) return E->getDependentSubExpr()->getDependence(); - ReflectionValue RV = E->getReflection(); + APValue RV = E->getReflection(); ExprDependence D = ExprDependence::None; - switch (RV.getKind()) { - case ReflectionValue::RK_type: { - QualType T = RV.getAsType(); + switch (RV.getReflectionKind()) { + case ReflectionKind::Type: { + QualType T = RV.getReflectedType(); if (T->isDependentType()) D |= ExprDependence::ValueInstantiation; @@ -957,16 +957,16 @@ ExprDependence clang::computeDependence(CXXReflectExpr *E, D |= ExprDependence::UnexpandedPack; return D; } - case ReflectionValue::RK_declaration: { - ValueDecl *VD = RV.getAsDecl(); + case ReflectionKind::Declaration: { + ValueDecl *VD = RV.getReflectedDecl(); if (VD->getType()->isDependentType()) D |= ExprDependence::ValueInstantiation; if (VD->getType()->containsUnexpandedParameterPack()) D |= ExprDependence::UnexpandedPack; return D | computeDeclDependence(VD, Ctx); } - case ReflectionValue::RK_template: { - const TemplateName Template = RV.getAsTemplate(); + case ReflectionKind::Template: { + const TemplateName Template = RV.getReflectedTemplate(); if (Template.isDependent()) D |= ExprDependence::ValueInstantiation; @@ -976,12 +976,12 @@ ExprDependence clang::computeDependence(CXXReflectExpr *E, D |= ExprDependence::UnexpandedPack; return D; } - case ReflectionValue::RK_null: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + case ReflectionKind::Null: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return ExprDependence::None; } llvm_unreachable("unknown reflection kind while computing dependence"); diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index 6815eb0809fb76..a8c870c4c9d869 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -1889,11 +1889,12 @@ TypeTraitExpr *TypeTraitExpr::CreateDeserialized(const ASTContext &C, return new (Mem) TypeTraitExpr(EmptyShell()); } -CXXReflectExpr::CXXReflectExpr(const ASTContext &C, QualType ExprTy, - ReflectionValue RV) +CXXReflectExpr::CXXReflectExpr(const ASTContext &C, QualType ExprTy, APValue RV) : Expr(CXXReflectExprClass, ExprTy, VK_PRValue, OK_Ordinary), Kind(OperandKind::Reflection) { - new ((void *)(char *)&Operand) ReflectionValue(RV); + assert(RV.isReflection()); + + new ((void *)(char *)&Operand) APValue(RV); setDependence(computeDependence(this, C)); } @@ -1901,17 +1902,16 @@ CXXReflectExpr::CXXReflectExpr(const ASTContext &C, QualType ExprTy, Expr *DepSubExpr) : Expr(CXXReflectExprClass, ExprTy, VK_PRValue, OK_Ordinary), Kind(OperandKind::DependentExpr) { - new ((void *)(char *)&Operand) Expr *(DepSubExpr); assert(DepSubExpr->isValueDependent() && "reflection operand must be a reflection or a dependent expression"); + new ((void *)(char *)&Operand) Expr *(DepSubExpr); setDependence(computeDependence(this, C)); } CXXReflectExpr *CXXReflectExpr::Create(ASTContext &C, SourceLocation OperatorLoc, - SourceRange OperandRange, - ReflectionValue RV) { + SourceRange OperandRange, APValue RV) { CXXReflectExpr *E = new (C) CXXReflectExpr(C, C.MetaInfoTy, RV); E->setOperatorLoc(OperatorLoc); E->setOperandRange(OperandRange); diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index d18fc01ac0b687..fbf6243e6fbbed 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -66,6 +66,7 @@ #include #include #include +#include #define DEBUG_TYPE "exprconstant" @@ -8482,9 +8483,9 @@ bool ExprEvaluatorBase::VisitStackLocationExpr( if (!Frame) return Error(E); - ReflectionValue RV(ReflectionValue::RK_declaration, - const_cast(Frame->Callee)); - return DerivedSuccess(APValue(RV), E); + APValue RV(ReflectionKind::Declaration, + const_cast(Frame->Callee)); + return DerivedSuccess(RV, E); } } // namespace @@ -14028,12 +14029,16 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, if (LHSTy->isReflectionType() && RHSTy->isReflectionType()) { 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 (LHSValue.getReflection() == RHSValue.getReflection()) + if (LID == RID) return Success(CmpResult::Equal, E); else return Success(CmpResult::Unequal, E); @@ -15927,7 +15932,7 @@ class ReflectionEvaluator } bool ZeroInitialization(const Expr *E) { - Result = APValue(ReflectionValue{}); + Result = APValue(ReflectionKind::Null, nullptr); return true; } diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index d68b063053c545..b6dae91cf838fc 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -606,7 +606,7 @@ class CXXNameMangler { void mangleInitListElements(const InitListExpr *InitList); void mangleRequirement(SourceLocation RequiresExprLoc, const concepts::Requirement *Req); - void mangleReflection(const ReflectionValue &R); + void mangleReflection(const APValue &R); void mangleExpression(const Expr *E, unsigned Arity = UnknownArity, bool AsTemplateArg = false); void mangleCXXCtorType(CXXCtorType T, const CXXRecordDecl *InheritedFrom); @@ -4676,16 +4676,18 @@ void CXXNameMangler::mangleRequirement(SourceLocation RequiresExprLoc, } } -void CXXNameMangler::mangleReflection(const ReflectionValue &R) { +void CXXNameMangler::mangleReflection(const APValue &R) { + assert(R.isReflection()); + Out << 'M'; - switch (R.getKind()) { - case ReflectionValue::RK_null: + switch (R.getReflectionKind()) { + case ReflectionKind::Null: Out << '0'; break; - case ReflectionValue::RK_type: { + case ReflectionKind::Type: { Out << 't'; - QualType QT = R.getAsType(); + QualType QT = R.getReflectedType(); if (const TypedefType *TDT = dyn_cast(QT)) { mangleQualifiers(QT.getQualifiers()); @@ -4695,18 +4697,20 @@ void CXXNameMangler::mangleReflection(const ReflectionValue &R) { Context.mangleCanonicalTypeName(QT, Out, false); break; } - case ReflectionValue::RK_object: + case ReflectionKind::Object: Out << 'o'; - mangleValueInTemplateArg(R.getResultType(), R.getAsObject(), false, true); + mangleValueInTemplateArg(R.getTypeOfReflectedResult(getASTContext()), + R.getReflectedObject(), false, true); break; - case ReflectionValue::RK_value: + case ReflectionKind::Value: Out << "v"; - mangleValueInTemplateArg(R.getResultType(), R.getAsValue(), false, true); + mangleValueInTemplateArg(R.getTypeOfReflectedResult(getASTContext()), + R.getReflectedValue(), false, true); break; - case ReflectionValue::RK_declaration: { + case ReflectionKind::Declaration: { Out << 'd'; - Decl *D = R.getAsDecl(); + Decl *D = R.getReflectedDecl(); if (auto * ED = dyn_cast(D)) { mangleIntegerLiteral(ED->getType(), ED->getInitVal()); } else if (auto *CD = dyn_cast(D)) { @@ -4729,31 +4733,31 @@ void CXXNameMangler::mangleReflection(const ReflectionValue &R) { } break; } - case ReflectionValue::RK_template: { + case ReflectionKind::Template: { Out << 't'; ArrayRef Args; - mangleTemplateName(R.getAsTemplate().getAsTemplateDecl(), Args); + mangleTemplateName(R.getReflectedTemplate().getAsTemplateDecl(), Args); break; } - case ReflectionValue::RK_namespace: { + case ReflectionKind::Namespace: { Out << 'n'; - if (auto *ND = dyn_cast(R.getAsNamespace())) + if (auto *ND = dyn_cast(R.getReflectedNamespace())) mangleNameWithAbiTags(ND, nullptr); // Otherwise, this is the global namespace. Out << '$'; break; } - case ReflectionValue::RK_base_specifier: { + case ReflectionKind::BaseSpecifier: { Out << 'b'; - Context.mangleCanonicalTypeName(R.getAsBaseSpecifier()->getType(), Out, - false); + Context.mangleCanonicalTypeName(R.getReflectedBaseSpecifier()->getType(), + Out, false); break; } - case ReflectionValue::RK_data_member_spec: { + case ReflectionKind::DataMemberSpec: { Out << "sdm"; - TagDataMemberSpec *TDMS = R.getAsDataMemberSpec(); + TagDataMemberSpec *TDMS = R.getReflectedDataMemberSpec(); Context.mangleCanonicalTypeName(TDMS->Ty, Out, false); if (TDMS->Name) Out << "N$" << (*TDMS->Name) << '$'; @@ -6851,7 +6855,7 @@ void CXXNameMangler::mangleValueInTemplateArg(QualType T, const APValue &V, } case APValue::Reflection: { - mangleReflection(V.getReflection()); + mangleReflection(V); break; } } diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 761c1c3fe4c6a2..37632fc902f90b 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -474,7 +474,7 @@ class MicrosoftCXXNameMangler { const NamedDecl *Parm); void mangleTemplateArgValue(QualType T, const APValue &V, TplArgKind, bool WithScalarType = false); - void mangleReflection(const ReflectionValue &R); + void mangleReflection(const APValue &R); void mangleObjCProtocol(const ObjCProtocolDecl *PD); void mangleObjCLifetime(const QualType T, Qualifiers Quals, @@ -2160,17 +2160,16 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T, } } -void MicrosoftCXXNameMangler::mangleReflection(const ReflectionValue &R) { +void MicrosoftCXXNameMangler::mangleReflection(const APValue &R) { Out << 'M'; - const void *opaque = R.getOpaqueValue(); - switch (R.getKind()) { - case ReflectionValue::RK_null: + switch (R.getReflectionKind()) { + case ReflectionKind::Null: Out << '0'; break; - case ReflectionValue::RK_type: { + case ReflectionKind::Type: { Out << 't'; - QualType QT = QualType::getFromOpaquePtr(opaque); + QualType QT = R.getReflectedType(); if (const LocInfoType *LIT = dyn_cast(QT)) { QT = LIT->getType(); } @@ -2185,13 +2184,13 @@ void MicrosoftCXXNameMangler::mangleReflection(const ReflectionValue &R) { Context.mangleCanonicalTypeName(QT, Out, false); break; } - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_declaration: - case ReflectionValue::RK_template: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Declaration: + case ReflectionKind::Template: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: llvm_unreachable("unimplemented"); } Out << 'E'; diff --git a/clang/lib/AST/Reflection.cpp b/clang/lib/AST/Reflection.cpp index 5c426eaf8b2e2b..c55f1b6bb1581d 100644 --- a/clang/lib/AST/Reflection.cpp +++ b/clang/lib/AST/Reflection.cpp @@ -12,245 +12,10 @@ // //===----------------------------------------------------------------------===// -#include "clang/AST/APValue.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/Decl.h" -#include "clang/AST/DeclTemplate.h" -#include "clang/AST/Expr.h" -#include "clang/AST/LocInfoType.h" #include "clang/AST/Reflection.h" namespace clang { -namespace { - -QualType ComputeLValueType(const APValue &V) { - assert(V.isLValue()); - assert(!V.getLValueBase().isNull()); - - SplitQualType SQT = V.getLValueBase().getType().split(); - - for (auto p = V.getLValuePath().begin(); - p != V.getLValuePath().end(); ++p) { - const Decl *D = V.getLValuePath().back().getAsBaseOrMember().getPointer(); - if (D) { // base or member case - if (auto *VD = dyn_cast(D)) { - QualType QT = VD->getType(); - SQT.Ty = QT.getTypePtr(); - - if (QT.isConstQualified()) SQT.Quals.addConst(); - if (QT.isVolatileQualified()) SQT.Quals.addVolatile(); - - continue; - } else if (auto *TD = dyn_cast(D)) { - SQT.Ty = TD->getTypeForDecl(); - continue; - } - - llvm_unreachable("unknown lvalue path kind"); - } else { // array case - QualType QT = cast(SQT.Ty)->getElementType(); - SQT.Ty = QT.getTypePtr(); - if (QT.isConstQualified()) SQT.Quals.addConst(); - if (QT.isVolatileQualified()) SQT.Quals.addVolatile(); - } - } - return QualType(SQT.Ty, SQT.Quals.getAsOpaqueValue()); -} - -} // end anonymous namespace - -ReflectionValue::ReflectionValue() : Kind(RK_null), Entity(nullptr) { } - -ReflectionValue::ReflectionValue(ReflectionKind Kind, void *Entity, - QualType ResultType) - : Kind(Kind), Entity(Entity), ResultType(ResultType) { - assert(ResultType.isNull() ^ (Kind == RK_value)); - - if (Kind == RK_object) - this->ResultType = ComputeLValueType(getAsObject()); - - if (Kind == RK_value) getAsValue(); -} - -ReflectionValue::ReflectionValue(ReflectionValue const& Rhs) - : Kind(Rhs.Kind), Entity(Rhs.Entity), ResultType(Rhs.ResultType) { -} - -ReflectionValue &ReflectionValue::operator=(ReflectionValue const& Rhs) { - Kind = Rhs.Kind; - Entity = Rhs.Entity; - ResultType = Rhs.ResultType; - - return *this; -} - -bool ReflectionValue::isNull() const { return Kind == RK_null; } - -QualType ReflectionValue::getAsType() const { - assert(getKind() == RK_type && "not a type"); - - QualType QT = QualType::getFromOpaquePtr(Entity); - - bool UnwrapAliases = false; - bool IsConst = QT.isConstQualified(); - bool IsVolatile = QT.isVolatileQualified(); - - void *AsPtr; - do { - AsPtr = QT.getAsOpaquePtr(); - - if (const auto *LIT = dyn_cast(QT)) - QT = LIT->getType(); - if (const auto *ET = dyn_cast(QT)) { - QualType New = ET->getNamedType(); - New.setLocalFastQualifiers(QT.getLocalFastQualifiers()); - QT = New; - } - if (const auto *STTPT = dyn_cast(QT); - STTPT && !STTPT->isDependentType()) - QT = STTPT->getReplacementType(); - if (const auto *RST = dyn_cast(QT); - RST && !RST->isDependentType()) - QT = RST->getUnderlyingType(); - if (const auto *TST = dyn_cast(QT); - TST && !TST->isTypeAlias()) { - QT = TST->desugar(); - } - if (const auto *DTST = dyn_cast(QT)) - QT = DTST->getDeducedType(); - if (const auto *DTT = dyn_cast(QT)) { - QT = DTT->desugar(); - UnwrapAliases = true; - } - if (const auto *UT = dyn_cast(QT); - UT && UnwrapAliases) - QT = UT->desugar(); - if (const auto *TDT = dyn_cast(QT); - TDT && UnwrapAliases) - QT = TDT->desugar(); - } while (QT.getAsOpaquePtr() != AsPtr); - - if (IsConst) - QT = QT.withConst(); - if (IsVolatile) - QT = QT.withVolatile(); - - return QT; -} - -const APValue &ReflectionValue::getAsObject() const { - assert(getKind() == RK_object && "not an object"); - - APValue *Result = reinterpret_cast(Entity); - assert(Result->isLValue()); - assert(!Result->getLValueBase().isNull()); - - return *Result; -} - -const APValue &ReflectionValue::getAsValue() const { - assert(getKind() == RK_value && "not a value"); - - APValue *Result = reinterpret_cast(Entity); - - // A reflection of a value will be either: - // - a non-lvalue APValue, - // - an lvalue APValue with pointer type, or - // - an lvalue APValue with null pointer type. - if (Result->isLValue()) - assert(ResultType->isPointerType() || Result->isNullPointer()); - - return *Result; -} - -void ReflectionValue::Profile(llvm::FoldingSetNodeID &ID) const { - ID.AddInteger(Kind); - - switch (Kind) { - case RK_null: - break; - case RK_type: { - // Quals | Kind/0 | ... - - QualType QT = getAsType(); - - QT.getQualifiers().Profile(ID); - - if (auto *TST = dyn_cast(QT)) { - // Note: This sugar only kept for alias template specializations. - ID.AddInteger(Type::TemplateSpecialization); - ID.AddPointer(TST->getTemplateName().getAsTemplateDecl()); - if (auto *D = QT->getAsRecordDecl()) - ID.AddPointer(D->getCanonicalDecl()); - } else { - ID.AddInteger(0); - if (auto *TDT = dyn_cast(QT)) { - ID.AddBoolean(true); - ID.AddPointer(TDT->getDecl()); - } else { - ID.AddBoolean(false); - QT.getCanonicalType().Profile(ID); - } - } - break; - } - case RK_object: - getAsObject().Profile(ID); - break; - case RK_value: - ResultType.getCanonicalType().getUnqualifiedType().Profile(ID); - getAsValue().Profile(ID); - break; - case RK_declaration: - if (auto *PVD = dyn_cast(getAsDecl())) { - auto *FD = cast(PVD->getDeclContext()); - FD = FD->getFirstDecl(); - PVD = FD->getParamDecl(PVD->getFunctionScopeIndex()); - - ID.AddPointer(PVD); - } else { - ID.AddPointer(getAsDecl()); - } - break; - case RK_template: - ID.AddPointer(getAsTemplate().getAsTemplateDecl()->getCanonicalDecl()); - break; - case RK_namespace: - ID.AddPointer(getAsNamespace()); - break; - case RK_base_specifier: - ID.AddPointer(getAsBaseSpecifier()); - break; - case RK_data_member_spec: { - TagDataMemberSpec *TDMS = getAsDataMemberSpec(); - TDMS->Ty.Profile(ID); - ID.AddBoolean(TDMS->Name.has_value()); - if (TDMS->Name) - ID.AddString(TDMS->Name.value()); - ID.AddBoolean(TDMS->Alignment.has_value()); - if (TDMS->Alignment) - ID.AddBoolean(TDMS->Alignment.value()); - ID.AddBoolean(TDMS->BitWidth.has_value()); - if (TDMS->BitWidth) - ID.AddBoolean(TDMS->BitWidth.value()); - break; - } - } -} - -bool ReflectionValue::operator==(ReflectionValue const& Rhs) const { - llvm::FoldingSetNodeID LID, RID; - Profile(LID); - Rhs.Profile(RID); - - return LID == RID; -} - -bool ReflectionValue::operator!=(ReflectionValue const& Rhs) const { - return !(*this == Rhs); -} - bool TagDataMemberSpec::operator==(TagDataMemberSpec const &Rhs) const { return (Ty == Ty && Alignment == Rhs.Alignment && diff --git a/clang/lib/Sema/Metafunctions.cpp b/clang/lib/Sema/Metafunctions.cpp index 485c5151e022c5..45bb0adc873f07 100644 --- a/clang/lib/Sema/Metafunctions.cpp +++ b/clang/lib/Sema/Metafunctions.cpp @@ -617,34 +617,27 @@ static APValue makeBool(ASTContext &C, bool B) { } static APValue makeReflection(QualType QT) { - ReflectionValue RV(ReflectionValue::RK_type, QT.getAsOpaquePtr()); - return APValue(RV); + return APValue(ReflectionKind::Type, QT.getAsOpaquePtr()); } static APValue makeReflection(Decl *D) { if (isa(D) || isa(D) || - isa(D)) { - ReflectionValue RV(ReflectionValue::RK_namespace, D); - return APValue(RV); - } + isa(D)) + return APValue(ReflectionKind::Namespace, D); - ReflectionValue RV(ReflectionValue::RK_declaration, D); - return APValue(RV); + return APValue(ReflectionKind::Declaration, D); } static APValue makeReflection(TemplateName TName) { - ReflectionValue RV(ReflectionValue::RK_template, TName.getAsVoidPointer()); - return APValue(RV); + return APValue(ReflectionKind::Template, TName.getAsVoidPointer()); } static APValue makeReflection(CXXBaseSpecifier *Base) { - ReflectionValue RV(ReflectionValue::RK_base_specifier, Base); - return APValue(RV); + return APValue(ReflectionKind::BaseSpecifier, Base); } static APValue makeReflection(TagDataMemberSpec *TDMS) { - ReflectionValue RV(ReflectionValue::RK_data_member_spec, TDMS); - return APValue(RV); + return APValue(ReflectionKind::DataMemberSpec, TDMS); } static Expr *makeStrLiteral(StringRef Str, ASTContext &C, bool Utf8) { @@ -687,8 +680,12 @@ static TemplateName findTemplateOfType(QualType QT) { if (const ElaboratedType *ET = dyn_cast(QT)) QT = ET->getNamedType(); - if (auto *TST = dyn_cast(QT)) - return TST->getTemplateName(); + if (auto *TST = dyn_cast(QT)) { + TemplateName TName = TST->getTemplateName(); + if (TName.getKind() == TemplateName::QualifiedTemplate) + TName = TName.getAsQualifiedTemplateName()->getUnderlyingTemplate(); + return TName; + } if (auto *CXXRD = QT->getAsCXXRecordDecl()) if (auto *CTSD = dyn_cast(CXXRD)) @@ -914,17 +911,13 @@ static APValue getNthTemplateArgument(Sema &S, ArrayRef templateArgs, EvalFn Evaluator, APValue Sentinel, size_t Idx) { - if (Idx >= templateArgs.size()) { + if (Idx >= templateArgs.size()) return Sentinel; - } const auto& templArgument = templateArgs[Idx]; switch (templArgument.getKind()) { - // Works for type parameters pack as well case TemplateArgument::Type: return makeReflection(templArgument.getAsType()); - // Works for non-template parameters and parameter packs of types: - // int, pointers case TemplateArgument::Expression: { Expr *TExpr = templArgument.getAsExpr(); @@ -932,63 +925,41 @@ static APValue getNthTemplateArgument(Sema &S, bool success = Evaluator(ArgResult, TExpr, !TExpr->isLValue()); assert(success); - ReflectionValue RV; - if (ArgResult.isLValue()) - RV = {ReflectionValue::RK_object, new (S.Context) APValue(ArgResult)}; - else { - RV = {ReflectionValue::RK_value, new (S.Context) APValue(ArgResult), - TExpr->getType()}; - } - - return APValue(RV); + return ArgResult.Lift(TExpr->getType()); } - case TemplateArgument::Template: - return makeReflection(templArgument.getAsTemplate()); - case TemplateArgument::Declaration: + case TemplateArgument::Template: { + TemplateName TName = templArgument.getAsTemplate(); + if (TName.getKind() == TemplateName::QualifiedTemplate) + TName = TName.getAsQualifiedTemplateName()->getUnderlyingTemplate(); + return makeReflection(TName); + } case TemplateArgument::Declaration: return makeReflection(templArgument.getAsDecl()); - case TemplateArgument::Pack: - llvm_unreachable("Packs should be expanded before calling this"); - - // Could not get a test case to hit one of the below - case TemplateArgument::Null: - llvm_unreachable("TemplateArgument::Null not supported"); case TemplateArgument::NullPtr: { - ReflectionValue RV( - ReflectionValue::RK_value, - new (S.Context) APValue((const ValueDecl *)nullptr, - CharUnits::fromQuantity( - S.Context.getTargetNullPointerValue( - templArgument.getNullPtrType())), - APValue::NoLValuePath(), - /*IsNullPtr=*/true), - templArgument.getNullPtrType()); - - return APValue(RV); + APValue NullPtrValue((ValueDecl *)nullptr, + CharUnits::fromQuantity( + S.Context.getTargetNullPointerValue( + templArgument.getNullPtrType())), + APValue::NoLValuePath(), + /*IsNullPtr=*/true); + return NullPtrValue.Lift(templArgument.getNullPtrType()); } case TemplateArgument::StructuralValue: { - if (templArgument.getStructuralValueType()->isReferenceType()) { - ReflectionValue RV(ReflectionValue::RK_object, - const_cast( - &templArgument.getAsStructuralValue())); - return APValue(RV); - } else { - ReflectionValue RV(ReflectionValue::RK_value, - const_cast( - &templArgument.getAsStructuralValue()), - templArgument.getStructuralValueType()); - return APValue(RV); - } + APValue SV = templArgument.getAsStructuralValue(); + return SV.Lift(templArgument.getStructuralValueType()); } case TemplateArgument::Integral: { - ReflectionValue RV(ReflectionValue::RK_value, - new (S.Context) APValue(templArgument.getAsIntegral()), - templArgument.getIntegralType()); - - return APValue(RV); + APValue IV(templArgument.getAsIntegral()); + return IV.Lift(templArgument.getIntegralType()); } case TemplateArgument::SpliceSpecifier: llvm_unreachable("TemplateArgument::SpliceSpecifier should have been " "transformed by now"); + case TemplateArgument::Pack: + llvm_unreachable("Packs should be expanded before calling this"); + + // Could not get a test case to hit one of the below + case TemplateArgument::Null: + llvm_unreachable("TemplateArgument::Null not supported"); case TemplateArgument::TemplateExpansion: llvm_unreachable("TemplateArgument::TemplateExpansion not supported"); } @@ -1277,19 +1248,19 @@ QualType Sema::ComputeResultType(QualType ExprTy, const APValue &V) { // Diagnostic helper function // ----------------------------------------------------------------------------- -StringRef DescriptionOf(ReflectionValue RV, bool Granular = true) { - switch (RV.getKind()) { - case ReflectionValue::RK_null: +StringRef DescriptionOf(APValue RV, bool Granular = true) { + switch (RV.getReflectionKind()) { + case ReflectionKind::Null: return "a null reflection"; - case ReflectionValue::RK_type: - if (isTypeAlias(RV.getAsType())) return "type alias"; + case ReflectionKind::Type: + if (isTypeAlias(RV.getReflectedType())) return "type alias"; else return "a type"; - case ReflectionValue::RK_object: + case ReflectionKind::Object: return "an object"; - case ReflectionValue::RK_value: + case ReflectionKind::Value: return "a value"; - case ReflectionValue::RK_declaration: { - ValueDecl *D = RV.getAsDecl(); + case ReflectionKind::Declaration: { + ValueDecl *D = RV.getReflectedDecl(); switch (D->getDeclName().getNameKind()) { case DeclarationName::CXXConstructorName: @@ -1317,8 +1288,8 @@ StringRef DescriptionOf(ReflectionValue RV, bool Granular = true) { else if (isa(D)) return "a enumerator"; llvm_unreachable("unhandled declaration kind"); } - case ReflectionValue::RK_template: { - TemplateDecl *TD = RV.getAsTemplate().getAsTemplateDecl(); + case ReflectionKind::Template: { + TemplateDecl *TD = RV.getReflectedTemplate().getAsTemplateDecl(); switch (TD->getDeclName().getNameKind()) { case DeclarationName::CXXConstructorName: @@ -1341,17 +1312,17 @@ StringRef DescriptionOf(ReflectionValue RV, bool Granular = true) { else if (isa(TD)) return "a concept"; llvm_unreachable("unhandled template kind"); } - case ReflectionValue::RK_namespace: { - Decl *D = RV.getAsNamespace(); + case ReflectionKind::Namespace: { + Decl *D = RV.getReflectedNamespace(); if (isa(D)) return "the global namespace"; else if (isa(D)) return "a namespace alias"; else if (isa(D)) return "a namespace"; llvm_unreachable("unhandled namespace kind"); } - case ReflectionValue::RK_base_specifier: { + case ReflectionKind::BaseSpecifier: { return "a base class specifier"; } - case ReflectionValue::RK_data_member_spec: { + case ReflectionKind::DataMemberSpec: { return "a description of a non-static data member"; } } @@ -1380,18 +1351,18 @@ bool get_begin_enumerator_decl_of(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.MetaInfoTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; APValue Sentinel; if (!Evaluator(Sentinel, Args[1], true)) return true; - assert(Sentinel.getReflection().getKind() == ReflectionValue::RK_type); + assert(Sentinel.isReflectedType()); - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_type: { - Decl *D = findTypeDecl(R.getReflectedType()); + switch (RV.getReflectionKind()) { + case ReflectionKind::Type: { + Decl *D = findTypeDecl(RV.getReflectedType()); if (auto enumDecl = dyn_cast_or_null(D)) { if (auto itr = enumDecl->enumerator_begin(); @@ -1402,16 +1373,16 @@ bool get_begin_enumerator_decl_of(APValue &Result, Sema &S, EvalFn Evaluator, } return DiagnoseReflectionKind(Diagnoser, Range, "an enum type"); } - case ReflectionValue::RK_null: - case ReflectionValue::RK_declaration: - case ReflectionValue::RK_template: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: { + case ReflectionKind::Null: + case ReflectionKind::Declaration: + case ReflectionKind::Template: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: { return DiagnoseReflectionKind(Diagnoser, Range, "an enum type", - DescriptionOf(R.getReflection())); + DescriptionOf(RV)); } } llvm_unreachable("unknown reflection kind"); @@ -1423,31 +1394,31 @@ bool get_next_enumerator_decl_of(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.MetaInfoTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; APValue Sentinel; if (!Evaluator(Sentinel, Args[1], true)) return true; - assert(Sentinel.getReflection().getKind() == ReflectionValue::RK_type); + assert(Sentinel.isReflectedType()); - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_declaration: { - Decl *currEnumConstDecl = R.getReflectedDecl(); + switch (RV.getReflectionKind()) { + case ReflectionKind::Declaration: { + Decl *currEnumConstDecl = RV.getReflectedDecl(); if(auto nextEnumConstDecl = currEnumConstDecl->getNextDeclInContext()) { return SetAndSucceed(Result, makeReflection(nextEnumConstDecl)); } return SetAndSucceed(Result, Sentinel); } - case ReflectionValue::RK_null: - case ReflectionValue::RK_type: - case ReflectionValue::RK_template: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: { + case ReflectionKind::Null: + case ReflectionKind::Type: + case ReflectionKind::Template: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: { llvm_unreachable("should have failed in 'get_begin_enumerator_decl_of'"); } } @@ -1460,27 +1431,27 @@ bool get_ith_base_of(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.MetaInfoTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; APValue Sentinel; if (!Evaluator(Sentinel, Args[1], true)) return true; - assert(Sentinel.getReflection().getKind() == ReflectionValue::RK_type); + assert(Sentinel.isReflectedType()); APValue Idx; if (!Evaluator(Idx, Args[2], true)) return true; size_t idx = Idx.getInt().getExtValue(); - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_type: { - Decl *typeDecl = findTypeDecl(R.getReflectedType()); + switch (RV.getReflectionKind()) { + case ReflectionKind::Type: { + Decl *typeDecl = findTypeDecl(RV.getReflectedType()); if (auto cxxRecordDecl = dyn_cast_or_null(typeDecl)) { ensureInstantiated(S, typeDecl, Range); - if (R.getReflectedType()->isIncompleteType()) + if (RV.getReflectedType()->isIncompleteType()) return Diagnoser(Range.getBegin(), diag::metafn_cannot_introspect_type) << 0 << 0 << Range; @@ -1495,16 +1466,16 @@ bool get_ith_base_of(APValue &Result, Sema &S, EvalFn Evaluator, return Diagnoser(Range.getBegin(), diag::metafn_cannot_introspect_type) << 0 << 1 << Range; } - case ReflectionValue::RK_null: - case ReflectionValue::RK_declaration: - case ReflectionValue::RK_template: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + case ReflectionKind::Null: + case ReflectionKind::Declaration: + case ReflectionKind::Template: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return DiagnoseReflectionKind(Diagnoser, Range, "a class type", - DescriptionOf(R.getReflection())); + DescriptionOf(RV)); } llvm_unreachable("unknown reflection kind"); } @@ -1515,48 +1486,48 @@ bool get_ith_template_argument_of(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.MetaInfoTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; APValue Sentinel; if (!Evaluator(Sentinel, Args[1], true)) return true; - assert(Sentinel.getReflection().getKind() == ReflectionValue::RK_type); + assert(Sentinel.isReflectedType()); APValue Idx; if (!Evaluator(Idx, Args[2], true)) return true; size_t idx = Idx.getInt().getExtValue(); - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_type: { - QualType QT = R.getReflectedType(); + switch (RV.getReflectionKind()) { + case ReflectionKind::Type: { + QualType QT = RV.getReflectedType(); SmallVector TArgs; if (getTemplateArgumentsFromType(QT, TArgs)) return DiagnoseReflectionKind(Diagnoser, Range, "a template specialization"); - return SetAndSucceed(Result, getNthTemplateArgument(S, TArgs, Evaluator, - Sentinel, idx)); + APValue R = getNthTemplateArgument(S, TArgs, Evaluator, Sentinel, idx); + return SetAndSucceed(Result, R); } - case ReflectionValue::RK_declaration: { + case ReflectionKind::Declaration: { SmallVector TArgs; - if (getTemplateArgumentsFromDecl(R.getReflectedDecl(), TArgs)) + if (getTemplateArgumentsFromDecl(RV.getReflectedDecl(), TArgs)) return DiagnoseReflectionKind(Diagnoser, Range, "a template specialization"); return SetAndSucceed(Result, getNthTemplateArgument(S, TArgs, Evaluator, Sentinel, idx)); } - case ReflectionValue::RK_null: - case ReflectionValue::RK_template: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + case ReflectionKind::Null: + case ReflectionKind::Template: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return DiagnoseReflectionKind(Diagnoser, Range, "a template specialization", - DescriptionOf(R.getReflection())); + DescriptionOf(RV)); } llvm_unreachable("unknown reflection kind"); } @@ -1567,8 +1538,8 @@ bool get_begin_member_decl_of(APValue &Result, Sema &S, EvalFn Evaluator, assert(ResultTy == S.Context.MetaInfoTy); assert(Args[0]->getType()->isReflectionType()); - APValue R; - if (!Evaluator(R, Args[0], true)) { + APValue RV; + if (!Evaluator(RV, Args[0], true)) { return true; } @@ -1576,12 +1547,12 @@ bool get_begin_member_decl_of(APValue &Result, Sema &S, EvalFn Evaluator, APValue Sentinel; if (!Evaluator(Sentinel, Args[1], true)) return true; - assert(Sentinel.getReflection().getKind() == ReflectionValue::RK_type); + assert(Sentinel.isReflectedType()); - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_type: + switch (RV.getReflectionKind()) { + case ReflectionKind::Type: { - QualType QT = R.getReflectedType(); + QualType QT = RV.getReflectedType(); if (isTypeAlias(QT)) QT = desugarType(QT, /*UnwrapAliases=*/true, /*DropCV=*/false, /*DropRefs=*/false); @@ -1619,11 +1590,11 @@ bool get_begin_member_decl_of(APValue &Result, Sema &S, EvalFn Evaluator, *declContext->decls_begin(), true); if (!beginMember) return SetAndSucceed(Result, Sentinel); - ReflectionValue RV(ReflectionValue::RK_declaration, beginMember); - return SetAndSucceed(Result, APValue(RV)); + return SetAndSucceed(Result, + APValue(ReflectionKind::Declaration, beginMember)); } - case ReflectionValue::RK_namespace: { - Decl *NS = R.getReflectedNamespace(); + case ReflectionKind::Namespace: { + Decl *NS = RV.getReflectedNamespace(); if (auto *A = dyn_cast(NS)) NS = A->getNamespace(); @@ -1632,16 +1603,16 @@ bool get_begin_member_decl_of(APValue &Result, Sema &S, EvalFn Evaluator, Decl *beginMember = findIterableMember(S.Context, *DC->decls_begin(), true); if (!beginMember) return SetAndSucceed(Result, Sentinel); - ReflectionValue RV(ReflectionValue::RK_declaration, beginMember); - return SetAndSucceed(Result, APValue(RV)); + return SetAndSucceed(Result, + APValue(ReflectionKind::Declaration, beginMember)); } - case ReflectionValue::RK_null: - case ReflectionValue::RK_declaration: - case ReflectionValue::RK_template: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + case ReflectionKind::Null: + case ReflectionKind::Declaration: + case ReflectionKind::Template: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return true; } llvm_unreachable("unknown reflection kind"); @@ -1653,20 +1624,18 @@ bool get_next_member_decl_of(APValue &Result, Sema &S, EvalFn Evaluator, assert(ResultTy == S.Context.MetaInfoTy); assert(Args[0]->getType()->isReflectionType()); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; assert(Args[1]->getType()->isReflectionType()); APValue Sentinel; if (!Evaluator(Sentinel, Args[1], true)) return true; - assert(Sentinel.getReflection().getKind() == ReflectionValue::RK_type); + assert(Sentinel.isReflectedType()); - if (Decl *Next = findIterableMember(S.Context, R.getReflectedDecl(), false)) { - ReflectionValue RV(ReflectionValue::RK_declaration, Next); - return SetAndSucceed(Result, APValue(RV)); - } + if (Decl *Next = findIterableMember(S.Context, RV.getReflectedDecl(), false)) + return SetAndSucceed(Result, APValue(ReflectionKind::Declaration, Next)); return SetAndSucceed(Result, Sentinel); } @@ -1676,10 +1645,10 @@ bool map_decl_to_entity(APValue &Result, Sema &S, EvalFn Evaluator, assert(ResultTy == S.Context.MetaInfoTy); assert(Args[0]->getType()->isReflectionType()); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - Decl *D = R.getReflectedDecl(); + Decl *D = RV.getReflectedDecl(); if (auto *TyDecl = dyn_cast(D)) { QualType QT = S.Context.getTypeDeclType(TyDecl); @@ -1698,8 +1667,8 @@ bool identifier_of(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, ArrayRef Args) { assert(Args[0]->getType()->isReflectionType()); - APValue R; - if (!Evaluator(R, Args[1], true)) + APValue RV; + if (!Evaluator(RV, Args[1], true)) return true; bool IsUtf8; @@ -1719,9 +1688,9 @@ bool identifier_of(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, } std::string Name; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_type: { - QualType QT = R.getReflectedType(); + switch (RV.getReflectionKind()) { + case ReflectionKind::Type: { + QualType QT = RV.getReflectedType(); if (isTemplateSpecialization(QT)) return Diagnoser(Range.getBegin(), diag::metafn_name_is_not_identifier) << 0 << Range; @@ -1732,17 +1701,17 @@ bool identifier_of(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, break; } - case ReflectionValue::RK_declaration: { - if (auto *PVD = dyn_cast(R.getReflectedDecl())) { + case ReflectionKind::Declaration: { + if (auto *PVD = dyn_cast(RV.getReflectedDecl())) { bool ConsistentName = getParameterName(PVD, Name); if (EnforceConsistent && !ConsistentName) { return Diagnoser(Range.getBegin(), diag::metafn_inconsistent_name) - << DescriptionOf(R.getReflection()) << Range; + << DescriptionOf(RV) << Range; } break; } - if (auto *ND = dyn_cast(R.getReflectedDecl())) { + if (auto *ND = dyn_cast(RV.getReflectedDecl())) { if (!findTemplateOfDecl(ND).isNull()) return Diagnoser(Range.getBegin(), diag::metafn_name_is_not_identifier) << 0 << Range; @@ -1769,8 +1738,8 @@ bool identifier_of(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, break; } - case ReflectionValue::RK_template: { - const TemplateDecl *TD = R.getReflectedTemplate().getAsTemplateDecl(); + case ReflectionKind::Template: { + const TemplateDecl *TD = RV.getReflectedTemplate().getAsTemplateDecl(); if (auto *FTD = dyn_cast(TD)) { if (isa(FTD->getTemplatedDecl())) return Diagnoser(Range.getBegin(), diag::metafn_name_is_not_identifier) @@ -1793,31 +1762,31 @@ bool identifier_of(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, break; } - case ReflectionValue::RK_namespace: { - if (isa(R.getReflectedNamespace())) + case ReflectionKind::Namespace: { + if (isa(RV.getReflectedNamespace())) return Diagnoser(Range.getBegin(), diag::metafn_name_of_unnamed_singleton) << 1 << Range; - getDeclName(Name, S.Context, R.getReflectedNamespace()); + getDeclName(Name, S.Context, RV.getReflectedNamespace()); break; } - case ReflectionValue::RK_data_member_spec: { - TagDataMemberSpec *TDMS = R.getReflectedDataMemberSpec(); + case ReflectionKind::DataMemberSpec: { + TagDataMemberSpec *TDMS = RV.getReflectedDataMemberSpec(); if (TDMS->Name) Name = *TDMS->Name; break; } - case ReflectionValue::RK_null: + case ReflectionKind::Null: return Diagnoser(Range.getBegin(), diag::metafn_name_of_unnamed_singleton) << 0 << Range; - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_base_specifier: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::BaseSpecifier: return Diagnoser(Range.getBegin(), diag::metafn_cannot_have_name) - << DescriptionOf(R.getReflection()) << Range; + << DescriptionOf(RV) << Range; } if (Name.empty()) return Diagnoser(Range.getBegin(), diag::metafn_anonymous_entity) - << DescriptionOf(R.getReflection()) << Range; + << DescriptionOf(RV) << Range; Expr *StrLit = makeStrLiteral(Name, S.Context, IsUtf8); @@ -1831,14 +1800,14 @@ bool has_identifier(APValue &Result, Sema &S, EvalFn Evaluator, ArrayRef Args) { assert(Args[0]->getType()->isReflectionType()); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool HasIdentifier = false; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_type: { - QualType QT = R.getReflectedType(); + switch (RV.getReflectionKind()) { + case ReflectionKind::Type: { + QualType QT = RV.getReflectedType(); if (isTemplateSpecialization(QT)) break; @@ -1848,8 +1817,8 @@ bool has_identifier(APValue &Result, Sema &S, EvalFn Evaluator, break; } - case ReflectionValue::RK_declaration: { - auto *D = R.getReflectedDecl(); + case ReflectionKind::Declaration: { + auto *D = RV.getReflectedDecl(); if (auto *PVD = dyn_cast(D)) { std::string Name; (void) getParameterName(PVD, Name); @@ -1866,8 +1835,8 @@ bool has_identifier(APValue &Result, Sema &S, EvalFn Evaluator, break; } - case ReflectionValue::RK_template: { - const TemplateDecl *TD = R.getReflectedTemplate().getAsTemplateDecl(); + case ReflectionKind::Template: { + const TemplateDecl *TD = RV.getReflectedTemplate().getAsTemplateDecl(); if (auto *FTD = dyn_cast(TD)) if (isa(FTD->getTemplatedDecl())) break; @@ -1875,20 +1844,20 @@ bool has_identifier(APValue &Result, Sema &S, EvalFn Evaluator, HasIdentifier = (TD->getIdentifier() != nullptr); break; } - case ReflectionValue::RK_namespace: { - if (auto *ND = dyn_cast(R.getReflectedNamespace())) + case ReflectionKind::Namespace: { + if (auto *ND = dyn_cast(RV.getReflectedNamespace())) HasIdentifier = (ND->getIdentifier() != nullptr); break; } - case ReflectionValue::RK_data_member_spec: { - TagDataMemberSpec *TDMS = R.getReflectedDataMemberSpec(); + case ReflectionKind::DataMemberSpec: { + TagDataMemberSpec *TDMS = RV.getReflectedDataMemberSpec(); HasIdentifier = TDMS->Name && !TDMS->Name->empty(); break; } - case ReflectionValue::RK_null: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: + case ReflectionKind::Null: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::Object: + case ReflectionKind::Value: break; } @@ -1924,23 +1893,23 @@ bool operator_of(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, return (OpPtr - OperatorIndices); }; - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; size_t OperatorId = 0; - if (R.getReflection().getKind() == ReflectionValue::RK_template) { - const TemplateDecl *TD = R.getReflectedTemplate().getAsTemplateDecl(); + if (RV.isReflectedTemplate()) { + const TemplateDecl *TD = RV.getReflectedTemplate().getAsTemplateDecl(); if (auto *FTD = dyn_cast(TD)) OperatorId = findOperatorOf(FTD->getTemplatedDecl()); - } else if (R.getReflection().getKind() == ReflectionValue::RK_declaration) { - if (auto *FD = dyn_cast(R.getReflectedDecl())) + } else if (RV.isReflectedDecl()) { + if (auto *FD = dyn_cast(RV.getReflectedDecl())) OperatorId = findOperatorOf(FD); } if (OperatorId == 0) return Diagnoser(Range.getBegin(), diag::metafn_not_an_operator) - << DescriptionOf(R.getReflection()) << Range; + << DescriptionOf(RV) << Range; return SetAndSucceed( Result, @@ -1952,33 +1921,33 @@ bool source_location_of(APValue &Result, Sema &S, EvalFn Evaluator, ArrayRef Args) { assert(Args[0]->getType()->isReflectionType()); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_type: + switch (RV.getReflectionKind()) { + case ReflectionKind::Type: return findTypeDeclLoc(Result, S.Context, Evaluator, ResultTy, - R.getReflectedType()); - case ReflectionValue::RK_declaration: + RV.getReflectedType()); + case ReflectionKind::Declaration: return findDeclLoc(Result, S.Context, Evaluator, ResultTy, - R.getReflectedDecl()); - case ReflectionValue::RK_template: { - TemplateName TName = R.getReflectedTemplate(); + RV.getReflectedDecl()); + case ReflectionKind::Template: { + TemplateName TName = RV.getReflectedTemplate(); return findDeclLoc(Result, S.Context, Evaluator, ResultTy, TName.getAsTemplateDecl()); } - case ReflectionValue::RK_namespace: + case ReflectionKind::Namespace: return findDeclLoc(Result, S.Context, Evaluator, ResultTy, - R.getReflectedNamespace()); - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: + RV.getReflectedNamespace()); + case ReflectionKind::Object: + case ReflectionKind::Value: // TODO(P2996): Passing 'nullptr' here (and for base spec) can't be right. return findDeclLoc(Result, S.Context, Evaluator, ResultTy, nullptr); - case ReflectionValue::RK_base_specifier: + case ReflectionKind::BaseSpecifier: return findBaseSpecLoc(Result, S.Context, Evaluator, ResultTy, nullptr); - case ReflectionValue::RK_null: - case ReflectionValue::RK_data_member_spec: + case ReflectionKind::Null: + case ReflectionKind::DataMemberSpec: return true; } llvm_unreachable("unknown reflection kind"); @@ -1988,34 +1957,34 @@ bool type_of(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, QualType ResultTy, SourceRange Range, ArrayRef Args) { assert(Args[0]->getType()->isReflectionType()); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_null: - case ReflectionValue::RK_type: - case ReflectionValue::RK_template: - case ReflectionValue::RK_namespace: + switch (RV.getReflectionKind()) { + case ReflectionKind::Null: + case ReflectionKind::Type: + case ReflectionKind::Template: + case ReflectionKind::Namespace: return Diagnoser(Range.getBegin(), diag::metafn_no_associated_property) - << DescriptionOf(R.getReflection()) << 0 << Range; - case ReflectionValue::RK_object: { - QualType QT = desugarType(R.getReflection().getResultType(), + << DescriptionOf(RV) << 0 << Range; + case ReflectionKind::Object: { + QualType QT = desugarType(RV.getTypeOfReflectedResult(S.Context), /*UnwrapAliases=*/false, /*DropCV=*/false, /*DropRefs=*/false); return SetAndSucceed(Result, makeReflection(QT)); } - case ReflectionValue::RK_value: { - QualType QT = desugarType(R.getReflection().getResultType(), + case ReflectionKind::Value: { + QualType QT = desugarType(RV.getTypeOfReflectedResult(S.Context), /*UnwrapAliases=*/true, /*DropCV=*/false, /*DropRefs=*/false); return SetAndSucceed(Result, makeReflection(QT)); } - case ReflectionValue::RK_declaration: { - ValueDecl *VD = cast(R.getReflectedDecl()); + case ReflectionKind::Declaration: { + ValueDecl *VD = cast(RV.getReflectedDecl()); if (isa(VD)) return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property) - << 0 << DescriptionOf(R.getReflection()) << Range; + << 0 << DescriptionOf(RV) << Range; bool UnwrapAliases = isa(VD) || isa(VD); bool DropCV = isa(VD); @@ -2023,15 +1992,15 @@ bool type_of(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, /*DropRefs=*/false); return SetAndSucceed(Result, makeReflection(QT)); } - case ReflectionValue::RK_base_specifier: { - QualType QT = R.getReflectedBaseSpecifier()->getType(); + case ReflectionKind::BaseSpecifier: { + QualType QT = RV.getReflectedBaseSpecifier()->getType(); QT = desugarType(QT, /*UnwrapAliases=*/false, /*DropCV=*/false, /*DropRefs=*/false); return SetAndSucceed(Result, makeReflection(QT)); } - case ReflectionValue::RK_data_member_spec: + case ReflectionKind::DataMemberSpec: { - QualType QT = R.getReflectedDataMemberSpec()->Ty; + QualType QT = RV.getReflectedDataMemberSpec()->Ty; QT = desugarType(QT, /*UnwrapAliases=*/false, /*DropCV=*/false, /*DropRefs=*/false); return SetAndSucceed(Result, makeReflection(QT)); @@ -2044,54 +2013,54 @@ bool parent_of(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, QualType ResultTy, SourceRange Range, ArrayRef Args) { assert(Args[0]->getType()->isReflectionType()); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; auto DiagWrapper = [&](unsigned DiagId) { if (DiagId && Diagnoser) return bool(Diagnoser(Range.getBegin(), DiagId) - << DescriptionOf(R.getReflection()) << Range); + << DescriptionOf(RV) << Range); return DiagId > 0; }; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_null: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_data_member_spec: - case ReflectionValue::RK_base_specifier: + switch (RV.getReflectionKind()) { + case ReflectionKind::Null: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::DataMemberSpec: + case ReflectionKind::BaseSpecifier: if (Diagnoser) return Diagnoser(Range.getBegin(), diag::metafn_no_associated_property) - << DescriptionOf(R.getReflection()) << 1 << Range; + << DescriptionOf(RV) << 1 << Range; return true; - case ReflectionValue::RK_type: { - if (TemplateName TName = findTemplateOfType(R.getReflectedType()); + case ReflectionKind::Type: { + if (TemplateName TName = findTemplateOfType(RV.getReflectedType()); !TName.isNull()) return DiagWrapper(parentOf(Result, TName.getAsTemplateDecl())); - return DiagWrapper(parentOf(Result, findTypeDecl(R.getReflectedType()))); + return DiagWrapper(parentOf(Result, findTypeDecl(RV.getReflectedType()))); } - case ReflectionValue::RK_declaration: { - if (TemplateName TName = findTemplateOfDecl(R.getReflectedDecl()); + case ReflectionKind::Declaration: { + if (TemplateName TName = findTemplateOfDecl(RV.getReflectedDecl()); !TName.isNull()) return DiagWrapper(parentOf(Result, TName.getAsTemplateDecl())); - return DiagWrapper(parentOf(Result, R.getReflectedDecl())); + return DiagWrapper(parentOf(Result, RV.getReflectedDecl())); } - case ReflectionValue::RK_template: { + case ReflectionKind::Template: { return DiagWrapper(parentOf(Result, - R.getReflectedTemplate().getAsTemplateDecl())); + RV.getReflectedTemplate().getAsTemplateDecl())); } - case ReflectionValue::RK_namespace: - if (isa(R.getReflectedNamespace())) { + case ReflectionKind::Namespace: + if (isa(RV.getReflectedNamespace())) { if (Diagnoser) return Diagnoser(Range.getBegin(), diag::metafn_no_associated_property) - << DescriptionOf(R.getReflection()) << 1 << Range; + << DescriptionOf(RV) << 1 << Range; return true; } - return DiagWrapper(parentOf(Result, R.getReflectedNamespace())); + return DiagWrapper(parentOf(Result, RV.getReflectedNamespace())); } llvm_unreachable("unknown reflection kind"); } @@ -2101,27 +2070,27 @@ bool dealias(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.MetaInfoTy); - APValue R; - if (!Evaluator(R, Args[0], true)) - return true; - - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_null: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_declaration: - case ReflectionValue::RK_template: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: - return SetAndSucceed(Result, R); - case ReflectionValue::RK_type: { - QualType QT = R.getReflectedType(); + APValue RV; + if (!Evaluator(RV, Args[0], true)) + return true; + + switch (RV.getReflectionKind()) { + case ReflectionKind::Null: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Declaration: + case ReflectionKind::Template: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: + return SetAndSucceed(Result, RV); + case ReflectionKind::Type: { + QualType QT = RV.getReflectedType(); QT = desugarType(QT, /*UnwrapAliases=*/true, /*DropCV=*/false, /*DropRefs=*/false); return SetAndSucceed(Result, makeReflection(QT)); } - case ReflectionValue::RK_namespace: { - Decl *NS = R.getReflectedNamespace(); + case ReflectionKind::Namespace: { + Decl *NS = RV.getReflectedNamespace(); if (auto *A = dyn_cast(NS)) NS = A->getNamespace(); return SetAndSucceed(Result, makeReflection(NS)); @@ -2135,18 +2104,18 @@ bool object_of(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.MetaInfoTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_object: - return SetAndSucceed(Result, R); - case ReflectionValue::RK_declaration: { - VarDecl *VD = dyn_cast(R.getReflectedDecl()); + switch (RV.getReflectionKind()) { + case ReflectionKind::Object: + return SetAndSucceed(Result, RV); + case ReflectionKind::Declaration: { + VarDecl *VD = dyn_cast(RV.getReflectedDecl()); if (!VD) return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property) - << 1 << DescriptionOf(R.getReflection()) << Range; + << 1 << DescriptionOf(RV) << Range; QualType QT = VD->getType(); if (auto *LVRT = dyn_cast(QT)) { @@ -2162,19 +2131,18 @@ bool object_of(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, if (!Evaluator(Value, Synthesized, false) || !Value.isLValue()) return true; - ReflectionValue RV(ReflectionValue::RK_object, - new (S.Context) APValue(Value)); - return SetAndSucceed(Result, APValue(RV)); - } - case ReflectionValue::RK_null: - case ReflectionValue::RK_value: - case ReflectionValue::RK_type: - case ReflectionValue::RK_template: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + APValue OV = Value.Lift(QualType{}); + return SetAndSucceed(Result, OV); + } + case ReflectionKind::Null: + case ReflectionKind::Value: + case ReflectionKind::Type: + case ReflectionKind::Template: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property) - << 1 << DescriptionOf(R.getReflection()) << Range; + << 1 << DescriptionOf(RV) << Range; } llvm_unreachable("unimplemented"); } @@ -2185,37 +2153,35 @@ bool value_of(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.MetaInfoTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - ReflectionValue RV = R.getReflection(); - switch (RV.getKind()) { - case ReflectionValue::RK_value: - return SetAndSucceed(Result, R); - case ReflectionValue::RK_object: { - if (!RV.getResultType()->isStructuralType()) + switch (RV.getReflectionKind()) { + case ReflectionKind::Value: + return SetAndSucceed(Result, RV); + case ReflectionKind::Object: { + if (!RV.getTypeOfReflectedResult(S.Context)->isStructuralType()) return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property) << 2 << "an object of non-structural type" << Range; + QualType ObjectTy = RV.getTypeOfReflectedResult(S.Context); Expr *OVE = new (S.Context) OpaqueValueExpr(Range.getBegin(), - RV.getResultType(), + ObjectTy, VK_LValue); - Expr *CE = ConstantExpr::Create(S.Context, OVE, RV.getAsObject()); + Expr *CE = ConstantExpr::Create(S.Context, OVE, RV.getReflectedObject()); Expr::EvalResult ER; if (!CE->EvaluateAsRValue(ER, S.Context, true)) return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property) << 2 << "an object not usable in constant expressions" << Range; - ReflectionValue RVResult(ReflectionValue::RK_value, - new (S.Context) APValue(ER.Val), - S.ComputeResultType(RV.getResultType(), ER.Val)); - - return SetAndSucceed(Result, APValue(RVResult)); + QualType ValueTy = + S.ComputeResultType(RV.getTypeOfReflectedResult(S.Context), ER.Val); + return SetAndSucceed(Result, ER.Val.Lift(ValueTy)); } - case ReflectionValue::RK_declaration: { - ValueDecl *Decl = R.getReflectedDecl(); + case ReflectionKind::Declaration: { + ValueDecl *Decl = RV.getReflectedDecl(); APValue Value; QualType QT; @@ -2253,19 +2219,17 @@ bool value_of(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, QT = TPOD->getType(); } - ReflectionValue RVResult(ReflectionValue::RK_value, - new (S.Context) APValue(Value), - S.ComputeResultType(QT, Value)); - return SetAndSucceed(Result, APValue(RVResult)); - } - case ReflectionValue::RK_null: - case ReflectionValue::RK_type: - case ReflectionValue::RK_template: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + QualType ValueTy = S.ComputeResultType(QT, Value); + return SetAndSucceed(Result, Value.Lift(ValueTy)); + } + case ReflectionKind::Null: + case ReflectionKind::Type: + case ReflectionKind::Template: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property) - << 2 << DescriptionOf(R.getReflection()) << Range; + << 2 << DescriptionOf(RV) << Range; } llvm_unreachable("unimplemented"); } @@ -2275,84 +2239,89 @@ bool template_of(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.MetaInfoTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_type: { - TemplateName TName = findTemplateOfType(R.getReflectedType()); + switch (RV.getReflectionKind()) { + case ReflectionKind::Type: { + TemplateName TName = findTemplateOfType(RV.getReflectedType()); if (TName.isNull()) return DiagnoseReflectionKind(Diagnoser, Range, "a template specialization"); return SetAndSucceed(Result, makeReflection(TName)); } - case ReflectionValue::RK_declaration: { - TemplateName TName = findTemplateOfDecl(R.getReflectedDecl()); + case ReflectionKind::Declaration: { + TemplateName TName = findTemplateOfDecl(RV.getReflectedDecl()); if (TName.isNull()) return DiagnoseReflectionKind(Diagnoser, Range, "a template specialization"); return SetAndSucceed(Result, makeReflection(TName)); } - case ReflectionValue::RK_null: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_template: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + case ReflectionKind::Null: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Template: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return DiagnoseReflectionKind(Diagnoser, Range, "a template specialization", - DescriptionOf(R.getReflection())); + DescriptionOf(RV)); return true; } llvm_unreachable("unknown reflection kind"); } -static bool CanActAsTemplateArg(const ReflectionValue &RV) { - switch (RV.getKind()) { - case ReflectionValue::RK_type: - case ReflectionValue::RK_declaration: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - return true; - case ReflectionValue::RK_template: - return isa(RV.getAsTemplate().getAsTemplateDecl()); - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: - case ReflectionValue::RK_null: +static bool CanActAsTemplateArg(const APValue &RV) { + switch (RV.getReflectionKind()) { + case ReflectionKind::Type: + case ReflectionKind::Declaration: + case ReflectionKind::Object: + case ReflectionKind::Value: + return true; + case ReflectionKind::Template: { + TemplateDecl *TDecl = RV.getReflectedTemplate().getAsTemplateDecl(); + return isa(TDecl); + } + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: + case ReflectionKind::Null: return false; } llvm_unreachable("unknown reflection kind"); } static TemplateArgument TArgFromReflection(Sema &S, EvalFn Evaluator, - const ReflectionValue &RV, + const APValue &RV, SourceLocation Loc) { - switch (RV.getKind()) { - case ReflectionValue::RK_type: - return RV.getAsType().getCanonicalType(); - case ReflectionValue::RK_object: { - QualType RefTy = S.Context.getLValueReferenceType(RV.getResultType()); - return TemplateArgument(S.Context, RefTy, RV.getAsObject(), false); - } - case ReflectionValue::RK_value: { - if (RV.getResultType()->isIntegralOrEnumerationType()) - return TemplateArgument(S.Context, RV.getAsValue().getInt(), - RV.getResultType().getCanonicalType()); - - return TemplateArgument(S.Context, RV.getResultType(), RV.getAsValue(), - false); - } - case ReflectionValue::RK_declaration: { - ValueDecl *Decl = RV.getAsDecl(); + switch (RV.getReflectionKind()) { + case ReflectionKind::Type: + return RV.getReflectedType().getCanonicalType(); + case ReflectionKind::Object: { + QualType RefTy = S.Context.getLValueReferenceType( + RV.getTypeOfReflectedResult(S.Context)); + return TemplateArgument(S.Context, RefTy, RV.getReflectedObject(), false); + } + case ReflectionKind::Value: { + APValue Lowered = RV.getReflectedValue(); + QualType ResultTy = RV.getTypeOfReflectedResult(S.Context); + if (Lowered.isInt()) { + return TemplateArgument(S.Context, Lowered.getInt(), + ResultTy.getCanonicalType()); + } + TemplateArgument TArg(S.Context, ResultTy, Lowered, false); + return TArg; + } + case ReflectionKind::Declaration: { + ValueDecl *Decl = RV.getReflectedDecl(); Expr *Synthesized = DeclRefExpr::Create(S.Context, NestedNameSpecifierLoc(), SourceLocation(), Decl, false, Loc, Decl->getType(), VK_LValue, Decl, nullptr); + // TODO(P2996): Just throw this in an lvalue APValue. APValue R; if (!Evaluator(R, Synthesized, true)) break; @@ -2366,8 +2335,8 @@ static TemplateArgument TArgFromReflection(Sema &S, EvalFn Evaluator, return TemplateArgument(Synthesized); break; } - case ReflectionValue::RK_template: - return TemplateArgument(RV.getAsTemplate()); + case ReflectionKind::Template: + return TemplateArgument(RV.getReflectedTemplate()); break; default: llvm_unreachable("unimplemented for template argument kind"); @@ -2389,9 +2358,9 @@ bool can_substitute(APValue &Result, Sema &S, EvalFn Evaluator, if (!Evaluator(Template, Args[0], true)) return true; - if (Template.getReflection().getKind() != ReflectionValue::RK_template) + if (!Template.isReflectedTemplate()) return DiagnoseReflectionKind(Diagnoser, Range, "a template", - DescriptionOf(Template.getReflection())); + DescriptionOf(Template)); TemplateDecl *TDecl = Template.getReflectedTemplate().getAsTemplateDecl(); if (TDecl->isInvalidDecl()) return true; @@ -2422,12 +2391,11 @@ bool can_substitute(APValue &Result, Sema &S, EvalFn Evaluator, if (!Evaluator(Unwrapped, Synthesized, true) || !Unwrapped.isReflection()) return true; - if (!CanActAsTemplateArg(Unwrapped.getReflection())) + if (!CanActAsTemplateArg(Unwrapped)) return SetAndSucceed(Result, makeBool(S.Context, false)); TemplateArgument TArg = TArgFromReflection(S, Evaluator, - Unwrapped.getReflection(), - Range.getBegin()); + Unwrapped, Range.getBegin()); if (TArg.isNull()) llvm_unreachable("could not form template argument?"); TArgs.push_back(TArg); @@ -2461,9 +2429,9 @@ bool substitute(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, if (!Evaluator(Template, Args[0], true)) return true; - if (Template.getReflection().getKind() != ReflectionValue::RK_template) + if (!Template.isReflectedTemplate()) return DiagnoseReflectionKind(Diagnoser, Range, "a template", - DescriptionOf(Template.getReflection())); + DescriptionOf(Template)); TemplateDecl *TDecl = Template.getReflectedTemplate().getAsTemplateDecl(); if (TDecl->isInvalidDecl()) @@ -2495,13 +2463,12 @@ bool substitute(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, if (!Evaluator(Unwrapped, Synthesized, true) || !Unwrapped.isReflection()) return true; - if (!CanActAsTemplateArg(Unwrapped.getReflection())) + if (!CanActAsTemplateArg(Unwrapped)) return Diagnoser(Range.getBegin(), diag::metafn_cannot_be_arg) - << DescriptionOf(Unwrapped.getReflection()) << 1 << Range; + << DescriptionOf(Unwrapped) << 1 << Range; TemplateArgument TArg = TArgFromReflection(S, Evaluator, - Unwrapped.getReflection(), - Range.getBegin()); + Unwrapped, Range.getBegin()); if (TArg.isNull()) llvm_unreachable("could not form template argument?"); TArgs.push_back(TArg); @@ -2534,9 +2501,9 @@ bool substitute(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, } assert(TSpecDecl); - ReflectionValue RV(ReflectionValue::RK_type, - const_cast(TSpecDecl->getTypeForDecl())); - return SetAndSucceed(Result, APValue(RV)); + APValue RV(ReflectionKind::Type, + const_cast(TSpecDecl->getTypeForDecl())); + return SetAndSucceed(Result, RV); } else if (isa(TDecl)) { TemplateArgumentListInfo TAListInfo = addLocToTemplateArgs(S, TArgs, Args[1]); @@ -2567,8 +2534,8 @@ bool substitute(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, // Could not instantiate function with the provided arguments. llvm_unreachable("Substitution failed after validating arguments?"); - ReflectionValue RV(ReflectionValue::RK_declaration, TSpecDecl); - return SetAndSucceed(Result, APValue(RV)); + return SetAndSucceed(Result, + APValue(ReflectionKind::Declaration, TSpecDecl)); } else if (auto *VTD = dyn_cast(TDecl)) { void *InsertPos; VarTemplateSpecializationDecl *TSpecDecl = @@ -2601,10 +2568,7 @@ bool substitute(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, if (!Evaluator(SatisfiesConcept, ER.get(), true)) llvm_unreachable("Substitution failed after validating arguments?"); - ReflectionValue RV(ReflectionValue::RK_value, - new (S.Context) APValue(SatisfiesConcept), - S.Context.BoolTy); - return SetAndSucceed(Result, APValue(RV)); + return SetAndSucceed(Result, SatisfiesConcept.Lift(S.Context.BoolTy)); } llvm_unreachable("unimplemented for template kind"); } @@ -2647,38 +2611,39 @@ bool extract(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, return SetAndSucceed(Out, CallOpLV); }; - APValue R; - if (!Evaluator(R, Args[1], true)) + APValue RV; + if (!Evaluator(RV, Args[1], true)) return true; - ReflectionValue RV = R.getReflection(); - switch (RV.getKind()) { - case ReflectionValue::RK_object: { - if (RV.getResultType().getCanonicalType().getTypePtr() != + switch (RV.getReflectionKind()) { + case ReflectionKind::Object: { + QualType ObjectTy = RV.getTypeOfReflectedResult(S.Context); + if (ObjectTy.getCanonicalType().getTypePtr() != ResultTy.getCanonicalType().getTypePtr()) return Diagnoser(Range.getBegin(), diag::metafn_extract_type_mismatch) - << 1 << RV.getResultType() << ReturnsLValue << ResultTy << Range; + << 1 << ObjectTy << ReturnsLValue << ResultTy << Range; - return SetAndSucceed(Result, RV.getAsObject()); + return SetAndSucceed(Result, RV.getReflectedObject()); } - case ReflectionValue::RK_value: { + case ReflectionKind::Value: { if (ReturnsLValue) return Diagnoser(Range.getBegin(), diag::metafn_cannot_extract) << 1 << DescriptionOf(RV) << Range; - if (auto *RD = RV.getResultType()->getAsCXXRecordDecl(); + QualType ValueTy = RV.getTypeOfReflectedResult(S.Context); + if (auto *RD = ValueTy->getAsCXXRecordDecl(); RD && RD->isLambda() && ResultTy->isPointerType()) return extractLambda(Result, RD); - if (RV.getResultType().getCanonicalType().getTypePtr() != + if (ValueTy.getCanonicalType().getTypePtr() != ResultTy.getCanonicalType().getTypePtr()) return Diagnoser(Range.getBegin(), diag::metafn_extract_type_mismatch) - << 0 << RV.getResultType() << ReturnsLValue << ResultTy << Range; + << 0 << ValueTy << ReturnsLValue << ResultTy << Range; - return SetAndSucceed(Result, RV.getAsValue()); + return SetAndSucceed(Result, RV.getReflectedValue()); } - case ReflectionValue::RK_declaration: { - ValueDecl *Decl = R.getReflectedDecl(); + case ReflectionKind::Declaration: { + ValueDecl *Decl = RV.getReflectedDecl(); ensureInstantiated(S, Decl, Args[1]->getSourceRange()); if (auto *RD = Decl->getType()->getAsCXXRecordDecl(); @@ -2736,12 +2701,12 @@ bool extract(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, } else if (ReturnsLValue) { // Only variables may be returned as LValues. return Diagnoser(Range.getBegin(), diag::metafn_cannot_extract) - << 1 << DescriptionOf(R.getReflection()); + << 1 << DescriptionOf(RV); } else if (isa(Decl)) { // Extracting a non-static member as a pointer. if (auto *FD = dyn_cast(Decl); FD && FD->isBitField()) return Diagnoser(Range.getBegin(), diag::metafn_cannot_extract) << 2 - << DescriptionOf(R.getReflection()) << Range; + << DescriptionOf(RV) << Range; auto *ParentTy = cast( Decl->getDeclContext())->getTypeForDecl(); @@ -2751,8 +2716,7 @@ bool extract(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, ResultTy.getCanonicalType().getTypePtr()) return Diagnoser(Range.getBegin(), diag::metafn_extract_entity_type_mismatch) - << ResultTy << DescriptionOf(R.getReflection()) << MemPtrTy - << Range; + << ResultTy << DescriptionOf(RV) << MemPtrTy << Range; APValue MemPtrLV(Decl, false, ArrayRef {}); return SetAndSucceed(Result, MemPtrLV); @@ -2774,15 +2738,14 @@ bool extract(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, APValue::NoLValuePath())); } } - case ReflectionValue::RK_null: - case ReflectionValue::RK_type: - case ReflectionValue::RK_template: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + case ReflectionKind::Null: + case ReflectionKind::Type: + case ReflectionKind::Template: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return Diagnoser(Range.getBegin(), diag::metafn_cannot_extract) - << (ReturnsLValue ? 1 : 0) - << DescriptionOf(R.getReflection()) << Range; + << (ReturnsLValue ? 1 : 0) << DescriptionOf(RV) << Range; } llvm_unreachable("invalid reflection type"); } @@ -2792,38 +2755,38 @@ bool is_public(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_type: { + switch (RV.getReflectionKind()) { + case ReflectionKind::Type: { bool IsPublic = false; - if (const Decl *D = findTypeDecl(R.getReflectedType())) + if (const Decl *D = findTypeDecl(RV.getReflectedType())) IsPublic = (D->getAccess() == AS_public); return SetAndSucceed(Result, makeBool(S.Context, IsPublic)); } - case ReflectionValue::RK_declaration: { - bool IsPublic = (R.getReflectedDecl()->getAccess() == AS_public); + case ReflectionKind::Declaration: { + bool IsPublic = (RV.getReflectedDecl()->getAccess() == AS_public); return SetAndSucceed(Result, makeBool(S.Context, IsPublic)); } - case ReflectionValue::RK_template: { - const Decl *D = R.getReflectedTemplate().getAsTemplateDecl(); + case ReflectionKind::Template: { + const Decl *D = RV.getReflectedTemplate().getAsTemplateDecl(); bool IsPublic = (D->getAccess() == AS_public); return SetAndSucceed(Result, makeBool(S.Context, IsPublic)); } - case ReflectionValue::RK_base_specifier: { - CXXBaseSpecifier *Base = R.getReflectedBaseSpecifier(); + case ReflectionKind::BaseSpecifier: { + CXXBaseSpecifier *Base = RV.getReflectedBaseSpecifier(); bool IsPublic = (Base->getAccessSpecifier() == AS_public); return SetAndSucceed(Result, makeBool(S.Context, IsPublic)); } - case ReflectionValue::RK_null: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_data_member_spec: - case ReflectionValue::RK_namespace: + case ReflectionKind::Null: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::DataMemberSpec: + case ReflectionKind::Namespace: return SetAndSucceed(Result, makeBool(S.Context, false)); } llvm_unreachable("invalid reflection type"); @@ -2834,38 +2797,38 @@ bool is_protected(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_type: { + switch (RV.getReflectionKind()) { + case ReflectionKind::Type: { bool IsProtected = false; - if (const Decl *D = findTypeDecl(R.getReflectedType())) + if (const Decl *D = findTypeDecl(RV.getReflectedType())) IsProtected = (D->getAccess() == AS_protected); return SetAndSucceed(Result, makeBool(S.Context, IsProtected)); } - case ReflectionValue::RK_declaration: { - bool IsProtected = (R.getReflectedDecl()->getAccess() == AS_protected); + case ReflectionKind::Declaration: { + bool IsProtected = (RV.getReflectedDecl()->getAccess() == AS_protected); return SetAndSucceed(Result, makeBool(S.Context, IsProtected)); } - case ReflectionValue::RK_template: { - const Decl *D = R.getReflectedTemplate().getAsTemplateDecl(); + case ReflectionKind::Template: { + const Decl *D = RV.getReflectedTemplate().getAsTemplateDecl(); bool IsProtected = (D->getAccess() == AS_protected); return SetAndSucceed(Result, makeBool(S.Context, IsProtected)); } - case ReflectionValue::RK_base_specifier: { - CXXBaseSpecifier *Base = R.getReflectedBaseSpecifier(); + case ReflectionKind::BaseSpecifier: { + CXXBaseSpecifier *Base = RV.getReflectedBaseSpecifier(); bool IsProtected = (Base->getAccessSpecifier() == AS_protected); return SetAndSucceed(Result, makeBool(S.Context, IsProtected)); } - case ReflectionValue::RK_null: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_data_member_spec: - case ReflectionValue::RK_namespace: + case ReflectionKind::Null: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::DataMemberSpec: + case ReflectionKind::Namespace: return SetAndSucceed(Result, makeBool(S.Context, false)); } llvm_unreachable("invalid reflection type"); @@ -2876,38 +2839,38 @@ bool is_private(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_type: { + switch (RV.getReflectionKind()) { + case ReflectionKind::Type: { bool IsPrivate = false; - if (const Decl *D = findTypeDecl(R.getReflectedType())) + if (const Decl *D = findTypeDecl(RV.getReflectedType())) IsPrivate = (D->getAccess() == AS_private); return SetAndSucceed(Result, makeBool(S.Context, IsPrivate)); } - case ReflectionValue::RK_declaration: { - bool IsPrivate = (R.getReflectedDecl()->getAccess() == AS_private); + case ReflectionKind::Declaration: { + bool IsPrivate = (RV.getReflectedDecl()->getAccess() == AS_private); return SetAndSucceed(Result, makeBool(S.Context, IsPrivate)); } - case ReflectionValue::RK_template: { - const Decl *D = R.getReflectedTemplate().getAsTemplateDecl(); + case ReflectionKind::Template: { + const Decl *D = RV.getReflectedTemplate().getAsTemplateDecl(); bool IsPrivate = (D->getAccess() == AS_private); return SetAndSucceed(Result, makeBool(S.Context, IsPrivate)); } - case ReflectionValue::RK_base_specifier: { - CXXBaseSpecifier *Base = R.getReflectedBaseSpecifier(); + case ReflectionKind::BaseSpecifier: { + CXXBaseSpecifier *Base = RV.getReflectedBaseSpecifier(); bool IsPrivate = (Base->getAccessSpecifier() == AS_private); return SetAndSucceed(Result, makeBool(S.Context, IsPrivate)); } - case ReflectionValue::RK_null: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_data_member_spec: + case ReflectionKind::Null: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Namespace: + case ReflectionKind::DataMemberSpec: return SetAndSucceed(Result, makeBool(S.Context, false)); } llvm_unreachable("invalid reflection type"); @@ -2945,53 +2908,53 @@ bool is_accessible(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, return true; DeclContext *AccessDC = nullptr; - switch (Scratch.getReflection().getKind()) { - case ReflectionValue::RK_type: + switch (Scratch.getReflectionKind()) { + case ReflectionKind::Type: AccessDC = dyn_cast(findTypeDecl(Scratch.getReflectedType())); if (!AccessDC) return true; break; - case ReflectionValue::RK_namespace: + case ReflectionKind::Namespace: AccessDC = dyn_cast(Scratch.getReflectedNamespace()); break; - case ReflectionValue::RK_declaration: + case ReflectionKind::Declaration: AccessDC = dyn_cast(Scratch.getReflectedDecl()); break; default: llvm_unreachable("invalid access context"); } - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_type: { - NamedDecl *D = findTypeDecl(R.getReflectedType()); + switch (RV.getReflectionKind()) { + case ReflectionKind::Type: { + NamedDecl *D = findTypeDecl(RV.getReflectedType()); if (!D || !D->getDeclContext() || !isa(D->getDeclContext())) return DiagnoseReflectionKind(Diagnoser, Range, "a class member"); bool Accessible = isAccessible(S, AccessDC, D); return SetAndSucceed(Result, makeBool(S.Context, Accessible)); } - case ReflectionValue::RK_declaration: { - ValueDecl *D = R.getReflectedDecl(); + case ReflectionKind::Declaration: { + ValueDecl *D = RV.getReflectedDecl(); if (!D->getDeclContext() || !isa(D->getDeclContext())) return DiagnoseReflectionKind(Diagnoser, Range, "a class member"); - bool Accessible = isAccessible(S, AccessDC, R.getReflectedDecl()); + bool Accessible = isAccessible(S, AccessDC, RV.getReflectedDecl()); return SetAndSucceed(Result, makeBool(S.Context, Accessible)); } - case ReflectionValue::RK_template: { - TemplateDecl *D = R.getReflectedTemplate().getAsTemplateDecl(); + case ReflectionKind::Template: { + TemplateDecl *D = RV.getReflectedTemplate().getAsTemplateDecl(); if (!D->getDeclContext() || !isa(D->getDeclContext())) return DiagnoseReflectionKind(Diagnoser, Range, "a class member"); bool Accessible = isAccessible(S, AccessDC, D); return SetAndSucceed(Result, makeBool(S.Context, Accessible)); } - case ReflectionValue::RK_base_specifier: { - CXXBaseSpecifier *BaseSpec = R.getReflectedBaseSpecifier(); + case ReflectionKind::BaseSpecifier: { + CXXBaseSpecifier *BaseSpec = RV.getReflectedBaseSpecifier(); auto *Base = findTypeDecl(BaseSpec->getType()); assert(Base && "base class has no type declaration?"); @@ -3014,13 +2977,13 @@ bool is_accessible(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, bool Accessible = (AR == Sema::AR_accessible); return SetAndSucceed(Result, makeBool(S.Context, Accessible)); } - case ReflectionValue::RK_null: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_data_member_spec: + case ReflectionKind::Null: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Namespace: + case ReflectionKind::DataMemberSpec: return DiagnoseReflectionKind(Diagnoser, Range, "a class member", - DescriptionOf(R.getReflection())); + DescriptionOf(RV)); } llvm_unreachable("invalid reflection type"); } @@ -3030,28 +2993,28 @@ bool is_virtual(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool IsVirtual = false; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_declaration: { - if (const auto *MD = dyn_cast(R.getReflectedDecl())) + switch (RV.getReflectionKind()) { + case ReflectionKind::Declaration: { + if (const auto *MD = dyn_cast(RV.getReflectedDecl())) IsVirtual = MD->isVirtual(); return SetAndSucceed(Result, makeBool(S.Context, IsVirtual)); } - case ReflectionValue::RK_base_specifier: { - IsVirtual = R.getReflectedBaseSpecifier()->isVirtual(); + case ReflectionKind::BaseSpecifier: { + IsVirtual = RV.getReflectedBaseSpecifier()->isVirtual(); return SetAndSucceed(Result, makeBool(S.Context, IsVirtual)); } - case ReflectionValue::RK_null: - case ReflectionValue::RK_type: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_template: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_data_member_spec: + case ReflectionKind::Null: + case ReflectionKind::Type: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Template: + case ReflectionKind::Namespace: + case ReflectionKind::DataMemberSpec: return SetAndSucceed(Result, makeBool(S.Context, IsVirtual)); } llvm_unreachable("invalid reflection type"); @@ -3063,23 +3026,23 @@ bool is_pure_virtual(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_null: - case ReflectionValue::RK_type: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_template: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + switch (RV.getReflectionKind()) { + case ReflectionKind::Null: + case ReflectionKind::Type: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Template: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return SetAndSucceed(Result, makeBool(S.Context, false)); - case ReflectionValue::RK_declaration: { + case ReflectionKind::Declaration: { bool IsPureVirtual = false; - if (const auto *FD = dyn_cast(R.getReflectedDecl())) + if (const auto *FD = dyn_cast(RV.getReflectedDecl())) IsPureVirtual = FD->isPureVirtual(); return SetAndSucceed(Result, makeBool(S.Context, IsPureVirtual)); @@ -3093,23 +3056,23 @@ bool is_override(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool IsOverride = false; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_null: - case ReflectionValue::RK_type: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_template: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + switch (RV.getReflectionKind()) { + case ReflectionKind::Null: + case ReflectionKind::Type: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Template: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return SetAndSucceed(Result, makeBool(S.Context, false)); - case ReflectionValue::RK_declaration: { - if (const auto *MD = dyn_cast(R.getReflectedDecl())) + case ReflectionKind::Declaration: { + if (const auto *MD = dyn_cast(RV.getReflectedDecl())) IsOverride = MD->size_overridden_methods() > 0; return SetAndSucceed(Result, makeBool(S.Context, IsOverride)); } @@ -3122,23 +3085,23 @@ bool is_deleted(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_null: - case ReflectionValue::RK_type: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_template: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + switch (RV.getReflectionKind()) { + case ReflectionKind::Null: + case ReflectionKind::Type: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Template: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return SetAndSucceed(Result, makeBool(S.Context, false)); - case ReflectionValue::RK_declaration: { + case ReflectionKind::Declaration: { bool IsDeleted = false; - if (const auto *FD = dyn_cast(R.getReflectedDecl())) + if (const auto *FD = dyn_cast(RV.getReflectedDecl())) IsDeleted = FD->isDeleted(); return SetAndSucceed(Result, makeBool(S.Context, IsDeleted)); } @@ -3151,23 +3114,23 @@ bool is_defaulted(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_null: - case ReflectionValue::RK_type: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_template: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + switch (RV.getReflectionKind()) { + case ReflectionKind::Null: + case ReflectionKind::Type: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Template: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return SetAndSucceed(Result, makeBool(S.Context, false)); - case ReflectionValue::RK_declaration: { + case ReflectionKind::Declaration: { bool IsDefaulted = false; - if (const auto *FD = dyn_cast(R.getReflectedDecl())) + if (const auto *FD = dyn_cast(RV.getReflectedDecl())) IsDefaulted = FD->isDefaulted(); return SetAndSucceed(Result, makeBool(S.Context, IsDefaulted)); @@ -3181,22 +3144,22 @@ bool is_explicit(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_null: - case ReflectionValue::RK_type: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: - case ReflectionValue::RK_template: + switch (RV.getReflectionKind()) { + case ReflectionKind::Null: + case ReflectionKind::Type: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: + case ReflectionKind::Template: return SetAndSucceed(Result, makeBool(S.Context, false)); - case ReflectionValue::RK_declaration: { - ValueDecl *D = R.getReflectedDecl(); + case ReflectionKind::Declaration: { + ValueDecl *D = RV.getReflectedDecl(); bool result = false; if (auto *CtorD = dyn_cast(D)) @@ -3214,27 +3177,27 @@ bool is_noexcept(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_null: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_template: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + switch (RV.getReflectionKind()) { + case ReflectionKind::Null: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Template: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return SetAndSucceed(Result, makeBool(S.Context, false)); - case ReflectionValue::RK_type: { - const QualType QT = R.getReflectedType(); + case ReflectionKind::Type: { + const QualType QT = RV.getReflectedType(); const auto result = isFunctionOrMethodNoexcept(QT); return SetAndSucceed(Result, makeBool(S.Context, result)); } - case ReflectionValue::RK_declaration: { - const ValueDecl *D = R.getReflectedDecl(); + case ReflectionKind::Declaration: { + const ValueDecl *D = RV.getReflectedDecl(); const auto result = isFunctionOrMethodNoexcept(D->getType()); return SetAndSucceed(Result, makeBool(S.Context, result)); @@ -3248,17 +3211,16 @@ bool is_bit_field(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool result = false; - if (R.getReflection().getKind() == ReflectionValue::RK_declaration) { - if (const auto *FD = dyn_cast(R.getReflectedDecl())) + if (RV.isReflectedDecl()) { + if (const auto *FD = dyn_cast(RV.getReflectedDecl())) result = FD->isBitField(); - } else if (R.getReflection().getKind() == - ReflectionValue::RK_data_member_spec) { - result = R.getReflectedDataMemberSpec()->BitWidth.has_value(); + } else if (RV.isReflectedDataMemberSpec()) { + result = RV.getReflectedDataMemberSpec()->BitWidth.has_value(); } return SetAndSucceed(Result, makeBool(S.Context, result)); } @@ -3269,13 +3231,13 @@ bool is_enumerator(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool result = false; - if (R.getReflection().getKind() == ReflectionValue::RK_declaration) - result = isa(R.getReflectedDecl()); + if (RV.isReflectedDecl()) + result = isa(RV.getReflectedDecl()); return SetAndSucceed(Result, makeBool(S.Context, result)); } @@ -3285,32 +3247,32 @@ bool is_const(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_null: - case ReflectionValue::RK_template: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + switch (RV.getReflectionKind()) { + case ReflectionKind::Null: + case ReflectionKind::Template: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return SetAndSucceed(Result, makeBool(S.Context, false)); - case ReflectionValue::RK_type: { - bool result = isConstQualifiedType(R.getReflectedType()); + case ReflectionKind::Type: { + bool result = isConstQualifiedType(RV.getReflectedType()); return SetAndSucceed(Result, makeBool(S.Context, result)); } - case ReflectionValue::RK_declaration: { + case ReflectionKind::Declaration: { bool result = false; - if (!isa(R.getReflectedDecl())) - result = isConstQualifiedType(R.getReflectedDecl()->getType()); + if (!isa(RV.getReflectedDecl())) + result = isConstQualifiedType(RV.getReflectedDecl()->getType()); return SetAndSucceed(Result, makeBool(S.Context, result)); } - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: { - bool result = isConstQualifiedType(R.getReflection().getResultType()); + case ReflectionKind::Object: + case ReflectionKind::Value: { + bool result = isConstQualifiedType(RV.getTypeOfReflectedResult(S.Context)); return SetAndSucceed(Result, makeBool(S.Context, result)); } @@ -3323,32 +3285,33 @@ bool is_volatile(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_null: - case ReflectionValue::RK_template: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + switch (RV.getReflectionKind()) { + case ReflectionKind::Null: + case ReflectionKind::Template: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return SetAndSucceed(Result, makeBool(S.Context, false)); - case ReflectionValue::RK_type: { - bool result = isVolatileQualifiedType(R.getReflectedType()); + case ReflectionKind::Type: { + bool result = isVolatileQualifiedType(RV.getReflectedType()); return SetAndSucceed(Result, makeBool(S.Context, result)); } - case ReflectionValue::RK_declaration: { + case ReflectionKind::Declaration: { bool result = false; - if (!isa(R.getReflectedDecl())) - result = isVolatileQualifiedType(R.getReflectedDecl()->getType()); + if (!isa(RV.getReflectedDecl())) + result = isVolatileQualifiedType(RV.getReflectedDecl()->getType()); return SetAndSucceed(Result, makeBool(S.Context, result)); } - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: { - bool result = isVolatileQualifiedType(R.getReflection().getResultType()); + case ReflectionKind::Object: + case ReflectionKind::Value: { + bool result = isVolatileQualifiedType( + RV.getTypeOfReflectedResult(S.Context)); return SetAndSucceed(Result, makeBool(S.Context, result)); } @@ -3362,16 +3325,16 @@ bool is_lvalue_reference_qualified(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool result = false; - if (R.getReflection().getKind() == ReflectionValue::RK_type) { - if (auto FT = dyn_cast(R.getReflectedType())) + if (RV.isReflectedType()) { + if (auto FT = dyn_cast(RV.getReflectedType())) result = (FT->getRefQualifier() == RQ_LValue); - } else if (R.getReflection().getKind() == ReflectionValue::RK_declaration) { - if (const auto *FD = dyn_cast(R.getReflectedDecl())) + } else if (RV.isReflectedDecl()) { + if (const auto *FD = dyn_cast(RV.getReflectedDecl())) if (auto FT = dyn_cast(FD->getType())) result = (FT->getRefQualifier() == RQ_LValue); } @@ -3384,16 +3347,16 @@ bool is_rvalue_reference_qualified(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool result = false; - if (R.getReflection().getKind() == ReflectionValue::RK_type) { - if (auto FT = dyn_cast(R.getReflectedType())) + if (RV.isReflectedType()) { + if (auto FT = dyn_cast(RV.getReflectedType())) result = (FT->getRefQualifier() == RQ_RValue); - } else if (R.getReflection().getKind() == ReflectionValue::RK_declaration) { - if (const auto *FD = dyn_cast(R.getReflectedDecl())) + } else if (RV.isReflectedDecl()) { + if (const auto *FD = dyn_cast(RV.getReflectedDecl())) if (auto FT = dyn_cast(FD->getType())) result = (FT->getRefQualifier() == RQ_RValue); } @@ -3406,17 +3369,17 @@ bool has_static_storage_duration(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool result = false; - if (R.getReflection().getKind() == ReflectionValue::RK_declaration) { - if (const auto *VD = dyn_cast(R.getReflectedDecl())) + if (RV.isReflectedDecl()) { + if (const auto *VD = dyn_cast(RV.getReflectedDecl())) result = VD->getStorageDuration() == SD_Static; - else if (isa(R.getReflectedDecl())) + else if (isa(RV.getReflectedDecl())) result = true; - } else if (R.getReflection().getKind() == ReflectionValue::RK_object) { + } else if (RV.isReflectedObject()) { result = true; } return SetAndSucceed(Result, makeBool(S.Context, result)); @@ -3428,20 +3391,20 @@ bool has_internal_linkage(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool result = false; - if (R.getReflection().getKind() == ReflectionValue::RK_type) { + if (RV.isReflectedType()) { if (NamedDecl *typeDecl = - dyn_cast_or_null(findTypeDecl(R.getReflectedType()))) + dyn_cast_or_null(findTypeDecl(RV.getReflectedType()))) result = (typeDecl->getFormalLinkage() == Linkage::Internal); - } else if (R.getReflection().getKind() == ReflectionValue::RK_declaration) { - if (const auto *ND = dyn_cast(R.getReflectedDecl())) + } else if (RV.isReflectedDecl()) { + if (const auto *ND = dyn_cast(RV.getReflectedDecl())) result = (ND->getFormalLinkage() == Linkage::Internal); - } else if (R.getReflection().getKind() == ReflectionValue::RK_object) { - if (APValue::LValueBase LVBase = R.getReflectedObject().getLValueBase(); + } else if (RV.isReflectedObject()) { + if (APValue::LValueBase LVBase = RV.getReflectedObject().getLValueBase(); LVBase.is()) { const ValueDecl *VD = LVBase.get(); result = (VD->getFormalLinkage() == Linkage::Internal); @@ -3456,20 +3419,20 @@ bool has_module_linkage(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool result = false; - if (R.getReflection().getKind() == ReflectionValue::RK_type) { + if (RV.isReflectedType()) { if (NamedDecl *typeDecl = - dyn_cast_or_null(findTypeDecl(R.getReflectedType()))) + dyn_cast_or_null(findTypeDecl(RV.getReflectedType()))) result = (typeDecl->getFormalLinkage() == Linkage::Module); - } else if (R.getReflection().getKind() == ReflectionValue::RK_declaration) { - if (const auto *ND = dyn_cast(R.getReflectedDecl())) + } else if (RV.isReflectedDecl()) { + if (const auto *ND = dyn_cast(RV.getReflectedDecl())) result = (ND->getFormalLinkage() == Linkage::Module); - } else if (R.getReflection().getKind() == ReflectionValue::RK_object) { - if (APValue::LValueBase LVBase = R.getReflectedObject().getLValueBase(); + } else if (RV.isReflectedObject()) { + if (APValue::LValueBase LVBase = RV.getReflectedObject().getLValueBase(); LVBase.is()) { const ValueDecl *VD = LVBase.get(); result = (VD->getFormalLinkage() == Linkage::Module); @@ -3484,22 +3447,22 @@ bool has_external_linkage(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool result = false; - if (R.getReflection().getKind() == ReflectionValue::RK_type) { + if (RV.isReflectedType()) { if (NamedDecl *typeDecl = - dyn_cast_or_null(findTypeDecl(R.getReflectedType()))) + dyn_cast_or_null(findTypeDecl(RV.getReflectedType()))) result = (typeDecl->getFormalLinkage() == Linkage::External || typeDecl->getFormalLinkage() == Linkage::UniqueExternal); - } else if (R.getReflection().getKind() == ReflectionValue::RK_declaration) { - if (const auto *ND = dyn_cast(R.getReflectedDecl())) + } else if (RV.isReflectedDecl()) { + if (const auto *ND = dyn_cast(RV.getReflectedDecl())) result = (ND->getFormalLinkage() == Linkage::External || ND->getFormalLinkage() == Linkage::UniqueExternal); - } else if (R.getReflection().getKind() == ReflectionValue::RK_object) { - if (APValue::LValueBase LVBase = R.getReflectedObject().getLValueBase(); + } else if (RV.isReflectedObject()) { + if (APValue::LValueBase LVBase = RV.getReflectedObject().getLValueBase(); LVBase.is()) { const ValueDecl *VD = LVBase.get(); result = (VD->getFormalLinkage() == Linkage::External || @@ -3514,20 +3477,20 @@ bool has_linkage(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool result = false; - if (R.getReflection().getKind() == ReflectionValue::RK_type) { + if (RV.isReflectedType()) { if (NamedDecl *typeDecl = - dyn_cast_or_null(findTypeDecl(R.getReflectedType()))) + dyn_cast_or_null(findTypeDecl(RV.getReflectedType()))) result = typeDecl->hasLinkage(); - } else if (R.getReflection().getKind() == ReflectionValue::RK_declaration) { - if (const auto *ND = dyn_cast(R.getReflectedDecl())) + } else if (RV.isReflectedDecl()) { + if (const auto *ND = dyn_cast(RV.getReflectedDecl())) result = ND->hasLinkage(); - } else if (R.getReflection().getKind() == ReflectionValue::RK_object) { - if (APValue::LValueBase LVBase = R.getReflectedObject().getLValueBase(); + } else if (RV.isReflectedObject()) { + if (APValue::LValueBase LVBase = RV.getReflectedObject().getLValueBase(); LVBase.is()) { const ValueDecl *VD = LVBase.get(); result = (VD->hasLinkage()); @@ -3549,7 +3512,7 @@ bool is_class_member(APValue &Result, Sema &S, EvalFn Evaluator, if (!parent_of(Scratch, S, Evaluator, SwallowDiags, S.Context.MetaInfoTy, Range, Args)) { assert(Scratch.isReflection()); - result = (Scratch.getReflection().getKind() == ReflectionValue::RK_type); + result = Scratch.isReflectedType(); } return SetAndSucceed(Result, makeBool(S.Context, result)); } @@ -3567,8 +3530,7 @@ bool is_namespace_member(APValue &Result, Sema &S, EvalFn Evaluator, if (!parent_of(Scratch, S, Evaluator, SwallowDiags, S.Context.MetaInfoTy, Range, Args)) { assert(Scratch.isReflection()); - result = (Scratch.getReflection().getKind() == - ReflectionValue::RK_namespace); + result = Scratch.isReflectedNamespace(); } return SetAndSucceed(Result, makeBool(S.Context, result)); } @@ -3579,13 +3541,13 @@ bool is_nonstatic_data_member(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool result = false; - if (R.getReflection().getKind() == ReflectionValue::RK_declaration) { - result = isa(R.getReflectedDecl()); + if (RV.isReflectedDecl()) { + result = isa(RV.getReflectedDecl()); } return SetAndSucceed(Result, makeBool(S.Context, result)); } @@ -3596,22 +3558,22 @@ bool is_static_member(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool result = false; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_declaration: { - const ValueDecl *D = cast(R.getReflectedDecl()); + switch (RV.getReflectionKind()) { + case ReflectionKind::Declaration: { + const ValueDecl *D = cast(RV.getReflectedDecl()); if (const auto *MD = dyn_cast(D)) result = MD->isStatic(); else if (const auto *VD = dyn_cast(D)) result = VD->isStaticDataMember(); return SetAndSucceed(Result, makeBool(S.Context, result)); } - case ReflectionValue::RK_template: { - const Decl *D = R.getReflectedTemplate().getAsTemplateDecl(); + case ReflectionKind::Template: { + const Decl *D = RV.getReflectedTemplate().getAsTemplateDecl(); if (const auto *FTD = dyn_cast(D)) { if (const auto *MD = dyn_cast(FTD->getTemplatedDecl())) result = MD->isStatic(); @@ -3621,13 +3583,13 @@ bool is_static_member(APValue &Result, Sema &S, EvalFn Evaluator, } return SetAndSucceed(Result, makeBool(S.Context, result)); } - case ReflectionValue::RK_null: - case ReflectionValue::RK_type: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + case ReflectionKind::Null: + case ReflectionKind::Type: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return SetAndSucceed(Result, makeBool(S.Context, result)); } llvm_unreachable("unknown reflection kind"); @@ -3638,14 +3600,12 @@ bool is_base(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; return SetAndSucceed(Result, - makeBool(S.Context, - R.getReflection().getKind() == - ReflectionValue::RK_base_specifier)); + makeBool(S.Context, RV.isReflectedBaseSpecifier())); } bool is_data_member_spec(APValue &Result, Sema &S, EvalFn Evaluator, @@ -3654,14 +3614,12 @@ bool is_data_member_spec(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; return SetAndSucceed(Result, - makeBool(S.Context, - R.getReflection().getKind() == - ReflectionValue::RK_data_member_spec)); + makeBool(S.Context, RV.isReflectedDataMemberSpec())); } bool is_namespace(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, @@ -3669,13 +3627,11 @@ bool is_namespace(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - return SetAndSucceed(Result, makeBool(S.Context, - R.getReflection().getKind() == - ReflectionValue::RK_namespace)); + return SetAndSucceed(Result, makeBool(S.Context, RV.isReflectedNamespace())); } bool is_function(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, @@ -3683,14 +3639,13 @@ bool is_function(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool result = false; - if (R.getReflection().getKind() == ReflectionValue::RK_declaration) { - result = isa(R.getReflectedDecl()); - } + if (RV.isReflectedDecl()) + result = isa(RV.getReflectedDecl()); return SetAndSucceed(Result, makeBool(S.Context, result)); } @@ -3699,14 +3654,13 @@ bool is_variable(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool result = false; - if (R.getReflection().getKind() == ReflectionValue::RK_declaration) { - result = isa(R.getReflectedDecl()); - } + if (RV.isReflectedDecl()) + result = isa(RV.getReflectedDecl()); return SetAndSucceed(Result, makeBool(S.Context, result)); } @@ -3715,13 +3669,11 @@ bool is_type(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - return SetAndSucceed(Result, makeBool(S.Context, - R.getReflection().getKind() == - ReflectionValue::RK_type)); + return SetAndSucceed(Result, makeBool(S.Context, RV.isReflectedType())); } bool is_alias(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, @@ -3729,30 +3681,30 @@ bool is_alias(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_type: { - bool result = isTypeAlias(R.getReflectedType()); + switch (RV.getReflectionKind()) { + case ReflectionKind::Type: { + bool result = isTypeAlias(RV.getReflectedType()); return SetAndSucceed(Result, makeBool(S.Context, result)); } - case ReflectionValue::RK_namespace: { - bool result = isa(R.getReflectedNamespace()); + case ReflectionKind::Namespace: { + bool result = isa(RV.getReflectedNamespace()); return SetAndSucceed(Result, makeBool(S.Context, result)); } - case ReflectionValue::RK_template: { - TemplateDecl *TDecl = R.getReflectedTemplate().getAsTemplateDecl(); + case ReflectionKind::Template: { + TemplateDecl *TDecl = RV.getReflectedTemplate().getAsTemplateDecl(); bool result = isa(TDecl); return SetAndSucceed(Result, makeBool(S.Context, result)); } - case ReflectionValue::RK_null: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_declaration: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + case ReflectionKind::Null: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Declaration: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return SetAndSucceed(Result, makeBool(S.Context, false)); } llvm_unreachable("unknown reflection kind"); @@ -3764,18 +3716,18 @@ bool is_incomplete_type(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool result = false; - if (R.getReflection().getKind() == ReflectionValue::RK_type) { + if (RV.isReflectedType()) { // If this is a declared type with a reachable definition, ensure that the // type is instantiated. - if (Decl *typeDecl = findTypeDecl(R.getReflectedType())) + if (Decl *typeDecl = findTypeDecl(RV.getReflectedType())) (void) ensureInstantiated(S, typeDecl, Range); - result = R.getReflectedType()->isIncompleteType(); + result = RV.getReflectedType()->isIncompleteType(); } return SetAndSucceed(Result, makeBool(S.Context, result)); } @@ -3785,13 +3737,11 @@ bool is_template(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - return SetAndSucceed(Result, makeBool(S.Context, - R.getReflection().getKind() == - ReflectionValue::RK_template)); + return SetAndSucceed(Result, makeBool(S.Context, RV.isReflectedTemplate())); } bool is_function_template(APValue &Result, Sema &S, EvalFn Evaluator, @@ -3800,13 +3750,13 @@ bool is_function_template(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool IsFnTemplate = false; - if (R.getReflection().getKind() == ReflectionValue::RK_template) { - const TemplateDecl *TD = R.getReflectedTemplate().getAsTemplateDecl(); + if (RV.isReflectedTemplate()) { + const TemplateDecl *TD = RV.getReflectedTemplate().getAsTemplateDecl(); IsFnTemplate = isa(TD); } return SetAndSucceed(Result, makeBool(S.Context, IsFnTemplate)); @@ -3818,13 +3768,13 @@ bool is_variable_template(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool IsVarTemplate = false; - if (R.getReflection().getKind() == ReflectionValue::RK_template) { - const TemplateDecl *TD = R.getReflectedTemplate().getAsTemplateDecl(); + if (RV.isReflectedTemplate()) { + const TemplateDecl *TD = RV.getReflectedTemplate().getAsTemplateDecl(); IsVarTemplate = isa(TD); } return SetAndSucceed(Result, makeBool(S.Context, IsVarTemplate)); @@ -3836,13 +3786,13 @@ bool is_class_template(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool IsClsTemplate = false; - if (R.getReflection().getKind() == ReflectionValue::RK_template) { - const TemplateDecl *TD = R.getReflectedTemplate().getAsTemplateDecl(); + if (RV.isReflectedTemplate()) { + const TemplateDecl *TD = RV.getReflectedTemplate().getAsTemplateDecl(); IsClsTemplate = isa(TD); } return SetAndSucceed(Result, makeBool(S.Context, IsClsTemplate)); @@ -3854,13 +3804,13 @@ bool is_alias_template(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool IsAliasTemplate = false; - if (R.getReflection().getKind() == ReflectionValue::RK_template) { - const TemplateDecl *TD = R.getReflectedTemplate().getAsTemplateDecl(); + if (RV.isReflectedTemplate()) { + const TemplateDecl *TD = RV.getReflectedTemplate().getAsTemplateDecl(); IsAliasTemplate = TD->isTypeAlias(); } return SetAndSucceed(Result, makeBool(S.Context, IsAliasTemplate)); @@ -3872,13 +3822,13 @@ bool is_conversion_function_template(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool IsConversionTemplate = false; - if (R.getReflection().getKind() == ReflectionValue::RK_template) { - const TemplateDecl *TD = R.getReflectedTemplate().getAsTemplateDecl(); + if (RV.isReflectedTemplate()) { + const TemplateDecl *TD = RV.getReflectedTemplate().getAsTemplateDecl(); if (auto *FTD = dyn_cast(TD)) IsConversionTemplate = isa(FTD->getTemplatedDecl()); } @@ -3891,13 +3841,13 @@ bool is_operator_function_template(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool IsOperatorTemplate = false; - if (R.getReflection().getKind() == ReflectionValue::RK_template) { - const TemplateDecl *TD = R.getReflectedTemplate().getAsTemplateDecl(); + if (RV.isReflectedTemplate()) { + const TemplateDecl *TD = RV.getReflectedTemplate().getAsTemplateDecl(); if (auto *FTD = dyn_cast(TD)) IsOperatorTemplate = (FTD->getTemplatedDecl()->getOverloadedOperator() != OO_None); @@ -3911,13 +3861,13 @@ bool is_literal_operator_template(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool IsLiteralOperator = false; - if (R.getReflection().getKind() == ReflectionValue::RK_template) { - const TemplateDecl *TD = R.getReflectedTemplate().getAsTemplateDecl(); + if (RV.isReflectedTemplate()) { + const TemplateDecl *TD = RV.getReflectedTemplate().getAsTemplateDecl(); if (auto *FTD = dyn_cast(TD)) IsLiteralOperator = FTD->getDeclName().getNameKind() == DeclarationName::CXXLiteralOperatorName; @@ -3931,13 +3881,13 @@ bool is_constructor_template(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool IsCtorTemplate = false; - if (R.getReflection().getKind() == ReflectionValue::RK_template) { - const TemplateDecl *TD = R.getReflectedTemplate().getAsTemplateDecl(); + if (RV.isReflectedTemplate()) { + const TemplateDecl *TD = RV.getReflectedTemplate().getAsTemplateDecl(); if (auto *FTD = dyn_cast(TD)) IsCtorTemplate = isa(FTD->getTemplatedDecl()); } @@ -3949,13 +3899,13 @@ bool is_concept(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool IsConcept = false; - if (R.getReflection().getKind() == ReflectionValue::RK_template) - IsConcept = isa(R.getReflectedTemplate().getAsTemplateDecl()); + if (RV.isReflectedTemplate()) + IsConcept = isa(RV.getReflectedTemplate().getAsTemplateDecl()); return SetAndSucceed(Result, makeBool(S.Context, IsConcept)); } @@ -3966,14 +3916,13 @@ bool is_structured_binding(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool result = false; - if (R.getReflection().getKind() == ReflectionValue::RK_declaration) { - result = isa(R.getReflectedDecl()); - } + if (RV.isReflectedDecl()) + result = isa(RV.getReflectedDecl()); return SetAndSucceed(Result, makeBool(S.Context, result)); } @@ -3983,12 +3932,11 @@ bool is_value(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - bool IsValue = (R.getReflection().getKind() == ReflectionValue::RK_value); - return SetAndSucceed(Result, makeBool(S.Context, IsValue)); + return SetAndSucceed(Result, makeBool(S.Context, RV.isReflectedValue())); } bool is_object(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, @@ -3996,16 +3944,13 @@ bool is_object(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - bool IsObject = (R.getReflection().getKind() == ReflectionValue::RK_object); - if (R.getReflection().getKind() == ReflectionValue::RK_declaration) { - Decl *D = R.getReflectedDecl(); - if (isa(D)) - IsObject = true; - } + bool IsObject = RV.isReflectedObject(); + if (RV.isReflectedDecl()) + IsObject = isa(RV.getReflectedDecl()); return SetAndSucceed(Result, makeBool(S.Context, IsObject)); } @@ -4016,20 +3961,20 @@ bool has_template_arguments(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_type: { - QualType QT = R.getReflectedType(); + switch (RV.getReflectionKind()) { + case ReflectionKind::Type: { + QualType QT = RV.getReflectedType(); bool result = isTemplateSpecialization(QT); return SetAndSucceed(Result, makeBool(S.Context, result)); } - case ReflectionValue::RK_declaration: { + case ReflectionKind::Declaration: { bool result = false; - Decl *D = R.getReflectedDecl(); + Decl *D = RV.getReflectedDecl(); if (auto *FD = dyn_cast(D)) result = (FD->getTemplateSpecializationArgs() != nullptr); else if (auto *VTSD = dyn_cast(D)) @@ -4037,13 +3982,13 @@ bool has_template_arguments(APValue &Result, Sema &S, EvalFn Evaluator, return SetAndSucceed(Result, makeBool(S.Context, result)); } - case ReflectionValue::RK_null: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_template: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + case ReflectionKind::Null: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Template: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return SetAndSucceed(Result, makeBool(S.Context, false)); } llvm_unreachable("unknown reflection kind"); @@ -4055,13 +4000,13 @@ bool has_default_member_initializer(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool HasInitializer = false; - if (R.getReflection().getKind() == ReflectionValue::RK_declaration) - if (auto *FD = dyn_cast(R.getReflectedDecl())) + if (RV.isReflectedDecl()) + if (auto *FD = dyn_cast(RV.getReflectedDecl())) HasInitializer = FD->hasInClassInitializer(); return SetAndSucceed(Result, makeBool(S.Context, HasInitializer)); @@ -4073,13 +4018,13 @@ bool is_conversion_function(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool IsConversion = false; - if (R.getReflection().getKind() == ReflectionValue::RK_declaration) - IsConversion = isa(R.getReflectedDecl()); + if (RV.isReflectedDecl()) + IsConversion = isa(RV.getReflectedDecl()); return SetAndSucceed(Result, makeBool(S.Context, IsConversion)); } @@ -4090,13 +4035,13 @@ bool is_operator_function(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool IsOperator = false; - if (R.getReflection().getKind() == ReflectionValue::RK_declaration) - if (auto *FD = dyn_cast(R.getReflectedDecl())) + if (RV.isReflectedDecl()) + if (auto *FD = dyn_cast(RV.getReflectedDecl())) IsOperator = (FD->getOverloadedOperator() != OO_None); return SetAndSucceed(Result, makeBool(S.Context, IsOperator)); @@ -4108,13 +4053,13 @@ bool is_literal_operator(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool IsLiteralOperator = false; - if (R.getReflection().getKind() == ReflectionValue::RK_declaration) - if (auto *FD = dyn_cast(R.getReflectedDecl())) + if (RV.isReflectedDecl()) + if (auto *FD = dyn_cast(RV.getReflectedDecl())) IsLiteralOperator = FD->getDeclName().getNameKind() == DeclarationName::CXXLiteralOperatorName; @@ -4127,22 +4072,22 @@ bool is_constructor(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_null: - case ReflectionValue::RK_type: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_template: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + switch (RV.getReflectionKind()) { + case ReflectionKind::Null: + case ReflectionKind::Type: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Namespace: + case ReflectionKind::Template: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return SetAndSucceed(Result, makeBool(S.Context, false)); - case ReflectionValue::RK_declaration: { - bool result = isa(R.getReflectedDecl()); + case ReflectionKind::Declaration: { + bool result = isa(RV.getReflectedDecl()); return SetAndSucceed(Result, makeBool(S.Context, result)); } } @@ -4155,13 +4100,13 @@ bool is_default_constructor(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool result = false; - if (R.getReflection().getKind() == ReflectionValue::RK_declaration) - if (auto *CtorD = dyn_cast(R.getReflectedDecl())) + if (RV.isReflectedDecl()) + if (auto *CtorD = dyn_cast(RV.getReflectedDecl())) result = CtorD->isDefaultConstructor(); return SetAndSucceed(Result, makeBool(S.Context, result)); @@ -4173,13 +4118,13 @@ bool is_copy_constructor(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool result = false; - if (R.getReflection().getKind() == ReflectionValue::RK_declaration) - if (auto *CtorD = dyn_cast(R.getReflectedDecl())) + if (RV.isReflectedDecl()) + if (auto *CtorD = dyn_cast(RV.getReflectedDecl())) result = CtorD->isCopyConstructor(); return SetAndSucceed(Result, makeBool(S.Context, result)); @@ -4191,13 +4136,13 @@ bool is_move_constructor(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool result = false; - if (R.getReflection().getKind() == ReflectionValue::RK_declaration) - if (auto *CtorD = dyn_cast(R.getReflectedDecl())) + if (RV.isReflectedDecl()) + if (auto *CtorD = dyn_cast(RV.getReflectedDecl())) result = CtorD->isMoveConstructor(); return SetAndSucceed(Result, makeBool(S.Context, result)); @@ -4209,13 +4154,13 @@ bool is_assignment(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool result = false; - if (R.getReflection().getKind() == ReflectionValue::RK_declaration) - if (auto *FD = dyn_cast(R.getReflectedDecl())) + if (RV.isReflectedDecl()) + if (auto *FD = dyn_cast(RV.getReflectedDecl())) result = (FD->getOverloadedOperator() == OO_Equal); return SetAndSucceed(Result, makeBool(S.Context, result)); @@ -4227,13 +4172,13 @@ bool is_copy_assignment(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool result = false; - if (R.getReflection().getKind() == ReflectionValue::RK_declaration) - if (auto *MD = dyn_cast(R.getReflectedDecl())) + if (RV.isReflectedDecl()) + if (auto *MD = dyn_cast(RV.getReflectedDecl())) result = MD->isCopyAssignmentOperator(); return SetAndSucceed(Result, makeBool(S.Context, result)); @@ -4245,13 +4190,13 @@ bool is_move_assignment(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool result = false; - if (R.getReflection().getKind() == ReflectionValue::RK_declaration) - if (auto *MD = dyn_cast(R.getReflectedDecl())) + if (RV.isReflectedDecl()) + if (auto *MD = dyn_cast(RV.getReflectedDecl())) result = MD->isMoveAssignmentOperator(); return SetAndSucceed(Result, makeBool(S.Context, result)); @@ -4263,22 +4208,22 @@ bool is_destructor(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_null: - case ReflectionValue::RK_type: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_template: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + switch (RV.getReflectionKind()) { + case ReflectionKind::Null: + case ReflectionKind::Type: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Template: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return SetAndSucceed(Result, makeBool(S.Context, false)); - case ReflectionValue::RK_declaration: { - bool result = isa(R.getReflectedDecl()); + case ReflectionKind::Declaration: { + bool result = isa(RV.getReflectedDecl()); return SetAndSucceed(Result, makeBool(S.Context, result)); } } @@ -4291,29 +4236,29 @@ bool is_special_member(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_null: - case ReflectionValue::RK_type: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + switch (RV.getReflectionKind()) { + case ReflectionKind::Null: + case ReflectionKind::Type: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return SetAndSucceed(Result, makeBool(S.Context, false)); - case ReflectionValue::RK_declaration: { + case ReflectionKind::Declaration: { bool IsSpecial = false; - if (auto *FD = dyn_cast(R.getReflectedDecl())) + if (auto *FD = dyn_cast(RV.getReflectedDecl())) IsSpecial = isSpecialMember(FD); return SetAndSucceed(Result, makeBool(S.Context, IsSpecial)); } - case ReflectionValue::RK_template: { + case ReflectionKind::Template: { bool result = false; - TemplateDecl *TDecl = R.getReflectedTemplate().getAsTemplateDecl(); + TemplateDecl *TDecl = RV.getReflectedTemplate().getAsTemplateDecl(); if (auto *FTD = dyn_cast(TDecl)) result = isSpecialMember(FTD->getTemplatedDecl()); return SetAndSucceed(Result, makeBool(S.Context, result)); @@ -4328,13 +4273,13 @@ bool is_user_provided(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool IsUserProvided = false; - if (R.getReflection().getKind() == ReflectionValue::RK_declaration) - if (auto *FD = dyn_cast(R.getReflectedDecl())) { + if (RV.isReflectedDecl()) + if (auto *FD = dyn_cast(RV.getReflectedDecl())) { FD = cast(FD->getFirstDecl()); IsUserProvided = !(FD->isImplicit() || FD->isDeleted() || FD->isDefaulted()); @@ -4351,7 +4296,7 @@ bool reflect_result(APValue &Result, Sema &S, EvalFn Evaluator, APValue ArgTy; if (!Evaluator(ArgTy, Args[0], true)) return true; - assert(ArgTy.getReflection().getKind() == ReflectionValue::RK_type); + assert(ArgTy.isReflectedType()); bool IsLValue = isa(ArgTy.getReflectedType()); if (!IsLValue && !ArgTy.getReflectedType()->isStructuralType()) @@ -4386,15 +4331,7 @@ bool reflect_result(APValue &Result, Sema &S, EvalFn Evaluator, makeReflection( const_cast(LVBase.get()))); - if (IsLValue) { - ReflectionValue RV(ReflectionValue::RK_object, - new (S.Context) APValue(Arg)); - return SetAndSucceed(Result, APValue(RV)); - } - - ReflectionValue RV(ReflectionValue::RK_value, - new (S.Context) APValue(Arg), Args[1]->getType()); - return SetAndSucceed(Result, APValue(RV)); + return SetAndSucceed(Result, Arg.Lift(Args[1]->getType())); } bool reflect_invoke(APValue &Result, Sema &S, EvalFn Evaluator, @@ -4408,7 +4345,7 @@ bool reflect_invoke(APValue &Result, Sema &S, EvalFn Evaluator, Args[3]->getType()->getPointeeOrArrayElementType()->isReflectionType()); assert(Args[4]->getType()->isIntegerType()); - using ReflectionVector = SmallVector; + using ReflectionVector = SmallVector; auto UnpackReflectionsIntoVector = [&](ReflectionVector &Out, Expr *DataExpr, Expr *SzExpr) -> bool { APValue Scratch; @@ -4433,7 +4370,7 @@ bool reflect_invoke(APValue &Result, Sema &S, EvalFn Evaluator, if (!Evaluator(Scratch, Synthesized, true) || !Scratch.isReflection()) return false; - Out.push_back(Scratch.getReflection()); + Out.push_back(Scratch); } return true; @@ -4442,12 +4379,12 @@ bool reflect_invoke(APValue &Result, Sema &S, EvalFn Evaluator, TemplateArgumentListInfo ExplicitTAListInfo; SmallVector ExplicitTArgs; { - SmallVector Reflections; + SmallVector Reflections; if (!UnpackReflectionsIntoVector(Reflections, Args[1], Args[2])) llvm_unreachable("failed to unpack template arguments from vector?"); SmallVector ExplicitTArgs; - for (ReflectionValue RV : Reflections) { + for (APValue RV : Reflections) { if (!CanActAsTemplateArg(RV)) return Diagnoser(Range.getBegin(), diag::metafn_cannot_be_arg) << DescriptionOf(RV) << 1 << Range; @@ -4464,25 +4401,26 @@ bool reflect_invoke(APValue &Result, Sema &S, EvalFn Evaluator, SmallVector ArgExprs; { - SmallVector Reflections; + SmallVector Reflections; if (!UnpackReflectionsIntoVector(Reflections, Args[3], Args[4])) llvm_unreachable("failed to unpack function arguments from vector?"); - for (ReflectionValue RV : Reflections) { - if (RV.getKind() == ReflectionValue::RK_object) { - Expr *OVE = new (S.Context) OpaqueValueExpr(Range.getBegin(), - RV.getResultType(), - VK_LValue); - Expr *CE = ConstantExpr::Create(S.Context, OVE, RV.getAsObject()); + for (APValue RV : Reflections) { + if (RV.isReflectedObject()) { + Expr *OVE = new (S.Context) OpaqueValueExpr( + Range.getBegin(), RV.getTypeOfReflectedResult(S.Context), + VK_LValue); + Expr *CE = ConstantExpr::Create(S.Context, OVE, + RV.getReflectedObject()); ArgExprs.push_back(CE); - } else if (RV.getKind() == ReflectionValue::RK_value) { - Expr *OVE = new (S.Context) OpaqueValueExpr(Range.getBegin(), - RV.getResultType(), - VK_PRValue); - Expr *CE = ConstantExpr::Create(S.Context, OVE, RV.getAsValue()); + } else if (RV.isReflectedValue()) { + Expr *OVE = new (S.Context) OpaqueValueExpr( + Range.getBegin(), RV.getTypeOfReflectedResult(S.Context), + VK_PRValue); + Expr *CE = ConstantExpr::Create(S.Context, OVE, RV.getReflectedValue()); ArgExprs.push_back(CE); - } else if (RV.getKind() == ReflectionValue::RK_declaration) { - ValueDecl *D = RV.getAsDecl(); + } else if (RV.isReflectedDecl()) { + ValueDecl *D = RV.getReflectedDecl(); ArgExprs.push_back( DeclRefExpr::Create(S.Context, NestedNameSpecifierLoc(), SourceLocation(), D, false, Range.getBegin(), @@ -4498,36 +4436,36 @@ bool reflect_invoke(APValue &Result, Sema &S, EvalFn Evaluator, if (!Evaluator(Scratch, Args[0], true)) return true; - if (ExplicitTAListInfo.size() > 0 && - Scratch.getReflection().getKind() != ReflectionValue::RK_template) + if (ExplicitTAListInfo.size() > 0 && !Scratch.isReflectedTemplate()) return DiagnoseReflectionKind(Diagnoser, Range, "a template", - DescriptionOf(Scratch.getReflection())); + DescriptionOf(Scratch)); Expr *FnRefExpr = nullptr; - switch (Scratch.getReflection().getKind()) { - case ReflectionValue::RK_null: - case ReflectionValue::RK_type: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + switch (Scratch.getReflectionKind()) { + case ReflectionKind::Null: + case ReflectionKind::Type: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return Diagnoser(Range.getBegin(), diag::metafn_cannot_invoke) - << DescriptionOf(Scratch.getReflection()) << Range; - case ReflectionValue::RK_object: { + << DescriptionOf(Scratch) << Range; + case ReflectionKind::Object: { Expr *OVE = new (S.Context) OpaqueValueExpr( - Range.getBegin(), Scratch.getReflection().getResultType(), VK_LValue); + Range.getBegin(), Scratch.getTypeOfReflectedResult(S.Context), + VK_LValue); FnRefExpr = ConstantExpr::Create(S.Context, OVE, Scratch.getReflectedObject()); break; } - case ReflectionValue::RK_value: { + case ReflectionKind::Value: { Expr *OVE = new (S.Context) OpaqueValueExpr( - Range.getBegin(), Scratch.getReflection().getResultType(), + Range.getBegin(), Scratch.getTypeOfReflectedResult(S.Context), VK_PRValue); FnRefExpr = ConstantExpr::Create(S.Context, OVE, Scratch.getReflectedValue()); break; } - case ReflectionValue::RK_declaration: { + case ReflectionKind::Declaration: { ValueDecl *D = Scratch.getReflectedDecl(); ensureInstantiated(S, D, Range); @@ -4537,12 +4475,12 @@ bool reflect_invoke(APValue &Result, Sema &S, EvalFn Evaluator, D->getType(), VK_LValue, D, nullptr); break; } - case ReflectionValue::RK_template: { + case ReflectionKind::Template: { TemplateDecl *TDecl = Scratch.getReflectedTemplate().getAsTemplateDecl(); auto *FTD = dyn_cast(TDecl); if (!FTD) { return Diagnoser(Range.getBegin(), diag::metafn_cannot_invoke) - << DescriptionOf(Scratch.getReflection()) << Range; + << DescriptionOf(Scratch) << Range; } FunctionDecl *Specialization; @@ -4617,16 +4555,7 @@ bool reflect_invoke(APValue &Result, Sema &S, EvalFn Evaluator, makeReflection( const_cast(LVBase.get()))); - if (ResultExpr->isLValue()) { - ReflectionValue RV(ReflectionValue::RK_object, - new (S.Context) APValue(EvalResult.Val)); - return SetAndSucceed(Result, APValue(RV)); - } - - ReflectionValue RV(ReflectionValue::RK_value, - new (S.Context) APValue(EvalResult.Val), - ResultExpr->getType()); - return SetAndSucceed(Result, APValue(RV)); + return SetAndSucceed(Result, EvalResult.Val.Lift(ResultExpr->getType())); } bool data_member_spec(APValue &Result, Sema &S, EvalFn Evaluator, @@ -4638,8 +4567,7 @@ bool data_member_spec(APValue &Result, Sema &S, EvalFn Evaluator, size_t ArgIdx = 0; // Extract the data member type. - if (!Evaluator(Scratch, Args[ArgIdx++], true) || - Scratch.getReflection().getKind() != ReflectionValue::RK_type) + if (!Evaluator(Scratch, Args[ArgIdx++], true) || !Scratch.isReflectedType()) return true; QualType MemberTy = Scratch.getReflectedType(); @@ -4747,9 +4675,9 @@ bool define_class(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, APValue Scratch; if (!Evaluator(Scratch, Args[0], true)) return true; - if (Scratch.getReflection().getKind() != ReflectionValue::RK_type) + if (!Scratch.isReflectedType()) return DiagnoseReflectionKind(Diagnoser, Range, "an incomplete class type", - DescriptionOf(Scratch.getReflection())); + DescriptionOf(Scratch)); QualType ToComplete = Scratch.getReflectedType(); TagDecl *OGTag, *Tag; @@ -4904,12 +4832,11 @@ bool define_class(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, if (!Evaluator(Scratch, Synthesized, true)) return true; - if (Scratch.getReflection().getKind() != - ReflectionValue::RK_data_member_spec) { + if (!Scratch.isReflectedDataMemberSpec()) { RestoreDC(); return DiagnoseReflectionKind(Diagnoser, Range, "a description of a data member", - DescriptionOf(Scratch.getReflection())); + DescriptionOf(Scratch)); } TagDataMemberSpec *TDMS = Scratch.getReflectedDataMemberSpec(); @@ -4994,23 +4921,23 @@ bool offset_of(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.getSizeType()); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_null: - case ReflectionValue::RK_type: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_template: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + switch (RV.getReflectionKind()) { + case ReflectionKind::Null: + case ReflectionKind::Type: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Template: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return DiagnoseReflectionKind(Diagnoser, Range, "a non-static data member", - DescriptionOf(R.getReflection())); - case ReflectionValue::RK_declaration: { - if (const FieldDecl *FD = dyn_cast(R.getReflectedDecl())) { + DescriptionOf(RV)); + case ReflectionKind::Declaration: { + if (const FieldDecl *FD = dyn_cast(RV.getReflectedDecl())) { size_t Offset = getBitOffsetOfField(S.Context, FD) / S.Context.getTypeSize(S.Context.CharTy); return SetAndSucceed( @@ -5018,7 +4945,7 @@ bool offset_of(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, APValue(S.Context.MakeIntValue(Offset, S.Context.getSizeType()))); } return DiagnoseReflectionKind(Diagnoser, Range, "a non-static data member", - DescriptionOf(R.getReflection())); + DescriptionOf(RV)); } } llvm_unreachable("unknown reflection kind"); @@ -5029,46 +4956,46 @@ bool size_of(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.getSizeType()); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_type: { - QualType QT = R.getReflectedType(); + switch (RV.getReflectionKind()) { + case ReflectionKind::Type: { + QualType QT = RV.getReflectedType(); size_t Sz = S.Context.getTypeSizeInChars(QT).getQuantity(); return SetAndSucceed( Result, APValue(S.Context.MakeIntValue(Sz, S.Context.getSizeType()))); } - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: { - QualType QT = R.getReflection().getResultType(); + case ReflectionKind::Object: + case ReflectionKind::Value: { + QualType QT = RV.getTypeOfReflectedResult(S.Context); size_t Sz = S.Context.getTypeSizeInChars(QT).getQuantity(); return SetAndSucceed( Result, APValue(S.Context.MakeIntValue(Sz, S.Context.getSizeType()))); } - case ReflectionValue::RK_declaration: { - ValueDecl *VD = R.getReflectedDecl(); + case ReflectionKind::Declaration: { + ValueDecl *VD = RV.getReflectedDecl(); size_t Sz = S.Context.getTypeSizeInChars(VD->getType()).getQuantity(); return SetAndSucceed( Result, APValue(S.Context.MakeIntValue(Sz, S.Context.getSizeType()))); } - case ReflectionValue::RK_data_member_spec: { - TagDataMemberSpec *TDMS = R.getReflectedDataMemberSpec(); + case ReflectionKind::DataMemberSpec: { + TagDataMemberSpec *TDMS = RV.getReflectedDataMemberSpec(); size_t Sz = S.Context.getTypeSizeInChars(TDMS->Ty).getQuantity(); return SetAndSucceed( Result, APValue(S.Context.MakeIntValue(Sz, S.Context.getSizeType()))); } - case ReflectionValue::RK_null: - case ReflectionValue::RK_template: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: + case ReflectionKind::Null: + case ReflectionKind::Template: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property) - << 3 << DescriptionOf(R.getReflection()); + << 3 << DescriptionOf(RV); } llvm_unreachable("unknown reflection kind"); } @@ -5079,23 +5006,23 @@ bool bit_offset_of(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.getSizeType()); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_null: - case ReflectionValue::RK_type: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_template: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + switch (RV.getReflectionKind()) { + case ReflectionKind::Null: + case ReflectionKind::Type: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Template: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return DiagnoseReflectionKind(Diagnoser, Range, "a non-static data member", - DescriptionOf(R.getReflection())); - case ReflectionValue::RK_declaration: { - if (const FieldDecl *FD = dyn_cast(R.getReflectedDecl())) { + DescriptionOf(RV)); + case ReflectionKind::Declaration: { + if (FieldDecl *FD = dyn_cast(RV.getReflectedDecl())) { size_t Offset = getBitOffsetOfField(S.Context, FD) % S.Context.getTypeSize(S.Context.CharTy); return SetAndSucceed( @@ -5103,7 +5030,7 @@ bool bit_offset_of(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, APValue(S.Context.MakeIntValue(Offset, S.Context.getSizeType()))); } return DiagnoseReflectionKind(Diagnoser, Range, "a non-static data member", - DescriptionOf(R.getReflection())); + DescriptionOf(RV)); } } llvm_unreachable("unknown reflection kind"); @@ -5114,27 +5041,27 @@ bool bit_size_of(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.getSizeType()); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_type: { - QualType QT = R.getReflectedType(); + switch (RV.getReflectionKind()) { + case ReflectionKind::Type: { + QualType QT = RV.getReflectedType(); size_t Sz = S.Context.getTypeSize(QT); return SetAndSucceed( Result, APValue(S.Context.MakeIntValue(Sz, S.Context.getSizeType()))); } - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: { - size_t Sz = S.Context.getTypeSize(R.getReflection().getResultType()); + case ReflectionKind::Object: + case ReflectionKind::Value: { + size_t Sz = S.Context.getTypeSize(RV.getTypeOfReflectedResult(S.Context)); return SetAndSucceed( Result, APValue(S.Context.MakeIntValue(Sz, S.Context.getSizeType()))); } - case ReflectionValue::RK_declaration: { - const ValueDecl *VD = cast(R.getReflectedDecl()); + case ReflectionKind::Declaration: { + const ValueDecl *VD = cast(RV.getReflectedDecl()); size_t Sz = S.Context.getTypeSize(VD->getType()); if (const FieldDecl *FD = dyn_cast(VD)) @@ -5145,8 +5072,8 @@ bool bit_size_of(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, Result, APValue(S.Context.MakeIntValue(Sz, S.Context.getSizeType()))); } - case ReflectionValue::RK_data_member_spec: { - TagDataMemberSpec *TDMS = R.getReflectedDataMemberSpec(); + case ReflectionKind::DataMemberSpec: { + TagDataMemberSpec *TDMS = RV.getReflectedDataMemberSpec(); size_t Sz = TDMS->BitWidth.value_or(S.Context.getTypeSize(TDMS->Ty)); return SetAndSucceed( @@ -5154,12 +5081,12 @@ bool bit_size_of(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, APValue(S.Context.MakeIntValue(Sz, S.Context.getSizeType()))); } - case ReflectionValue::RK_null: - case ReflectionValue::RK_template: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: + case ReflectionKind::Null: + case ReflectionKind::Template: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property) - << 3 << DescriptionOf(R.getReflection()); + << 3 << DescriptionOf(RV); } llvm_unreachable("unknown reflection kind"); } @@ -5170,28 +5097,28 @@ bool alignment_of(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.getSizeType()); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_type: { - QualType QT = R.getReflectedType(); + switch (RV.getReflectionKind()) { + case ReflectionKind::Type: { + QualType QT = RV.getReflectedType(); size_t Align = S.Context.getTypeAlignInChars(QT).getQuantity(); return SetAndSucceed( Result, APValue(S.Context.MakeIntValue(Align, S.Context.getSizeType()))); } - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: { - QualType QT = R.getReflection().getResultType(); + case ReflectionKind::Object: + case ReflectionKind::Value: { + QualType QT = RV.getTypeOfReflectedResult(S.Context); size_t Align = S.Context.getTypeAlignInChars(QT).getQuantity(); return SetAndSucceed( Result, APValue(S.Context.MakeIntValue(Align, S.Context.getSizeType()))); } - case ReflectionValue::RK_declaration: { - const ValueDecl *VD = cast(R.getReflectedDecl()); + case ReflectionKind::Declaration: { + const ValueDecl *VD = cast(RV.getReflectedDecl()); size_t Align = S.Context.getTypeAlignInChars(VD->getType()).getQuantity(); if (const FieldDecl *FD = dyn_cast(VD)) { @@ -5204,8 +5131,8 @@ bool alignment_of(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, Result, APValue(S.Context.MakeIntValue(Align, S.Context.getSizeType()))); } - case ReflectionValue::RK_data_member_spec: { - TagDataMemberSpec *TDMS = R.getReflectedDataMemberSpec(); + case ReflectionKind::DataMemberSpec: { + TagDataMemberSpec *TDMS = RV.getReflectedDataMemberSpec(); if (TDMS->BitWidth) return true; @@ -5216,12 +5143,12 @@ bool alignment_of(APValue &Result, Sema &S, EvalFn Evaluator, DiagFn Diagnoser, Result, APValue(S.Context.MakeIntValue(Align, S.Context.getSizeType()))); } - case ReflectionValue::RK_null: - case ReflectionValue::RK_template: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: + case ReflectionKind::Null: + case ReflectionKind::Template: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property) - << 4 << DescriptionOf(R.getReflection()); + << 4 << DescriptionOf(RV); } llvm_unreachable("unknown reflection kind"); } @@ -5293,23 +5220,23 @@ bool get_ith_parameter_of(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.MetaInfoTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; APValue Sentinel; if (!Evaluator(Sentinel, Args[1], true)) return true; - assert(Sentinel.getReflection().getKind() == ReflectionValue::RK_type); + assert(Sentinel.isReflectedType()); APValue Idx; if (!Evaluator(Idx, Args[2], true)) return true; size_t idx = Idx.getInt().getExtValue(); - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_type: { - if (auto FT = dyn_cast(R.getReflectedType())) { + switch (RV.getReflectionKind()) { + case ReflectionKind::Type: { + if (auto FT = dyn_cast(RV.getReflectedType())) { unsigned numParams = FT->getNumParams(); if (idx >= numParams) return SetAndSucceed(Result, Sentinel); @@ -5319,8 +5246,8 @@ bool get_ith_parameter_of(APValue &Result, Sema &S, EvalFn Evaluator, return Diagnoser(Range.getBegin(), diag::metafn_cannot_introspect_type) << 2 << 2; } - case ReflectionValue::RK_declaration: { - if (auto FD = dyn_cast(R.getReflectedDecl())) { + case ReflectionKind::Declaration: { + if (auto FD = dyn_cast(RV.getReflectedDecl())) { unsigned numParams = FD->getNumParams(); if (idx >= numParams) return SetAndSucceed(Result, Sentinel); @@ -5328,19 +5255,19 @@ bool get_ith_parameter_of(APValue &Result, Sema &S, EvalFn Evaluator, return SetAndSucceed(Result, makeReflection(FD->getParamDecl(idx))); } return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property) - << 5 << DescriptionOf(R.getReflection()) << Range; + << 5 << DescriptionOf(RV) << Range; } - case ReflectionValue::RK_null: - case ReflectionValue::RK_template: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + case ReflectionKind::Null: + case ReflectionKind::Template: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return true; } return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property) - << 5 << DescriptionOf(R.getReflection()) << Range; + << 5 << DescriptionOf(RV) << Range; } bool has_consistent_identifier(APValue &Result, Sema &S, EvalFn Evaluator, @@ -5349,27 +5276,27 @@ bool has_consistent_identifier(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_declaration: - if (auto *PVD = dyn_cast(R.getReflectedDecl())) { + switch (RV.getReflectionKind()) { + case ReflectionKind::Declaration: + if (auto *PVD = dyn_cast(RV.getReflectedDecl())) { [[maybe_unused]] std::string Unused; bool Consistent = getParameterName(PVD, Unused); return SetAndSucceed(Result, makeBool(S.Context, Consistent)); } [[fallthrough]]; - case ReflectionValue::RK_null: - case ReflectionValue::RK_type: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_template: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + case ReflectionKind::Null: + case ReflectionKind::Type: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Template: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return has_identifier(Result, S, Evaluator, Diagnoser, ResultTy, Range, Args); } @@ -5382,34 +5309,34 @@ bool has_ellipsis_parameter(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_null: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_template: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + switch (RV.getReflectionKind()) { + case ReflectionKind::Null: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Template: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property) - << 5 << DescriptionOf(R.getReflection()) << Range; - case ReflectionValue::RK_type: - if (auto *FPT = dyn_cast(R.getReflectedType())) { + << 5 << DescriptionOf(RV) << Range; + case ReflectionKind::Type: + if (auto *FPT = dyn_cast(RV.getReflectedType())) { bool HasEllipsis = FPT->isVariadic(); return SetAndSucceed(Result, makeBool(S.Context, HasEllipsis)); } return Diagnoser(Range.getBegin(), diag::metafn_cannot_introspect_type) << 2 << 2; - case ReflectionValue::RK_declaration: { - if (auto *FD = dyn_cast(R.getReflectedDecl())) { + case ReflectionKind::Declaration: { + if (auto *FD = dyn_cast(RV.getReflectedDecl())) { bool HasEllipsis = FD->getEllipsisLoc().isValid(); return SetAndSucceed(Result, makeBool(S.Context, HasEllipsis)); } return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property) - << 5 << DescriptionOf(R.getReflection()) << Range; + << 5 << DescriptionOf(RV) << Range; } } llvm_unreachable("unknown reflection kind"); @@ -5421,26 +5348,26 @@ bool has_default_argument(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_declaration: { - if (auto *PVD = dyn_cast(R.getReflectedDecl())) { + switch (RV.getReflectionKind()) { + case ReflectionKind::Declaration: { + if (auto *PVD = dyn_cast(RV.getReflectedDecl())) { return SetAndSucceed(Result, makeBool(S.Context, PVD->hasDefaultArg())); } [[fallthrough]]; - case ReflectionValue::RK_null: - case ReflectionValue::RK_type: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_template: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + case ReflectionKind::Null: + case ReflectionKind::Type: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Template: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return DiagnoseReflectionKind(Diagnoser, Range, "a function parameter", - DescriptionOf(R.getReflection())); + DescriptionOf(RV)); } } llvm_unreachable("unknown reflection kind"); @@ -5452,13 +5379,13 @@ bool is_explicit_object_parameter(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool result = false; - if (R.getReflection().getKind() == ReflectionValue::RK_declaration) { - if (auto *PVD = dyn_cast(R.getReflectedDecl())) + if (RV.isReflectedDecl()) { + if (auto *PVD = dyn_cast(RV.getReflectedDecl())) result = PVD->isExplicitObjectParameter(); } return SetAndSucceed(Result, makeBool(S.Context, result)); @@ -5470,13 +5397,13 @@ bool is_function_parameter(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.BoolTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; bool result = false; - if (R.getReflection().getKind() == ReflectionValue::RK_declaration) { - result = isa(R.getReflectedDecl()); + if (RV.isReflectedDecl()) { + result = isa(RV.getReflectedDecl()); } return SetAndSucceed(Result, makeBool(S.Context, result)); } @@ -5487,31 +5414,31 @@ bool return_type_of(APValue &Result, Sema &S, EvalFn Evaluator, assert(Args[0]->getType()->isReflectionType()); assert(ResultTy == S.Context.MetaInfoTy); - APValue R; - if (!Evaluator(R, Args[0], true)) + APValue RV; + if (!Evaluator(RV, Args[0], true)) return true; - switch (R.getReflection().getKind()) { - case ReflectionValue::RK_type: - if (auto *FPT = dyn_cast(R.getReflectedType())) + switch (RV.getReflectionKind()) { + case ReflectionKind::Type: + if (auto *FPT = dyn_cast(RV.getReflectedType())) return SetAndSucceed(Result, makeReflection(FPT->getReturnType())); return Diagnoser(Range.getBegin(), diag::metafn_cannot_introspect_type) << 3 << 2; - case ReflectionValue::RK_declaration: - if (auto *FD = dyn_cast(R.getReflectedDecl()); + case ReflectionKind::Declaration: + if (auto *FD = dyn_cast(RV.getReflectedDecl()); FD && !isa(FD) && !isa(FD)) return SetAndSucceed(Result, makeReflection(FD->getReturnType())); [[fallthrough]]; - case ReflectionValue::RK_null: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_template: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + case ReflectionKind::Null: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Template: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: return Diagnoser(Range.getBegin(), diag::metafn_cannot_query_property) - << 6 << DescriptionOf(R.getReflection()) << Range; + << 6 << DescriptionOf(RV) << Range; } llvm_unreachable("unknown reflection kind"); } diff --git a/clang/lib/Sema/SemaReflect.cpp b/clang/lib/Sema/SemaReflect.cpp index f407c1ebba0c04..a72d648e634ab9 100644 --- a/clang/lib/Sema/SemaReflect.cpp +++ b/clang/lib/Sema/SemaReflect.cpp @@ -177,6 +177,7 @@ ExprResult Sema::ActOnCXXReflectExpr(SourceLocation OpLoc, if (isa(ND)) return BuildCXXReflectExpr(OpLoc, NameInfo.getBeginLoc(), ND); + // Why do we have to build an expression here? Just stash in an APValue? if (isa(ND)) { ExprResult Result = BuildDeclarationNameExpr(SS, Found, false, false); @@ -369,58 +370,59 @@ ParsedTemplateArgument Sema::ActOnTemplateSpliceSpecifierArgument( } assert(ER.Val.getKind() == APValue::Reflection); - ReflectionValue RV = ER.Val.getReflection(); - if (Splice->getTemplateKWLoc().isValid() && - RV.getKind() != ReflectionValue::RK_template) { + if (Splice->getTemplateKWLoc().isValid() && !ER.Val.isReflectedTemplate()) { Diag(Splice->getOperand()->getExprLoc(), diag::err_unexpected_reflection_kind_in_splice) << 3; return ParsedTemplateArgument(); } - switch (RV.getKind()) { - case ReflectionValue::RK_type: + switch (ER.Val.getReflectionKind()) { + case ReflectionKind::Type: return ParsedTemplateArgument(ParsedTemplateArgument::Type, - RV.getAsType().getAsOpaquePtr(), + const_cast( + ER.Val.getOpaqueReflectionData()), Splice->getExprLoc()); - case ReflectionValue::RK_object: { - Expr *OVE = new (Context) OpaqueValueExpr(Splice->getExprLoc(), - RV.getResultType(), VK_LValue); - Expr *CE = ConstantExpr::Create(Context, OVE, RV.getAsObject()); + case ReflectionKind::Object: { + QualType ResultTy = ER.Val.getTypeOfReflectedResult(Context); + Expr *OVE = new (Context) OpaqueValueExpr(Splice->getExprLoc(), ResultTy, + VK_LValue); + Expr *CE = ConstantExpr::Create(Context, OVE, ER.Val.getReflectedObject()); return ParsedTemplateArgument(ParsedTemplateArgument::NonType, CE, Splice->getExprLoc()); } - case ReflectionValue::RK_value: { - Expr *OVE = new (Context) OpaqueValueExpr(Splice->getExprLoc(), - RV.getResultType(), VK_PRValue); - Expr *CE = ConstantExpr::Create(Context, OVE, RV.getAsValue()); + case ReflectionKind::Value: { + QualType ResultTy = ER.Val.getTypeOfReflectedResult(Context); + Expr *OVE = new (Context) OpaqueValueExpr(Splice->getExprLoc(), ResultTy, + VK_PRValue); + Expr *CE = ConstantExpr::Create(Context, OVE, ER.Val.getReflectedValue()); return ParsedTemplateArgument(ParsedTemplateArgument::NonType, CE, Splice->getExprLoc()); } - case ReflectionValue::RK_template: { - TemplateName TName = RV.getAsTemplate(); + case ReflectionKind::Template: { + TemplateName TName = ER.Val.getReflectedTemplate(); return ParsedTemplateArgument(ParsedTemplateArgument::Template, TName.getAsTemplateDecl(), Splice->getExprLoc()); } - case ReflectionValue::RK_declaration: { - Expr *E = CreateRefToDecl(*this, cast(RV.getAsDecl()), + case ReflectionKind::Declaration: { + Expr *E = CreateRefToDecl(*this, cast(ER.Val.getReflectedDecl()), Splice->getExprLoc()); return ParsedTemplateArgument(ParsedTemplateArgument::NonType, E, E->getExprLoc()); } - case ReflectionValue::RK_null: + case ReflectionKind::Null: Diag(Splice->getExprLoc(), diag::err_unsupported_splice_kind) << "null reflections" << 0 << 0; break; - case ReflectionValue::RK_namespace: + case ReflectionKind::Namespace: Diag(Splice->getExprLoc(), diag::err_unsupported_splice_kind) << "namespaces" << 0 << 0; break; - case ReflectionValue::RK_base_specifier: + case ReflectionKind::BaseSpecifier: Diag(Splice->getExprLoc(), diag::err_unsupported_splice_kind) << "base specifiers" << 0 << 0; break; - case ReflectionValue::RK_data_member_spec: + case ReflectionKind::DataMemberSpec: Diag(Splice->getExprLoc(), diag::err_unsupported_splice_kind) << "data member specs" << 0 << 0; break; @@ -442,7 +444,7 @@ bool Sema::ActOnCXXNestedNameSpecifierReflectionSplice( ExprResult Sema::BuildCXXReflectExpr(SourceLocation OperatorLoc, SourceLocation OperandLoc, QualType T) { - ReflectionValue RV(ReflectionValue::RK_type, T.getAsOpaquePtr()); + APValue RV(ReflectionKind::Type, T.getAsOpaquePtr()); return CXXReflectExpr::Create(Context, OperatorLoc, OperandLoc, RV); } @@ -452,8 +454,8 @@ ExprResult Sema::BuildCXXReflectExpr(SourceLocation OperatorLoc, bool IsNamespace = isa(D); - ReflectionValue RV(IsNamespace ? ReflectionValue::RK_namespace : - ReflectionValue::RK_declaration, D); + APValue RV(IsNamespace ? ReflectionKind::Namespace : + ReflectionKind::Declaration, D); return CXXReflectExpr::Create(Context, OperatorLoc, SourceRange(OperandLoc, OperandLoc), RV); } @@ -467,7 +469,7 @@ ExprResult Sema::BuildCXXReflectExpr(SourceLocation OperatorLoc, return ExprError(); } - ReflectionValue RV(ReflectionValue::RK_template, Template.getAsVoidPointer()); + APValue RV(ReflectionKind::Template, Template.getAsVoidPointer()); return CXXReflectExpr::Create(Context, OperatorLoc, SourceRange(OperandLoc, OperandLoc), RV); } @@ -563,14 +565,8 @@ ExprResult Sema::BuildCXXReflectExpr(SourceLocation OperatorLoc, const_cast(VD)); } - ReflectionValue RV; - if (E->isLValue()) - RV = {ReflectionValue::RK_object, new (Context) APValue(ER.Val)}; - else - RV = {ReflectionValue::RK_value, new (Context) APValue(ER.Val), - E->getType()}; - return CXXReflectExpr::Create(Context, OperatorLoc, E->getSourceRange(), - RV); + APValue RV = ER.Val.Lift(E->getType()); + return CXXReflectExpr::Create(Context, OperatorLoc, E->getSourceRange(), RV); } ExprResult Sema::BuildCXXReflectExpr(SourceLocation OperatorLoc, @@ -599,7 +595,7 @@ ExprResult Sema::BuildCXXReflectExpr(SourceLocation OperatorLoc, } return CXXReflectExpr::Create(Context, OperatorLoc, E->getSourceRange(), - ER.Val.getReflection()); + ER.Val); } ExprResult Sema::BuildCXXMetafunctionExpr( @@ -654,14 +650,13 @@ ExprResult Sema::BuildCXXMetafunctionExpr( Diag(TyRefl->getExprLoc(), diag::err_splice_operand_not_reflection); return true; } - ReflectionValue& R = ER.Val.getReflection(); - if (R.getKind() != ReflectionValue::RK_type) { + if (!ER.Val.isReflectedType()) { Diag(TyRefl->getExprLoc(), diag::err_unexpected_reflection_kind) << 0; return true; } - Result = R.getAsType().getCanonicalType(); + Result = ER.Val.getReflectedType().getCanonicalType(); return false; } } @@ -720,20 +715,18 @@ QualType Sema::BuildReflectionSpliceType(SourceLocation LSplice, Diag(Operand->getExprLoc(), diag::err_splice_operand_not_reflection); return QualType(); } - ReflectionValue &R = ER.Val.getReflection(); - if (R.getKind() == ReflectionValue::RK_template) { - return Context.getDeducedTemplateSpecializationType(R.getAsTemplate(), - QualType(), - false); - } else if (R.getKind() != ReflectionValue::RK_type) { + if (ER.Val.isReflectedTemplate()) { + return Context.getDeducedTemplateSpecializationType( + ER.Val.getReflectedTemplate(), QualType(), false); + } else if (!ER.Val.isReflectedType()) { if (Complain) Diag(Operand->getExprLoc(), diag::err_unexpected_reflection_kind_in_splice) << 0; return QualType(); } - QualType ReflectedTy = R.getAsType(); + QualType ReflectedTy = ER.Val.getReflectedType(); // Check if the type refers to a substituted but uninstantiated template. if (auto *TT = dyn_cast(ReflectedTy)) @@ -805,19 +798,17 @@ ExprResult Sema::BuildReflectionSpliceExpr( Diag(Operand->getExprLoc(), diag::err_splice_operand_not_reflection); return ExprError(); } - ReflectionValue RV = ER.Val.getReflection(); - bool RequireTemplate = TemplateKWLoc.isValid() || TArgs->getLAngleLoc().isValid(); - if (RequireTemplate && RV.getKind() != ReflectionValue::RK_template) { + if (RequireTemplate && !ER.Val.isReflectedTemplate()) { Diag(Operand->getExprLoc(), diag::err_unexpected_reflection_kind_in_splice) << 3; return ExprError(); } - switch (RV.getKind()) { - case ReflectionValue::RK_declaration: { - Decl *TheDecl = RV.getAsDecl(); + switch (ER.Val.getReflectionKind()) { + case ReflectionKind::Declaration: { + Decl *TheDecl = ER.Val.getReflectedDecl(); // Class members may not be implicitly referenced through a splice. if (!AllowMemberReference && @@ -849,27 +840,30 @@ ExprResult Sema::BuildReflectionSpliceExpr( TArgs, AllowMemberReference); break; } - case ReflectionValue::RK_object: { - Expr *OVE = new (Context) OpaqueValueExpr(SpliceOp->getExprLoc(), - RV.getResultType(), VK_LValue); - Expr *CE = ConstantExpr::Create(Context, OVE, RV.getAsObject()); + case ReflectionKind::Object: { + QualType QT = ER.Val.getTypeOfReflectedResult(Context); + Expr *OVE = new (Context) OpaqueValueExpr(SpliceOp->getExprLoc(), QT, + VK_LValue); + Expr *CE = ConstantExpr::Create(Context, OVE, + ER.Val.getReflectedObject()); Operand = CXXSpliceExpr::Create(Context, VK_LValue, TemplateKWLoc, LSplice, CE, RSplice, TArgs, AllowMemberReference); break; } - case ReflectionValue::RK_value: { - Expr *OVE = new (Context) OpaqueValueExpr(SpliceOp->getExprLoc(), - RV.getResultType(), VK_PRValue); - Expr *CE = ConstantExpr::Create(Context, OVE, RV.getAsValue()); + case ReflectionKind::Value: { + QualType QT = ER.Val.getTypeOfReflectedResult(Context); + Expr *OVE = new (Context) OpaqueValueExpr(SpliceOp->getExprLoc(), QT, + VK_PRValue); + Expr *CE = ConstantExpr::Create(Context, OVE, ER.Val.getReflectedValue()); Operand = CXXSpliceExpr::Create(Context, VK_PRValue, TemplateKWLoc, LSplice, CE, RSplice, TArgs, AllowMemberReference); break; } - case ReflectionValue::RK_template: { + case ReflectionKind::Template: { if (SpliceOp->getTemplateKWLoc().isInvalid()) { Diag(SpliceOp->getOperand()->getExprLoc(), diag::err_unexpected_reflection_kind_in_splice) @@ -877,7 +871,7 @@ ExprResult Sema::BuildReflectionSpliceExpr( return ExprError(); } - TemplateName TName = RV.getAsTemplate(); + TemplateName TName = ER.Val.getReflectedTemplate(); assert(!TName.isDependent()); TemplateDecl *TDecl = TName.getAsTemplateDecl(); @@ -951,11 +945,11 @@ ExprResult Sema::BuildReflectionSpliceExpr( AllowMemberReference); break; } - case ReflectionValue::RK_null: - case ReflectionValue::RK_type: - case ReflectionValue::RK_namespace: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + case ReflectionKind::Null: + case ReflectionKind::Type: + case ReflectionKind::Namespace: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: Diag(SpliceOp->getOperand()->getExprLoc(), diag::err_unexpected_reflection_kind_in_splice) << 1 << SpliceOp->getOperand()->getSourceRange(); @@ -991,18 +985,17 @@ DeclResult Sema::BuildReflectionSpliceNamespace(SourceLocation LSplice, Diag(Operand->getExprLoc(), diag::err_splice_operand_not_reflection); return DeclError(); } - ReflectionValue &R = ER.Val.getReflection(); - if (R.getKind() != ReflectionValue::RK_namespace) { + if (!ER.Val.isReflectedNamespace()) { Diag(Operand->getExprLoc(), diag::err_unexpected_reflection_kind) << 2; return DeclError(); - } else if (isa(R.getAsNamespace())) { + } else if (isa(ER.Val.getReflectedNamespace())) { Diag(Operand->getExprLoc(), diag::err_splice_global_scope_as_namespace); return DeclError(); } - return R.getAsNamespace(); + return ER.Val.getReflectedNamespace(); } Sema::TemplateTy Sema::BuildReflectionSpliceTemplate(SourceLocation LSplice, @@ -1034,9 +1027,8 @@ Sema::TemplateTy Sema::BuildReflectionSpliceTemplate(SourceLocation LSplice, diag::err_splice_operand_not_reflection) << SpliceOp->getSourceRange(); return TemplateTy(); } - ReflectionValue &R = ER.Val.getReflection(); - if (R.getKind() != ReflectionValue::RK_template) { + if (!ER.Val.isReflectedTemplate()) { if (Complain) Diag(SpliceOp->getOperand()->getExprLoc(), diag::err_unexpected_reflection_kind) @@ -1044,7 +1036,7 @@ Sema::TemplateTy Sema::BuildReflectionSpliceTemplate(SourceLocation LSplice, return TemplateTy(); } - return TemplateTy::make(R.getAsTemplate()); + return TemplateTy::make(ER.Val.getReflectedTemplate()); } DeclContext *Sema::TryFindDeclContextOf(const Expr *E) { @@ -1055,18 +1047,16 @@ DeclContext *Sema::TryFindDeclContextOf(const Expr *E) { Expr::EvalResult ER; ER.Diag = &Diags; - Expr::EvalResult Result; - if (!E->EvaluateAsRValue(Result, Context, true)) { + if (!E->EvaluateAsRValue(ER, Context, true)) { Diag(E->getExprLoc(), diag::err_splice_operand_not_constexpr); for (PartialDiagnosticAt PD : Diags) Diag(PD.first, PD.second); return nullptr; } - ReflectionValue Reflection = Result.Val.getReflection(); - switch (Reflection.getKind()) { - case ReflectionValue::RK_type: { - QualType QT = Reflection.getAsType(); + switch (ER.Val.getReflectionKind()) { + case ReflectionKind::Type: { + QualType QT = ER.Val.getReflectedType(); if (const TagType *TT = QT->getAs()) return TT->getDecl(); @@ -1074,19 +1064,19 @@ DeclContext *Sema::TryFindDeclContextOf(const Expr *E) { << QT << getLangOpts().CPlusPlus; return nullptr; } - case ReflectionValue::RK_namespace: { - Decl *NS = Reflection.getAsNamespace(); + case ReflectionKind::Namespace: { + Decl *NS = ER.Val.getReflectedNamespace(); if (auto *A = dyn_cast(NS)) NS = A->getNamespace(); return cast(NS); } - case ReflectionValue::RK_null: - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: - case ReflectionValue::RK_declaration: - case ReflectionValue::RK_template: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + case ReflectionKind::Null: + case ReflectionKind::Object: + case ReflectionKind::Value: + case ReflectionKind::Declaration: + case ReflectionKind::Template: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: Diag(E->getExprLoc(), diag::err_expected_class_or_namespace) << "spliced entity" << getLangOpts().CPlusPlus; return nullptr; diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 64c1a3d0c293c5..3196f78ebf3f6d 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -46,6 +46,7 @@ #include #include +#include using namespace clang; using namespace sema; @@ -7472,8 +7473,7 @@ static Expr *BuildExpressionFromIntegralTemplateArgumentValue( } static ExprResult -BuildExpressionFromReflection(Sema &S, const ReflectionValue &RV, - SourceLocation Loc) { +BuildExpressionFromReflection(Sema &S, const APValue &RV, SourceLocation Loc) { return CXXReflectExpr::Create(S.Context, Loc, SourceRange {Loc, Loc}, RV); } @@ -7553,7 +7553,7 @@ static Expr *BuildExpressionFromNonTypeTemplateArgumentValue( return ConstantExpr::Create(S.Context, OVE, Val); } case APValue::Reflection: { - return BuildExpressionFromReflection(S, Val.getReflection(), Loc).get(); + return BuildExpressionFromReflection(S, Val, Loc).get(); } } llvm_unreachable("Unhandled APValue::ValueKind enum"); diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index cf127c082dc5cf..4e1df8110d1384 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -2432,8 +2432,8 @@ TemplateInstantiator::TransformCXXReflectExpr(CXXReflectExpr *E) { return getSema().BuildCXXReflectExpr(E->getOperatorLoc(), Result.get()); } - if (E->getReflection().getKind() == ReflectionValue::RK_declaration) { - Decl *D = E->getReflection().getAsDecl(); + if (E->getReflection().isReflectedDecl()) { + Decl *D = E->getReflection().getReflectedDecl(); // Handle references to non-type template parameters and non-type template // parameter packs. diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp index 0abd7cd5ba2881..08cc5ba32552eb 100644 --- a/clang/lib/Sema/SemaTemplateVariadic.cpp +++ b/clang/lib/Sema/SemaTemplateVariadic.cpp @@ -109,12 +109,12 @@ namespace { if (E->hasDependentSubExpr()) return true; - if (E->getReflection().getKind() == ReflectionValue::RK_declaration) { - ValueDecl *VD = E->getReflection().getAsDecl(); + if (E->getReflection().isReflectedDecl()) { + ValueDecl *VD = E->getReflection().getReflectedDecl(); if (VD->isParameterPack()) addUnexpanded(VD, E->getExprLoc()); - } else if (E->getReflection().getKind() == ReflectionValue::RK_template) { - TemplateName TName = E->getReflection().getAsTemplate(); + } else if (E->getReflection().isReflectedTemplate()) { + TemplateName TName = E->getReflection().getReflectedTemplate(); if (TName.containsUnexpandedParameterPack()) { addUnexpanded(TName.getAsTemplateDecl()); } @@ -1101,10 +1101,8 @@ static bool isParameterPack(Expr *PackExpression) { ValueDecl *VD = D->getDecl(); return VD->isParameterPack(); } else if (auto *R = dyn_cast(PackExpression)) { - if (!R->hasDependentSubExpr() && - R->getReflection().getKind() == ReflectionValue::RK_declaration) { - return R->getReflection().getAsDecl()->isParameterPack(); - } + if (!R->hasDependentSubExpr() && R->getReflection().isReflectedDecl()) + return R->getReflection().getReflectedDecl()->isParameterPack(); } return false; } diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index fdebe1265cd8a4..6b95fb71f6d8d5 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -4561,15 +4561,14 @@ NestedNameSpecifierLoc TreeTransform::TransformNestedNameSpecifierLoc( Expr::EvalResult Result; if (!ER.get()->EvaluateAsRValue(Result, SemaRef.Context)) return NestedNameSpecifierLoc(); - ReflectionValue Reflection = Result.Val.getReflection(); // Form new nested-name-specifier component based on the reflection kind. - if (Reflection.getKind() == ReflectionValue::RK_type) { + if (Result.Val.isReflectedType()) { // Verify that the resulting type is a tag type. - if (!Reflection.getAsType()->isRecordType() && - !Reflection.getAsType()->isEnumeralType()) { + if (!Result.Val.getReflectedType()->isRecordType() && + !Result.Val.getReflectedType()->isEnumeralType()) { SemaRef.Diag(Splice->getExprLoc(), diag::err_nested_name_spec_non_tag) - << Reflection.getAsType() << SS.getRange(); + << Result.Val.getReflectedType() << SS.getRange(); return NestedNameSpecifierLoc(); } @@ -4586,8 +4585,8 @@ NestedNameSpecifierLoc TreeTransform::TransformNestedNameSpecifierLoc( SS.Extend(SemaRef.Context, Splice->getLSpliceLoc(), TLB.getTypeLocInContext(getSema().Context, QT), Q.getLocalEndLoc()); - } else if (Reflection.getKind() == ReflectionValue::RK_namespace) { - Decl *D = Reflection.getAsNamespace(); + } else if (Result.Val.isReflectedNamespace()) { + Decl *D = Result.Val.getReflectedNamespace(); if (auto *TD = dyn_cast(D)) SS.MakeGlobal(SemaRef.Context, Splice->getLSpliceLoc()); else if (auto *ND = dyn_cast(D)) @@ -8805,10 +8804,10 @@ TreeTransform::TransformCXXReflectExpr(CXXReflectExpr *E) { Result.get()); } - ReflectionValue RV = E->getReflection(); - switch (RV.getKind()) { - case ReflectionValue::RK_type: { - QualType Old = RV.getAsType(); + APValue RV = E->getReflection(); + switch (RV.getReflectionKind()) { + case ReflectionKind::Type: { + QualType Old = RV.getReflectedType(); // Adjust the type in case we get parsed type information. if (const LocInfoType *LIT = dyn_cast(Old)) { @@ -8822,15 +8821,15 @@ TreeTransform::TransformCXXReflectExpr(CXXReflectExpr *E) { return getSema().BuildCXXReflectExpr(E->getOperatorLoc(), E->getOperandRange().getBegin(), New); } - case ReflectionValue::RK_declaration: { + case ReflectionKind::Declaration: { Decl *Transformed = getDerived().TransformDecl(E->getExprLoc(), - RV.getAsDecl()); + RV.getReflectedDecl()); return getSema().BuildCXXReflectExpr(E->getOperatorLoc(), E->getOperandRange().getBegin(), cast(Transformed)); } - case ReflectionValue::RK_template: { - TemplateName TName = RV.getAsTemplate(); + case ReflectionKind::Template: { + TemplateName TName = RV.getReflectedTemplate(); NestedNameSpecifier *NNS = nullptr; if (TName.getKind() == TemplateName::QualifiedTemplate) @@ -8860,19 +8859,20 @@ TreeTransform::TransformCXXReflectExpr(CXXReflectExpr *E) { E->getOperandRange().getBegin(), Template); } - case ReflectionValue::RK_namespace: { + case ReflectionKind::Namespace: { Decl *Transformed = - getDerived().TransformDecl(E->getExprLoc(), RV.getAsNamespace()); + getDerived().TransformDecl(E->getExprLoc(), + RV.getReflectedNamespace()); return getSema().BuildCXXReflectExpr(E->getOperatorLoc(), E->getOperandRange().getBegin(), Transformed); } - case ReflectionValue::RK_object: - case ReflectionValue::RK_value: + case ReflectionKind::Object: + case ReflectionKind::Value: return E; - case ReflectionValue::RK_null: - case ReflectionValue::RK_base_specifier: - case ReflectionValue::RK_data_member_spec: + case ReflectionKind::Null: + case ReflectionKind::BaseSpecifier: + case ReflectionKind::DataMemberSpec: llvm_unreachable("reflect expression should not have this reflection kind"); } llvm_unreachable("invalid reflection"); diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index a34da9ba240da5..85f5ff932ce26b 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -472,7 +472,7 @@ void ASTStmtWriter::VisitCXXReflectExpr(CXXReflectExpr *E) { if (E->hasDependentSubExpr()) Record.AddStmt(E->getDependentSubExpr()); else - Record.AddReflectionValue(E->getReflection()); + Record.AddAPValue(E->getReflection()); Code = serialization::EXPR_REFLECT; } diff --git a/libcxx/include/experimental/meta b/libcxx/include/experimental/meta index 07eb04190520f1..c30732966f8dc5 100644 --- a/libcxx/include/experimental/meta +++ b/libcxx/include/experimental/meta @@ -511,16 +511,9 @@ consteval auto __workaround_expand_compiler_builtins(info type) -> info; namespace __range_of_infos { -constexpr struct always_true_fn { - consteval bool operator()(info) { - return true; - } -} always_true; - struct sentinel {}; -template +template class iterator { static constexpr Front m_front = { }; static constexpr Next m_next = { }; @@ -532,37 +525,26 @@ class iterator { // m_currInfoItr can be either ^int, ^double and ^string info m_currInfoItr{^sentinel}; - Pred m_pred; Map m_mapFn; size_t m_nextIndex {0}; - consteval void advance() { - while ((m_currInfoItr != ^sentinel) && !m_pred(m_mapFn(m_currInfoItr))) - m_currInfoItr = m_next(m_currInfoItr, m_reflectedEntity, m_nextIndex++); - } - public: using value_type = info; using reference = info; using pointer = info; using difference_type = ptrdiff_t; using iterator_category = forward_iterator_tag; - using filter_type = Pred; - consteval iterator(Pred pred) + consteval iterator() : m_currInfoItr{^sentinel} - , m_pred{pred} , m_mapFn{} { } - consteval iterator(meta::info reflectedEntity, Pred pred) + consteval iterator(meta::info reflectedEntity) : m_reflectedEntity{reflectedEntity} , m_currInfoItr{m_front(reflectedEntity)} - , m_pred{pred} , m_nextIndex{1} // after we fetch the front, next index is 1 - { - advance(); - } + { } consteval info operator*() const { return m_mapFn(m_currInfoItr); @@ -571,7 +553,6 @@ public: // pre-incr ++itr; consteval iterator operator++() { m_currInfoItr = m_next(m_currInfoItr, m_reflectedEntity, m_nextIndex++); - advance(); return *this; } @@ -582,10 +563,6 @@ public: return tmp; } - consteval Pred filter() const { - return m_pred; - } - consteval friend bool operator==(iterator a, iterator b) { return a.m_currInfoItr == b.m_currInfoItr; } @@ -602,10 +579,9 @@ class range { public: using iterator = Iter; - using filter_type = typename Iter::filter_type; - consteval range(info reflection, filter_type pred = {}) - : m_first(reflection, pred) , m_last(pred) + consteval range(info reflection) + : m_first(reflection), m_last() { } consteval iterator begin() const @@ -619,9 +595,9 @@ public: } }; -template -consteval ptrdiff_t distance(iterator first, - iterator last) { +template +consteval ptrdiff_t distance(iterator first, + iterator last) { ptrdiff_t n = 0; for (; first != last; ++first) ++n; @@ -848,10 +824,9 @@ consteval auto members_of(info r) -> vector { using iterator = __range_of_infos::iterator<__range_of_infos::front_member_of_fn, __range_of_infos::next_member_of_fn, - __range_of_infos::map_decl_to_entity_fn, - __range_of_infos::always_true_fn>; + __range_of_infos::map_decl_to_entity_fn>; using range = __range_of_infos::range; - auto rng = range{r, __range_of_infos::always_true}; + auto rng = range{r}; return vector{rng.begin(), rng.end()}; } @@ -867,10 +842,9 @@ consteval auto bases_of(info r) -> vector { using iterator = __range_of_infos::iterator<__range_of_infos::front_base_of_fn, __range_of_infos::next_base_of_fn, - __range_of_infos::map_identity_fn, - __range_of_infos::always_true_fn>; + __range_of_infos::map_identity_fn>; using range = __range_of_infos::range; - auto rng = range{r, __range_of_infos::always_true}; + auto rng = range{r}; return vector{rng.begin(), rng.end()}; } diff --git a/libcxx/test/std/experimental/reflection/to-and-from-values.pass.cpp b/libcxx/test/std/experimental/reflection/to-and-from-values.pass.cpp index 04047b7316da6d..80ebddac7b4fff 100644 --- a/libcxx/test/std/experimental/reflection/to-and-from-values.pass.cpp +++ b/libcxx/test/std/experimental/reflection/to-and-from-values.pass.cpp @@ -313,6 +313,38 @@ static_assert(rvfirst == std::meta::reflect_value(std::make_pair(1, true))); static_assert([:rvfirst:].first == 1); } // namespace values_from_objects +// ======================== +// pointer_object_ambiguity +// ======================== + +namespace pointer_object_ambiguity { + +constexpr int k = 3; +constexpr const int *p = &k; + +constexpr auto rp = ^p; +static_assert(is_variable(rp)); +//static_assert(!is_object(rp)); +static_assert(!is_value(rp)); + +constexpr auto ro = object_of(rp); +static_assert(!is_variable(ro)); +static_assert(is_object(ro)); +static_assert(!is_value(ro)); +static_assert(ro == std::meta::reflect_object(p)); +static_assert(ro != std::meta::reflect_value(&k)); + +constexpr auto rv = value_of(ro); +static_assert(!is_variable(rv)); +static_assert(!is_object(rv)); +static_assert(is_value(rv)); +static_assert(rv == std::meta::reflect_value(&k)); + +static_assert(rp != ro); +static_assert(rp != rv); +static_assert(ro != rv); +} // namespace pointer_object_ambiguity + // ======================================= // bb_clang_p2996_issue_67_regression_test // ======================================= From 149cca52811b59b22608f6f6e303f6589969c999 Mon Sep 17 00:00:00 2001 From: Dan Katz Date: Mon, 5 Aug 2024 11:46:12 -0400 Subject: [PATCH 2/7] Replace the macro for 'define_static_string'. --- libcxx/include/experimental/meta | 207 ++++++++++++++++--------------- 1 file changed, 105 insertions(+), 102 deletions(-) diff --git a/libcxx/include/experimental/meta b/libcxx/include/experimental/meta index c30732966f8dc5..fcd26754ccd6e8 100644 --- a/libcxx/include/experimental/meta +++ b/libcxx/include/experimental/meta @@ -2081,16 +2081,9 @@ consteval auto test_trait(info templ, R &&args) -> bool { // For now, seeing as Clang/P2996 is still first and foremost a prototype, the // implementation stands as both a "test" of the power of the APIs proposed by // the paper, and a demonstratation of some reflection techniques. -// -// The use of the "STRING_CONSTANT" macro is....regrettable. Tools have been -// proposed to make it easier to work with u8strings, but for now - this seemed -// like the most immediate solution. namespace detail { -#define STRING_CONSTANT(X) \ - [] { if constexpr(IsUtf8) return u8##X; else return X; }() - template struct pretty_printer { static_assert(dealias(^CharT) == ^char || dealias(^CharT) == ^char8_t); @@ -2098,23 +2091,35 @@ struct pretty_printer { using string_t = basic_string; + static consteval const CharT *string_constant(std::string_view contents) { + if constexpr (IsUtf8) { + std::u8string result(contents.size(), 0); + for (size_t idx = 0; char c : contents) + result[idx++] = char8_t(c); + + return std::meta::define_static_string(result); + } else { + return contents.data(); + } + } + static constexpr basic_string_view op_names[45] = { - {}, STRING_CONSTANT("new"), STRING_CONSTANT("delete"), - STRING_CONSTANT("new[]"), STRING_CONSTANT("delete[]"), - STRING_CONSTANT("coawait"), STRING_CONSTANT("()"), STRING_CONSTANT("[]"), - STRING_CONSTANT("->"), STRING_CONSTANT("->*"), STRING_CONSTANT("~"), - STRING_CONSTANT("!"), STRING_CONSTANT("+"), STRING_CONSTANT("-"), - STRING_CONSTANT("*"), STRING_CONSTANT("/"), STRING_CONSTANT("%"), - STRING_CONSTANT("^"), STRING_CONSTANT("&"), STRING_CONSTANT("|"), - STRING_CONSTANT("="), STRING_CONSTANT("+="), STRING_CONSTANT("-="), - STRING_CONSTANT("*="), STRING_CONSTANT("/="), STRING_CONSTANT("%="), - STRING_CONSTANT("^"), STRING_CONSTANT("&="), STRING_CONSTANT("|="), - STRING_CONSTANT("=="), STRING_CONSTANT("!="), STRING_CONSTANT("<"), - STRING_CONSTANT(">"), STRING_CONSTANT("<="), STRING_CONSTANT(">="), - STRING_CONSTANT("<=>"), STRING_CONSTANT("&&"), STRING_CONSTANT("||"), - STRING_CONSTANT("<<"), STRING_CONSTANT(">>"), STRING_CONSTANT("<<="), - STRING_CONSTANT(">>="), STRING_CONSTANT("++"), STRING_CONSTANT("--"), - STRING_CONSTANT(","), + {}, string_constant("new"), string_constant("delete"), + string_constant("new[]"), string_constant("delete[]"), + string_constant("coawait"), string_constant("()"), string_constant("[]"), + string_constant("->"), string_constant("->*"), string_constant("~"), + string_constant("!"), string_constant("+"), string_constant("-"), + string_constant("*"), string_constant("/"), string_constant("%"), + string_constant("^"), string_constant("&"), string_constant("|"), + string_constant("="), string_constant("+="), string_constant("-="), + string_constant("*="), string_constant("/="), string_constant("%="), + string_constant("^"), string_constant("&="), string_constant("|="), + string_constant("=="), string_constant("!="), string_constant("<"), + string_constant(">"), string_constant("<="), string_constant(">="), + string_constant("<=>"), string_constant("&&"), string_constant("||"), + string_constant("<<"), string_constant(">>"), string_constant("<<="), + string_constant(">>="), string_constant("++"), string_constant("--"), + string_constant(","), }; static consteval auto identifier_helper(info R) { @@ -2171,7 +2176,7 @@ struct pretty_printer { template // Null reflection. requires (R == info{}) static consteval string_t render() { - return STRING_CONSTANT("(null-reflection)"); + return string_constant("(null-reflection)"); } template // Values of fundamental type. @@ -2284,17 +2289,17 @@ consteval auto pretty_printer::render_template_argument_list_of() size_t Idx = 0; [:expand(template_arguments_of(R)):] >> [&] { - result += (Idx++ < 1 ? STRING_CONSTANT("<") : STRING_CONSTANT(", ")); + result += (Idx++ < 1 ? string_constant("<") : string_constant(", ")); result += tprint_impl::template render(); }; - return result + STRING_CONSTANT(">"); + return result + string_constant(">"); } template template requires (is_value(R)) consteval auto pretty_printer::render_value_as_hex() -> string_t { - string_t result = STRING_CONSTANT("0x"); + string_t result = string_constant("0x"); auto bytes = bit_cast>([:R:]); if (endian::native == endian::little) @@ -2323,19 +2328,19 @@ consteval auto pretty_printer::tprint_impl::render() -> string_t { constexpr info Ty = dealias(type_of(R)); if constexpr (Ty == ^nullptr_t) - result = STRING_CONSTANT("nullptr"); + result = string_constant("nullptr"); if constexpr (type_is_same(Ty, ^bool)) { if (extract(R)) - result = STRING_CONSTANT("true"); + result = string_constant("true"); else - result = STRING_CONSTANT("false"); + result = string_constant("false"); } else if constexpr (type_is_same(Ty, ^char)) { - result = STRING_CONSTANT("'"); + result = string_constant("'"); result.append(1, extract(R)); - result += STRING_CONSTANT("'"); + result += string_constant("'"); } else if constexpr (type_is_integral(Ty) && dealias(^CharT) == ^char) { @@ -2350,9 +2355,9 @@ consteval auto pretty_printer::tprint_impl::render() -> string_t { } else { - result += STRING_CONSTANT("(value : "); + result += string_constant("(value : "); result += render(); - result += STRING_CONSTANT(")"); + result += string_constant(")"); } return result; @@ -2362,14 +2367,14 @@ template template // Values of aggregate type. requires(is_value(R) && type_is_aggregate(type_of(R))) consteval auto pretty_printer::tprint_impl::render() -> string_t { - string_t result = render() + STRING_CONSTANT("{"); + string_t result = render() + string_constant("{"); size_t Idx = 0; [:expand(nonstatic_data_members_of(type_of(R))):] >> [&] { - if (Idx++ > 0) result += STRING_CONSTANT(", "); + if (Idx++ > 0) result += string_constant(", "); result += tprint_impl::render(); }; - result += STRING_CONSTANT("}"); + result += string_constant("}"); return result; } @@ -2378,17 +2383,17 @@ template template // Values of pointer type. requires (is_value(R) && type_is_pointer(type_of(R))) consteval auto pretty_printer::tprint_impl::render() -> string_t { - return STRING_CONSTANT("(value : ") + render() + - STRING_CONSTANT(")"); + return string_constant("(value : ") + render() + + string_constant(")"); } template template // Objects. requires (is_object(R)) consteval auto pretty_printer::tprint_impl::render() -> string_t { - string_t result = STRING_CONSTANT("(object : "); + string_t result = string_constant("(object : "); result += render(); - return result + STRING_CONSTANT(")"); + return result + string_constant(")"); } template @@ -2413,9 +2418,9 @@ consteval auto pretty_printer::tprint_impl::render() -> string_t { return result + string_t {op_names[int(operator_of(R))]}; } } else if (is_conversion_function_template(R)) - return STRING_CONSTANT("(conversion-function-template)"); + return string_constant("(conversion-function-template)"); else if (is_literal_operator_template(R)) - return STRING_CONSTANT(R"(operator"")") + string_t {identifier_helper(R) }; + return string_constant(R"(operator"")") + string_t {identifier_helper(R) }; return string_t {identifier_helper(R)}; } @@ -2425,9 +2430,9 @@ template // Namespaces. requires(is_namespace(R)) consteval auto pretty_printer::tprint_impl::render() -> string_t { if (R == ^::) - return STRING_CONSTANT("(global-namespace)"); + return string_constant("(global-namespace)"); if (!has_identifier(R)) - return STRING_CONSTANT("(anonymous-namespace)"); + return string_constant("(anonymous-namespace)"); return string_t {identifier_helper(R)}; } @@ -2442,7 +2447,7 @@ consteval auto pretty_printer::tprint_impl::render() -> string_t { return render() + render_template_argument_list_of(); } else if constexpr (is_destructor(R)) { constexpr info P = parent_of(R); - return STRING_CONSTANT("~") + + return string_constant("~") + render(); } else if constexpr (is_constructor(R)) { return render(); @@ -2463,12 +2468,12 @@ consteval auto pretty_printer::tprint_impl::render() -> string_t { } } else if constexpr (is_conversion_function(R)) { #if __has_feature(parameter_reflection) - return STRING_CONSTANT("operator ") + render(); + return string_constant("operator ") + render(); #else - return STRING_CONSTANT("conversion-function"); + return string_constant("conversion-function"); #endif } else if constexpr (is_literal_operator(R)) { - return STRING_CONSTANT(R"(operator"")") + string_t {identifier_helper(R) }; + return string_constant(R"(operator"")") + string_t {identifier_helper(R) }; } return string_t {identifier_helper(R)}; @@ -2486,40 +2491,40 @@ consteval auto pretty_printer::tprint_impl::render() -> string_t { if constexpr (has_template_arguments(R)) { return render() + render_template_argument_list_of(); } else if constexpr (type_is_fundamental(R)) { - if (R == ^void) return STRING_CONSTANT("void"); + if (R == ^void) return string_constant("void"); if (R == ^decltype(nullptr) || R == ^nullptr_t) - return STRING_CONSTANT("std::nullptr_t"); + return string_constant("std::nullptr_t"); if (R == ^decltype(^::) || R == ^info) - return STRING_CONSTANT("std::meta::info"); + return string_constant("std::meta::info"); - if (R == ^bool) return STRING_CONSTANT("bool"); - if (R == ^signed char) return STRING_CONSTANT("signed char"); - if (R == ^unsigned char) return STRING_CONSTANT("unsigned char"); - if (R == ^char) return STRING_CONSTANT("char"); + if (R == ^bool) return string_constant("bool"); + if (R == ^signed char) return string_constant("signed char"); + if (R == ^unsigned char) return string_constant("unsigned char"); + if (R == ^char) return string_constant("char"); - if (R == ^char8_t) return STRING_CONSTANT("char8_t"); - if (R == ^char16_t) return STRING_CONSTANT("char16_t"); - if (R == ^char32_t) return STRING_CONSTANT("char32_t"); + if (R == ^char8_t) return string_constant("char8_t"); + if (R == ^char16_t) return string_constant("char16_t"); + if (R == ^char32_t) return string_constant("char32_t"); - if (R == ^float) return STRING_CONSTANT("float"); - if (R == ^double) return STRING_CONSTANT("double"); - if (R == ^long double) return STRING_CONSTANT("long double"); + if (R == ^float) return string_constant("float"); + if (R == ^double) return string_constant("double"); + if (R == ^long double) return string_constant("long double"); - if (type_is_unsigned(R)) result += STRING_CONSTANT("unsigned "); + if (type_is_unsigned(R)) result += string_constant("unsigned "); if constexpr (!is_alias(R)) { auto U = type_make_signed(R); - if (U == ^short) return result + STRING_CONSTANT("short"); - if (U == ^int) return result + STRING_CONSTANT("int"); - if (U == ^long) return result + STRING_CONSTANT("long"); - if (U == ^long long) return result + STRING_CONSTANT("long long"); + if (U == ^short) return result + string_constant("short"); + if (U == ^int) return result + string_constant("int"); + if (U == ^long) return result + string_constant("long"); + if (U == ^long long) return result + string_constant("long long"); } } if (has_identifier(R)) { return string_t {identifier_helper(R)}; } else { - return STRING_CONSTANT("(anonymous type)"); + return string_constant("(anonymous type)"); } } @@ -2530,9 +2535,9 @@ template // CV-qualified non-function, non-array types. consteval auto pretty_printer::tprint_impl::render() -> string_t { string_t result; if (is_const(R)) - result += STRING_CONSTANT("const "); + result += string_constant("const "); if (is_volatile(R)) - result += STRING_CONSTANT("volatile "); + result += string_constant("volatile "); return result + render(); } @@ -2541,9 +2546,9 @@ template // Reference types. requires (is_type(R) && !(is_const(R) || is_volatile(R)) && type_is_reference(R)) consteval auto pretty_printer::tprint_impl::render() -> string_t { - string_t result = render() + STRING_CONSTANT(" &"); + string_t result = render() + string_constant(" &"); if (type_is_rvalue_reference(R)) - result += STRING_CONSTANT("&"); + result += string_constant("&"); return result; } @@ -2569,7 +2574,7 @@ template // Non-function, non-member pointer types. !(is_const(R) || is_volatile(R)) && !type_is_function(type_remove_pointer(R))) consteval auto pretty_printer::tprint_impl::render() -> string_t { - return render() + STRING_CONSTANT(" *"); + return render() + string_constant(" *"); } template @@ -2580,18 +2585,18 @@ consteval auto pretty_printer::tprint_impl::render() -> string_t { #if __has_feature(parameter_reflection) constexpr auto FnTy = type_remove_pointer(R); - string_t result = render() + STRING_CONSTANT("(*)("); + string_t result = render() + string_constant("(*)("); size_t Idx = 0; [:expand(parameters_of(FnTy)):] >> [&] { - if (Idx++ > 0) result += STRING_CONSTANT(", "); + if (Idx++ > 0) result += string_constant(", "); result += tprint_impl::render(); }; - result += STRING_CONSTANT(")"); + result += string_constant(")"); if (is_noexcept(FnTy)) - result += STRING_CONSTANT(" noexcept"); + result += string_constant(" noexcept"); #else - string_t result = STRING_CONSTANT("(function-pointer-type)"); + string_t result = string_constant("(function-pointer-type)"); #endif return result; @@ -2602,28 +2607,28 @@ template // Function types. requires (is_type(R) && type_is_function(R)) consteval auto pretty_printer::tprint_impl::render() -> string_t { #if __has_feature(parameter_reflection) - string_t result = render() + STRING_CONSTANT("("); + string_t result = render() + string_constant("("); size_t Idx = 0; [:expand(parameters_of(R)):] >> [&] { - if (Idx++ > 0) result += STRING_CONSTANT(", "); + if (Idx++ > 0) result += string_constant(", "); result += tprint_impl::render(); }; - result += STRING_CONSTANT(")"); + result += string_constant(")"); if (is_const(R)) - result += STRING_CONSTANT(" const"); + result += string_constant(" const"); if (is_volatile(R)) - result += STRING_CONSTANT(" volatile"); + result += string_constant(" volatile"); if (is_lvalue_reference_qualified(R)) - result += STRING_CONSTANT(" &"); + result += string_constant(" &"); else if (is_rvalue_reference_qualified(R)) - result += STRING_CONSTANT(" &&"); + result += string_constant(" &&"); if (is_noexcept(R)) - result += STRING_CONSTANT(" noexcept"); + result += string_constant(" noexcept"); #else - string_t result = STRING_CONSTANT("(function-type)"); + string_t result = string_constant("(function-type)"); #endif return result; @@ -2636,8 +2641,8 @@ template // Pointer to data member types. !type_is_member_function_pointer(R)) consteval auto pretty_printer::tprint_impl::render() -> string_t { string_t result = render()>() + - STRING_CONSTANT(" "); - result += render()>() + STRING_CONSTANT("::*"); + string_constant(" "); + result += render()>() + string_constant("::*"); return result; } @@ -2649,31 +2654,31 @@ consteval auto pretty_printer::tprint_impl::render() -> string_t { constexpr auto FnTy = type_of_member_from_memptr(); #if __has_feature(parameter_reflection) - string_t result = render() + STRING_CONSTANT("("); + string_t result = render() + string_constant("("); result += render()>() + - STRING_CONSTANT("::*)("); + string_constant("::*)("); size_t Idx = 0; [:expand(parameters_of(FnTy)):] >> [&] { - if (Idx++ > 0) result += STRING_CONSTANT(", "); + if (Idx++ > 0) result += string_constant(", "); result += tprint_impl::render(); }; - result += STRING_CONSTANT(")"); + result += string_constant(")"); if (is_const(FnTy)) - result += STRING_CONSTANT(" const"); + result += string_constant(" const"); if (is_volatile(FnTy)) - result += STRING_CONSTANT(" volatile"); + result += string_constant(" volatile"); if (is_lvalue_reference_qualified(FnTy)) - result += STRING_CONSTANT(" &"); + result += string_constant(" &"); else if (is_rvalue_reference_qualified(FnTy)) - result += STRING_CONSTANT(" &&"); + result += string_constant(" &&"); if (is_noexcept(FnTy)) - result += STRING_CONSTANT(" noexcept"); + result += string_constant(" noexcept"); #else - string_t result = STRING_CONSTANT("(member-function-pointer-type)"); + string_t result = string_constant("(member-function-pointer-type)"); #endif return result; @@ -2690,7 +2695,7 @@ consteval auto pretty_printer::tprint_impl::render() -> string_t { template template // Fallback. consteval auto pretty_printer::tprint_impl::render() -> string_t { - return STRING_CONSTANT("(unsupported-reflection)"); + return string_constant("(unsupported-reflection)"); } template @@ -2699,8 +2704,6 @@ template // Variables, data members, enumerators. consteval auto pretty_printer::tprint_impl::render() -> string_t { return string_t {identifier_helper(R)}; } - -#undef STRING_CONSTANT } // namespace detail consteval auto display_string_of(info R) -> string_view { From f26b7a0243e11a3a4f89840892616ac81e342e30 Mon Sep 17 00:00:00 2001 From: Dan Katz Date: Mon, 5 Aug 2024 15:41:02 -0400 Subject: [PATCH 3/7] Remove support for '^ splice-expression' production. --- clang/lib/Parse/ParseReflect.cpp | 65 ++--------------- .../test/Reflection/reflection-of-splice.cpp | 71 ------------------- clang/test/Reflection/splice-templates.cpp | 10 --- 3 files changed, 5 insertions(+), 141 deletions(-) delete mode 100644 clang/test/Reflection/reflection-of-splice.cpp diff --git a/clang/lib/Parse/ParseReflect.cpp b/clang/lib/Parse/ParseReflect.cpp index 9d0a44da216219..01d9813b265c07 100644 --- a/clang/lib/Parse/ParseReflect.cpp +++ b/clang/lib/Parse/ParseReflect.cpp @@ -26,51 +26,14 @@ ExprResult Parser::ParseCXXReflectExpression() { EnterExpressionEvaluationContext EvalContext( Actions, Sema::ExpressionEvaluationContext::ReflectionContext); - // ^ template [:splice-specifier:] - // - SourceLocation TemplateKWLoc; - if (Tok.is(tok::kw_template)) { - TemplateKWLoc = ConsumeToken(); - - if (!Tok.is(tok::l_splice)) { - Diag(TemplateKWLoc, diag::err_unexpected_template_in_unqualified_id); - SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); - return ExprError(); - } - - if (ParseCXXSpliceSpecifier(TemplateKWLoc)) { - SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); - return ExprError(); - } - - if (!NextToken().is(tok::less)) { - Token Splice = Tok; - TemplateTy Template = ParseCXXSpliceAsTemplate(); - if (Template) - return Actions.BuildCXXReflectExpr(OpLoc, Splice.getLocation(), - Template.get()); - SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); - return ExprError(); - } - - if (ParseTemplateAnnotationFromSplice(SourceLocation(), false, false, - /*Complain=*/true)) { - SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); - return ExprError(); - } - } - - // Parse a leading nested-name-specifier, e.g., // CXXScopeSpec SS; - if (TemplateKWLoc.isInvalid()) { - if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, - /*ObjectHasErrors=*/false, - /*EnteringContext=*/false)) { - SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); - return ExprError(); - } + if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, + /*ObjectHasErrors=*/false, + /*EnteringContext=*/false)) { + SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); + return ExprError(); } // Start the tentative parse: This will be reverted if the operand is found @@ -79,24 +42,6 @@ ExprResult Parser::ParseCXXReflectExpression() { // TentativeParsingAction TentativeAction(*this); - // ^ [:splice-specifier:] - // - if (!SS.isSet() && Tok.is(tok::annot_splice)) { - assert(TemplateKWLoc.isInvalid()); - - ExprResult ER = getExprAnnotation(Tok); - assert(!ER.isInvalid()); - ER = ParseCXXSpliceAsExpr(true); - if (ER.isInvalid()) { - TentativeAction.Commit(); - SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); - return ExprError(); - } - - TentativeAction.Commit(); - return Actions.ActOnCXXReflectExpr(OpLoc, cast(ER.get())); - } - // Next, check for an unqualified-id. if (Tok.isOneOf(tok::identifier, tok::kw_operator, tok::kw_template, tok::tilde, tok::annot_template_id)) { diff --git a/clang/test/Reflection/reflection-of-splice.cpp b/clang/test/Reflection/reflection-of-splice.cpp deleted file mode 100644 index 821c523a2bff48..00000000000000 --- a/clang/test/Reflection/reflection-of-splice.cpp +++ /dev/null @@ -1,71 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Copyright 2024 Bloomberg Finance L.P. -// -// 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 -// -//===----------------------------------------------------------------------===// -// -// RUN: %clang_cc1 %s -std=c++23 -freflection - -using info = decltype(^int); - -namespace myns { - namespace Inner {} - struct Cls {}; - template struct TCls { - void memfn(); - }; -} // namespace myns - - // =========== - // idempotency - // =========== - -namespace idempotency { -static_assert(^template [:^myns::TCls:] == ^myns::TCls); - -static_assert(^[:^myns:]::Cls == ^myns::Cls); -static_assert(^[:^myns:]::TCls == ^myns::TCls); - -static_assert(^[:^myns::TCls:]::memfn == ^myns::TCls::memfn); -static_assert(^[:^myns::TCls:]::memfn != ^myns::TCls::memfn); - -static_assert(^[:^myns:]::TCls == ^myns::TCls); -static_assert(^[:^myns:]::Inner == ^myns::Inner); -} // namespace idempotency - - // ================= - // dependent_splices - // ================= - -namespace dependent_splices { -template