1 //===--- ASTConcept.cpp - Concepts Related AST Data Structures --*- C++ -*-===// 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 /// \file 10 /// \brief This file defines AST data structures related to concepts. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/AST/ASTConcept.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/Decl.h" 17 #include "clang/AST/TemplateBase.h" 18 #include "llvm/ADT/ArrayRef.h" 19 #include "llvm/ADT/FoldingSet.h" 20 using namespace clang; 21 22 namespace { 23 void CreatUnsatisfiedConstraintRecord( 24 const ASTContext &C, const UnsatisfiedConstraintRecord &Detail, 25 UnsatisfiedConstraintRecord *TrailingObject) { 26 if (Detail.second.is<Expr *>()) 27 new (TrailingObject) UnsatisfiedConstraintRecord{ 28 Detail.first, 29 UnsatisfiedConstraintRecord::second_type(Detail.second.get<Expr *>())}; 30 else { 31 auto &SubstitutionDiagnostic = 32 *Detail.second.get<std::pair<SourceLocation, StringRef> *>(); 33 unsigned MessageSize = SubstitutionDiagnostic.second.size(); 34 char *Mem = new (C) char[MessageSize]; 35 memcpy(Mem, SubstitutionDiagnostic.second.data(), MessageSize); 36 auto *NewSubstDiag = new (C) std::pair<SourceLocation, StringRef>( 37 SubstitutionDiagnostic.first, StringRef(Mem, MessageSize)); 38 new (TrailingObject) UnsatisfiedConstraintRecord{ 39 Detail.first, UnsatisfiedConstraintRecord::second_type(NewSubstDiag)}; 40 } 41 } 42 } // namespace 43 44 ASTConstraintSatisfaction::ASTConstraintSatisfaction( 45 const ASTContext &C, const ConstraintSatisfaction &Satisfaction) 46 : NumRecords{Satisfaction.Details.size()}, 47 IsSatisfied{Satisfaction.IsSatisfied}, ContainsErrors{ 48 Satisfaction.ContainsErrors} { 49 for (unsigned I = 0; I < NumRecords; ++I) 50 CreatUnsatisfiedConstraintRecord( 51 C, Satisfaction.Details[I], 52 getTrailingObjects<UnsatisfiedConstraintRecord>() + I); 53 } 54 55 ASTConstraintSatisfaction::ASTConstraintSatisfaction( 56 const ASTContext &C, const ASTConstraintSatisfaction &Satisfaction) 57 : NumRecords{Satisfaction.NumRecords}, 58 IsSatisfied{Satisfaction.IsSatisfied}, 59 ContainsErrors{Satisfaction.ContainsErrors} { 60 for (unsigned I = 0; I < NumRecords; ++I) 61 CreatUnsatisfiedConstraintRecord( 62 C, *(Satisfaction.begin() + I), 63 getTrailingObjects<UnsatisfiedConstraintRecord>() + I); 64 } 65 66 ASTConstraintSatisfaction * 67 ASTConstraintSatisfaction::Create(const ASTContext &C, 68 const ConstraintSatisfaction &Satisfaction) { 69 std::size_t size = 70 totalSizeToAlloc<UnsatisfiedConstraintRecord>( 71 Satisfaction.Details.size()); 72 void *Mem = C.Allocate(size, alignof(ASTConstraintSatisfaction)); 73 return new (Mem) ASTConstraintSatisfaction(C, Satisfaction); 74 } 75 76 ASTConstraintSatisfaction *ASTConstraintSatisfaction::Rebuild( 77 const ASTContext &C, const ASTConstraintSatisfaction &Satisfaction) { 78 std::size_t size = 79 totalSizeToAlloc<UnsatisfiedConstraintRecord>(Satisfaction.NumRecords); 80 void *Mem = C.Allocate(size, alignof(ASTConstraintSatisfaction)); 81 return new (Mem) ASTConstraintSatisfaction(C, Satisfaction); 82 } 83 84 void ConstraintSatisfaction::Profile( 85 llvm::FoldingSetNodeID &ID, const ASTContext &C, 86 const NamedDecl *ConstraintOwner, ArrayRef<TemplateArgument> TemplateArgs) { 87 ID.AddPointer(ConstraintOwner); 88 ID.AddInteger(TemplateArgs.size()); 89 for (auto &Arg : TemplateArgs) 90 Arg.Profile(ID, C); 91 } 92