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