1 | //===- DeclFriend.cpp - C++ Friend Declaration AST Node Implementation ----===// |
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 | // This file implements the AST classes related to C++ friend |
10 | // declarations. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #include "clang/AST/DeclFriend.h" |
15 | #include "clang/AST/ASTContext.h" |
16 | #include "clang/AST/Decl.h" |
17 | #include "clang/AST/DeclBase.h" |
18 | #include "clang/AST/DeclCXX.h" |
19 | #include "clang/AST/DeclTemplate.h" |
20 | #include "clang/Basic/LLVM.h" |
21 | #include <cassert> |
22 | #include <cstddef> |
23 | |
24 | using namespace clang; |
25 | |
26 | void FriendDecl::anchor() {} |
27 | |
28 | FriendDecl *FriendDecl::getNextFriendSlowCase() { |
29 | return cast_or_null<FriendDecl>( |
30 | NextFriend.get(Source: getASTContext().getExternalSource())); |
31 | } |
32 | |
33 | FriendDecl * |
34 | FriendDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, |
35 | FriendUnion Friend, SourceLocation FriendL, |
36 | SourceLocation EllipsisLoc, |
37 | ArrayRef<TemplateParameterList *> FriendTypeTPLists) { |
38 | #ifndef NDEBUG |
39 | if (const auto *D = dyn_cast<NamedDecl *>(Val&: Friend)) { |
40 | assert(isa<FunctionDecl>(D) || |
41 | isa<CXXRecordDecl>(D) || |
42 | isa<FunctionTemplateDecl>(D) || |
43 | isa<ClassTemplateDecl>(D)); |
44 | |
45 | // As a temporary hack, we permit template instantiation to point |
46 | // to the original declaration when instantiating members. |
47 | assert(D->getFriendObjectKind() || |
48 | (cast<CXXRecordDecl>(DC)->getTemplateSpecializationKind())); |
49 | // These template parameters are for friend types only. |
50 | assert(FriendTypeTPLists.empty()); |
51 | } |
52 | #endif |
53 | |
54 | std::size_t = |
55 | FriendDecl::additionalSizeToAlloc<TemplateParameterList *>( |
56 | Counts: FriendTypeTPLists.size()); |
57 | auto *FD = new (C, DC, Extra) |
58 | FriendDecl(DC, L, Friend, FriendL, EllipsisLoc, FriendTypeTPLists); |
59 | cast<CXXRecordDecl>(Val: DC)->pushFriendDecl(FD); |
60 | return FD; |
61 | } |
62 | |
63 | FriendDecl *FriendDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, |
64 | unsigned FriendTypeNumTPLists) { |
65 | std::size_t = |
66 | additionalSizeToAlloc<TemplateParameterList *>(Counts: FriendTypeNumTPLists); |
67 | return new (C, ID, Extra) FriendDecl(EmptyShell(), FriendTypeNumTPLists); |
68 | } |
69 | |
70 | FriendDecl *CXXRecordDecl::getFirstFriend() const { |
71 | ExternalASTSource *Source = getParentASTContext().getExternalSource(); |
72 | Decl *First = data().FirstFriend.get(Source); |
73 | return First ? cast<FriendDecl>(Val: First) : nullptr; |
74 | } |
75 | |