1//===--- ParseReflect.cpp - C++26 Reflection Parsing ---------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements parsing for reflection facilities.
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/AST/LocInfoType.h"
14#include "clang/Basic/DiagnosticParse.h"
15#include "clang/Parse/Parser.h"
16#include "clang/Sema/EnterExpressionEvaluationContext.h"
17using namespace clang;
18
19ExprResult Parser::ParseCXXReflectExpression() {
20 // TODO(reflection) : support parsing for global namespace,
21 // reflection-name, id-expression and remaining supports for
22 // type-id (placeholder type, alias template, etc.)
23 EnterExpressionEvaluationContext Unevaluated(
24 Actions, Sema::ExpressionEvaluationContext::Unevaluated);
25 assert(Tok.is(tok::caretcaret));
26 SourceLocation CaretCaretLoc = ConsumeToken();
27 SourceLocation OperandLoc = Tok.getLocation();
28
29 if (isCXXTypeId(Context: TentativeCXXTypeIdContext::AsReflectionOperand)) {
30 TypeResult TR = ParseTypeName(/*TypeOf=*/Range: nullptr);
31 if (TR.isInvalid())
32 return ExprError();
33
34 TypeSourceInfo *TSI = nullptr;
35 QualType QT = Actions.GetTypeFromParser(Ty: TR.get(), TInfo: &TSI);
36
37 if (QT.isNull())
38 return ExprError();
39
40 if (!TSI)
41 TSI = Actions.getASTContext().getTrivialTypeSourceInfo(T: QT, Loc: OperandLoc);
42
43 QT = QT.getCanonicalType().getUnqualifiedType();
44 if (TSI && QT.getTypePtr()->isBuiltinType()) {
45 // Only supports builtin types for now
46 return Actions.ActOnCXXReflectExpr(OpLoc: CaretCaretLoc, TSI);
47 }
48 }
49
50 Diag(Loc: OperandLoc, DiagID: diag::err_cannot_reflect_operand);
51 return ExprError();
52}
53