brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.0 KiB · 36f910d Raw
189 lines · cpp
1//===- ExprCXX.cpp - (C++) Expression AST Node Implementation -------------===//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-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the subclesses of Expr class declared in ExprCXX.h10//11//===----------------------------------------------------------------------===//12 13#include "clang/AST/ExprConcepts.h"14#include "clang/AST/ASTConcept.h"15#include "clang/AST/ASTContext.h"16#include "clang/AST/ComputeDependence.h"17#include "clang/AST/Decl.h"18#include "clang/AST/DeclTemplate.h"19#include "clang/AST/DeclarationName.h"20#include "clang/AST/DependenceFlags.h"21#include "clang/AST/Expr.h"22#include "clang/AST/NestedNameSpecifier.h"23#include "clang/AST/TemplateBase.h"24#include "clang/AST/Type.h"25#include "clang/Basic/SourceLocation.h"26 27using namespace clang;28 29ConceptSpecializationExpr::ConceptSpecializationExpr(30    const ASTContext &C, ConceptReference *Loc,31    ImplicitConceptSpecializationDecl *SpecDecl,32    const ConstraintSatisfaction *Satisfaction)33    : Expr(ConceptSpecializationExprClass, C.BoolTy, VK_PRValue, OK_Ordinary),34      ConceptRef(Loc), SpecDecl(SpecDecl),35      Satisfaction(Satisfaction36                       ? ASTConstraintSatisfaction::Create(C, *Satisfaction)37                       : nullptr) {38  setDependence(computeDependence(this, /*ValueDependent=*/!Satisfaction));39 40  // Currently guaranteed by the fact concepts can only be at namespace-scope.41  assert(!Loc->getNestedNameSpecifierLoc() ||42         (!Loc->getNestedNameSpecifierLoc()43               .getNestedNameSpecifier()44               .isInstantiationDependent() &&45          !Loc->getNestedNameSpecifierLoc()46               .getNestedNameSpecifier()47               .containsUnexpandedParameterPack()));48  assert((!isValueDependent() || isInstantiationDependent()) &&49         "should not be value-dependent");50}51 52ConceptSpecializationExpr::ConceptSpecializationExpr(EmptyShell Empty)53    : Expr(ConceptSpecializationExprClass, Empty) {}54 55ConceptSpecializationExpr *56ConceptSpecializationExpr::Create(const ASTContext &C, ConceptReference *Loc,57                                  ImplicitConceptSpecializationDecl *SpecDecl,58                                  const ConstraintSatisfaction *Satisfaction) {59  return new (C) ConceptSpecializationExpr(C, Loc, SpecDecl, Satisfaction);60}61 62ConceptSpecializationExpr::ConceptSpecializationExpr(63    const ASTContext &C, ConceptReference *Loc,64    ImplicitConceptSpecializationDecl *SpecDecl,65    const ConstraintSatisfaction *Satisfaction, bool Dependent,66    bool ContainsUnexpandedParameterPack)67    : Expr(ConceptSpecializationExprClass, C.BoolTy, VK_PRValue, OK_Ordinary),68      ConceptRef(Loc), SpecDecl(SpecDecl),69      Satisfaction(Satisfaction70                       ? ASTConstraintSatisfaction::Create(C, *Satisfaction)71                       : nullptr) {72  ExprDependence D = ExprDependence::None;73  if (!Satisfaction)74    D |= ExprDependence::Value;75  if (Dependent)76    D |= ExprDependence::Instantiation;77  if (ContainsUnexpandedParameterPack)78    D |= ExprDependence::UnexpandedPack;79  setDependence(D);80}81 82ConceptSpecializationExpr *83ConceptSpecializationExpr::Create(const ASTContext &C, ConceptReference *Loc,84                                  ImplicitConceptSpecializationDecl *SpecDecl,85                                  const ConstraintSatisfaction *Satisfaction,86                                  bool Dependent,87                                  bool ContainsUnexpandedParameterPack) {88  return new (C)89      ConceptSpecializationExpr(C, Loc, SpecDecl, Satisfaction, Dependent,90                                ContainsUnexpandedParameterPack);91}92 93const TypeConstraint *94concepts::ExprRequirement::ReturnTypeRequirement::getTypeConstraint() const {95  assert(isTypeConstraint());96  auto TPL = cast<TemplateParameterList *>(TypeConstraintInfo.getPointer());97  return cast<TemplateTypeParmDecl>(TPL->getParam(0))98      ->getTypeConstraint();99}100 101// Search through the requirements, and see if any have a RecoveryExpr in it,102// which means this RequiresExpr ALSO needs to be invalid.103static bool RequirementContainsError(concepts::Requirement *R) {104  if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(R))105    return ExprReq->getExpr() && ExprReq->getExpr()->containsErrors();106 107  if (auto *NestedReq = dyn_cast<concepts::NestedRequirement>(R))108    return !NestedReq->hasInvalidConstraint() &&109           NestedReq->getConstraintExpr() &&110           NestedReq->getConstraintExpr()->containsErrors();111  return false;112}113 114RequiresExpr::RequiresExpr(ASTContext &C, SourceLocation RequiresKWLoc,115                           RequiresExprBodyDecl *Body, SourceLocation LParenLoc,116                           ArrayRef<ParmVarDecl *> LocalParameters,117                           SourceLocation RParenLoc,118                           ArrayRef<concepts::Requirement *> Requirements,119                           SourceLocation RBraceLoc)120    : Expr(RequiresExprClass, C.BoolTy, VK_PRValue, OK_Ordinary),121      NumLocalParameters(LocalParameters.size()),122      NumRequirements(Requirements.size()), Body(Body), LParenLoc(LParenLoc),123      RParenLoc(RParenLoc), RBraceLoc(RBraceLoc) {124  RequiresExprBits.IsSatisfied = false;125  RequiresExprBits.RequiresKWLoc = RequiresKWLoc;126  bool Dependent = false;127  bool ContainsUnexpandedParameterPack = false;128  for (ParmVarDecl *P : LocalParameters) {129    Dependent |= P->getType()->isInstantiationDependentType();130    ContainsUnexpandedParameterPack |=131        P->getType()->containsUnexpandedParameterPack();132  }133  RequiresExprBits.IsSatisfied = true;134  for (concepts::Requirement *R : Requirements) {135    Dependent |= R->isDependent();136    ContainsUnexpandedParameterPack |= R->containsUnexpandedParameterPack();137    if (!Dependent) {138      RequiresExprBits.IsSatisfied = R->isSatisfied();139      if (!RequiresExprBits.IsSatisfied)140        break;141    }142 143    if (RequirementContainsError(R))144      setDependence(getDependence() | ExprDependence::Error);145  }146  llvm::copy(LocalParameters, getTrailingObjects<ParmVarDecl *>());147  llvm::copy(Requirements, getTrailingObjects<concepts::Requirement *>());148  RequiresExprBits.IsSatisfied |= Dependent;149  // FIXME: move the computing dependency logic to ComputeDependence.h150  if (ContainsUnexpandedParameterPack)151    setDependence(getDependence() | ExprDependence::UnexpandedPack);152  // FIXME: this is incorrect for cases where we have a non-dependent153  // requirement, but its parameters are instantiation-dependent. RequiresExpr154  // should be instantiation-dependent if it has instantiation-dependent155  // parameters.156  if (Dependent)157    setDependence(getDependence() | ExprDependence::ValueInstantiation);158}159 160RequiresExpr::RequiresExpr(ASTContext &C, EmptyShell Empty,161                           unsigned NumLocalParameters,162                           unsigned NumRequirements)163  : Expr(RequiresExprClass, Empty), NumLocalParameters(NumLocalParameters),164    NumRequirements(NumRequirements) { }165 166RequiresExpr *RequiresExpr::Create(167    ASTContext &C, SourceLocation RequiresKWLoc, RequiresExprBodyDecl *Body,168    SourceLocation LParenLoc, ArrayRef<ParmVarDecl *> LocalParameters,169    SourceLocation RParenLoc, ArrayRef<concepts::Requirement *> Requirements,170    SourceLocation RBraceLoc) {171  void *Mem =172      C.Allocate(totalSizeToAlloc<ParmVarDecl *, concepts::Requirement *>(173                     LocalParameters.size(), Requirements.size()),174                 alignof(RequiresExpr));175  return new (Mem)176      RequiresExpr(C, RequiresKWLoc, Body, LParenLoc, LocalParameters,177                   RParenLoc, Requirements, RBraceLoc);178}179 180RequiresExpr *181RequiresExpr::Create(ASTContext &C, EmptyShell Empty,182                     unsigned NumLocalParameters, unsigned NumRequirements) {183  void *Mem =184      C.Allocate(totalSizeToAlloc<ParmVarDecl *, concepts::Requirement *>(185                     NumLocalParameters, NumRequirements),186                 alignof(RequiresExpr));187  return new (Mem) RequiresExpr(C, Empty, NumLocalParameters, NumRequirements);188}189