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