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