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/PrettyPrinter.h" 17 #include "llvm/ADT/ArrayRef.h" 18 #include "llvm/ADT/StringExtras.h" 19 20 using namespace clang; 21 22 static void 23 CreateUnsatisfiedConstraintRecord(const ASTContext &C, 24 const UnsatisfiedConstraintRecord &Detail, 25 UnsatisfiedConstraintRecord *TrailingObject) { 26 if (Detail.is<Expr *>()) 27 new (TrailingObject) UnsatisfiedConstraintRecord(Detail.get<Expr *>()); 28 else { 29 auto &SubstitutionDiagnostic = 30 *Detail.get<std::pair<SourceLocation, StringRef> *>(); 31 StringRef Message = C.backupStr(SubstitutionDiagnostic.second); 32 auto *NewSubstDiag = new (C) std::pair<SourceLocation, StringRef>( 33 SubstitutionDiagnostic.first, Message); 34 new (TrailingObject) UnsatisfiedConstraintRecord(NewSubstDiag); 35 } 36 } 37 38 ASTConstraintSatisfaction::ASTConstraintSatisfaction( 39 const ASTContext &C, const ConstraintSatisfaction &Satisfaction) 40 : NumRecords{Satisfaction.Details.size()}, 41 IsSatisfied{Satisfaction.IsSatisfied}, ContainsErrors{ 42 Satisfaction.ContainsErrors} { 43 for (unsigned I = 0; I < NumRecords; ++I) 44 CreateUnsatisfiedConstraintRecord( 45 C, Satisfaction.Details[I], 46 getTrailingObjects<UnsatisfiedConstraintRecord>() + I); 47 } 48 49 ASTConstraintSatisfaction::ASTConstraintSatisfaction( 50 const ASTContext &C, const ASTConstraintSatisfaction &Satisfaction) 51 : NumRecords{Satisfaction.NumRecords}, 52 IsSatisfied{Satisfaction.IsSatisfied}, 53 ContainsErrors{Satisfaction.ContainsErrors} { 54 for (unsigned I = 0; I < NumRecords; ++I) 55 CreateUnsatisfiedConstraintRecord( 56 C, *(Satisfaction.begin() + I), 57 getTrailingObjects<UnsatisfiedConstraintRecord>() + I); 58 } 59 60 ASTConstraintSatisfaction * 61 ASTConstraintSatisfaction::Create(const ASTContext &C, 62 const ConstraintSatisfaction &Satisfaction) { 63 std::size_t size = 64 totalSizeToAlloc<UnsatisfiedConstraintRecord>( 65 Satisfaction.Details.size()); 66 void *Mem = C.Allocate(size, alignof(ASTConstraintSatisfaction)); 67 return new (Mem) ASTConstraintSatisfaction(C, Satisfaction); 68 } 69 70 ASTConstraintSatisfaction *ASTConstraintSatisfaction::Rebuild( 71 const ASTContext &C, const ASTConstraintSatisfaction &Satisfaction) { 72 std::size_t size = 73 totalSizeToAlloc<UnsatisfiedConstraintRecord>(Satisfaction.NumRecords); 74 void *Mem = C.Allocate(size, alignof(ASTConstraintSatisfaction)); 75 return new (Mem) ASTConstraintSatisfaction(C, Satisfaction); 76 } 77 78 void ConstraintSatisfaction::Profile( 79 llvm::FoldingSetNodeID &ID, const ASTContext &C, 80 const NamedDecl *ConstraintOwner, ArrayRef<TemplateArgument> TemplateArgs) { 81 ID.AddPointer(ConstraintOwner); 82 ID.AddInteger(TemplateArgs.size()); 83 for (auto &Arg : TemplateArgs) 84 Arg.Profile(ID, C); 85 } 86 87 ConceptReference * 88 ConceptReference::Create(const ASTContext &C, NestedNameSpecifierLoc NNS, 89 SourceLocation TemplateKWLoc, 90 DeclarationNameInfo ConceptNameInfo, 91 NamedDecl *FoundDecl, ConceptDecl *NamedConcept, 92 const ASTTemplateArgumentListInfo *ArgsAsWritten) { 93 return new (C) ConceptReference(NNS, TemplateKWLoc, ConceptNameInfo, 94 FoundDecl, NamedConcept, ArgsAsWritten); 95 } 96 97 void ConceptReference::print(llvm::raw_ostream &OS, 98 const PrintingPolicy &Policy) const { 99 if (NestedNameSpec) 100 NestedNameSpec.getNestedNameSpecifier()->print(OS, Policy); 101 ConceptName.printName(OS, Policy); 102 if (hasExplicitTemplateArgs()) { 103 OS << "<"; 104 llvm::ListSeparator Sep(", "); 105 // FIXME: Find corresponding parameter for argument 106 for (auto &ArgLoc : ArgsAsWritten->arguments()) { 107 OS << Sep; 108 ArgLoc.getArgument().print(Policy, OS, /*IncludeType*/ false); 109 } 110 OS << ">"; 111 } 112 } 113