blob: 8ec1dea84df5f19ed29c4e1068de854c87a0a68d [file] [log] [blame]
Eugene Zelenko8998f102017-11-10 00:59:22 +00001//===- DeclFriend.cpp - C++ Friend Declaration AST Node Implementation ----===//
John McCallbbbbe4e2010-03-11 07:50:04 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
John McCallbbbbe4e2010-03-11 07:50:04 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the AST classes related to C++ friend
10// declarations.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/DeclFriend.h"
Eugene Zelenko8998f102017-11-10 00:59:22 +000015#include "clang/AST/Decl.h"
16#include "clang/AST/DeclBase.h"
17#include "clang/AST/DeclCXX.h"
18#include "clang/AST/ASTContext.h"
John McCallbbbbe4e2010-03-11 07:50:04 +000019#include "clang/AST/DeclTemplate.h"
Eugene Zelenko8998f102017-11-10 00:59:22 +000020#include "clang/Basic/LLVM.h"
21#include "llvm/Support/Casting.h"
22#include <cassert>
23#include <cstddef>
24
John McCallbbbbe4e2010-03-11 07:50:04 +000025using namespace clang;
26
Eugene Zelenko8998f102017-11-10 00:59:22 +000027void FriendDecl::anchor() {}
David Blaikie68e081d2011-12-20 02:48:34 +000028
Benjamin Kramer4ab984e2012-07-04 20:19:54 +000029FriendDecl *FriendDecl::getNextFriendSlowCase() {
30 return cast_or_null<FriendDecl>(
31 NextFriend.get(getASTContext().getExternalSource()));
32}
33
John McCallbbbbe4e2010-03-11 07:50:04 +000034FriendDecl *FriendDecl::Create(ASTContext &C, DeclContext *DC,
35 SourceLocation L,
36 FriendUnion Friend,
Enea Zaffanellaeb22c872013-01-31 09:54:08 +000037 SourceLocation FriendL,
Eugene Zelenko8998f102017-11-10 00:59:22 +000038 ArrayRef<TemplateParameterList *> FriendTypeTPLists) {
John McCallbbbbe4e2010-03-11 07:50:04 +000039#ifndef NDEBUG
Eugene Zelenko8998f102017-11-10 00:59:22 +000040 if (Friend.is<NamedDecl *>()) {
Eugene Zelenko7855e772018-04-03 00:11:50 +000041 const auto *D = Friend.get<NamedDecl*>();
John McCallbbbbe4e2010-03-11 07:50:04 +000042 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()));
Enea Zaffanellaeb22c872013-01-31 09:54:08 +000051 // These template parameters are for friend types only.
Eugene Zelenko8998f102017-11-10 00:59:22 +000052 assert(FriendTypeTPLists.empty());
John McCallbbbbe4e2010-03-11 07:50:04 +000053 }
54#endif
55
James Y Knight967eb202015-12-29 22:13:13 +000056 std::size_t Extra =
57 FriendDecl::additionalSizeToAlloc<TemplateParameterList *>(
58 FriendTypeTPLists.size());
Eugene Zelenko7855e772018-04-03 00:11:50 +000059 auto *FD = new (C, DC, Extra) FriendDecl(DC, L, Friend, FriendL,
60 FriendTypeTPLists);
John McCall16927f62010-03-12 01:19:31 +000061 cast<CXXRecordDecl>(DC)->pushFriendDecl(FD);
62 return FD;
John McCallbbbbe4e2010-03-11 07:50:04 +000063}
Argyrios Kyrtzidis74d28bd2010-06-29 22:47:00 +000064
Enea Zaffanellaeb22c872013-01-31 09:54:08 +000065FriendDecl *FriendDecl::CreateDeserialized(ASTContext &C, unsigned ID,
66 unsigned FriendTypeNumTPLists) {
James Y Knight967eb202015-12-29 22:13:13 +000067 std::size_t Extra =
68 additionalSizeToAlloc<TemplateParameterList *>(FriendTypeNumTPLists);
Richard Smithf7981722013-11-22 09:01:48 +000069 return new (C, ID, Extra) FriendDecl(EmptyShell(), FriendTypeNumTPLists);
Argyrios Kyrtzidis74d28bd2010-06-29 22:47:00 +000070}
Enea Zaffanellaeb22c872013-01-31 09:54:08 +000071
Richard Smith68ad0e72013-06-26 02:41:25 +000072FriendDecl *CXXRecordDecl::getFirstFriend() const {
73 ExternalASTSource *Source = getParentASTContext().getExternalSource();
74 Decl *First = data().FirstFriend.get(Source);
Craig Topper36250ad2014-05-12 05:36:57 +000075 return First ? cast<FriendDecl>(First) : nullptr;
Richard Smith68ad0e72013-06-26 02:41:25 +000076}