1480093f4SDimitry Andric //===--- ASTConcept.cpp - Concepts Related AST Data Structures --*- C++ -*-===// 2480093f4SDimitry Andric // 3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6480093f4SDimitry Andric // 7480093f4SDimitry Andric //===----------------------------------------------------------------------===// 8480093f4SDimitry Andric /// 9480093f4SDimitry Andric /// \file 10480093f4SDimitry Andric /// \brief This file defines AST data structures related to concepts. 11480093f4SDimitry Andric /// 12480093f4SDimitry Andric //===----------------------------------------------------------------------===// 13480093f4SDimitry Andric 14480093f4SDimitry Andric #include "clang/AST/ASTConcept.h" 15480093f4SDimitry Andric #include "clang/AST/ASTContext.h" 165f757f3fSDimitry Andric #include "clang/AST/PrettyPrinter.h" 1755e4f9d5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 18*0fca6ea1SDimitry Andric #include "llvm/ADT/StringExtras.h" 195f757f3fSDimitry Andric 20480093f4SDimitry Andric using namespace clang; 21480093f4SDimitry Andric 22*0fca6ea1SDimitry Andric static void 23*0fca6ea1SDimitry Andric CreateUnsatisfiedConstraintRecord(const ASTContext &C, 24*0fca6ea1SDimitry Andric const UnsatisfiedConstraintRecord &Detail, 25bdd1243dSDimitry Andric UnsatisfiedConstraintRecord *TrailingObject) { 26*0fca6ea1SDimitry Andric if (Detail.is<Expr *>()) 27*0fca6ea1SDimitry Andric new (TrailingObject) UnsatisfiedConstraintRecord(Detail.get<Expr *>()); 28480093f4SDimitry Andric else { 29480093f4SDimitry Andric auto &SubstitutionDiagnostic = 30*0fca6ea1SDimitry Andric *Detail.get<std::pair<SourceLocation, StringRef> *>(); 31*0fca6ea1SDimitry Andric StringRef Message = C.backupStr(SubstitutionDiagnostic.second); 32480093f4SDimitry Andric auto *NewSubstDiag = new (C) std::pair<SourceLocation, StringRef>( 33*0fca6ea1SDimitry Andric SubstitutionDiagnostic.first, Message); 34*0fca6ea1SDimitry Andric new (TrailingObject) UnsatisfiedConstraintRecord(NewSubstDiag); 35480093f4SDimitry Andric } 36480093f4SDimitry Andric } 37bdd1243dSDimitry Andric 38bdd1243dSDimitry Andric ASTConstraintSatisfaction::ASTConstraintSatisfaction( 39bdd1243dSDimitry Andric const ASTContext &C, const ConstraintSatisfaction &Satisfaction) 40bdd1243dSDimitry Andric : NumRecords{Satisfaction.Details.size()}, 41bdd1243dSDimitry Andric IsSatisfied{Satisfaction.IsSatisfied}, ContainsErrors{ 42bdd1243dSDimitry Andric Satisfaction.ContainsErrors} { 43bdd1243dSDimitry Andric for (unsigned I = 0; I < NumRecords; ++I) 44*0fca6ea1SDimitry Andric CreateUnsatisfiedConstraintRecord( 45bdd1243dSDimitry Andric C, Satisfaction.Details[I], 46bdd1243dSDimitry Andric getTrailingObjects<UnsatisfiedConstraintRecord>() + I); 47480093f4SDimitry Andric } 48480093f4SDimitry Andric 49bdd1243dSDimitry Andric ASTConstraintSatisfaction::ASTConstraintSatisfaction( 50bdd1243dSDimitry Andric const ASTContext &C, const ASTConstraintSatisfaction &Satisfaction) 51bdd1243dSDimitry Andric : NumRecords{Satisfaction.NumRecords}, 52bdd1243dSDimitry Andric IsSatisfied{Satisfaction.IsSatisfied}, 53bdd1243dSDimitry Andric ContainsErrors{Satisfaction.ContainsErrors} { 54bdd1243dSDimitry Andric for (unsigned I = 0; I < NumRecords; ++I) 55*0fca6ea1SDimitry Andric CreateUnsatisfiedConstraintRecord( 56bdd1243dSDimitry Andric C, *(Satisfaction.begin() + I), 57bdd1243dSDimitry Andric getTrailingObjects<UnsatisfiedConstraintRecord>() + I); 58bdd1243dSDimitry Andric } 59480093f4SDimitry Andric 60480093f4SDimitry Andric ASTConstraintSatisfaction * 61480093f4SDimitry Andric ASTConstraintSatisfaction::Create(const ASTContext &C, 62480093f4SDimitry Andric const ConstraintSatisfaction &Satisfaction) { 63480093f4SDimitry Andric std::size_t size = 64480093f4SDimitry Andric totalSizeToAlloc<UnsatisfiedConstraintRecord>( 65480093f4SDimitry Andric Satisfaction.Details.size()); 66480093f4SDimitry Andric void *Mem = C.Allocate(size, alignof(ASTConstraintSatisfaction)); 67480093f4SDimitry Andric return new (Mem) ASTConstraintSatisfaction(C, Satisfaction); 68480093f4SDimitry Andric } 6955e4f9d5SDimitry Andric 70bdd1243dSDimitry Andric ASTConstraintSatisfaction *ASTConstraintSatisfaction::Rebuild( 71bdd1243dSDimitry Andric const ASTContext &C, const ASTConstraintSatisfaction &Satisfaction) { 72bdd1243dSDimitry Andric std::size_t size = 73bdd1243dSDimitry Andric totalSizeToAlloc<UnsatisfiedConstraintRecord>(Satisfaction.NumRecords); 74bdd1243dSDimitry Andric void *Mem = C.Allocate(size, alignof(ASTConstraintSatisfaction)); 75bdd1243dSDimitry Andric return new (Mem) ASTConstraintSatisfaction(C, Satisfaction); 76bdd1243dSDimitry Andric } 77bdd1243dSDimitry Andric 7855e4f9d5SDimitry Andric void ConstraintSatisfaction::Profile( 7913138422SDimitry Andric llvm::FoldingSetNodeID &ID, const ASTContext &C, 8013138422SDimitry Andric const NamedDecl *ConstraintOwner, ArrayRef<TemplateArgument> TemplateArgs) { 8155e4f9d5SDimitry Andric ID.AddPointer(ConstraintOwner); 8255e4f9d5SDimitry Andric ID.AddInteger(TemplateArgs.size()); 8355e4f9d5SDimitry Andric for (auto &Arg : TemplateArgs) 8455e4f9d5SDimitry Andric Arg.Profile(ID, C); 8555e4f9d5SDimitry Andric } 865f757f3fSDimitry Andric 875f757f3fSDimitry Andric ConceptReference * 885f757f3fSDimitry Andric ConceptReference::Create(const ASTContext &C, NestedNameSpecifierLoc NNS, 895f757f3fSDimitry Andric SourceLocation TemplateKWLoc, 905f757f3fSDimitry Andric DeclarationNameInfo ConceptNameInfo, 915f757f3fSDimitry Andric NamedDecl *FoundDecl, ConceptDecl *NamedConcept, 925f757f3fSDimitry Andric const ASTTemplateArgumentListInfo *ArgsAsWritten) { 935f757f3fSDimitry Andric return new (C) ConceptReference(NNS, TemplateKWLoc, ConceptNameInfo, 945f757f3fSDimitry Andric FoundDecl, NamedConcept, ArgsAsWritten); 955f757f3fSDimitry Andric } 965f757f3fSDimitry Andric 975f757f3fSDimitry Andric void ConceptReference::print(llvm::raw_ostream &OS, 985f757f3fSDimitry Andric const PrintingPolicy &Policy) const { 995f757f3fSDimitry Andric if (NestedNameSpec) 1005f757f3fSDimitry Andric NestedNameSpec.getNestedNameSpecifier()->print(OS, Policy); 1015f757f3fSDimitry Andric ConceptName.printName(OS, Policy); 1025f757f3fSDimitry Andric if (hasExplicitTemplateArgs()) { 1035f757f3fSDimitry Andric OS << "<"; 104*0fca6ea1SDimitry Andric llvm::ListSeparator Sep(", "); 1055f757f3fSDimitry Andric // FIXME: Find corresponding parameter for argument 106*0fca6ea1SDimitry Andric for (auto &ArgLoc : ArgsAsWritten->arguments()) { 107*0fca6ea1SDimitry Andric OS << Sep; 1085f757f3fSDimitry Andric ArgLoc.getArgument().print(Policy, OS, /*IncludeType*/ false); 109*0fca6ea1SDimitry Andric } 1105f757f3fSDimitry Andric OS << ">"; 1115f757f3fSDimitry Andric } 1125f757f3fSDimitry Andric } 113