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