003 File Manager
Current Path:
/usr/src/contrib/llvm-project/clang/include/clang/AST
usr
/
src
/
contrib
/
llvm-project
/
clang
/
include
/
clang
/
AST
/
📁
..
📄
APValue.h
(20.92 KB)
📄
AST.h
(907 B)
📄
ASTConcept.h
(7.02 KB)
📄
ASTConsumer.h
(5.99 KB)
📄
ASTContext.h
(122.68 KB)
📄
ASTContextAllocate.h
(1.33 KB)
📄
ASTDiagnostic.h
(1.34 KB)
📄
ASTDumper.h
(1.59 KB)
📄
ASTDumperUtils.h
(3.49 KB)
📄
ASTFwd.h
(1.01 KB)
📄
ASTImporter.h
(22.86 KB)
📄
ASTImporterLookupTable.h
(2.7 KB)
📄
ASTImporterSharedState.h
(2.51 KB)
📄
ASTLambda.h
(3.04 KB)
📄
ASTMutationListener.h
(5.84 KB)
📄
ASTNodeTraverser.h
(21.38 KB)
📄
ASTStructuralEquivalence.h
(5.08 KB)
📄
ASTTypeTraits.h
(19.65 KB)
📄
ASTUnresolvedSet.h
(3.37 KB)
📄
ASTVector.h
(11.75 KB)
📄
AbstractBasicReader.h
(8.82 KB)
📄
AbstractBasicWriter.h
(7.97 KB)
📄
AbstractTypeReader.h
(922 B)
📄
AbstractTypeWriter.h
(944 B)
📄
Attr.h
(11.87 KB)
📄
AttrIterator.h
(4.14 KB)
📄
AttrVisitor.h
(2.56 KB)
📄
Availability.h
(1.97 KB)
📄
BaseSubobject.h
(2.74 KB)
📄
BuiltinTypes.def
(9.91 KB)
📄
CXXInheritance.h
(14.87 KB)
📄
CXXRecordDeclDefinitionBits.def
(9.23 KB)
📄
CanonicalType.h
(24.86 KB)
📄
CharUnits.h
(8.02 KB)
📄
Comment.h
(31.03 KB)
📄
CommentBriefParser.h
(1.39 KB)
📄
CommentCommandTraits.h
(5.86 KB)
📄
CommentCommands.td
(9.27 KB)
📄
CommentDiagnostic.h
(509 B)
📄
CommentHTMLNamedCharacterReferences.td
(4.98 KB)
📄
CommentHTMLTags.td
(2.17 KB)
📄
CommentLexer.h
(9.96 KB)
📄
CommentParser.h
(3.24 KB)
📄
CommentSema.h
(9.87 KB)
📄
CommentVisitor.h
(2.38 KB)
📄
ComparisonCategories.h
(7.41 KB)
📄
ComputeDependence.h
(7.41 KB)
📄
CurrentSourceLocExprScope.h
(2.43 KB)
📄
DataCollection.h
(2.45 KB)
📄
Decl.h
(168.07 KB)
📄
DeclAccessPair.h
(1.77 KB)
📄
DeclBase.h
(93.13 KB)
📄
DeclCXX.h
(151.69 KB)
📄
DeclContextInternals.h
(8.22 KB)
📄
DeclFriend.h
(8.06 KB)
📄
DeclGroup.h
(4.11 KB)
📄
DeclLookups.h
(3.64 KB)
📄
DeclObjC.h
(101.2 KB)
📄
DeclObjCCommon.h
(1.72 KB)
📄
DeclOpenMP.h
(19.33 KB)
📄
DeclTemplate.h
(122.19 KB)
📄
DeclVisitor.h
(2.51 KB)
📄
DeclarationName.h
(33.77 KB)
📄
DependenceFlags.h
(10.99 KB)
📄
DependentDiagnostic.h
(5.4 KB)
📄
EvaluatedExprVisitor.h
(4.45 KB)
📄
Expr.h
(234.85 KB)
📄
ExprCXX.h
(169.78 KB)
📄
ExprConcepts.h
(19.62 KB)
📄
ExprObjC.h
(58.96 KB)
📄
ExprOpenMP.h
(15.48 KB)
📄
ExternalASTMerger.h
(8.11 KB)
📄
ExternalASTSource.h
(20.55 KB)
📄
FormatString.h
(22.81 KB)
📄
GlobalDecl.h
(7.16 KB)
📄
JSONNodeDumper.h
(17.53 KB)
📄
LambdaCapture.h
(4.71 KB)
📄
LexicallyOrderedRecursiveASTVisitor.h
(5.92 KB)
📄
LocInfoType.h
(1.84 KB)
📄
Mangle.h
(10.65 KB)
📄
MangleNumberingContext.h
(2 KB)
📄
NSAPI.h
(9.23 KB)
📄
NestedNameSpecifier.h
(18.53 KB)
📄
NonTrivialTypeVisitor.h
(4 KB)
📄
ODRHash.h
(3.42 KB)
📄
OSLog.h
(5.08 KB)
📄
OpenMPClause.h
(276.08 KB)
📄
OperationKinds.def
(14.91 KB)
📄
OperationKinds.h
(1.5 KB)
📄
OptionalDiagnostic.h
(2.39 KB)
📄
ParentMap.h
(1.89 KB)
📄
ParentMapContext.h
(4.74 KB)
📄
PrettyDeclStackTrace.h
(1.39 KB)
📄
PrettyPrinter.h
(8.47 KB)
📄
PropertiesBase.td
(17.03 KB)
📄
QualTypeNames.h
(3.15 KB)
📄
RawCommentList.h
(6.6 KB)
📄
RecordLayout.h
(11.49 KB)
📄
RecursiveASTVisitor.h
(124.41 KB)
📄
Redeclarable.h
(14.34 KB)
📄
SelectorLocationsKind.h
(3.28 KB)
📄
Stmt.h
(113 KB)
📄
StmtCXX.h
(17.59 KB)
📄
StmtDataCollectors.td
(5.64 KB)
📄
StmtGraphTraits.h
(2.18 KB)
📄
StmtIterator.h
(4.2 KB)
📄
StmtObjC.h
(12.86 KB)
📄
StmtOpenMP.h
(189.5 KB)
📄
StmtVisitor.h
(8.74 KB)
📄
TemplateArgumentVisitor.h
(3.38 KB)
📄
TemplateBase.h
(22.86 KB)
📄
TemplateName.h
(19.34 KB)
📄
TextNodeDumper.h
(15.7 KB)
📄
Type.h
(248.38 KB)
📄
TypeLoc.h
(73.03 KB)
📄
TypeLocNodes.def
(1.45 KB)
📄
TypeLocVisitor.h
(1.76 KB)
📄
TypeOrdering.h
(2.38 KB)
📄
TypeProperties.td
(25.87 KB)
📄
TypeVisitor.h
(3.32 KB)
📄
UnresolvedSet.h
(5.25 KB)
📄
VTTBuilder.h
(5.19 KB)
📄
VTableBuilder.h
(20.31 KB)
Editing: ExprConcepts.h
//===- ExprConcepts.h - C++2a Concepts expressions --------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // /// \file /// Defines Expressions and AST nodes for C++2a concepts. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_EXPRCONCEPTS_H #define LLVM_CLANG_AST_EXPRCONCEPTS_H #include "clang/AST/ASTContext.h" #include "clang/AST/ASTConcept.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/Type.h" #include "clang/Basic/SourceLocation.h" #include "llvm/Support/TrailingObjects.h" #include <utility> #include <string> namespace clang { class ASTStmtReader; class ASTStmtWriter; /// \brief Represents the specialization of a concept - evaluates to a prvalue /// of type bool. /// /// According to C++2a [expr.prim.id]p3 an id-expression that denotes the /// specialization of a concept results in a prvalue of type bool. class ConceptSpecializationExpr final : public Expr, public ConceptReference, private llvm::TrailingObjects<ConceptSpecializationExpr, TemplateArgument> { friend class ASTStmtReader; friend TrailingObjects; public: using SubstitutionDiagnostic = std::pair<SourceLocation, std::string>; protected: /// \brief The number of template arguments in the tail-allocated list of /// converted template arguments. unsigned NumTemplateArgs; /// \brief Information about the satisfaction of the named concept with the /// given arguments. If this expression is value dependent, this is to be /// ignored. ASTConstraintSatisfaction *Satisfaction; ConceptSpecializationExpr(const ASTContext &C, NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl, ConceptDecl *NamedConcept, const ASTTemplateArgumentListInfo *ArgsAsWritten, ArrayRef<TemplateArgument> ConvertedArgs, const ConstraintSatisfaction *Satisfaction); ConceptSpecializationExpr(const ASTContext &C, ConceptDecl *NamedConcept, ArrayRef<TemplateArgument> ConvertedArgs, const ConstraintSatisfaction *Satisfaction, bool Dependent, bool ContainsUnexpandedParameterPack); ConceptSpecializationExpr(EmptyShell Empty, unsigned NumTemplateArgs); public: static ConceptSpecializationExpr * Create(const ASTContext &C, NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl, ConceptDecl *NamedConcept, const ASTTemplateArgumentListInfo *ArgsAsWritten, ArrayRef<TemplateArgument> ConvertedArgs, const ConstraintSatisfaction *Satisfaction); static ConceptSpecializationExpr * Create(const ASTContext &C, ConceptDecl *NamedConcept, ArrayRef<TemplateArgument> ConvertedArgs, const ConstraintSatisfaction *Satisfaction, bool Dependent, bool ContainsUnexpandedParameterPack); static ConceptSpecializationExpr * Create(ASTContext &C, EmptyShell Empty, unsigned NumTemplateArgs); ArrayRef<TemplateArgument> getTemplateArguments() const { return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(), NumTemplateArgs); } /// \brief Set new template arguments for this concept specialization. void setTemplateArguments(ArrayRef<TemplateArgument> Converted); /// \brief Whether or not the concept with the given arguments was satisfied /// when the expression was created. /// The expression must not be dependent. bool isSatisfied() const { assert(!isValueDependent() && "isSatisfied called on a dependent ConceptSpecializationExpr"); return Satisfaction->IsSatisfied; } /// \brief Get elaborated satisfaction info about the template arguments' /// satisfaction of the named concept. /// The expression must not be dependent. const ASTConstraintSatisfaction &getSatisfaction() const { assert(!isValueDependent() && "getSatisfaction called on dependent ConceptSpecializationExpr"); return *Satisfaction; } static bool classof(const Stmt *T) { return T->getStmtClass() == ConceptSpecializationExprClass; } SourceLocation getBeginLoc() const LLVM_READONLY { return ConceptName.getBeginLoc(); } SourceLocation getEndLoc() const LLVM_READONLY { return ArgsAsWritten->RAngleLoc; } // Iterators child_range children() { return child_range(child_iterator(), child_iterator()); } const_child_range children() const { return const_child_range(const_child_iterator(), const_child_iterator()); } }; namespace concepts { /// \brief A static requirement that can be used in a requires-expression to /// check properties of types and expression. class Requirement { public: // Note - simple and compound requirements are both represented by the same // class (ExprRequirement). enum RequirementKind { RK_Type, RK_Simple, RK_Compound, RK_Nested }; private: const RequirementKind Kind; // FIXME: use RequirementDependence to model dependence? bool Dependent : 1; bool ContainsUnexpandedParameterPack : 1; bool Satisfied : 1; public: struct SubstitutionDiagnostic { StringRef SubstitutedEntity; // FIXME: Store diagnostics semantically and not as prerendered strings. // Fixing this probably requires serialization of PartialDiagnostic // objects. SourceLocation DiagLoc; StringRef DiagMessage; }; Requirement(RequirementKind Kind, bool IsDependent, bool ContainsUnexpandedParameterPack, bool IsSatisfied = true) : Kind(Kind), Dependent(IsDependent), ContainsUnexpandedParameterPack(ContainsUnexpandedParameterPack), Satisfied(IsSatisfied) {} RequirementKind getKind() const { return Kind; } bool isSatisfied() const { assert(!Dependent && "isSatisfied can only be called on non-dependent requirements."); return Satisfied; } void setSatisfied(bool IsSatisfied) { assert(!Dependent && "setSatisfied can only be called on non-dependent requirements."); Satisfied = IsSatisfied; } void setDependent(bool IsDependent) { Dependent = IsDependent; } bool isDependent() const { return Dependent; } void setContainsUnexpandedParameterPack(bool Contains) { ContainsUnexpandedParameterPack = Contains; } bool containsUnexpandedParameterPack() const { return ContainsUnexpandedParameterPack; } }; /// \brief A requires-expression requirement which queries the existence of a /// type name or type template specialization ('type' requirements). class TypeRequirement : public Requirement { public: enum SatisfactionStatus { SS_Dependent, SS_SubstitutionFailure, SS_Satisfied }; private: llvm::PointerUnion<SubstitutionDiagnostic *, TypeSourceInfo *> Value; SatisfactionStatus Status; public: friend ASTStmtReader; friend ASTStmtWriter; /// \brief Construct a type requirement from a type. If the given type is not /// dependent, this indicates that the type exists and the requirement will be /// satisfied. Otherwise, the SubstitutionDiagnostic constructor is to be /// used. TypeRequirement(TypeSourceInfo *T); /// \brief Construct a type requirement when the nested name specifier is /// invalid due to a bad substitution. The requirement is unsatisfied. TypeRequirement(SubstitutionDiagnostic *Diagnostic) : Requirement(RK_Type, false, false, false), Value(Diagnostic), Status(SS_SubstitutionFailure) {} SatisfactionStatus getSatisfactionStatus() const { return Status; } void setSatisfactionStatus(SatisfactionStatus Status) { this->Status = Status; } bool isSubstitutionFailure() const { return Status == SS_SubstitutionFailure; } SubstitutionDiagnostic *getSubstitutionDiagnostic() const { assert(Status == SS_SubstitutionFailure && "Attempted to get substitution diagnostic when there has been no " "substitution failure."); return Value.get<SubstitutionDiagnostic *>(); } TypeSourceInfo *getType() const { assert(!isSubstitutionFailure() && "Attempted to get type when there has been a substitution failure."); return Value.get<TypeSourceInfo *>(); } static bool classof(const Requirement *R) { return R->getKind() == RK_Type; } }; /// \brief A requires-expression requirement which queries the validity and /// properties of an expression ('simple' and 'compound' requirements). class ExprRequirement : public Requirement { public: enum SatisfactionStatus { SS_Dependent, SS_ExprSubstitutionFailure, SS_NoexceptNotMet, SS_TypeRequirementSubstitutionFailure, SS_ConstraintsNotSatisfied, SS_Satisfied }; class ReturnTypeRequirement { llvm::PointerIntPair< llvm::PointerUnion<TemplateParameterList *, SubstitutionDiagnostic *>, 1, bool> TypeConstraintInfo; public: friend ASTStmtReader; friend ASTStmtWriter; /// \brief No return type requirement was specified. ReturnTypeRequirement() : TypeConstraintInfo(nullptr, 0) {} /// \brief A return type requirement was specified but it was a /// substitution failure. ReturnTypeRequirement(SubstitutionDiagnostic *SubstDiag) : TypeConstraintInfo(SubstDiag, 0) {} /// \brief A 'type constraint' style return type requirement. /// \param TPL an invented template parameter list containing a single /// type parameter with a type-constraint. // TODO: Can we maybe not save the whole template parameter list and just // the type constraint? Saving the whole TPL makes it easier to handle in // serialization but is less elegant. ReturnTypeRequirement(TemplateParameterList *TPL); bool isDependent() const { return TypeConstraintInfo.getInt(); } bool containsUnexpandedParameterPack() const { if (!isTypeConstraint()) return false; return getTypeConstraintTemplateParameterList() ->containsUnexpandedParameterPack(); } bool isEmpty() const { return TypeConstraintInfo.getPointer().isNull(); } bool isSubstitutionFailure() const { return !isEmpty() && TypeConstraintInfo.getPointer().is<SubstitutionDiagnostic *>(); } bool isTypeConstraint() const { return !isEmpty() && TypeConstraintInfo.getPointer().is<TemplateParameterList *>(); } SubstitutionDiagnostic *getSubstitutionDiagnostic() const { assert(isSubstitutionFailure()); return TypeConstraintInfo.getPointer().get<SubstitutionDiagnostic *>(); } const TypeConstraint *getTypeConstraint() const; TemplateParameterList *getTypeConstraintTemplateParameterList() const { assert(isTypeConstraint()); return TypeConstraintInfo.getPointer().get<TemplateParameterList *>(); } }; private: llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> Value; SourceLocation NoexceptLoc; // May be empty if noexcept wasn't specified. ReturnTypeRequirement TypeReq; ConceptSpecializationExpr *SubstitutedConstraintExpr; SatisfactionStatus Status; public: friend ASTStmtReader; friend ASTStmtWriter; /// \brief Construct a compound requirement. /// \param E the expression which is checked by this requirement. /// \param IsSimple whether this was a simple requirement in source. /// \param NoexceptLoc the location of the noexcept keyword, if it was /// specified, otherwise an empty location. /// \param Req the requirement for the type of the checked expression. /// \param Status the satisfaction status of this requirement. ExprRequirement( Expr *E, bool IsSimple, SourceLocation NoexceptLoc, ReturnTypeRequirement Req, SatisfactionStatus Status, ConceptSpecializationExpr *SubstitutedConstraintExpr = nullptr); /// \brief Construct a compound requirement whose expression was a /// substitution failure. The requirement is not satisfied. /// \param E the diagnostic emitted while instantiating the original /// expression. /// \param IsSimple whether this was a simple requirement in source. /// \param NoexceptLoc the location of the noexcept keyword, if it was /// specified, otherwise an empty location. /// \param Req the requirement for the type of the checked expression (omit /// if no requirement was specified). ExprRequirement(SubstitutionDiagnostic *E, bool IsSimple, SourceLocation NoexceptLoc, ReturnTypeRequirement Req = {}); bool isSimple() const { return getKind() == RK_Simple; } bool isCompound() const { return getKind() == RK_Compound; } bool hasNoexceptRequirement() const { return NoexceptLoc.isValid(); } SourceLocation getNoexceptLoc() const { return NoexceptLoc; } SatisfactionStatus getSatisfactionStatus() const { return Status; } bool isExprSubstitutionFailure() const { return Status == SS_ExprSubstitutionFailure; } const ReturnTypeRequirement &getReturnTypeRequirement() const { return TypeReq; } ConceptSpecializationExpr * getReturnTypeRequirementSubstitutedConstraintExpr() const { assert(Status >= SS_TypeRequirementSubstitutionFailure); return SubstitutedConstraintExpr; } SubstitutionDiagnostic *getExprSubstitutionDiagnostic() const { assert(isExprSubstitutionFailure() && "Attempted to get expression substitution diagnostic when there has " "been no expression substitution failure"); return Value.get<SubstitutionDiagnostic *>(); } Expr *getExpr() const { assert(!isExprSubstitutionFailure() && "ExprRequirement has no expression because there has been a " "substitution failure."); return Value.get<Expr *>(); } static bool classof(const Requirement *R) { return R->getKind() == RK_Compound || R->getKind() == RK_Simple; } }; /// \brief A requires-expression requirement which is satisfied when a general /// constraint expression is satisfied ('nested' requirements). class NestedRequirement : public Requirement { llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> Value; const ASTConstraintSatisfaction *Satisfaction = nullptr; public: friend ASTStmtReader; friend ASTStmtWriter; NestedRequirement(SubstitutionDiagnostic *SubstDiag) : Requirement(RK_Nested, /*Dependent=*/false, /*ContainsUnexpandedParameterPack*/false, /*Satisfied=*/false), Value(SubstDiag) {} NestedRequirement(Expr *Constraint) : Requirement(RK_Nested, /*Dependent=*/true, Constraint->containsUnexpandedParameterPack()), Value(Constraint) { assert(Constraint->isInstantiationDependent() && "Nested requirement with non-dependent constraint must be " "constructed with a ConstraintSatisfaction object"); } NestedRequirement(ASTContext &C, Expr *Constraint, const ConstraintSatisfaction &Satisfaction) : Requirement(RK_Nested, Constraint->isInstantiationDependent(), Constraint->containsUnexpandedParameterPack(), Satisfaction.IsSatisfied), Value(Constraint), Satisfaction(ASTConstraintSatisfaction::Create(C, Satisfaction)) {} bool isSubstitutionFailure() const { return Value.is<SubstitutionDiagnostic *>(); } SubstitutionDiagnostic *getSubstitutionDiagnostic() const { assert(isSubstitutionFailure() && "getSubstitutionDiagnostic() may not be called when there was no " "substitution failure."); return Value.get<SubstitutionDiagnostic *>(); } Expr *getConstraintExpr() const { assert(!isSubstitutionFailure() && "getConstraintExpr() may not be called " "on nested requirements with " "substitution failures."); return Value.get<Expr *>(); } const ASTConstraintSatisfaction &getConstraintSatisfaction() const { assert(!isSubstitutionFailure() && "getConstraintSatisfaction() may not be " "called on nested requirements with " "substitution failures."); return *Satisfaction; } static bool classof(const Requirement *R) { return R->getKind() == RK_Nested; } }; } // namespace concepts /// C++2a [expr.prim.req]: /// A requires-expression provides a concise way to express requirements on /// template arguments. A requirement is one that can be checked by name /// lookup (6.4) or by checking properties of types and expressions. /// [...] /// A requires-expression is a prvalue of type bool [...] class RequiresExpr final : public Expr, llvm::TrailingObjects<RequiresExpr, ParmVarDecl *, concepts::Requirement *> { friend TrailingObjects; friend class ASTStmtReader; unsigned NumLocalParameters; unsigned NumRequirements; RequiresExprBodyDecl *Body; SourceLocation RBraceLoc; unsigned numTrailingObjects(OverloadToken<ParmVarDecl *>) const { return NumLocalParameters; } unsigned numTrailingObjects(OverloadToken<concepts::Requirement *>) const { return NumRequirements; } RequiresExpr(ASTContext &C, SourceLocation RequiresKWLoc, RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> LocalParameters, ArrayRef<concepts::Requirement *> Requirements, SourceLocation RBraceLoc); RequiresExpr(ASTContext &C, EmptyShell Empty, unsigned NumLocalParameters, unsigned NumRequirements); public: static RequiresExpr * Create(ASTContext &C, SourceLocation RequiresKWLoc, RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> LocalParameters, ArrayRef<concepts::Requirement *> Requirements, SourceLocation RBraceLoc); static RequiresExpr * Create(ASTContext &C, EmptyShell Empty, unsigned NumLocalParameters, unsigned NumRequirements); ArrayRef<ParmVarDecl *> getLocalParameters() const { return {getTrailingObjects<ParmVarDecl *>(), NumLocalParameters}; } RequiresExprBodyDecl *getBody() const { return Body; } ArrayRef<concepts::Requirement *> getRequirements() const { return {getTrailingObjects<concepts::Requirement *>(), NumRequirements}; } /// \brief Whether or not the requires clause is satisfied. /// The expression must not be dependent. bool isSatisfied() const { assert(!isValueDependent() && "isSatisfied called on a dependent RequiresExpr"); return RequiresExprBits.IsSatisfied; } SourceLocation getRequiresKWLoc() const { return RequiresExprBits.RequiresKWLoc; } SourceLocation getRBraceLoc() const { return RBraceLoc; } static bool classof(const Stmt *T) { return T->getStmtClass() == RequiresExprClass; } SourceLocation getBeginLoc() const LLVM_READONLY { return RequiresExprBits.RequiresKWLoc; } SourceLocation getEndLoc() const LLVM_READONLY { return RBraceLoc; } // Iterators child_range children() { return child_range(child_iterator(), child_iterator()); } const_child_range children() const { return const_child_range(const_child_iterator(), const_child_iterator()); } }; } // namespace clang #endif // LLVM_CLANG_AST_EXPRCONCEPTS_H
Upload File
Create Folder