blob: 0f96bf0762ca406ad8130767bf8b1acad69cc51c [file] [log] [blame]
Eugene Zelenkode0215c2017-11-13 23:01:27 +00001//===- Decl.h - Classes for representing declarations -----------*- C++ -*-===//
Chris Lattnerd0745a02006-08-17 05:18:35 +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
Chris Lattnerd0745a02006-08-17 05:18:35 +00006//
7//===----------------------------------------------------------------------===//
8//
Argyrios Kyrtzidis2951e142008-06-09 21:05:31 +00009// This file defines the Decl subclasses.
Chris Lattnerd0745a02006-08-17 05:18:35 +000010//
11//===----------------------------------------------------------------------===//
12
Chris Lattner3e7bd4e2006-08-17 05:51:27 +000013#ifndef LLVM_CLANG_AST_DECL_H
14#define LLVM_CLANG_AST_DECL_H
Chris Lattnerd0745a02006-08-17 05:18:35 +000015
Craig Topper142f2702024-01-16 12:49:11 -080016#include "clang/AST/APNumericStorage.h"
Douglas Gregor31cf12c2009-05-26 18:54:04 +000017#include "clang/AST/APValue.h"
Richard Trieuafd67112019-01-10 03:23:25 +000018#include "clang/AST/ASTContextAllocate.h"
Richard Smith848934c2019-12-05 13:37:35 -080019#include "clang/AST/DeclAccessPair.h"
Chris Lattnerc5ffed42008-04-04 06:12:32 +000020#include "clang/AST/DeclBase.h"
Chris Lattnera2e21672009-02-20 21:06:29 +000021#include "clang/AST/DeclarationName.h"
Douglas Gregore3dcb2d2009-04-18 00:02:19 +000022#include "clang/AST/ExternalASTSource.h"
Eugene Zelenkode0215c2017-11-13 23:01:27 +000023#include "clang/AST/NestedNameSpecifier.h"
Benjamin Kramerd7d2b1f2012-12-01 16:35:25 +000024#include "clang/AST/Redeclarable.h"
25#include "clang/AST/Type.h"
Eugene Zelenkode0215c2017-11-13 23:01:27 +000026#include "clang/Basic/AddressSpaces.h"
27#include "clang/Basic/Diagnostic.h"
28#include "clang/Basic/IdentifierTable.h"
29#include "clang/Basic/LLVM.h"
Douglas Gregor7dc5c172010-02-03 09:33:45 +000030#include "clang/Basic/Linkage.h"
Benjamin Kramerf3ca26982014-05-10 16:31:55 +000031#include "clang/Basic/OperatorKinds.h"
Eugene Zelenkode0215c2017-11-13 23:01:27 +000032#include "clang/Basic/PartialDiagnostic.h"
Nico Weber66220292016-03-02 17:28:48 +000033#include "clang/Basic/PragmaKinds.h"
Eugene Zelenkode0215c2017-11-13 23:01:27 +000034#include "clang/Basic/SourceLocation.h"
35#include "clang/Basic/Specifiers.h"
36#include "clang/Basic/Visibility.h"
37#include "llvm/ADT/APSInt.h"
David Blaikie9c70e042011-09-21 18:16:56 +000038#include "llvm/ADT/ArrayRef.h"
Eugene Zelenkode0215c2017-11-13 23:01:27 +000039#include "llvm/ADT/PointerIntPair.h"
40#include "llvm/ADT/PointerUnion.h"
41#include "llvm/ADT/StringRef.h"
42#include "llvm/ADT/iterator_range.h"
43#include "llvm/Support/Casting.h"
Daniel Dunbare4775e12012-03-09 19:35:29 +000044#include "llvm/Support/Compiler.h"
James Y Knight7a22b242015-08-06 20:26:32 +000045#include "llvm/Support/TrailingObjects.h"
Eugene Zelenkode0215c2017-11-13 23:01:27 +000046#include <cassert>
47#include <cstddef>
48#include <cstdint>
Kazu Hirataa1580d72023-01-14 11:07:21 -080049#include <optional>
Eugene Zelenkode0215c2017-11-13 23:01:27 +000050#include <string>
51#include <utility>
Ted Kremenek1f1e7562007-10-25 21:37:16 +000052
Chris Lattnerd0745a02006-08-17 05:18:35 +000053namespace clang {
Eugene Zelenkode0215c2017-11-13 23:01:27 +000054
55class ASTContext;
Benjamin Kramerd7d2b1f2012-12-01 16:35:25 +000056struct ASTTemplateArgumentListInfo;
Benjamin Kramerd7d2b1f2012-12-01 16:35:25 +000057class CompoundStmt;
58class DependentFunctionTemplateSpecializationInfo;
Eugene Zelenkode0215c2017-11-13 23:01:27 +000059class EnumDecl;
Chris Lattnerc1915e22007-01-25 07:29:02 +000060class Expr;
Douglas Gregor24c332b2009-05-14 21:06:31 +000061class FunctionTemplateDecl;
Douglas Gregor70d83e22009-06-29 17:30:29 +000062class FunctionTemplateSpecializationInfo;
Richard Smithd052a5782019-10-22 17:44:08 -070063class FunctionTypeLoc;
Benjamin Kramerd7d2b1f2012-12-01 16:35:25 +000064class LabelStmt;
65class MemberSpecializationInfo;
Eugene Zelenkode0215c2017-11-13 23:01:27 +000066class Module;
67class NamespaceDecl;
David Majnemerfa7bc782015-05-19 00:57:16 +000068class ParmVarDecl;
Eugene Zelenkode0215c2017-11-13 23:01:27 +000069class RecordDecl;
Benjamin Kramerd7d2b1f2012-12-01 16:35:25 +000070class Stmt;
71class StringLiteral;
Eugene Zelenkode0215c2017-11-13 23:01:27 +000072class TagDecl;
Benjamin Kramerd7d2b1f2012-12-01 16:35:25 +000073class TemplateArgumentList;
Eugene Zelenkode0215c2017-11-13 23:01:27 +000074class TemplateArgumentListInfo;
Benjamin Kramerd7d2b1f2012-12-01 16:35:25 +000075class TemplateParameterList;
Richard Smith43ccec8e2014-08-26 03:52:16 +000076class TypeAliasTemplateDecl;
John McCallb9c78482010-04-08 09:05:18 +000077class UnresolvedSetImpl;
Larisse Voufo39a1e502013-08-06 01:03:05 +000078class VarTemplateDecl;
Vlad Serebrennikovad278482023-11-06 12:17:21 +030079enum class ImplicitParamKind;
Benjamin Kramerd7d2b1f2012-12-01 16:35:25 +000080
James Dennett31a57342018-02-02 21:38:22 +000081/// The top declaration context.
Vassil Vassilev11b47c12021-07-12 13:35:20 +000082class TranslationUnitDecl : public Decl,
83 public DeclContext,
84 public Redeclarable<TranslationUnitDecl> {
85 using redeclarable_base = Redeclarable<TranslationUnitDecl>;
86
87 TranslationUnitDecl *getNextRedeclarationImpl() override {
88 return getNextRedeclaration();
89 }
90
91 TranslationUnitDecl *getPreviousDeclImpl() override {
92 return getPreviousDecl();
93 }
94
95 TranslationUnitDecl *getMostRecentDeclImpl() override {
96 return getMostRecentDecl();
97 }
98
Argyrios Kyrtzidis743e7db2009-06-29 17:38:40 +000099 ASTContext &Ctx;
Mike Stump11289f42009-09-09 15:08:12 +0000100
John McCall0db42252009-12-16 02:06:49 +0000101 /// The (most recently entered) anonymous namespace for this
102 /// translation unit, if one has been created.
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000103 NamespaceDecl *AnonymousNamespace = nullptr;
John McCall0db42252009-12-16 02:06:49 +0000104
Richard Smith42413142015-05-15 20:05:43 +0000105 explicit TranslationUnitDecl(ASTContext &ctx);
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000106
107 virtual void anchor();
108
Argyrios Kyrtzidisc3b69ae2008-04-17 14:40:12 +0000109public:
Vassil Vassilev11b47c12021-07-12 13:35:20 +0000110 using redecl_range = redeclarable_base::redecl_range;
111 using redecl_iterator = redeclarable_base::redecl_iterator;
112
113 using redeclarable_base::getMostRecentDecl;
114 using redeclarable_base::getPreviousDecl;
115 using redeclarable_base::isFirstDecl;
116 using redeclarable_base::redecls;
117 using redeclarable_base::redecls_begin;
118 using redeclarable_base::redecls_end;
119
Argyrios Kyrtzidis743e7db2009-06-29 17:38:40 +0000120 ASTContext &getASTContext() const { return Ctx; }
Mike Stump11289f42009-09-09 15:08:12 +0000121
John McCall0db42252009-12-16 02:06:49 +0000122 NamespaceDecl *getAnonymousNamespace() const { return AnonymousNamespace; }
Chuanqi Xuf2695a12024-04-17 16:40:00 +0800123 void setAnonymousNamespace(NamespaceDecl *D);
John McCall0db42252009-12-16 02:06:49 +0000124
Argyrios Kyrtzidisc3b69ae2008-04-17 14:40:12 +0000125 static TranslationUnitDecl *Create(ASTContext &C);
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000126
Argyrios Kyrtzidisc3b69ae2008-04-17 14:40:12 +0000127 // Implement isa/cast/dyncast/etc.
John McCall180ef092010-01-29 01:45:37 +0000128 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
John McCall180ef092010-01-29 01:45:37 +0000129 static bool classofKind(Kind K) { return K == TranslationUnit; }
Argyrios Kyrtzidis3768ad62008-10-12 16:14:48 +0000130 static DeclContext *castToDeclContext(const TranslationUnitDecl *D) {
131 return static_cast<DeclContext *>(const_cast<TranslationUnitDecl*>(D));
132 }
133 static TranslationUnitDecl *castFromDeclContext(const DeclContext *DC) {
134 return static_cast<TranslationUnitDecl *>(const_cast<DeclContext*>(DC));
135 }
Vipul Cariappa61c8b712024-09-27 12:33:32 +0530136
137 /// Retrieves the canonical declaration of this translation unit.
138 TranslationUnitDecl *getCanonicalDecl() override { return getFirstDecl(); }
139 const TranslationUnitDecl *getCanonicalDecl() const { return getFirstDecl(); }
Argyrios Kyrtzidisc3b69ae2008-04-17 14:40:12 +0000140};
141
James Dennettb8973efb2018-02-02 20:22:29 +0000142/// Represents a `#pragma comment` line. Always a child of
Nico Weber66220292016-03-02 17:28:48 +0000143/// TranslationUnitDecl.
144class PragmaCommentDecl final
145 : public Decl,
146 private llvm::TrailingObjects<PragmaCommentDecl, char> {
Nico Weber66220292016-03-02 17:28:48 +0000147 friend class ASTDeclReader;
148 friend class ASTDeclWriter;
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000149 friend TrailingObjects;
150
151 PragmaMSCommentKind CommentKind;
Nico Weber66220292016-03-02 17:28:48 +0000152
153 PragmaCommentDecl(TranslationUnitDecl *TU, SourceLocation CommentLoc,
154 PragmaMSCommentKind CommentKind)
155 : Decl(PragmaComment, TU, CommentLoc), CommentKind(CommentKind) {}
156
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000157 virtual void anchor();
158
Nico Weber66220292016-03-02 17:28:48 +0000159public:
160 static PragmaCommentDecl *Create(const ASTContext &C, TranslationUnitDecl *DC,
161 SourceLocation CommentLoc,
162 PragmaMSCommentKind CommentKind,
163 StringRef Arg);
Chuanqi Xud86cc732024-04-25 11:43:13 +0800164 static PragmaCommentDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID,
Nico Weber66220292016-03-02 17:28:48 +0000165 unsigned ArgSize);
166
167 PragmaMSCommentKind getCommentKind() const { return CommentKind; }
168
169 StringRef getArg() const { return getTrailingObjects<char>(); }
170
171 // Implement isa/cast/dyncast/etc.
172 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
173 static bool classofKind(Kind K) { return K == PragmaComment; }
174};
175
James Dennettb8973efb2018-02-02 20:22:29 +0000176/// Represents a `#pragma detect_mismatch` line. Always a child of
Nico Webercbbaeb12016-03-02 19:28:54 +0000177/// TranslationUnitDecl.
178class PragmaDetectMismatchDecl final
179 : public Decl,
180 private llvm::TrailingObjects<PragmaDetectMismatchDecl, char> {
Nico Webercbbaeb12016-03-02 19:28:54 +0000181 friend class ASTDeclReader;
182 friend class ASTDeclWriter;
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000183 friend TrailingObjects;
184
185 size_t ValueStart;
Nico Webercbbaeb12016-03-02 19:28:54 +0000186
187 PragmaDetectMismatchDecl(TranslationUnitDecl *TU, SourceLocation Loc,
188 size_t ValueStart)
189 : Decl(PragmaDetectMismatch, TU, Loc), ValueStart(ValueStart) {}
190
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000191 virtual void anchor();
192
Nico Webercbbaeb12016-03-02 19:28:54 +0000193public:
194 static PragmaDetectMismatchDecl *Create(const ASTContext &C,
195 TranslationUnitDecl *DC,
196 SourceLocation Loc, StringRef Name,
197 StringRef Value);
198 static PragmaDetectMismatchDecl *
Chuanqi Xud86cc732024-04-25 11:43:13 +0800199 CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NameValueSize);
Nico Webercbbaeb12016-03-02 19:28:54 +0000200
201 StringRef getName() const { return getTrailingObjects<char>(); }
202 StringRef getValue() const { return getTrailingObjects<char>() + ValueStart; }
203
204 // Implement isa/cast/dyncast/etc.
205 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
206 static bool classofKind(Kind K) { return K == PragmaDetectMismatch; }
207};
208
James Dennettb8973efb2018-02-02 20:22:29 +0000209/// Declaration context for names declared as extern "C" in C++. This
Richard Smithf19e1272015-03-07 00:04:49 +0000210/// is neither the semantic nor lexical context for such declarations, but is
211/// used to check for conflicts with other extern "C" declarations. Example:
212///
213/// \code
214/// namespace N { extern "C" void f(); } // #1
215/// void N::f() {} // #2
216/// namespace M { extern "C" void f(); } // #3
217/// \endcode
218///
219/// The semantic context of #1 is namespace N and its lexical context is the
220/// LinkageSpecDecl; the semantic context of #2 is namespace N and its lexical
221/// context is the TU. However, both declarations are also visible in the
222/// extern "C" context.
223///
224/// The declaration at #3 finds it is a redeclaration of \c N::f through
225/// lookup in the extern "C" context.
226class ExternCContextDecl : public Decl, public DeclContext {
Richard Smithf19e1272015-03-07 00:04:49 +0000227 explicit ExternCContextDecl(TranslationUnitDecl *TU)
228 : Decl(ExternCContext, TU, SourceLocation()),
229 DeclContext(ExternCContext) {}
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000230
231 virtual void anchor();
232
Richard Smithf19e1272015-03-07 00:04:49 +0000233public:
234 static ExternCContextDecl *Create(const ASTContext &C,
235 TranslationUnitDecl *TU);
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000236
Richard Smithf19e1272015-03-07 00:04:49 +0000237 // Implement isa/cast/dyncast/etc.
238 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
239 static bool classofKind(Kind K) { return K == ExternCContext; }
240 static DeclContext *castToDeclContext(const ExternCContextDecl *D) {
241 return static_cast<DeclContext *>(const_cast<ExternCContextDecl*>(D));
242 }
243 static ExternCContextDecl *castFromDeclContext(const DeclContext *DC) {
244 return static_cast<ExternCContextDecl *>(const_cast<DeclContext*>(DC));
245 }
246};
247
James Dennettb8973efb2018-02-02 20:22:29 +0000248/// This represents a decl that may have a name. Many decls have names such
Chandler Carruth48687a52012-06-07 17:55:42 +0000249/// as ObjCMethodDecl, but not \@class, etc.
James Dennettb8973efb2018-02-02 20:22:29 +0000250///
251/// Note that not every NamedDecl is actually named (e.g., a struct might
252/// be anonymous), and not every name is an identifier.
Chris Lattnera4016552007-10-06 22:53:46 +0000253class NamedDecl : public Decl {
James Dennettb8973efb2018-02-02 20:22:29 +0000254 /// The name of this declaration, which is typically a normal
Douglas Gregor77324f32008-11-17 14:58:09 +0000255 /// identifier but may also be a special kind of name (C++
256 /// constructor, Objective-C selector, etc.)
257 DeclarationName Name;
258
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000259 virtual void anchor();
260
Daniel Dunbar47c32282012-03-08 20:29:02 +0000261private:
Alp Tokera2794f92014-01-22 07:29:52 +0000262 NamedDecl *getUnderlyingDeclImpl() LLVM_READONLY;
Daniel Dunbar47c32282012-03-08 20:29:02 +0000263
Douglas Gregor77324f32008-11-17 14:58:09 +0000264protected:
Douglas Gregor6e6ad602009-01-20 01:17:11 +0000265 NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000266 : Decl(DK, DC, L), Name(N) {}
Douglas Gregor027ba502010-12-06 17:49:01 +0000267
Douglas Gregor6e6ad602009-01-20 01:17:11 +0000268public:
James Dennettb8973efb2018-02-02 20:22:29 +0000269 /// Get the identifier that names this declaration, if there is one.
270 ///
271 /// This will return NULL if this declaration has no name (e.g., for
272 /// an unnamed class) or if the name is a special name (C++ constructor,
273 /// Objective-C selector, etc.).
Douglas Gregor77324f32008-11-17 14:58:09 +0000274 IdentifierInfo *getIdentifier() const { return Name.getAsIdentifierInfo(); }
275
James Dennettb8973efb2018-02-02 20:22:29 +0000276 /// Get the name of identifier for this declaration as a StringRef.
277 ///
Daniel Dunbar0013afb2009-10-18 02:09:45 +0000278 /// This requires that the declaration have a name and that it be a simple
279 /// identifier.
Chris Lattner01cf8db2011-07-20 06:58:45 +0000280 StringRef getName() const {
Daniel Dunbar0914afe2009-10-19 01:21:12 +0000281 assert(Name.isIdentifier() && "Name is not a simple identifier");
282 return getIdentifier() ? getIdentifier()->getName() : "";
Daniel Dunbar0013afb2009-10-18 02:09:45 +0000283 }
284
James Dennettb8973efb2018-02-02 20:22:29 +0000285 /// Get a human-readable name for the declaration, even if it is one of the
286 /// special kinds of names (C++ constructor, Objective-C selector, etc).
287 ///
288 /// Creating this name requires expensive string manipulation, so it should
289 /// be called only when performance doesn't matter. For simple declarations,
290 /// getNameAsCString() should suffice.
Daniel Dunbar0013afb2009-10-18 02:09:45 +0000291 //
Daniel Dunbar8b794812009-10-19 01:20:50 +0000292 // FIXME: This function should be renamed to indicate that it is not just an
293 // alternate form of getName(), and clients should move as appropriate.
294 //
Daniel Dunbar0013afb2009-10-18 02:09:45 +0000295 // FIXME: Deprecated, move clients to getName().
296 std::string getNameAsString() const { return Name.getAsString(); }
297
Bruno Ricci6f2fa9d2020-08-05 11:43:39 +0100298 /// Pretty-print the unqualified name of this declaration. Can be overloaded
299 /// by derived classes to provide a more user-friendly name when appropriate.
Aaron Ballman19e984e2022-10-14 08:17:16 -0400300 virtual void printName(raw_ostream &OS, const PrintingPolicy &Policy) const;
301 /// Calls printName() with the ASTContext printing policy from the decl.
302 void printName(raw_ostream &OS) const;
Ted Kremenekc14f5eb2010-05-07 20:07:19 +0000303
James Dennettb8973efb2018-02-02 20:22:29 +0000304 /// Get the actual, stored name of the declaration, which may be a special
305 /// name.
Bruno Ricci984cf992020-07-28 15:39:17 +0100306 ///
307 /// Note that generally in diagnostics, the non-null \p NamedDecl* itself
308 /// should be sent into the diagnostic instead of using the result of
309 /// \p getDeclName().
310 ///
311 /// A \p DeclarationName in a diagnostic will just be streamed to the output,
312 /// which will directly result in a call to \p DeclarationName::print.
313 ///
314 /// A \p NamedDecl* in a diagnostic will also ultimately result in a call to
315 /// \p DeclarationName::print, but with two customisation points along the
316 /// way (\p getNameForDiagnostic and \p printName). These are used to print
317 /// the template arguments if any, and to provide a user-friendly name for
318 /// some entities (such as unnamed variables and anonymous records).
Douglas Gregor77324f32008-11-17 14:58:09 +0000319 DeclarationName getDeclName() const { return Name; }
320
James Dennettb8973efb2018-02-02 20:22:29 +0000321 /// Set the name of this declaration.
Douglas Gregorbcced4e2009-04-09 21:40:53 +0000322 void setDeclName(DeclarationName N) { Name = N; }
323
James Dennettb8973efb2018-02-02 20:22:29 +0000324 /// Returns a human-readable qualified name for this declaration, like
325 /// A::B::i, for i being member of namespace A::B.
326 ///
327 /// If the declaration is not a member of context which can be named (record,
328 /// namespace), it will return the same result as printName().
329 ///
Douglas Gregor2ada0482009-02-04 17:27:36 +0000330 /// Creating this name is expensive, so it should be called only when
331 /// performance doesn't matter.
Benjamin Kramer24ebf7c2013-02-23 13:53:57 +0000332 void printQualifiedName(raw_ostream &OS) const;
333 void printQualifiedName(raw_ostream &OS, const PrintingPolicy &Policy) const;
334
Ilya Biryukov66482232019-09-25 15:46:04 +0000335 /// Print only the nested name specifier part of a fully-qualified name,
336 /// including the '::' at the end. E.g.
337 /// when `printQualifiedName(D)` prints "A::B::i",
338 /// this function prints "A::B::".
339 void printNestedNameSpecifier(raw_ostream &OS) const;
340 void printNestedNameSpecifier(raw_ostream &OS,
341 const PrintingPolicy &Policy) const;
342
Aaron Ballman75ee4cc2014-01-03 18:42:48 +0000343 // FIXME: Remove string version.
Douglas Gregor2ada0482009-02-04 17:27:36 +0000344 std::string getQualifiedNameAsString() const;
Douglas Gregor2ada0482009-02-04 17:27:36 +0000345
Erich Keane7670b4b2017-12-15 16:37:14 +0000346 /// Appends a human-readable name for this declaration into the given stream.
John McCalle1f2ec22009-09-11 06:45:03 +0000347 ///
348 /// This is the method invoked by Sema when displaying a NamedDecl
349 /// in a diagnostic. It does not necessarily produce the same
Benjamin Kramer24ebf7c2013-02-23 13:53:57 +0000350 /// result as printName(); for example, class template
John McCalle1f2ec22009-09-11 06:45:03 +0000351 /// specializations are printed with their template arguments.
Benjamin Kramer9170e912013-02-22 15:46:01 +0000352 virtual void getNameForDiagnostic(raw_ostream &OS,
Douglas Gregorb11aad82011-02-19 18:51:44 +0000353 const PrintingPolicy &Policy,
Benjamin Kramer24ebf7c2013-02-23 13:53:57 +0000354 bool Qualified) const;
John McCalle1f2ec22009-09-11 06:45:03 +0000355
James Dennettb8973efb2018-02-02 20:22:29 +0000356 /// Determine whether this declaration, if known to be well-formed within
357 /// its context, will replace the declaration OldD if introduced into scope.
358 ///
359 /// A declaration will replace another declaration if, for example, it is
360 /// a redeclaration of the same variable or function, but not if it is a
361 /// declaration of a different kind (function vs. class) or an overloaded
362 /// function.
Richard Smithe8292b12015-02-10 03:28:10 +0000363 ///
364 /// \param IsKnownNewer \c true if this declaration is known to be newer
365 /// than \p OldD (for instance, if this declaration is newly-created).
Timm Bäder17fa04e2023-12-19 10:18:43 +0100366 bool declarationReplaces(const NamedDecl *OldD,
367 bool IsKnownNewer = true) const;
Douglas Gregor6e6ad602009-01-20 01:17:11 +0000368
James Dennettb8973efb2018-02-02 20:22:29 +0000369 /// Determine whether this declaration has linkage.
Douglas Gregoreddf4332009-02-24 20:03:32 +0000370 bool hasLinkage() const;
371
Douglas Gregor781f7132012-01-06 16:59:53 +0000372 using Decl::isModulePrivate;
373 using Decl::setModulePrivate;
Richard Smith42713d72013-07-14 02:01:48 +0000374
James Dennettb8973efb2018-02-02 20:22:29 +0000375 /// Determine whether this declaration is a C++ class member.
John McCall57500772009-12-16 12:17:52 +0000376 bool isCXXClassMember() const {
377 const DeclContext *DC = getDeclContext();
378
379 // C++0x [class.mem]p1:
380 // The enumerators of an unscoped enumeration defined in
381 // the class are members of the class.
John McCall57500772009-12-16 12:17:52 +0000382 if (isa<EnumDecl>(DC))
Alp Toker363e7c42014-05-31 06:11:09 +0000383 DC = DC->getRedeclContext();
John McCall57500772009-12-16 12:17:52 +0000384
385 return DC->isRecord();
386 }
387
James Dennettb8973efb2018-02-02 20:22:29 +0000388 /// Determine whether the given declaration is an instance member of
Douglas Gregor3f28ec22012-03-08 02:08:05 +0000389 /// a C++ class.
John McCalla8ae2222010-04-06 21:38:20 +0000390 bool isCXXInstanceMember() const;
391
serge-sans-pailleb83b2322020-12-09 09:26:27 +0100392 /// Determine if the declaration obeys the reserved identifier rules of the
393 /// given language.
394 ReservedIdentifierStatus isReserved(const LangOptions &LangOpts) const;
395
James Dennettb8973efb2018-02-02 20:22:29 +0000396 /// Determine what kind of linkage this entity has.
397 ///
Rafael Espindola3ae00052013-05-13 00:12:11 +0000398 /// This is not the linkage as defined by the standard or the codegen notion
399 /// of linkage. It is just an implementation detail that is used to compute
400 /// those.
401 Linkage getLinkageInternal() const;
402
James Dennettb8973efb2018-02-02 20:22:29 +0000403 /// Get the linkage from a semantic point of view. Entities in
Rafael Espindola3ae00052013-05-13 00:12:11 +0000404 /// anonymous namespaces are external (in c++98).
Chuanqi Xu2e9977c2023-03-13 15:43:08 +0800405 Linkage getFormalLinkage() const;
John McCall457a04e2010-10-22 21:05:15 +0000406
James Dennettb8973efb2018-02-02 20:22:29 +0000407 /// True if this decl has external linkage.
Rafael Espindola3ae00052013-05-13 00:12:11 +0000408 bool hasExternalFormalLinkage() const {
Rafael Espindolab97e8962013-05-27 14:14:42 +0000409 return isExternalFormalLinkage(getLinkageInternal());
Rafael Espindola3ae00052013-05-13 00:12:11 +0000410 }
Rafael Espindolab97e8962013-05-27 14:14:42 +0000411
Rafael Espindola3ae00052013-05-13 00:12:11 +0000412 bool isExternallyVisible() const {
Rafael Espindolab97e8962013-05-27 14:14:42 +0000413 return clang::isExternallyVisible(getLinkageInternal());
Rafael Espindola45b620a2013-03-07 02:00:27 +0000414 }
415
Richard Smithbecb92d2017-10-10 22:33:17 +0000416 /// Determine whether this declaration can be redeclared in a
417 /// different translation unit.
418 bool isExternallyDeclarable() const {
419 return isExternallyVisible() && !getOwningModuleForLinkage();
420 }
421
James Dennettb8973efb2018-02-02 20:22:29 +0000422 /// Determines the visibility of this entity.
David Blaikie21bfbf82011-11-09 06:07:30 +0000423 Visibility getVisibility() const {
Rafael Espindola4a5da442013-02-27 02:56:45 +0000424 return getLinkageAndVisibility().getVisibility();
David Blaikie21bfbf82011-11-09 06:07:30 +0000425 }
John McCall457a04e2010-10-22 21:05:15 +0000426
James Dennettb8973efb2018-02-02 20:22:29 +0000427 /// Determines the linkage and visibility of this entity.
John McCallc273f242010-10-30 11:50:40 +0000428 LinkageInfo getLinkageAndVisibility() const;
Douglas Gregorf73b2822009-11-25 22:24:25 +0000429
John McCalld041a9b2013-02-20 01:54:26 +0000430 /// Kinds of explicit visibility.
431 enum ExplicitVisibilityKind {
Richard Smithfbe7b462017-09-22 02:22:32 +0000432 /// Do an LV computation for, ultimately, a type.
433 /// Visibility may be restricted by type visibility settings and
434 /// the visibility of template arguments.
John McCalld041a9b2013-02-20 01:54:26 +0000435 VisibilityForType,
Richard Smithfbe7b462017-09-22 02:22:32 +0000436
437 /// Do an LV computation for, ultimately, a non-type declaration.
438 /// Visibility may be restricted by value visibility settings and
439 /// the visibility of template arguments.
John McCalld041a9b2013-02-20 01:54:26 +0000440 VisibilityForValue
441 };
442
James Dennettb8973efb2018-02-02 20:22:29 +0000443 /// If visibility was explicitly specified for this
Douglas Gregor1baf38f2011-03-26 12:10:19 +0000444 /// declaration, return that visibility.
Kazu Hirata6ad07882023-01-14 12:31:01 -0800445 std::optional<Visibility>
John McCalld041a9b2013-02-20 01:54:26 +0000446 getExplicitVisibility(ExplicitVisibilityKind kind) const;
Douglas Gregor1baf38f2011-03-26 12:10:19 +0000447
James Dennettb8973efb2018-02-02 20:22:29 +0000448 /// True if the computed linkage is valid. Used for consistency
Rafael Espindola0e0d0092013-03-14 03:07:35 +0000449 /// checking. Should always return true.
450 bool isLinkageValid() const;
Douglas Gregorbf62d642010-12-06 18:36:25 +0000451
James Dennettb8973efb2018-02-02 20:22:29 +0000452 /// True if something has required us to compute the linkage
John McCall2575d882014-01-30 01:12:53 +0000453 /// of this declaration.
454 ///
455 /// Language features which can retroactively change linkage (like a
456 /// typedef name for linkage purposes) may need to consider this,
457 /// but hopefully only in transitory ways during parsing.
458 bool hasLinkageBeenComputed() const {
459 return hasCachedLinkage();
460 }
461
Corentin Jabota8bef882023-06-22 14:18:38 +0200462 bool isPlaceholderVar(const LangOptions &LangOpts) const;
463
James Dennettb8973efb2018-02-02 20:22:29 +0000464 /// Looks through UsingDecls and ObjCCompatibleAliasDecls for
Anders Carlsson6915bf62009-06-26 06:29:23 +0000465 /// the underlying named decl.
Daniel Dunbar166ea9ad2012-03-08 18:20:41 +0000466 NamedDecl *getUnderlyingDecl() {
Daniel Dunbar47c32282012-03-08 20:29:02 +0000467 // Fast-path the common case.
468 if (this->getKind() != UsingShadow &&
Richard Smith5179eb72016-06-28 19:03:57 +0000469 this->getKind() != ConstructorUsingShadow &&
Richard Smithf2005d32015-12-29 23:34:32 +0000470 this->getKind() != ObjCCompatibleAlias &&
471 this->getKind() != NamespaceAlias)
Daniel Dunbar166ea9ad2012-03-08 18:20:41 +0000472 return this;
Daniel Dunbar47c32282012-03-08 20:29:02 +0000473
Daniel Dunbar166ea9ad2012-03-08 18:20:41 +0000474 return getUnderlyingDeclImpl();
475 }
Anders Carlsson6915bf62009-06-26 06:29:23 +0000476 const NamedDecl *getUnderlyingDecl() const {
477 return const_cast<NamedDecl*>(this)->getUnderlyingDecl();
478 }
Mike Stump11289f42009-09-09 15:08:12 +0000479
Rafael Espindola7b56f6c2013-10-19 16:55:03 +0000480 NamedDecl *getMostRecentDecl() {
Aaron Ballman5116a8e2013-11-06 22:39:46 +0000481 return cast<NamedDecl>(static_cast<Decl *>(this)->getMostRecentDecl());
Rafael Espindola7b56f6c2013-10-19 16:55:03 +0000482 }
483 const NamedDecl *getMostRecentDecl() const {
484 return const_cast<NamedDecl*>(this)->getMostRecentDecl();
485 }
486
Fariborz Jahanian6485fe42014-09-09 23:10:54 +0000487 ObjCStringFormatFamily getObjCFStringFormattingFamily() const;
488
John McCall180ef092010-01-29 01:45:37 +0000489 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
Alexis Hunted053252010-05-30 07:21:58 +0000490 static bool classofKind(Kind K) { return K >= firstNamed && K <= lastNamed; }
Chris Lattnera4016552007-10-06 22:53:46 +0000491};
492
Benjamin Kramerb89514a2011-10-14 18:45:37 +0000493inline raw_ostream &operator<<(raw_ostream &OS, const NamedDecl &ND) {
494 ND.printName(OS);
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000495 return OS;
496}
Benjamin Kramerb11416d2010-04-17 09:33:03 +0000497
James Dennett31a57342018-02-02 21:38:22 +0000498/// Represents the declaration of a label. Labels also have a
Chris Lattnerc8e630e2011-02-17 07:39:24 +0000499/// corresponding LabelStmt, which indicates the position that the label was
500/// defined at. For normal labels, the location of the decl is the same as the
501/// location of the statement. For GNU local labels (__label__), the decl
502/// location is where the __label__ is.
503class LabelDecl : public NamedDecl {
Abramo Bagnara1c3af962011-03-05 18:21:20 +0000504 LabelStmt *TheStmt;
Ehsan Akhgari31097582014-09-22 02:21:54 +0000505 StringRef MSAsmName;
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000506 bool MSAsmNameResolved = false;
507
James Dennett31a57342018-02-02 21:38:22 +0000508 /// For normal labels, this is the same as the main declaration
Abramo Bagnara1c3af962011-03-05 18:21:20 +0000509 /// label, i.e., the location of the identifier; for GNU local labels,
510 /// this is the location of the __label__ keyword.
511 SourceLocation LocStart;
512
513 LabelDecl(DeclContext *DC, SourceLocation IdentL, IdentifierInfo *II,
514 LabelStmt *S, SourceLocation StartL)
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000515 : NamedDecl(Label, DC, IdentL, II), TheStmt(S), LocStart(StartL) {}
516
517 void anchor() override;
Abramo Bagnara1c3af962011-03-05 18:21:20 +0000518
Chris Lattnerc8e630e2011-02-17 07:39:24 +0000519public:
520 static LabelDecl *Create(ASTContext &C, DeclContext *DC,
Abramo Bagnara1c3af962011-03-05 18:21:20 +0000521 SourceLocation IdentL, IdentifierInfo *II);
522 static LabelDecl *Create(ASTContext &C, DeclContext *DC,
523 SourceLocation IdentL, IdentifierInfo *II,
524 SourceLocation GnuLabelL);
Chuanqi Xud86cc732024-04-25 11:43:13 +0800525 static LabelDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
Fangrui Song6907ce22018-07-30 19:24:48 +0000526
Abramo Bagnara1c3af962011-03-05 18:21:20 +0000527 LabelStmt *getStmt() const { return TheStmt; }
528 void setStmt(LabelStmt *T) { TheStmt = T; }
529
530 bool isGnuLocal() const { return LocStart != getLocation(); }
531 void setLocStart(SourceLocation L) { LocStart = L; }
532
Craig Toppercbce6e92014-03-11 06:22:39 +0000533 SourceRange getSourceRange() const override LLVM_READONLY {
Abramo Bagnara1c3af962011-03-05 18:21:20 +0000534 return SourceRange(LocStart, getLocation());
535 }
Abramo Bagnara124fdf62011-03-03 18:24:14 +0000536
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000537 bool isMSAsmLabel() const { return !MSAsmName.empty(); }
Ehsan Akhgari31097582014-09-22 02:21:54 +0000538 bool isResolvedMSAsmLabel() const { return isMSAsmLabel() && MSAsmNameResolved; }
539 void setMSAsmLabel(StringRef Name);
540 StringRef getMSAsmLabel() const { return MSAsmName; }
541 void setMSAsmLabelResolved() { MSAsmNameResolved = true; }
542
Chris Lattnerc8e630e2011-02-17 07:39:24 +0000543 // Implement isa/cast/dyncast/etc.
544 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
Chris Lattnerc8e630e2011-02-17 07:39:24 +0000545 static bool classofKind(Kind K) { return K == Label; }
546};
David Blaikie21bfbf82011-11-09 06:07:30 +0000547
James Dennett31a57342018-02-02 21:38:22 +0000548/// Represent a C++ namespace.
Krystian Stasiowskie6ec7c82024-07-15 13:57:56 -0400549class NamespaceDecl : public NamedDecl,
550 public DeclContext,
551 public Redeclarable<NamespaceDecl> {
James Dennett31a57342018-02-02 21:38:22 +0000552 /// The starting location of the source range, pointing
Abramo Bagnarab5545be2011-03-08 12:38:20 +0000553 /// to either the namespace or the inline keyword.
554 SourceLocation LocStart;
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000555
James Dennett31a57342018-02-02 21:38:22 +0000556 /// The ending location of the source range.
Abramo Bagnarab5545be2011-03-08 12:38:20 +0000557 SourceLocation RBraceLoc;
Mike Stump11289f42009-09-09 15:08:12 +0000558
Krystian Stasiowskie6ec7c82024-07-15 13:57:56 -0400559 /// The unnamed namespace that inhabits this namespace, if any.
560 NamespaceDecl *AnonymousNamespace = nullptr;
Mike Stump11289f42009-09-09 15:08:12 +0000561
Richard Smith053f6c62014-05-16 23:01:30 +0000562 NamespaceDecl(ASTContext &C, DeclContext *DC, bool Inline,
563 SourceLocation StartLoc, SourceLocation IdLoc,
Nathan James15e76ee2022-11-24 12:44:33 +0000564 IdentifierInfo *Id, NamespaceDecl *PrevDecl, bool Nested);
Rafael Espindola8ef7f682013-11-26 15:12:20 +0000565
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000566 using redeclarable_base = Redeclarable<NamespaceDecl>;
567
Richard Smithd7af8a32014-05-10 01:17:36 +0000568 NamespaceDecl *getNextRedeclarationImpl() override;
Craig Toppercbce6e92014-03-11 06:22:39 +0000569 NamespaceDecl *getPreviousDeclImpl() override;
570 NamespaceDecl *getMostRecentDeclImpl() override;
Rafael Espindola8ef7f682013-11-26 15:12:20 +0000571
Argyrios Kyrtzidis08114892008-04-27 13:50:30 +0000572public:
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000573 friend class ASTDeclReader;
574 friend class ASTDeclWriter;
575
Nathan James15e76ee2022-11-24 12:44:33 +0000576 static NamespaceDecl *Create(ASTContext &C, DeclContext *DC, bool Inline,
577 SourceLocation StartLoc, SourceLocation IdLoc,
578 IdentifierInfo *Id, NamespaceDecl *PrevDecl,
579 bool Nested);
Mike Stump11289f42009-09-09 15:08:12 +0000580
Chuanqi Xud86cc732024-04-25 11:43:13 +0800581 static NamespaceDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
Douglas Gregorec9fd132012-01-14 16:38:05 +0000582
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000583 using redecl_range = redeclarable_base::redecl_range;
584 using redecl_iterator = redeclarable_base::redecl_iterator;
585
Aaron Ballman211cd8c2014-03-07 00:10:58 +0000586 using redeclarable_base::redecls_begin;
587 using redeclarable_base::redecls_end;
Aaron Ballman86c93902014-03-06 23:45:36 +0000588 using redeclarable_base::redecls;
Douglas Gregorec9fd132012-01-14 16:38:05 +0000589 using redeclarable_base::getPreviousDecl;
590 using redeclarable_base::getMostRecentDecl;
Rafael Espindola3f9e4442013-10-19 02:13:21 +0000591 using redeclarable_base::isFirstDecl;
Douglas Gregore57e7522012-01-07 09:11:48 +0000592
James Dennettb8973efb2018-02-02 20:22:29 +0000593 /// Returns true if this is an anonymous namespace declaration.
Sebastian Redlb5c2baa2010-08-31 00:36:36 +0000594 ///
595 /// For example:
Chris Lattnerca025db2010-05-07 21:43:38 +0000596 /// \code
Sebastian Redlb5c2baa2010-08-31 00:36:36 +0000597 /// namespace {
598 /// ...
599 /// };
600 /// \endcode
601 /// q.v. C++ [namespace.unnamed]
John McCall4fa53422009-10-01 00:25:31 +0000602 bool isAnonymousNamespace() const {
603 return !getIdentifier();
604 }
605
James Dennettb8973efb2018-02-02 20:22:29 +0000606 /// Returns true if this is an inline namespace declaration.
Krystian Stasiowskie6ec7c82024-07-15 13:57:56 -0400607 bool isInline() const { return NamespaceDeclBits.IsInline; }
Sebastian Redlb5c2baa2010-08-31 00:36:36 +0000608
James Dennettb8973efb2018-02-02 20:22:29 +0000609 /// Set whether this is an inline namespace declaration.
Krystian Stasiowskie6ec7c82024-07-15 13:57:56 -0400610 void setInline(bool Inline) { NamespaceDeclBits.IsInline = Inline; }
Nathan James15e76ee2022-11-24 12:44:33 +0000611
612 /// Returns true if this is a nested namespace declaration.
613 /// \code
614 /// namespace outer::nested { }
615 /// \endcode
Krystian Stasiowskie6ec7c82024-07-15 13:57:56 -0400616 bool isNested() const { return NamespaceDeclBits.IsNested; }
Nathan James15e76ee2022-11-24 12:44:33 +0000617
618 /// Set whether this is a nested namespace declaration.
Krystian Stasiowskie6ec7c82024-07-15 13:57:56 -0400619 void setNested(bool Nested) { NamespaceDeclBits.IsNested = Nested; }
Sebastian Redl50c68252010-08-31 00:36:30 +0000620
Vassil Vassilev0cb7e7c2021-03-17 08:56:05 +0000621 /// Returns true if the inline qualifier for \c Name is redundant.
622 bool isRedundantInlineQualifierFor(DeclarationName Name) const {
623 if (!isInline())
624 return false;
625 auto X = lookup(Name);
Aaron Ballman48f73ee2021-08-20 09:49:07 -0400626 // We should not perform a lookup within a transparent context, so find a
627 // non-transparent parent context.
628 auto Y = getParent()->getNonTransparentContext()->lookup(Name);
Vassil Vassilev0cb7e7c2021-03-17 08:56:05 +0000629 return std::distance(X.begin(), X.end()) ==
630 std::distance(Y.begin(), Y.end());
631 }
632
Krystian Stasiowskie6ec7c82024-07-15 13:57:56 -0400633 /// Retrieve the anonymous namespace that inhabits this namespace, if any.
John McCall0db42252009-12-16 02:06:49 +0000634 NamespaceDecl *getAnonymousNamespace() const {
Krystian Stasiowskie6ec7c82024-07-15 13:57:56 -0400635 return getFirstDecl()->AnonymousNamespace;
John McCall0db42252009-12-16 02:06:49 +0000636 }
637
638 void setAnonymousNamespace(NamespaceDecl *D) {
Krystian Stasiowskie6ec7c82024-07-15 13:57:56 -0400639 getFirstDecl()->AnonymousNamespace = D;
John McCall0db42252009-12-16 02:06:49 +0000640 }
641
Douglas Gregore57e7522012-01-07 09:11:48 +0000642 /// Retrieves the canonical declaration of this namespace.
Krystian Stasiowskie6ec7c82024-07-15 13:57:56 -0400643 NamespaceDecl *getCanonicalDecl() override { return getFirstDecl(); }
644 const NamespaceDecl *getCanonicalDecl() const { return getFirstDecl(); }
Craig Toppercbce6e92014-03-11 06:22:39 +0000645
646 SourceRange getSourceRange() const override LLVM_READONLY {
Abramo Bagnarab5545be2011-03-08 12:38:20 +0000647 return SourceRange(LocStart, RBraceLoc);
Argyrios Kyrtzidis08114892008-04-27 13:50:30 +0000648 }
649
Stephen Kelly724e9e52018-08-09 20:05:03 +0000650 SourceLocation getBeginLoc() const LLVM_READONLY { return LocStart; }
Abramo Bagnarab5545be2011-03-08 12:38:20 +0000651 SourceLocation getRBraceLoc() const { return RBraceLoc; }
652 void setLocStart(SourceLocation L) { LocStart = L; }
653 void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
654
Argyrios Kyrtzidis08114892008-04-27 13:50:30 +0000655 // Implement isa/cast/dyncast/etc.
John McCall180ef092010-01-29 01:45:37 +0000656 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
John McCall180ef092010-01-29 01:45:37 +0000657 static bool classofKind(Kind K) { return K == Namespace; }
Argyrios Kyrtzidis3768ad62008-10-12 16:14:48 +0000658 static DeclContext *castToDeclContext(const NamespaceDecl *D) {
659 return static_cast<DeclContext *>(const_cast<NamespaceDecl*>(D));
660 }
661 static NamespaceDecl *castFromDeclContext(const DeclContext *DC) {
662 return static_cast<NamespaceDecl *>(const_cast<DeclContext*>(DC));
663 }
Argyrios Kyrtzidis08114892008-04-27 13:50:30 +0000664};
665
Corentin Jabote1111e22022-11-02 12:54:46 +0100666class VarDecl;
667
James Dennett31a57342018-02-02 21:38:22 +0000668/// Represent the declaration of a variable (in which case it is
Steve Naroff46ba1eb2007-04-03 23:13:13 +0000669/// an lvalue) a function (in which case it is a function designator) or
Mike Stump11289f42009-09-09 15:08:12 +0000670/// an enum constant.
Douglas Gregor6e6ad602009-01-20 01:17:11 +0000671class ValueDecl : public NamedDecl {
Steve Naroffe5aa9be2007-04-05 22:36:20 +0000672 QualType DeclType;
Nate Begemana0f78972007-11-13 22:14:47 +0000673
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000674 void anchor() override;
675
Steve Naroff6fbf0dc2007-03-16 00:33:25 +0000676protected:
Chris Lattnerbec41342008-04-22 18:39:57 +0000677 ValueDecl(Kind DK, DeclContext *DC, SourceLocation L,
Mike Stump11289f42009-09-09 15:08:12 +0000678 DeclarationName N, QualType T)
Douglas Gregor6e6ad602009-01-20 01:17:11 +0000679 : NamedDecl(DK, DC, L, N), DeclType(T) {}
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000680
Steve Naroff6fbf0dc2007-03-16 00:33:25 +0000681public:
Steve Naroffe5aa9be2007-04-05 22:36:20 +0000682 QualType getType() const { return DeclType; }
Steve Naroff4dddb612007-07-09 18:55:26 +0000683 void setType(QualType newType) { DeclType = newType; }
Mike Stump11289f42009-09-09 15:08:12 +0000684
James Dennettb8973efb2018-02-02 20:22:29 +0000685 /// Determine whether this symbol is weakly-imported,
Lang Hamesd42bb472011-12-05 20:16:26 +0000686 /// or declared with the weak or weak-ref attr.
Benjamin Kramerea70eb32012-12-01 15:09:41 +0000687 bool isWeak() const;
Lang Hamesd42bb472011-12-05 20:16:26 +0000688
Corentin Jabot127bf442022-03-30 14:27:44 +0200689 /// Whether this variable is the implicit variable for a lambda init-capture.
690 /// Only VarDecl can be init captures, but both VarDecl and BindingDecl
691 /// can be captured.
692 bool isInitCapture() const;
693
Corentin Jabote1111e22022-11-02 12:54:46 +0100694 // If this is a VarDecl, or a BindindDecl with an
695 // associated decomposed VarDecl, return that VarDecl.
696 VarDecl *getPotentiallyDecomposedVarDecl();
697 const VarDecl *getPotentiallyDecomposedVarDecl() const {
698 return const_cast<ValueDecl *>(this)->getPotentiallyDecomposedVarDecl();
699 }
700
Jason Riceabc88122025-01-29 12:43:52 -0800701 /// Determine whether this value is actually a function parameter pack,
702 /// init-capture pack, or structured binding pack
703 bool isParameterPack() const;
704
Chris Lattner17ed4872006-11-20 04:58:19 +0000705 // Implement isa/cast/dyncast/etc.
John McCall180ef092010-01-29 01:45:37 +0000706 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
Alexis Hunted053252010-05-30 07:21:58 +0000707 static bool classofKind(Kind K) { return K >= firstValue && K <= lastValue; }
Chris Lattner17ed4872006-11-20 04:58:19 +0000708};
709
James Dennett31a57342018-02-02 21:38:22 +0000710/// A struct with extended info about a syntactic
Abramo Bagnarada41d0c2010-06-12 08:15:14 +0000711/// name qualifier, to be used for the case of out-of-line declarations.
712struct QualifierInfo {
Douglas Gregor14454802011-02-25 02:25:35 +0000713 NestedNameSpecifierLoc QualifierLoc;
Abramo Bagnara60804e12011-03-18 15:16:37 +0000714
James Dennett31a57342018-02-02 21:38:22 +0000715 /// The number of "outer" template parameter lists.
Abramo Bagnara60804e12011-03-18 15:16:37 +0000716 /// The count includes all of the template parameter lists that were matched
717 /// against the template-ids occurring into the NNS and possibly (in the
718 /// case of an explicit specialization) a final "template <>".
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000719 unsigned NumTemplParamLists = 0;
Abramo Bagnara60804e12011-03-18 15:16:37 +0000720
James Dennett31a57342018-02-02 21:38:22 +0000721 /// A new-allocated array of size NumTemplParamLists,
Abramo Bagnara60804e12011-03-18 15:16:37 +0000722 /// containing pointers to the "outer" template parameter lists.
723 /// It includes all of the template parameter lists that were matched
724 /// against the template-ids occurring into the NNS and possibly (in the
725 /// case of an explicit specialization) a final "template <>".
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000726 TemplateParameterList** TemplParamLists = nullptr;
Abramo Bagnarada41d0c2010-06-12 08:15:14 +0000727
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000728 QualifierInfo() = default;
729 QualifierInfo(const QualifierInfo &) = delete;
730 QualifierInfo& operator=(const QualifierInfo &) = delete;
Abramo Bagnara60804e12011-03-18 15:16:37 +0000731
James Dennett31a57342018-02-02 21:38:22 +0000732 /// Sets info about "outer" template parameter lists.
Douglas Gregor20527e22010-06-15 17:44:38 +0000733 void setTemplateParameterListsInfo(ASTContext &Context,
Benjamin Kramer9cc210652015-08-05 09:40:49 +0000734 ArrayRef<TemplateParameterList *> TPLists);
Abramo Bagnarada41d0c2010-06-12 08:15:14 +0000735};
736
James Dennettb8973efb2018-02-02 20:22:29 +0000737/// Represents a ValueDecl that came out of a declarator.
John McCallbcd03502009-12-07 02:54:59 +0000738/// Contains type source information through TypeSourceInfo.
Argyrios Kyrtzidis60ed5602009-08-19 01:27:57 +0000739class DeclaratorDecl : public ValueDecl {
Saar Razb65b1f32020-01-09 15:07:51 +0200740 // A struct representing a TInfo, a trailing requires-clause and a syntactic
741 // qualifier, to be used for the (uncommon) case of out-of-line declarations
742 // and constrained function decls.
Abramo Bagnarada41d0c2010-06-12 08:15:14 +0000743 struct ExtInfo : public QualifierInfo {
Boaz Bricknerbf43a132024-11-05 08:57:52 +0100744 TypeSourceInfo *TInfo = nullptr;
Saar Razb65b1f32020-01-09 15:07:51 +0200745 Expr *TrailingRequiresClause = nullptr;
John McCall3e11ebe2010-03-15 10:12:16 +0000746 };
747
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000748 llvm::PointerUnion<TypeSourceInfo *, ExtInfo *> DeclInfo;
John McCall3e11ebe2010-03-15 10:12:16 +0000749
James Dennett31a57342018-02-02 21:38:22 +0000750 /// The start of the source range for this declaration,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000751 /// ignoring outer template declarations.
752 SourceLocation InnerLocStart;
753
Kazu Hirata624cc702024-12-11 08:35:41 -0800754 bool hasExtInfo() const { return isa<ExtInfo *>(DeclInfo); }
755 ExtInfo *getExtInfo() { return cast<ExtInfo *>(DeclInfo); }
756 const ExtInfo *getExtInfo() const { return cast<ExtInfo *>(DeclInfo); }
Argyrios Kyrtzidis60ed5602009-08-19 01:27:57 +0000757
758protected:
759 DeclaratorDecl(Kind DK, DeclContext *DC, SourceLocation L,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000760 DeclarationName N, QualType T, TypeSourceInfo *TInfo,
761 SourceLocation StartL)
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000762 : ValueDecl(DK, DC, L, N, T), DeclInfo(TInfo), InnerLocStart(StartL) {}
Argyrios Kyrtzidis60ed5602009-08-19 01:27:57 +0000763
764public:
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000765 friend class ASTDeclReader;
766 friend class ASTDeclWriter;
767
John McCall3e11ebe2010-03-15 10:12:16 +0000768 TypeSourceInfo *getTypeSourceInfo() const {
Kazu Hirata624cc702024-12-11 08:35:41 -0800769 return hasExtInfo() ? getExtInfo()->TInfo
770 : cast<TypeSourceInfo *>(DeclInfo);
John McCall3e11ebe2010-03-15 10:12:16 +0000771 }
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000772
John McCall3e11ebe2010-03-15 10:12:16 +0000773 void setTypeSourceInfo(TypeSourceInfo *TI) {
774 if (hasExtInfo())
Abramo Bagnarada41d0c2010-06-12 08:15:14 +0000775 getExtInfo()->TInfo = TI;
John McCall3e11ebe2010-03-15 10:12:16 +0000776 else
777 DeclInfo = TI;
778 }
779
James Dennett31a57342018-02-02 21:38:22 +0000780 /// Return start of source range ignoring outer template declarations.
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000781 SourceLocation getInnerLocStart() const { return InnerLocStart; }
Abramo Bagnaradff19302011-03-08 08:55:46 +0000782 void setInnerLocStart(SourceLocation L) { InnerLocStart = L; }
Douglas Gregorec9c6ae2010-07-06 18:42:40 +0000783
James Dennett31a57342018-02-02 21:38:22 +0000784 /// Return start of source range taking into account any outer template
785 /// declarations.
Douglas Gregorec9c6ae2010-07-06 18:42:40 +0000786 SourceLocation getOuterLocStart() const;
Abramo Bagnaraea947882011-03-08 16:41:52 +0000787
Craig Toppercbce6e92014-03-11 06:22:39 +0000788 SourceRange getSourceRange() const override LLVM_READONLY;
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000789
Stephen Kelly724e9e52018-08-09 20:05:03 +0000790 SourceLocation getBeginLoc() const LLVM_READONLY {
Daniel Dunbarcdf295c2012-03-09 15:39:24 +0000791 return getOuterLocStart();
792 }
Douglas Gregorec9c6ae2010-07-06 18:42:40 +0000793
James Dennettb8973efb2018-02-02 20:22:29 +0000794 /// Retrieve the nested-name-specifier that qualifies the name of this
Douglas Gregor14454802011-02-25 02:25:35 +0000795 /// declaration, if it was present in the source.
John McCall3e11ebe2010-03-15 10:12:16 +0000796 NestedNameSpecifier *getQualifier() const {
Douglas Gregor14454802011-02-25 02:25:35 +0000797 return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier()
Craig Topper34b4c432014-05-06 06:48:52 +0000798 : nullptr;
John McCall3e11ebe2010-03-15 10:12:16 +0000799 }
David Blaikie21bfbf82011-11-09 06:07:30 +0000800
James Dennettb8973efb2018-02-02 20:22:29 +0000801 /// Retrieve the nested-name-specifier (with source-location
David Blaikie21bfbf82011-11-09 06:07:30 +0000802 /// information) that qualifies the name of this declaration, if it was
Douglas Gregor14454802011-02-25 02:25:35 +0000803 /// present in the source.
804 NestedNameSpecifierLoc getQualifierLoc() const {
805 return hasExtInfo() ? getExtInfo()->QualifierLoc
806 : NestedNameSpecifierLoc();
John McCall3e11ebe2010-03-15 10:12:16 +0000807 }
David Blaikie21bfbf82011-11-09 06:07:30 +0000808
Douglas Gregor14454802011-02-25 02:25:35 +0000809 void setQualifierInfo(NestedNameSpecifierLoc QualifierLoc);
Argyrios Kyrtzidis6032ef12009-08-21 00:31:54 +0000810
Saar Razb65b1f32020-01-09 15:07:51 +0200811 /// \brief Get the constraint-expression introduced by the trailing
812 /// requires-clause in the function/member declaration, or null if no
813 /// requires-clause was provided.
814 Expr *getTrailingRequiresClause() {
815 return hasExtInfo() ? getExtInfo()->TrailingRequiresClause
816 : nullptr;
817 }
818
819 const Expr *getTrailingRequiresClause() const {
820 return hasExtInfo() ? getExtInfo()->TrailingRequiresClause
821 : nullptr;
822 }
823
824 void setTrailingRequiresClause(Expr *TrailingRequiresClause);
825
Abramo Bagnarada41d0c2010-06-12 08:15:14 +0000826 unsigned getNumTemplateParameterLists() const {
827 return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0;
828 }
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000829
Abramo Bagnarada41d0c2010-06-12 08:15:14 +0000830 TemplateParameterList *getTemplateParameterList(unsigned index) const {
831 assert(index < getNumTemplateParameterLists());
832 return getExtInfo()->TemplParamLists[index];
833 }
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000834
Benjamin Kramer9cc210652015-08-05 09:40:49 +0000835 void setTemplateParameterListsInfo(ASTContext &Context,
836 ArrayRef<TemplateParameterList *> TPLists);
Abramo Bagnarada41d0c2010-06-12 08:15:14 +0000837
Argyrios Kyrtzidis6032ef12009-08-21 00:31:54 +0000838 SourceLocation getTypeSpecStartLoc() const;
Mark de Weverf022a5a2020-01-01 17:23:19 +0100839 SourceLocation getTypeSpecEndLoc() const;
Argyrios Kyrtzidis6032ef12009-08-21 00:31:54 +0000840
Argyrios Kyrtzidis60ed5602009-08-19 01:27:57 +0000841 // Implement isa/cast/dyncast/etc.
John McCall180ef092010-01-29 01:45:37 +0000842 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
John McCall180ef092010-01-29 01:45:37 +0000843 static bool classofKind(Kind K) {
Alexis Hunted053252010-05-30 07:21:58 +0000844 return K >= firstDeclarator && K <= lastDeclarator;
John McCall180ef092010-01-29 01:45:37 +0000845 }
Argyrios Kyrtzidis60ed5602009-08-19 01:27:57 +0000846};
847
James Dennettb8973efb2018-02-02 20:22:29 +0000848/// Structure used to store a statement, the constant value to
Douglas Gregor31cf12c2009-05-26 18:54:04 +0000849/// which it was evaluated (if any), and whether or not the statement
850/// is an integral constant expression (if known).
851struct EvaluatedStmt {
James Dennettb8973efb2018-02-02 20:22:29 +0000852 /// Whether this statement was already evaluated.
Douglas Gregor31cf12c2009-05-26 18:54:04 +0000853 bool WasEvaluated : 1;
854
James Dennettb8973efb2018-02-02 20:22:29 +0000855 /// Whether this statement is being evaluated.
Eli Friedman1d6fb162009-12-03 20:31:57 +0000856 bool IsEvaluating : 1;
857
Richard Smith3692d202020-10-19 21:29:13 -0700858 /// Whether this variable is known to have constant initialization. This is
859 /// currently only computed in C++, for static / thread storage duration
860 /// variables that might have constant initialization and for variables that
861 /// are usable in constant expressions.
862 bool HasConstantInitialization : 1;
Douglas Gregor31cf12c2009-05-26 18:54:04 +0000863
Richard Smith2b4fa532019-09-29 05:08:46 +0000864 /// Whether this variable is known to have constant destruction. That is,
865 /// whether running the destructor on the initial value is a side-effect
866 /// (and doesn't inspect any state that might have changed during program
867 /// execution). This is currently only computed if the destructor is
868 /// non-trivial.
869 bool HasConstantDestruction : 1;
870
Richard Smith3692d202020-10-19 21:29:13 -0700871 /// In C++98, whether the initializer is an ICE. This affects whether the
872 /// variable is usable in constant expressions.
873 bool HasICEInit : 1;
874 bool CheckedForICEInit : 1;
875
Richard Smithbc73ef02023-03-30 14:21:31 -0700876 LazyDeclStmtPtr Value;
Douglas Gregor31cf12c2009-05-26 18:54:04 +0000877 APValue Evaluated;
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000878
Richard Smith2b4fa532019-09-29 05:08:46 +0000879 EvaluatedStmt()
Richard Smith3692d202020-10-19 21:29:13 -0700880 : WasEvaluated(false), IsEvaluating(false),
881 HasConstantInitialization(false), HasConstantDestruction(false),
882 HasICEInit(false), CheckedForICEInit(false) {}
Douglas Gregor31cf12c2009-05-26 18:54:04 +0000883};
884
James Dennett31a57342018-02-02 21:38:22 +0000885/// Represents a variable declaration or definition.
Argyrios Kyrtzidis60ed5602009-08-19 01:27:57 +0000886class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
Steve Naroff46ba1eb2007-04-03 23:13:13 +0000887public:
James Dennettb8973efb2018-02-02 20:22:29 +0000888 /// Initialization styles.
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000889 enum InitializationStyle {
Zequan Wue56e7bd2020-10-26 12:08:57 -0700890 /// C-style initialization with assignment
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000891 CInit,
892
893 /// Call-style initialization (C++98)
Zequan Wue56e7bd2020-10-26 12:08:57 -0700894 CallInit,
895
896 /// Direct list-initialization (C++11)
Alan Zhao95a4c0c2023-01-04 15:12:00 -0800897 ListInit,
898
899 /// Parenthesized list-initialization (C++20)
900 ParenListInit
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000901 };
902
James Dennettb8973efb2018-02-02 20:22:29 +0000903 /// Kinds of thread-local storage.
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000904 enum TLSKind {
905 /// Not a TLS variable.
906 TLS_None,
907
908 /// TLS with a known-constant initializer.
909 TLS_Static,
910
911 /// TLS with a dynamic initializer.
912 TLS_Dynamic
913 };
914
James Dennett31a57342018-02-02 21:38:22 +0000915 /// Return the string used to specify the storage class \p SC.
Daniel Dunbarb76b74572009-04-14 02:08:49 +0000916 ///
917 /// It is illegal to call this function with SC == None.
918 static const char *getStorageClassSpecifierString(StorageClass SC);
919
Douglas Gregord12df6b2009-07-20 22:03:28 +0000920protected:
Chandler Carruth813faed2015-12-30 02:51:00 +0000921 // A pointer union of Stmt * and EvaluatedStmt *. When an EvaluatedStmt, we
Justin Lebar41e9dad2016-07-29 05:26:58 +0000922 // have allocated the auxiliary struct of information there.
Chandler Carruth813faed2015-12-30 02:51:00 +0000923 //
924 // TODO: It is a bit unfortunate to use a PointerUnion inside the VarDecl for
925 // this as *many* VarDecls are ParmVarDecls that don't have default
926 // arguments. We could save some space by moving this pointer union to be
927 // allocated in trailing space when necessary.
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000928 using InitType = llvm::PointerUnion<Stmt *, EvaluatedStmt *>;
Mike Stump11289f42009-09-09 15:08:12 +0000929
James Dennettb8973efb2018-02-02 20:22:29 +0000930 /// The initializer for this variable or, for a ParmVarDecl, the
Douglas Gregord12df6b2009-07-20 22:03:28 +0000931 /// C++ default argument.
Douglas Gregor770a5322009-09-01 16:13:00 +0000932 mutable InitType Init;
Mike Stump11289f42009-09-09 15:08:12 +0000933
Chris Lattner4b08ca82008-03-15 21:10:16 +0000934private:
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000935 friend class ASTDeclReader;
936 friend class ASTNodeImporter;
937 friend class StmtIteratorBase;
938
John McCallbeaa11c2011-05-01 02:13:58 +0000939 class VarDeclBitfields {
John McCallbeaa11c2011-05-01 02:13:58 +0000940 friend class ASTDeclReader;
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000941 friend class VarDecl;
Douglas Gregor85970ca2008-12-10 23:01:14 +0000942
Vlad Serebrennikovad278482023-11-06 12:17:21 +0300943 LLVM_PREFERRED_TYPE(StorageClass)
John McCallbeaa11c2011-05-01 02:13:58 +0000944 unsigned SClass : 3;
Vlad Serebrennikovad278482023-11-06 12:17:21 +0300945 LLVM_PREFERRED_TYPE(ThreadStorageClassSpecifier)
Enea Zaffanellaacb8ecd2013-05-04 08:27:07 +0000946 unsigned TSCSpec : 2;
Vlad Serebrennikovad278482023-11-06 12:17:21 +0300947 LLVM_PREFERRED_TYPE(InitializationStyle)
Sebastian Redla9351792012-02-11 23:51:47 +0000948 unsigned InitStyle : 2;
Erik Pilkington1e368822019-01-04 18:33:06 +0000949
950 /// Whether this variable is an ARC pseudo-__strong variable; see
951 /// isARCPseudoStrong() for details.
Vlad Serebrennikovad278482023-11-06 12:17:21 +0300952 LLVM_PREFERRED_TYPE(bool)
Erik Pilkington1e368822019-01-04 18:33:06 +0000953 unsigned ARCPseudoStrong : 1;
John McCallbeaa11c2011-05-01 02:13:58 +0000954 };
Erik Pilkington1e368822019-01-04 18:33:06 +0000955 enum { NumVarDeclBits = 8 };
Richard Smith02e85f32011-04-14 22:09:26 +0000956
Chris Lattner4b08ca82008-03-15 21:10:16 +0000957protected:
Ted Kremenek9504ae92011-10-06 04:19:35 +0000958 enum { NumParameterIndexBits = 8 };
David Blaikie21bfbf82011-11-09 06:07:30 +0000959
Chandler Carruth813faed2015-12-30 02:51:00 +0000960 enum DefaultArgKind {
961 DAK_None,
962 DAK_Unparsed,
963 DAK_Uninstantiated,
964 DAK_Normal
965 };
966
Martin Storsjöf20fc652019-12-18 10:41:41 +0200967 enum { NumScopeDepthOrObjCQualsBits = 7 };
968
John McCallbeaa11c2011-05-01 02:13:58 +0000969 class ParmVarDeclBitfields {
John McCallbeaa11c2011-05-01 02:13:58 +0000970 friend class ASTDeclReader;
Eugene Zelenkode0215c2017-11-13 23:01:27 +0000971 friend class ParmVarDecl;
John McCallbeaa11c2011-05-01 02:13:58 +0000972
Vlad Serebrennikovad278482023-11-06 12:17:21 +0300973 LLVM_PREFERRED_TYPE(VarDeclBitfields)
John McCallbeaa11c2011-05-01 02:13:58 +0000974 unsigned : NumVarDeclBits;
John McCallbeaa11c2011-05-01 02:13:58 +0000975
976 /// Whether this parameter inherits a default argument from a
977 /// prior declaration.
Vlad Serebrennikovad278482023-11-06 12:17:21 +0300978 LLVM_PREFERRED_TYPE(bool)
John McCallbeaa11c2011-05-01 02:13:58 +0000979 unsigned HasInheritedDefaultArg : 1;
980
Chandler Carruth813faed2015-12-30 02:51:00 +0000981 /// Describes the kind of default argument for this parameter. By default
982 /// this is none. If this is normal, then the default argument is stored in
Simon Pilgrim750bde62017-03-31 11:00:53 +0000983 /// the \c VarDecl initializer expression unless we were unable to parse
Chandler Carruth813faed2015-12-30 02:51:00 +0000984 /// (even an invalid) expression for the default argument.
Vlad Serebrennikovad278482023-11-06 12:17:21 +0300985 LLVM_PREFERRED_TYPE(DefaultArgKind)
Chandler Carruth813faed2015-12-30 02:51:00 +0000986 unsigned DefaultArgKind : 2;
987
John McCallbeaa11c2011-05-01 02:13:58 +0000988 /// Whether this parameter undergoes K&R argument promotion.
Vlad Serebrennikovad278482023-11-06 12:17:21 +0300989 LLVM_PREFERRED_TYPE(bool)
John McCallbeaa11c2011-05-01 02:13:58 +0000990 unsigned IsKNRPromoted : 1;
John McCall82490832011-05-02 00:30:12 +0000991
992 /// Whether this parameter is an ObjC method parameter or not.
Vlad Serebrennikovad278482023-11-06 12:17:21 +0300993 LLVM_PREFERRED_TYPE(bool)
John McCall82490832011-05-02 00:30:12 +0000994 unsigned IsObjCMethodParam : 1;
995
996 /// If IsObjCMethodParam, a Decl::ObjCDeclQualifier.
997 /// Otherwise, the number of function parameter scopes enclosing
998 /// the function parameter scope in which this parameter was
999 /// declared.
Mark de Weverb9be5ce2019-11-09 15:32:35 +01001000 unsigned ScopeDepthOrObjCQuals : NumScopeDepthOrObjCQualsBits;
John McCall82490832011-05-02 00:30:12 +00001001
1002 /// The number of parameters preceding this parameter in the
1003 /// function parameter scope in which it was declared.
Ted Kremenek9504ae92011-10-06 04:19:35 +00001004 unsigned ParameterIndex : NumParameterIndexBits;
John McCallbeaa11c2011-05-01 02:13:58 +00001005 };
1006
David Majnemerfa7bc782015-05-19 00:57:16 +00001007 class NonParmVarDeclBitfields {
David Majnemerfa7bc782015-05-19 00:57:16 +00001008 friend class ASTDeclReader;
Eugene Zelenkode0215c2017-11-13 23:01:27 +00001009 friend class ImplicitParamDecl;
1010 friend class VarDecl;
David Majnemerfa7bc782015-05-19 00:57:16 +00001011
Vlad Serebrennikovad278482023-11-06 12:17:21 +03001012 LLVM_PREFERRED_TYPE(VarDeclBitfields)
David Majnemerfa7bc782015-05-19 00:57:16 +00001013 unsigned : NumVarDeclBits;
1014
Richard Smithedbc6e92016-10-14 21:41:24 +00001015 // FIXME: We need something similar to CXXRecordDecl::DefinitionData.
James Dennettb8973efb2018-02-02 20:22:29 +00001016 /// Whether this variable is a definition which was demoted due to
Richard Smithedbc6e92016-10-14 21:41:24 +00001017 /// module merge.
Vlad Serebrennikovad278482023-11-06 12:17:21 +03001018 LLVM_PREFERRED_TYPE(bool)
Richard Smithedbc6e92016-10-14 21:41:24 +00001019 unsigned IsThisDeclarationADemotedDefinition : 1;
1020
James Dennettb8973efb2018-02-02 20:22:29 +00001021 /// Whether this variable is the exception variable in a C++ catch
David Majnemerfa7bc782015-05-19 00:57:16 +00001022 /// or an Objective-C @catch statement.
Vlad Serebrennikovad278482023-11-06 12:17:21 +03001023 LLVM_PREFERRED_TYPE(bool)
David Majnemerfa7bc782015-05-19 00:57:16 +00001024 unsigned ExceptionVar : 1;
1025
James Dennettb8973efb2018-02-02 20:22:29 +00001026 /// Whether this local variable could be allocated in the return
David Majnemerfa7bc782015-05-19 00:57:16 +00001027 /// slot of its function, enabling the named return value optimization
1028 /// (NRVO).
Vlad Serebrennikovad278482023-11-06 12:17:21 +03001029 LLVM_PREFERRED_TYPE(bool)
Taiju Tsuiki3be68e12018-06-19 05:35:30 +00001030 unsigned NRVOVariable : 1;
David Majnemerfa7bc782015-05-19 00:57:16 +00001031
James Dennettb8973efb2018-02-02 20:22:29 +00001032 /// Whether this variable is the for-range-declaration in a C++0x
David Majnemerfa7bc782015-05-19 00:57:16 +00001033 /// for-range statement.
Vlad Serebrennikovad278482023-11-06 12:17:21 +03001034 LLVM_PREFERRED_TYPE(bool)
David Majnemerfa7bc782015-05-19 00:57:16 +00001035 unsigned CXXForRangeDecl : 1;
1036
George Karpenkovec38cf72018-03-29 00:56:24 +00001037 /// Whether this variable is the for-in loop declaration in Objective-C.
Vlad Serebrennikovad278482023-11-06 12:17:21 +03001038 LLVM_PREFERRED_TYPE(bool)
George Karpenkovec38cf72018-03-29 00:56:24 +00001039 unsigned ObjCForDecl : 1;
1040
James Dennettb8973efb2018-02-02 20:22:29 +00001041 /// Whether this variable is (C++1z) inline.
Vlad Serebrennikovad278482023-11-06 12:17:21 +03001042 LLVM_PREFERRED_TYPE(bool)
Richard Smith62f19e72016-06-25 00:15:56 +00001043 unsigned IsInline : 1;
1044
James Dennettb8973efb2018-02-02 20:22:29 +00001045 /// Whether this variable has (C++1z) inline explicitly specified.
Vlad Serebrennikovad278482023-11-06 12:17:21 +03001046 LLVM_PREFERRED_TYPE(bool)
Richard Smith62f19e72016-06-25 00:15:56 +00001047 unsigned IsInlineSpecified : 1;
1048
James Dennettb8973efb2018-02-02 20:22:29 +00001049 /// Whether this variable is (C++0x) constexpr.
Vlad Serebrennikovad278482023-11-06 12:17:21 +03001050 LLVM_PREFERRED_TYPE(bool)
David Majnemerfa7bc782015-05-19 00:57:16 +00001051 unsigned IsConstexpr : 1;
1052
James Dennettb8973efb2018-02-02 20:22:29 +00001053 /// Whether this variable is the implicit variable for a lambda
David Majnemerfa7bc782015-05-19 00:57:16 +00001054 /// init-capture.
Vlad Serebrennikovad278482023-11-06 12:17:21 +03001055 LLVM_PREFERRED_TYPE(bool)
David Majnemerfa7bc782015-05-19 00:57:16 +00001056 unsigned IsInitCapture : 1;
1057
James Dennettb8973efb2018-02-02 20:22:29 +00001058 /// Whether this local extern variable's previous declaration was
David Majnemerfa7bc782015-05-19 00:57:16 +00001059 /// declared in the same block scope. This controls whether we should merge
1060 /// the type of this declaration with its previous declaration.
Vlad Serebrennikovad278482023-11-06 12:17:21 +03001061 LLVM_PREFERRED_TYPE(bool)
David Majnemerfa7bc782015-05-19 00:57:16 +00001062 unsigned PreviousDeclInSameBlockScope : 1;
Alexey Bataev56223232017-06-09 13:40:18 +00001063
1064 /// Defines kind of the ImplicitParamDecl: 'this', 'self', 'vtt', '_cmd' or
1065 /// something else.
Vlad Serebrennikovad278482023-11-06 12:17:21 +03001066 LLVM_PREFERRED_TYPE(ImplicitParamKind)
Alexey Bataev56223232017-06-09 13:40:18 +00001067 unsigned ImplicitParamKind : 3;
Akira Hatanaka8e57b072018-10-01 21:51:28 +00001068
Vlad Serebrennikovad278482023-11-06 12:17:21 +03001069 LLVM_PREFERRED_TYPE(bool)
Akira Hatanaka8e57b072018-10-01 21:51:28 +00001070 unsigned EscapingByref : 1;
Youngsuk Kim90453f42024-04-04 20:45:18 -04001071
1072 LLVM_PREFERRED_TYPE(bool)
1073 unsigned IsCXXCondDecl : 1;
David Majnemerfa7bc782015-05-19 00:57:16 +00001074 };
1075
John McCallbeaa11c2011-05-01 02:13:58 +00001076 union {
1077 unsigned AllBits;
1078 VarDeclBitfields VarDeclBits;
1079 ParmVarDeclBitfields ParmVarDeclBits;
David Majnemerfa7bc782015-05-19 00:57:16 +00001080 NonParmVarDeclBitfields NonParmVarDeclBits;
John McCallbeaa11c2011-05-01 02:13:58 +00001081 };
1082
Richard Smith053f6c62014-05-16 23:01:30 +00001083 VarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
Hubert Tongda167a52022-03-23 11:03:44 -04001084 SourceLocation IdLoc, const IdentifierInfo *Id, QualType T,
Larisse Voufo39a1e502013-08-06 01:03:05 +00001085 TypeSourceInfo *TInfo, StorageClass SC);
Argyrios Kyrtzidis05898da2009-07-18 08:50:35 +00001086
Eugene Zelenkode0215c2017-11-13 23:01:27 +00001087 using redeclarable_base = Redeclarable<VarDecl>;
1088
Richard Smithd7af8a32014-05-10 01:17:36 +00001089 VarDecl *getNextRedeclarationImpl() override {
1090 return getNextRedeclaration();
1091 }
Eugene Zelenkode0215c2017-11-13 23:01:27 +00001092
Craig Toppercbce6e92014-03-11 06:22:39 +00001093 VarDecl *getPreviousDeclImpl() override {
Douglas Gregorec9fd132012-01-14 16:38:05 +00001094 return getPreviousDecl();
1095 }
Eugene Zelenkode0215c2017-11-13 23:01:27 +00001096
Craig Toppercbce6e92014-03-11 06:22:39 +00001097 VarDecl *getMostRecentDeclImpl() override {
Douglas Gregorec9fd132012-01-14 16:38:05 +00001098 return getMostRecentDecl();
1099 }
Douglas Gregorb11aad82011-02-19 18:51:44 +00001100
Chris Lattner4b08ca82008-03-15 21:10:16 +00001101public:
Eugene Zelenkode0215c2017-11-13 23:01:27 +00001102 using redecl_range = redeclarable_base::redecl_range;
1103 using redecl_iterator = redeclarable_base::redecl_iterator;
1104
Aaron Ballman211cd8c2014-03-07 00:10:58 +00001105 using redeclarable_base::redecls_begin;
1106 using redeclarable_base::redecls_end;
Aaron Ballman86c93902014-03-06 23:45:36 +00001107 using redeclarable_base::redecls;
Douglas Gregorec9fd132012-01-14 16:38:05 +00001108 using redeclarable_base::getPreviousDecl;
1109 using redeclarable_base::getMostRecentDecl;
Rafael Espindola3f9e4442013-10-19 02:13:21 +00001110 using redeclarable_base::isFirstDecl;
Douglas Gregor0bc8a212012-01-14 15:55:47 +00001111
Chris Lattnerbec41342008-04-22 18:39:57 +00001112 static VarDecl *Create(ASTContext &C, DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +00001113 SourceLocation StartLoc, SourceLocation IdLoc,
Hubert Tongda167a52022-03-23 11:03:44 -04001114 const IdentifierInfo *Id, QualType T,
1115 TypeSourceInfo *TInfo, StorageClass S);
Nuno Lopes394ec982008-12-17 23:39:55 +00001116
Chuanqi Xud86cc732024-04-25 11:43:13 +08001117 static VarDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
Craig Toppercbce6e92014-03-11 06:22:39 +00001118
1119 SourceRange getSourceRange() const override LLVM_READONLY;
Nuno Lopes394ec982008-12-17 23:39:55 +00001120
James Dennettb8973efb2018-02-02 20:22:29 +00001121 /// Returns the storage class as written in the source. For the
Rafael Espindola6ae7e502013-04-03 19:27:57 +00001122 /// computed linkage of symbol, see getLinkage.
John McCallbeaa11c2011-05-01 02:13:58 +00001123 StorageClass getStorageClass() const {
1124 return (StorageClass) VarDeclBits.SClass;
1125 }
Douglas Gregorbf62d642010-12-06 18:36:25 +00001126 void setStorageClass(StorageClass SC);
Mike Stump11289f42009-09-09 15:08:12 +00001127
Enea Zaffanellaacb8ecd2013-05-04 08:27:07 +00001128 void setTSCSpec(ThreadStorageClassSpecifier TSC) {
1129 VarDeclBits.TSCSpec = TSC;
Reid Kleckner7d6d2702014-05-01 03:16:47 +00001130 assert(VarDeclBits.TSCSpec == TSC && "truncation");
Enea Zaffanellaacb8ecd2013-05-04 08:27:07 +00001131 }
1132 ThreadStorageClassSpecifier getTSCSpec() const {
1133 return static_cast<ThreadStorageClassSpecifier>(VarDeclBits.TSCSpec);
1134 }
Reid Kleckner7d6d2702014-05-01 03:16:47 +00001135 TLSKind getTLSKind() const;
Sebastian Redl833ef452010-01-26 22:01:41 +00001136
James Dennett31a57342018-02-02 21:38:22 +00001137 /// Returns true if a variable with function scope is a non-static local
1138 /// variable.
Sebastian Redl833ef452010-01-26 22:01:41 +00001139 bool hasLocalStorage() const {
Thorsten Schütt2fd11e02021-01-04 23:17:45 +01001140 if (getStorageClass() == SC_None) {
Yaxun Liu4f33b3d2017-05-15 14:47:47 +00001141 // OpenCL v1.2 s6.5.3: The __constant or constant address space name is
1142 // used to describe variables allocated in global memory and which are
1143 // accessed inside a kernel(s) as read-only variables. As such, variables
1144 // in constant address space cannot have local storage.
1145 if (getType().getAddressSpace() == LangAS::opencl_constant)
1146 return false;
Enea Zaffanella28f36ba2013-05-10 20:34:44 +00001147 // Second check is for C++11 [dcl.stc]p4.
Richard Smithe6c01442013-06-05 00:46:14 +00001148 return !isFileVarDecl() && getTSCSpec() == TSCS_unspecified;
Yaxun Liu4f33b3d2017-05-15 14:47:47 +00001149 }
Sebastian Redl833ef452010-01-26 22:01:41 +00001150
Renato Golin230c5eb2014-05-19 18:15:42 +00001151 // Global Named Register (GNU extension)
Thorsten Schütt2fd11e02021-01-04 23:17:45 +01001152 if (getStorageClass() == SC_Register && !isLocalVarDeclOrParm())
Renato Golin230c5eb2014-05-19 18:15:42 +00001153 return false;
1154
Sebastian Redl833ef452010-01-26 22:01:41 +00001155 // Return true for: Auto, Register.
Peter Collingbourne2dbb7082011-09-19 21:14:35 +00001156 // Return false for: Extern, Static, PrivateExtern, OpenCLWorkGroupLocal.
Sebastian Redl833ef452010-01-26 22:01:41 +00001157
Thorsten Schütt2fd11e02021-01-04 23:17:45 +01001158 return getStorageClass() >= SC_Auto;
Sebastian Redl833ef452010-01-26 22:01:41 +00001159 }
1160
James Dennett31a57342018-02-02 21:38:22 +00001161 /// Returns true if a variable with function scope is a static local
1162 /// variable.
Fariborz Jahanian3fef72f2010-04-18 21:01:23 +00001163 bool isStaticLocal() const {
Thorsten Schütt2fd11e02021-01-04 23:17:45 +01001164 return (getStorageClass() == SC_Static ||
Enea Zaffanella28f36ba2013-05-10 20:34:44 +00001165 // C++11 [dcl.stc]p4
Thorsten Schütt2fd11e02021-01-04 23:17:45 +01001166 (getStorageClass() == SC_None && getTSCSpec() == TSCS_thread_local))
1167 && !isFileVarDecl();
Fariborz Jahanian3fef72f2010-04-18 21:01:23 +00001168 }
David Blaikie21bfbf82011-11-09 06:07:30 +00001169
James Dennettb8973efb2018-02-02 20:22:29 +00001170 /// Returns true if a variable has extern or __private_extern__
Rafael Espindola2199c122013-03-07 02:43:24 +00001171 /// storage.
Sebastian Redl833ef452010-01-26 22:01:41 +00001172 bool hasExternalStorage() const {
Thorsten Schütt2fd11e02021-01-04 23:17:45 +01001173 return getStorageClass() == SC_Extern ||
1174 getStorageClass() == SC_PrivateExtern;
Sebastian Redl833ef452010-01-26 22:01:41 +00001175 }
1176
James Dennettb8973efb2018-02-02 20:22:29 +00001177 /// Returns true for all variables that do not have local storage.
James Dennett42c4e502013-11-05 19:37:38 +00001178 ///
1179 /// This includes all global variables as well as static variables declared
1180 /// within a function.
Sebastian Redl833ef452010-01-26 22:01:41 +00001181 bool hasGlobalStorage() const { return !hasLocalStorage(); }
1182
James Dennettb8973efb2018-02-02 20:22:29 +00001183 /// Get the storage duration of this variable, per C++ [basic.stc].
Richard Smithe6c01442013-06-05 00:46:14 +00001184 StorageDuration getStorageDuration() const {
1185 return hasLocalStorage() ? SD_Automatic :
1186 getTSCSpec() ? SD_Thread : SD_Static;
1187 }
1188
James Dennettb8973efb2018-02-02 20:22:29 +00001189 /// Compute the language linkage.
Rafael Espindolaf4187652013-02-14 01:18:37 +00001190 LanguageLinkage getLanguageLinkage() const;
1191
James Dennettb8973efb2018-02-02 20:22:29 +00001192 /// Determines whether this variable is a variable with external, C linkage.
Rafael Espindola0e0d0092013-03-14 03:07:35 +00001193 bool isExternC() const;
Rafael Espindola576127d2012-12-28 14:21:58 +00001194
James Dennettb8973efb2018-02-02 20:22:29 +00001195 /// Determines whether this variable's context is, or is nested within,
Rafael Espindola593537a2013-05-05 20:15:21 +00001196 /// a C++ extern "C" linkage spec.
1197 bool isInExternCContext() const;
1198
James Dennettb8973efb2018-02-02 20:22:29 +00001199 /// Determines whether this variable's context is, or is nested within,
Rafael Espindola593537a2013-05-05 20:15:21 +00001200 /// a C++ extern "C++" linkage spec.
1201 bool isInExternCXXContext() const;
1202
James Dennettb8973efb2018-02-02 20:22:29 +00001203 /// Returns true for local variable declarations other than parameters.
1204 /// Note that this includes static variables inside of functions. It also
1205 /// includes variables inside blocks.
Sebastian Redl833ef452010-01-26 22:01:41 +00001206 ///
1207 /// void foo() { int x; static int y; extern int z; }
John McCall1c9c3fd2010-10-15 04:57:14 +00001208 bool isLocalVarDecl() const {
Richard Smith7873de02016-08-11 22:25:46 +00001209 if (getKind() != Decl::Var && getKind() != Decl::Decomposition)
Sebastian Redl833ef452010-01-26 22:01:41 +00001210 return false;
Richard Smith541b38b2013-09-20 01:15:31 +00001211 if (const DeclContext *DC = getLexicalDeclContext())
Sebastian Redl50c68252010-08-31 00:36:30 +00001212 return DC->getRedeclContext()->isFunctionOrMethod();
Sebastian Redl833ef452010-01-26 22:01:41 +00001213 return false;
1214 }
1215
James Dennettb8973efb2018-02-02 20:22:29 +00001216 /// Similar to isLocalVarDecl but also includes parameters.
David Majnemera3b04ce2015-01-14 00:31:13 +00001217 bool isLocalVarDeclOrParm() const {
1218 return isLocalVarDecl() || getKind() == Decl::ParmVar;
1219 }
1220
James Dennettb8973efb2018-02-02 20:22:29 +00001221 /// Similar to isLocalVarDecl, but excludes variables declared in blocks.
Fariborz Jahanian3a106e72010-03-11 18:20:03 +00001222 bool isFunctionOrMethodVarDecl() const {
Richard Smith7873de02016-08-11 22:25:46 +00001223 if (getKind() != Decl::Var && getKind() != Decl::Decomposition)
Fariborz Jahanian3a106e72010-03-11 18:20:03 +00001224 return false;
Richard Smith541b38b2013-09-20 01:15:31 +00001225 const DeclContext *DC = getLexicalDeclContext()->getRedeclContext();
Sebastian Redl50c68252010-08-31 00:36:30 +00001226 return DC->isFunctionOrMethod() && DC->getDeclKind() != Decl::Block;
Fariborz Jahanian3a106e72010-03-11 18:20:03 +00001227 }
1228
James Dennettb8973efb2018-02-02 20:22:29 +00001229 /// Determines whether this is a static data member.
Sebastian Redl833ef452010-01-26 22:01:41 +00001230 ///
1231 /// This will only be true in C++, and applies to, e.g., the
1232 /// variable 'x' in:
1233 /// \code
1234 /// struct S {
1235 /// static int x;
1236 /// };
1237 /// \endcode
1238 bool isStaticDataMember() const {
Sebastian Redl35351a92010-01-31 22:27:38 +00001239 // If it wasn't static, it would be a FieldDecl.
Argyrios Kyrtzidis3816ed42010-07-19 10:14:41 +00001240 return getKind() != Decl::ParmVar && getDeclContext()->isRecord();
Sebastian Redl833ef452010-01-26 22:01:41 +00001241 }
1242
Craig Toppercbce6e92014-03-11 06:22:39 +00001243 VarDecl *getCanonicalDecl() override;
Sebastian Redl833ef452010-01-26 22:01:41 +00001244 const VarDecl *getCanonicalDecl() const {
1245 return const_cast<VarDecl*>(this)->getCanonicalDecl();
1246 }
1247
Sebastian Redl35351a92010-01-31 22:27:38 +00001248 enum DefinitionKind {
Eugene Zelenkode0215c2017-11-13 23:01:27 +00001249 /// This declaration is only a declaration.
1250 DeclarationOnly,
1251
1252 /// This declaration is a tentative definition.
1253 TentativeDefinition,
1254
1255 /// This declaration is definitely a definition.
1256 Definition
Sebastian Redl35351a92010-01-31 22:27:38 +00001257 };
1258
James Dennettb8973efb2018-02-02 20:22:29 +00001259 /// Check whether this declaration is a definition. If this could be
Sebastian Redl35351a92010-01-31 22:27:38 +00001260 /// a tentative definition (in C), don't check whether there's an overriding
1261 /// definition.
Daniel Dunbar9d355812012-03-09 01:51:51 +00001262 DefinitionKind isThisDeclarationADefinition(ASTContext &) const;
1263 DefinitionKind isThisDeclarationADefinition() const {
1264 return isThisDeclarationADefinition(getASTContext());
1265 }
Sebastian Redl35351a92010-01-31 22:27:38 +00001266
James Dennettb8973efb2018-02-02 20:22:29 +00001267 /// Check whether this variable is defined in this translation unit.
Daniel Dunbar9d355812012-03-09 01:51:51 +00001268 DefinitionKind hasDefinition(ASTContext &) const;
1269 DefinitionKind hasDefinition() const {
1270 return hasDefinition(getASTContext());
1271 }
John McCall37bb6c92010-10-29 22:22:43 +00001272
James Dennettb8973efb2018-02-02 20:22:29 +00001273 /// Get the tentative definition that acts as the real definition in a TU.
1274 /// Returns null if there is a proper definition available.
Sebastian Redl35351a92010-01-31 22:27:38 +00001275 VarDecl *getActingDefinition();
Sebastian Redl5ca79842010-02-01 20:16:42 +00001276 const VarDecl *getActingDefinition() const {
1277 return const_cast<VarDecl*>(this)->getActingDefinition();
1278 }
Sebastian Redl35351a92010-01-31 22:27:38 +00001279
James Dennettb8973efb2018-02-02 20:22:29 +00001280 /// Get the real (not just tentative) definition for this declaration.
Daniel Dunbar9d355812012-03-09 01:51:51 +00001281 VarDecl *getDefinition(ASTContext &);
1282 const VarDecl *getDefinition(ASTContext &C) const {
1283 return const_cast<VarDecl*>(this)->getDefinition(C);
1284 }
1285 VarDecl *getDefinition() {
1286 return getDefinition(getASTContext());
1287 }
Sebastian Redl5ca79842010-02-01 20:16:42 +00001288 const VarDecl *getDefinition() const {
1289 return const_cast<VarDecl*>(this)->getDefinition();
Sebastian Redl833ef452010-01-26 22:01:41 +00001290 }
1291
James Dennettb8973efb2018-02-02 20:22:29 +00001292 /// Determine whether this is or was instantiated from an out-of-line
Sebastian Redl833ef452010-01-26 22:01:41 +00001293 /// definition of a static data member.
Craig Toppercbce6e92014-03-11 06:22:39 +00001294 bool isOutOfLine() const override;
Sebastian Redl833ef452010-01-26 22:01:41 +00001295
James Dennettb8973efb2018-02-02 20:22:29 +00001296 /// Returns true for file scoped variable declaration.
Sebastian Redl833ef452010-01-26 22:01:41 +00001297 bool isFileVarDecl() const {
Larisse Voufo39a1e502013-08-06 01:03:05 +00001298 Kind K = getKind();
1299 if (K == ParmVar || K == ImplicitParam)
Sebastian Redl833ef452010-01-26 22:01:41 +00001300 return false;
David Blaikie21bfbf82011-11-09 06:07:30 +00001301
Richard Smith541b38b2013-09-20 01:15:31 +00001302 if (getLexicalDeclContext()->getRedeclContext()->isFileContext())
Douglas Gregorfcee9462010-08-27 22:55:10 +00001303 return true;
David Blaikie21bfbf82011-11-09 06:07:30 +00001304
Sebastian Redl833ef452010-01-26 22:01:41 +00001305 if (isStaticDataMember())
1306 return true;
1307
1308 return false;
1309 }
1310
James Dennettb8973efb2018-02-02 20:22:29 +00001311 /// Get the initializer for this variable, no matter which
Sebastian Redl5ca79842010-02-01 20:16:42 +00001312 /// declaration it is attached to.
1313 const Expr *getAnyInitializer() const {
1314 const VarDecl *D;
1315 return getAnyInitializer(D);
1316 }
1317
James Dennettb8973efb2018-02-02 20:22:29 +00001318 /// Get the initializer for this variable, no matter which
Sebastian Redl5ca79842010-02-01 20:16:42 +00001319 /// declaration it is attached to. Also get that declaration.
1320 const Expr *getAnyInitializer(const VarDecl *&D) const;
1321
Chandler Carruth813faed2015-12-30 02:51:00 +00001322 bool hasInit() const;
Mike Stump11289f42009-09-09 15:08:12 +00001323 const Expr *getInit() const {
Chandler Carruth813faed2015-12-30 02:51:00 +00001324 return const_cast<VarDecl *>(this)->getInit();
Douglas Gregor31cf12c2009-05-26 18:54:04 +00001325 }
Chandler Carruth813faed2015-12-30 02:51:00 +00001326 Expr *getInit();
Douglas Gregor31cf12c2009-05-26 18:54:04 +00001327
James Dennettb8973efb2018-02-02 20:22:29 +00001328 /// Retrieve the address of the initializer expression.
Chandler Carruth813faed2015-12-30 02:51:00 +00001329 Stmt **getInitAddress();
Douglas Gregor31cf12c2009-05-26 18:54:04 +00001330
Douglas Gregord5058122010-02-11 01:19:42 +00001331 void setInit(Expr *I);
Mike Stump11289f42009-09-09 15:08:12 +00001332
Richard Smitha6e8b682019-09-04 20:30:37 +00001333 /// Get the initializing declaration of this variable, if any. This is
1334 /// usually the definition, except that for a static data member it can be
1335 /// the in-class declaration.
1336 VarDecl *getInitializingDeclaration();
1337 const VarDecl *getInitializingDeclaration() const {
1338 return const_cast<VarDecl *>(this)->getInitializingDeclaration();
1339 }
1340
Richard Smith715f7a12019-06-11 17:50:32 +00001341 /// Determine whether this variable's value might be usable in a
Richard Smith242ad892011-12-21 02:55:12 +00001342 /// constant expression, according to the relevant language standard.
1343 /// This only checks properties of the declaration, and does not check
1344 /// whether the initializer is in fact a constant expression.
Richard Smith7e7f38f2020-12-15 14:18:48 -08001345 ///
1346 /// This corresponds to C++20 [expr.const]p3's notion of a
1347 /// "potentially-constant" variable.
Zequan Wue56e7bd2020-10-26 12:08:57 -07001348 bool mightBeUsableInConstantExpressions(const ASTContext &C) const;
Richard Smith715f7a12019-06-11 17:50:32 +00001349
1350 /// Determine whether this variable's value can be used in a
1351 /// constant expression, according to the relevant language standard,
1352 /// including checking whether it was initialized by a constant expression.
Zequan Wue56e7bd2020-10-26 12:08:57 -07001353 bool isUsableInConstantExpressions(const ASTContext &C) const;
Richard Smith242ad892011-12-21 02:55:12 +00001354
Richard Smithd0b4dd62011-12-19 06:19:21 +00001355 EvaluatedStmt *ensureEvaluatedStmt() const;
Zequan Wue56e7bd2020-10-26 12:08:57 -07001356 EvaluatedStmt *getEvaluatedStmt() const;
Douglas Gregor31cf12c2009-05-26 18:54:04 +00001357
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001358 /// Attempt to evaluate the value of the initializer attached to this
Richard Smith08c8d5b2020-10-19 20:03:18 -07001359 /// declaration, and produce notes explaining why it cannot be evaluated.
1360 /// Returns a pointer to the value if evaluation succeeded, 0 otherwise.
Richard Smithdafff942012-01-14 04:30:29 +00001361 APValue *evaluateValue() const;
Mike Stump11289f42009-09-09 15:08:12 +00001362
Richard Smith08c8d5b2020-10-19 20:03:18 -07001363private:
1364 APValue *evaluateValueImpl(SmallVectorImpl<PartialDiagnosticAt> &Notes,
1365 bool IsConstantInitialization) const;
1366
1367public:
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001368 /// Return the already-evaluated value of this variable's
Eli Friedman1d6fb162009-12-03 20:31:57 +00001369 /// initializer, or NULL if the value is not yet known. Returns pointer
1370 /// to untyped APValue if the value could not be evaluated.
Chandler Carruth813faed2015-12-30 02:51:00 +00001371 APValue *getEvaluatedValue() const;
Douglas Gregor31cf12c2009-05-26 18:54:04 +00001372
Richard Smith2b4fa532019-09-29 05:08:46 +00001373 /// Evaluate the destruction of this variable to determine if it constitutes
1374 /// constant destruction.
1375 ///
Richard Smith3692d202020-10-19 21:29:13 -07001376 /// \pre hasConstantInitialization()
Richard Smith2b4fa532019-09-29 05:08:46 +00001377 /// \return \c true if this variable has constant destruction, \c false if
1378 /// not.
1379 bool evaluateDestruction(SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
1380
Richard Smith3692d202020-10-19 21:29:13 -07001381 /// Determine whether this variable has constant initialization.
Douglas Gregor31cf12c2009-05-26 18:54:04 +00001382 ///
Richard Smith3692d202020-10-19 21:29:13 -07001383 /// This is only set in two cases: when the language semantics require
1384 /// constant initialization (globals in C and some globals in C++), and when
1385 /// the variable is usable in constant expressions (constexpr, const int, and
1386 /// reference variables in C++).
1387 bool hasConstantInitialization() const;
Douglas Gregor31cf12c2009-05-26 18:54:04 +00001388
Richard Smith3692d202020-10-19 21:29:13 -07001389 /// Determine whether the initializer of this variable is an integer constant
1390 /// expression. For use in C++98, where this affects whether the variable is
1391 /// usable in constant expressions.
1392 bool hasICEInitializer(const ASTContext &Context) const;
1393
1394 /// Evaluate the initializer of this variable to determine whether it's a
1395 /// constant initializer. Should only be called once, after completing the
1396 /// definition of the variable.
1397 bool checkForConstantInitialization(
1398 SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
Douglas Gregor31cf12c2009-05-26 18:54:04 +00001399
Sebastian Redla9351792012-02-11 23:51:47 +00001400 void setInitStyle(InitializationStyle Style) {
1401 VarDeclBits.InitStyle = Style;
1402 }
Argyrios Kyrtzidis9a1191c2008-10-06 17:10:33 +00001403
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001404 /// The style of initialization for this declaration.
Argyrios Kyrtzidis9a1191c2008-10-06 17:10:33 +00001405 ///
Sebastian Redla9351792012-02-11 23:51:47 +00001406 /// C-style initialization is "int x = 1;". Call-style initialization is
1407 /// a C++98 direct-initializer, e.g. "int x(1);". The Init expression will be
1408 /// the expression inside the parens or a "ClassType(a,b,c)" class constructor
1409 /// expression for class types. List-style initialization is C++11 syntax,
1410 /// e.g. "int x{1};". Clients can distinguish between different forms of
1411 /// initialization by checking this value. In particular, "int x = {1};" is
1412 /// C-style, "int x({1})" is call-style, and "int x{1};" is list-style; the
1413 /// Init expression in all three cases is an InitListExpr.
1414 InitializationStyle getInitStyle() const {
1415 return static_cast<InitializationStyle>(VarDeclBits.InitStyle);
1416 }
Eugene Zelenkode0215c2017-11-13 23:01:27 +00001417
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001418 /// Whether the initializer is a direct-initializer (list or call).
Sebastian Redla9351792012-02-11 23:51:47 +00001419 bool isDirectInit() const {
1420 return getInitStyle() != CInit;
Argyrios Kyrtzidis9a1191c2008-10-06 17:10:33 +00001421 }
Mike Stump11289f42009-09-09 15:08:12 +00001422
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001423 /// If this definition should pretend to be a declaration.
Richard Smithedbc6e92016-10-14 21:41:24 +00001424 bool isThisDeclarationADemotedDefinition() const {
1425 return isa<ParmVarDecl>(this) ? false :
1426 NonParmVarDeclBits.IsThisDeclarationADemotedDefinition;
1427 }
1428
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001429 /// This is a definition which should be demoted to a declaration.
Richard Smithedbc6e92016-10-14 21:41:24 +00001430 ///
1431 /// In some cases (mostly module merging) we can end up with two visible
1432 /// definitions one of which needs to be demoted to a declaration to keep
1433 /// the AST invariants.
1434 void demoteThisDefinitionToDeclaration() {
Eugene Zelenkode0215c2017-11-13 23:01:27 +00001435 assert(isThisDeclarationADefinition() && "Not a definition!");
1436 assert(!isa<ParmVarDecl>(this) && "Cannot demote ParmVarDecls!");
Richard Smithedbc6e92016-10-14 21:41:24 +00001437 NonParmVarDeclBits.IsThisDeclarationADemotedDefinition = 1;
1438 }
1439
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001440 /// Determine whether this variable is the exception variable in a
Chandler Carruth48687a52012-06-07 17:55:42 +00001441 /// C++ catch statememt or an Objective-C \@catch statement.
Douglas Gregor3f324d562010-05-03 18:51:14 +00001442 bool isExceptionVariable() const {
David Majnemerfa7bc782015-05-19 00:57:16 +00001443 return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.ExceptionVar;
Douglas Gregor3f324d562010-05-03 18:51:14 +00001444 }
David Majnemerfa7bc782015-05-19 00:57:16 +00001445 void setExceptionVariable(bool EV) {
1446 assert(!isa<ParmVarDecl>(this));
1447 NonParmVarDeclBits.ExceptionVar = EV;
1448 }
David Blaikie21bfbf82011-11-09 06:07:30 +00001449
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001450 /// Determine whether this local variable can be used with the named
Douglas Gregor6fd1b182010-05-15 06:01:05 +00001451 /// return value optimization (NRVO).
1452 ///
1453 /// The named return value optimization (NRVO) works by marking certain
1454 /// non-volatile local variables of class type as NRVO objects. These
1455 /// locals can be allocated within the return slot of their containing
1456 /// function, in which case there is no need to copy the object to the
1457 /// return slot when returning from the function. Within the function body,
1458 /// each return that returns the NRVO object will have this variable as its
1459 /// NRVO candidate.
David Majnemerfa7bc782015-05-19 00:57:16 +00001460 bool isNRVOVariable() const {
Taiju Tsuiki3be68e12018-06-19 05:35:30 +00001461 return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.NRVOVariable;
David Majnemerfa7bc782015-05-19 00:57:16 +00001462 }
1463 void setNRVOVariable(bool NRVO) {
1464 assert(!isa<ParmVarDecl>(this));
Taiju Tsuiki3be68e12018-06-19 05:35:30 +00001465 NonParmVarDeclBits.NRVOVariable = NRVO;
David Majnemerfa7bc782015-05-19 00:57:16 +00001466 }
Richard Smith02e85f32011-04-14 22:09:26 +00001467
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001468 /// Determine whether this variable is the for-range-declaration in
Richard Smith02e85f32011-04-14 22:09:26 +00001469 /// a C++0x for-range statement.
David Majnemerfa7bc782015-05-19 00:57:16 +00001470 bool isCXXForRangeDecl() const {
1471 return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.CXXForRangeDecl;
1472 }
1473 void setCXXForRangeDecl(bool FRD) {
1474 assert(!isa<ParmVarDecl>(this));
1475 NonParmVarDeclBits.CXXForRangeDecl = FRD;
1476 }
John McCalld4631322011-06-17 06:42:21 +00001477
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001478 /// Determine whether this variable is a for-loop declaration for a
George Karpenkovec38cf72018-03-29 00:56:24 +00001479 /// for-in statement in Objective-C.
1480 bool isObjCForDecl() const {
1481 return NonParmVarDeclBits.ObjCForDecl;
1482 }
1483
1484 void setObjCForDecl(bool FRD) {
1485 NonParmVarDeclBits.ObjCForDecl = FRD;
1486 }
1487
Erik Pilkington1e368822019-01-04 18:33:06 +00001488 /// Determine whether this variable is an ARC pseudo-__strong variable. A
1489 /// pseudo-__strong variable has a __strong-qualified type but does not
1490 /// actually retain the object written into it. Generally such variables are
1491 /// also 'const' for safety. There are 3 cases where this will be set, 1) if
1492 /// the variable is annotated with the objc_externally_retained attribute, 2)
1493 /// if its 'self' in a non-init method, or 3) if its the variable in an for-in
1494 /// loop.
1495 bool isARCPseudoStrong() const { return VarDeclBits.ARCPseudoStrong; }
1496 void setARCPseudoStrong(bool PS) { VarDeclBits.ARCPseudoStrong = PS; }
David Blaikie21bfbf82011-11-09 06:07:30 +00001497
Richard Smith62f19e72016-06-25 00:15:56 +00001498 /// Whether this variable is (C++1z) inline.
1499 bool isInline() const {
1500 return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsInline;
1501 }
1502 bool isInlineSpecified() const {
1503 return isa<ParmVarDecl>(this) ? false
1504 : NonParmVarDeclBits.IsInlineSpecified;
1505 }
1506 void setInlineSpecified() {
1507 assert(!isa<ParmVarDecl>(this));
1508 NonParmVarDeclBits.IsInline = true;
1509 NonParmVarDeclBits.IsInlineSpecified = true;
1510 }
1511 void setImplicitlyInline() {
1512 assert(!isa<ParmVarDecl>(this));
1513 NonParmVarDeclBits.IsInline = true;
1514 }
1515
Richard Smith12f247f2012-06-08 21:09:22 +00001516 /// Whether this variable is (C++11) constexpr.
David Majnemerfa7bc782015-05-19 00:57:16 +00001517 bool isConstexpr() const {
1518 return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsConstexpr;
1519 }
1520 void setConstexpr(bool IC) {
1521 assert(!isa<ParmVarDecl>(this));
1522 NonParmVarDeclBits.IsConstexpr = IC;
1523 }
Richard Smitha77a0a62011-08-15 21:04:07 +00001524
Richard Smithbb13c9a2013-09-28 04:02:39 +00001525 /// Whether this variable is the implicit variable for a lambda init-capture.
David Majnemerfa7bc782015-05-19 00:57:16 +00001526 bool isInitCapture() const {
1527 return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsInitCapture;
1528 }
1529 void setInitCapture(bool IC) {
1530 assert(!isa<ParmVarDecl>(this));
1531 NonParmVarDeclBits.IsInitCapture = IC;
1532 }
Richard Smithbb13c9a2013-09-28 04:02:39 +00001533
Richard Smith1c34fb72013-08-13 18:18:50 +00001534 /// Whether this local extern variable declaration's previous declaration
1535 /// was declared in the same block scope. Only correct in C++.
1536 bool isPreviousDeclInSameBlockScope() const {
David Majnemerfa7bc782015-05-19 00:57:16 +00001537 return isa<ParmVarDecl>(this)
1538 ? false
1539 : NonParmVarDeclBits.PreviousDeclInSameBlockScope;
Richard Smith1c34fb72013-08-13 18:18:50 +00001540 }
1541 void setPreviousDeclInSameBlockScope(bool Same) {
David Majnemerfa7bc782015-05-19 00:57:16 +00001542 assert(!isa<ParmVarDecl>(this));
1543 NonParmVarDeclBits.PreviousDeclInSameBlockScope = Same;
Richard Smith1c34fb72013-08-13 18:18:50 +00001544 }
1545
Akira Hatanaka8e57b072018-10-01 21:51:28 +00001546 /// Indicates the capture is a __block variable that is captured by a block
1547 /// that can potentially escape (a block for which BlockDecl::doesNotEscape
1548 /// returns false).
1549 bool isEscapingByref() const;
1550
1551 /// Indicates the capture is a __block variable that is never captured by an
1552 /// escaping block.
1553 bool isNonEscapingByref() const;
1554
1555 void setEscapingByref() {
1556 NonParmVarDeclBits.EscapingByref = true;
1557 }
1558
Youngsuk Kim90453f42024-04-04 20:45:18 -04001559 bool isCXXCondDecl() const {
1560 return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsCXXCondDecl;
1561 }
1562
1563 void setCXXCondDecl() {
1564 assert(!isa<ParmVarDecl>(this));
1565 NonParmVarDeclBits.IsCXXCondDecl = true;
1566 }
1567
Matheus Izvekovf2d5fce2021-07-03 00:56:16 +02001568 /// Determines if this variable's alignment is dependent.
1569 bool hasDependentAlignment() const;
1570
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001571 /// Retrieve the variable declaration from which this variable could
Richard Smithedbc6e92016-10-14 21:41:24 +00001572 /// be instantiated, if it is an instantiation (rather than a non-template).
1573 VarDecl *getTemplateInstantiationPattern() const;
1574
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001575 /// If this variable is an instantiated static data member of a
Mike Stump11289f42009-09-09 15:08:12 +00001576 /// class template specialization, returns the templated static data member
Douglas Gregora6ef8f02009-07-24 20:34:43 +00001577 /// from which it was instantiated.
Douglas Gregor3cc3cde2009-10-14 21:29:40 +00001578 VarDecl *getInstantiatedFromStaticDataMember() const;
Mike Stump11289f42009-09-09 15:08:12 +00001579
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001580 /// If this variable is an instantiation of a variable template or a
Richard Smith8809a0c2013-09-27 20:14:12 +00001581 /// static data member of a class template, determine what kind of
Douglas Gregor86d142a2009-10-08 07:24:58 +00001582 /// template specialization or instantiation this is.
Douglas Gregor3c74d412009-10-14 20:14:33 +00001583 TemplateSpecializationKind getTemplateSpecializationKind() const;
David Blaikie21bfbf82011-11-09 06:07:30 +00001584
Richard Smitha6b41d72019-05-03 23:51:38 +00001585 /// Get the template specialization kind of this variable for the purposes of
1586 /// template instantiation. This differs from getTemplateSpecializationKind()
1587 /// for an instantiation of a class-scope explicit specialization.
1588 TemplateSpecializationKind
1589 getTemplateSpecializationKindForInstantiation() const;
1590
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001591 /// If this variable is an instantiation of a variable template or a
Richard Smith8809a0c2013-09-27 20:14:12 +00001592 /// static data member of a class template, determine its point of
1593 /// instantiation.
1594 SourceLocation getPointOfInstantiation() const;
1595
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001596 /// If this variable is an instantiation of a static data member of a
Douglas Gregor06db9f52009-10-12 20:18:28 +00001597 /// class template specialization, retrieves the member specialization
1598 /// information.
Douglas Gregor3cc3cde2009-10-14 21:29:40 +00001599 MemberSpecializationInfo *getMemberSpecializationInfo() const;
David Blaikie21bfbf82011-11-09 06:07:30 +00001600
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001601 /// For a static data member that was instantiated from a static
Douglas Gregor86d142a2009-10-08 07:24:58 +00001602 /// data member of a class template, set the template specialiation kind.
Douglas Gregor3d7e69f2009-10-15 17:21:20 +00001603 void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
1604 SourceLocation PointOfInstantiation = SourceLocation());
Douglas Gregor5a80bd12009-03-02 00:19:53 +00001605
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001606 /// Specify that this variable is an instantiation of the
Larisse Voufo39a1e502013-08-06 01:03:05 +00001607 /// static data member VD.
1608 void setInstantiationOfStaticDataMember(VarDecl *VD,
1609 TemplateSpecializationKind TSK);
1610
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001611 /// Retrieves the variable template that is described by this
Larisse Voufo39a1e502013-08-06 01:03:05 +00001612 /// variable declaration.
1613 ///
1614 /// Every variable template is represented as a VarTemplateDecl and a
1615 /// VarDecl. The former contains template properties (such as
1616 /// the template parameter lists) while the latter contains the
1617 /// actual description of the template's
1618 /// contents. VarTemplateDecl::getTemplatedDecl() retrieves the
1619 /// VarDecl that from a VarTemplateDecl, while
1620 /// getDescribedVarTemplate() retrieves the VarTemplateDecl from
1621 /// a VarDecl.
1622 VarTemplateDecl *getDescribedVarTemplate() const;
1623
1624 void setDescribedVarTemplate(VarTemplateDecl *Template);
1625
Justin Lebar5489f852018-05-17 16:15:07 +00001626 // Is this variable known to have a definition somewhere in the complete
1627 // program? This may be true even if the declaration has internal linkage and
1628 // has no definition within this source file.
1629 bool isKnownToBeDefined() const;
1630
Richard Smith2b4fa532019-09-29 05:08:46 +00001631 /// Is destruction of this variable entirely suppressed? If so, the variable
1632 /// need not have a usable destructor at all.
Erik Pilkington5a559e62018-08-21 17:24:06 +00001633 bool isNoDestroy(const ASTContext &) const;
1634
Richard Smith1b8c84b2020-01-10 15:47:29 -08001635 /// Would the destruction of this variable have any effect, and if so, what
1636 /// kind?
Richard Smith2b4fa532019-09-29 05:08:46 +00001637 QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const;
1638
Eli Friedman4802edd2022-04-14 15:20:37 -07001639 /// Whether this variable has a flexible array member initialized with one
1640 /// or more elements. This can only be called for declarations where
1641 /// hasInit() is true.
Eli Friedman5955a0f2022-04-14 11:56:40 -07001642 ///
1643 /// (The standard doesn't allow initializing flexible array members; this is
1644 /// a gcc/msvc extension.)
Eli Friedman4802edd2022-04-14 15:20:37 -07001645 bool hasFlexibleArrayInit(const ASTContext &Ctx) const;
1646
1647 /// If hasFlexibleArrayInit is true, compute the number of additional bytes
1648 /// necessary to store those elements. Otherwise, returns zero.
1649 ///
1650 /// This can only be called for declarations where hasInit() is true.
Eli Friedman5955a0f2022-04-14 11:56:40 -07001651 CharUnits getFlexibleArrayInitChars(const ASTContext &Ctx) const;
1652
Steve Naroffef2ab6a2007-04-02 20:50:54 +00001653 // Implement isa/cast/dyncast/etc.
John McCall180ef092010-01-29 01:45:37 +00001654 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
Alexis Hunted053252010-05-30 07:21:58 +00001655 static bool classofKind(Kind K) { return K >= firstVar && K <= lastVar; }
Steve Naroffef2ab6a2007-04-02 20:50:54 +00001656};
1657
Vlad Serebrennikovdda8e3d2023-11-06 12:00:40 +03001658/// Defines the kind of the implicit parameter: is this an implicit parameter
1659/// with pointer to 'this', 'self', '_cmd', virtual table pointers, captured
1660/// context or something else.
1661enum class ImplicitParamKind {
1662 /// Parameter for Objective-C 'self' argument
1663 ObjCSelf,
1664
1665 /// Parameter for Objective-C '_cmd' argument
1666 ObjCCmd,
1667
1668 /// Parameter for C++ 'this' argument
1669 CXXThis,
1670
1671 /// Parameter for C++ virtual table pointers
1672 CXXVTT,
1673
1674 /// Parameter for captured context
1675 CapturedContext,
1676
1677 /// Parameter for Thread private variable
1678 ThreadPrivateVar,
1679
1680 /// Other implicit parameter
1681 Other,
1682};
1683
Chris Lattner5696e7b2008-06-17 18:05:57 +00001684class ImplicitParamDecl : public VarDecl {
Craig Toppercbce6e92014-03-11 06:22:39 +00001685 void anchor() override;
Alexey Bataev56223232017-06-09 13:40:18 +00001686
Chris Lattner5696e7b2008-06-17 18:05:57 +00001687public:
Alexey Bataev56223232017-06-09 13:40:18 +00001688 /// Create implicit parameter.
Chris Lattner5696e7b2008-06-17 18:05:57 +00001689 static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +00001690 SourceLocation IdLoc, IdentifierInfo *Id,
Alexey Bataev56223232017-06-09 13:40:18 +00001691 QualType T, ImplicitParamKind ParamKind);
1692 static ImplicitParamDecl *Create(ASTContext &C, QualType T,
1693 ImplicitParamKind ParamKind);
John McCall550d13a2011-02-22 22:25:56 +00001694
Chuanqi Xud86cc732024-04-25 11:43:13 +08001695 static ImplicitParamDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
Richard Smith053f6c62014-05-16 23:01:30 +00001696
1697 ImplicitParamDecl(ASTContext &C, DeclContext *DC, SourceLocation IdLoc,
Bill Wendlingfca51912024-04-11 00:33:40 +00001698 const IdentifierInfo *Id, QualType Type,
Alexey Bataev56223232017-06-09 13:40:18 +00001699 ImplicitParamKind ParamKind)
1700 : VarDecl(ImplicitParam, C, DC, IdLoc, IdLoc, Id, Type,
Thorsten Schütt2fd11e02021-01-04 23:17:45 +01001701 /*TInfo=*/nullptr, SC_None) {
Vlad Serebrennikovdda8e3d2023-11-06 12:00:40 +03001702 NonParmVarDeclBits.ImplicitParamKind = llvm::to_underlying(ParamKind);
John McCall550d13a2011-02-22 22:25:56 +00001703 setImplicit();
1704 }
1705
Alexey Bataev56223232017-06-09 13:40:18 +00001706 ImplicitParamDecl(ASTContext &C, QualType Type, ImplicitParamKind ParamKind)
1707 : VarDecl(ImplicitParam, C, /*DC=*/nullptr, SourceLocation(),
1708 SourceLocation(), /*Id=*/nullptr, Type,
Thorsten Schütt2fd11e02021-01-04 23:17:45 +01001709 /*TInfo=*/nullptr, SC_None) {
Vlad Serebrennikovdda8e3d2023-11-06 12:00:40 +03001710 NonParmVarDeclBits.ImplicitParamKind = llvm::to_underlying(ParamKind);
Alexey Bataev56223232017-06-09 13:40:18 +00001711 setImplicit();
1712 }
1713
1714 /// Returns the implicit parameter kind.
1715 ImplicitParamKind getParameterKind() const {
1716 return static_cast<ImplicitParamKind>(NonParmVarDeclBits.ImplicitParamKind);
1717 }
Eugene Zelenkode0215c2017-11-13 23:01:27 +00001718
Chris Lattner5696e7b2008-06-17 18:05:57 +00001719 // Implement isa/cast/dyncast/etc.
John McCall180ef092010-01-29 01:45:37 +00001720 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1721 static bool classofKind(Kind K) { return K == ImplicitParam; }
Chris Lattner5696e7b2008-06-17 18:05:57 +00001722};
1723
James Dennettb8973efb2018-02-02 20:22:29 +00001724/// Represents a parameter to a function.
Steve Naroffef2ab6a2007-04-02 20:50:54 +00001725class ParmVarDecl : public VarDecl {
John McCall82490832011-05-02 00:30:12 +00001726public:
1727 enum { MaxFunctionScopeDepth = 255 };
1728 enum { MaxFunctionScopeIndex = 255 };
John McCall8fb0d9d2011-05-01 22:35:37 +00001729
Fariborz Jahanian7664ffb2008-12-20 20:56:12 +00001730protected:
Richard Smith053f6c62014-05-16 23:01:30 +00001731 ParmVarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
Bill Wendlingfca51912024-04-11 00:33:40 +00001732 SourceLocation IdLoc, const IdentifierInfo *Id, QualType T,
Richard Smith053f6c62014-05-16 23:01:30 +00001733 TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
1734 : VarDecl(DK, C, DC, StartLoc, IdLoc, Id, T, TInfo, S) {
John McCallbeaa11c2011-05-01 02:13:58 +00001735 assert(ParmVarDeclBits.HasInheritedDefaultArg == false);
Chandler Carruth813faed2015-12-30 02:51:00 +00001736 assert(ParmVarDeclBits.DefaultArgKind == DAK_None);
John McCallbeaa11c2011-05-01 02:13:58 +00001737 assert(ParmVarDeclBits.IsKNRPromoted == false);
John McCall82490832011-05-02 00:30:12 +00001738 assert(ParmVarDeclBits.IsObjCMethodParam == false);
Douglas Gregord12df6b2009-07-20 22:03:28 +00001739 setDefaultArg(DefArg);
1740 }
Chris Lattneraa9c7ae2008-04-08 04:40:51 +00001741
Chris Lattner4b08ca82008-03-15 21:10:16 +00001742public:
Chris Lattnerbec41342008-04-22 18:39:57 +00001743 static ParmVarDecl *Create(ASTContext &C, DeclContext *DC,
Bill Wendlingfca51912024-04-11 00:33:40 +00001744 SourceLocation StartLoc, SourceLocation IdLoc,
1745 const IdentifierInfo *Id, QualType T,
1746 TypeSourceInfo *TInfo, StorageClass S,
1747 Expr *DefArg);
Mike Stump11289f42009-09-09 15:08:12 +00001748
Chuanqi Xud86cc732024-04-25 11:43:13 +08001749 static ParmVarDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
Craig Toppercbce6e92014-03-11 06:22:39 +00001750
1751 SourceRange getSourceRange() const override LLVM_READONLY;
David Blaikie21bfbf82011-11-09 06:07:30 +00001752
John McCall82490832011-05-02 00:30:12 +00001753 void setObjCMethodScopeInfo(unsigned parameterIndex) {
1754 ParmVarDeclBits.IsObjCMethodParam = true;
Ted Kremenek9504ae92011-10-06 04:19:35 +00001755 setParameterIndex(parameterIndex);
John McCall82490832011-05-02 00:30:12 +00001756 }
1757
1758 void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex) {
1759 assert(!ParmVarDeclBits.IsObjCMethodParam);
1760
1761 ParmVarDeclBits.ScopeDepthOrObjCQuals = scopeDepth;
David Blaikie21bfbf82011-11-09 06:07:30 +00001762 assert(ParmVarDeclBits.ScopeDepthOrObjCQuals == scopeDepth
1763 && "truncation!");
John McCall82490832011-05-02 00:30:12 +00001764
Ted Kremenek9504ae92011-10-06 04:19:35 +00001765 setParameterIndex(parameterIndex);
John McCall82490832011-05-02 00:30:12 +00001766 }
1767
1768 bool isObjCMethodParameter() const {
1769 return ParmVarDeclBits.IsObjCMethodParam;
John McCall8fb0d9d2011-05-01 22:35:37 +00001770 }
1771
Akira Hatanaka34405b42020-12-28 11:52:27 -08001772 /// Determines whether this parameter is destroyed in the callee function.
1773 bool isDestroyedInCallee() const;
1774
John McCall8fb0d9d2011-05-01 22:35:37 +00001775 unsigned getFunctionScopeDepth() const {
John McCall82490832011-05-02 00:30:12 +00001776 if (ParmVarDeclBits.IsObjCMethodParam) return 0;
1777 return ParmVarDeclBits.ScopeDepthOrObjCQuals;
John McCall8fb0d9d2011-05-01 22:35:37 +00001778 }
1779
Mark de Weverb9be5ce2019-11-09 15:32:35 +01001780 static constexpr unsigned getMaxFunctionScopeDepth() {
Martin Storsjöf20fc652019-12-18 10:41:41 +02001781 return (1u << NumScopeDepthOrObjCQualsBits) - 1;
Mark de Weverb9be5ce2019-11-09 15:32:35 +01001782 }
1783
John McCall82490832011-05-02 00:30:12 +00001784 /// Returns the index of this parameter in its prototype or method scope.
John McCall8fb0d9d2011-05-01 22:35:37 +00001785 unsigned getFunctionScopeIndex() const {
Ted Kremenek540017e2011-10-06 05:00:56 +00001786 return getParameterIndex();
John McCall8fb0d9d2011-05-01 22:35:37 +00001787 }
1788
Ted Kremenek72be0682008-02-24 03:55:14 +00001789 ObjCDeclQualifier getObjCDeclQualifier() const {
John McCall82490832011-05-02 00:30:12 +00001790 if (!ParmVarDeclBits.IsObjCMethodParam) return OBJC_TQ_None;
1791 return ObjCDeclQualifier(ParmVarDeclBits.ScopeDepthOrObjCQuals);
Ted Kremenek72be0682008-02-24 03:55:14 +00001792 }
Chris Lattner3d722972008-12-17 07:32:46 +00001793 void setObjCDeclQualifier(ObjCDeclQualifier QTVal) {
John McCall82490832011-05-02 00:30:12 +00001794 assert(ParmVarDeclBits.IsObjCMethodParam);
1795 ParmVarDeclBits.ScopeDepthOrObjCQuals = QTVal;
Chris Lattner3d722972008-12-17 07:32:46 +00001796 }
Mike Stump11289f42009-09-09 15:08:12 +00001797
John McCall6a014d52011-03-09 04:22:44 +00001798 /// True if the value passed to this parameter must undergo
1799 /// K&R-style default argument promotion:
1800 ///
1801 /// C99 6.5.2.2.
1802 /// If the expression that denotes the called function has a type
1803 /// that does not include a prototype, the integer promotions are
1804 /// performed on each argument, and arguments that have type float
1805 /// are promoted to double.
John McCallbeaa11c2011-05-01 02:13:58 +00001806 bool isKNRPromoted() const {
1807 return ParmVarDeclBits.IsKNRPromoted;
1808 }
1809 void setKNRPromoted(bool promoted) {
1810 ParmVarDeclBits.IsKNRPromoted = promoted;
1811 }
John McCall6a014d52011-03-09 04:22:44 +00001812
Corentin Jabotaf475172022-01-27 13:55:08 +01001813 bool isExplicitObjectParameter() const {
1814 return ExplicitObjectParameterIntroducerLoc.isValid();
1815 }
1816
1817 void setExplicitObjectParameterLoc(SourceLocation Loc) {
1818 ExplicitObjectParameterIntroducerLoc = Loc;
1819 }
1820
1821 SourceLocation getExplicitObjectParamThisLoc() const {
1822 return ExplicitObjectParameterIntroducerLoc;
1823 }
1824
Anders Carlsson714d0962009-12-15 19:16:31 +00001825 Expr *getDefaultArg();
Mike Stump11289f42009-09-09 15:08:12 +00001826 const Expr *getDefaultArg() const {
Anders Carlsson714d0962009-12-15 19:16:31 +00001827 return const_cast<ParmVarDecl *>(this)->getDefaultArg();
Anders Carlsson85446472009-06-06 04:14:07 +00001828 }
David Blaikie21bfbf82011-11-09 06:07:30 +00001829
Chandler Carruth813faed2015-12-30 02:51:00 +00001830 void setDefaultArg(Expr *defarg);
Chris Lattneraa9c7ae2008-04-08 04:40:51 +00001831
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001832 /// Retrieve the source range that covers the entire default
Douglas Gregorc732aba2009-09-11 18:44:32 +00001833 /// argument.
David Blaikie21bfbf82011-11-09 06:07:30 +00001834 SourceRange getDefaultArgRange() const;
Chandler Carruth813faed2015-12-30 02:51:00 +00001835 void setUninstantiatedDefaultArg(Expr *arg);
1836 Expr *getUninstantiatedDefaultArg();
Douglas Gregorc732aba2009-09-11 18:44:32 +00001837 const Expr *getUninstantiatedDefaultArg() const {
Chandler Carruth813faed2015-12-30 02:51:00 +00001838 return const_cast<ParmVarDecl *>(this)->getUninstantiatedDefaultArg();
Douglas Gregorc732aba2009-09-11 18:44:32 +00001839 }
Mike Stump11289f42009-09-09 15:08:12 +00001840
James Dennettb8973efb2018-02-02 20:22:29 +00001841 /// Determines whether this parameter has a default argument,
Anders Carlsson85446472009-06-06 04:14:07 +00001842 /// either parsed or not.
Chandler Carruth813faed2015-12-30 02:51:00 +00001843 bool hasDefaultArg() const;
Mike Stump11289f42009-09-09 15:08:12 +00001844
James Dennettb8973efb2018-02-02 20:22:29 +00001845 /// Determines whether this parameter has a default argument that has not
1846 /// yet been parsed. This will occur during the processing of a C++ class
1847 /// whose member functions have default arguments, e.g.,
Douglas Gregor58354032008-12-24 00:01:03 +00001848 /// @code
1849 /// class X {
1850 /// public:
1851 /// void f(int x = 17); // x has an unparsed default argument now
1852 /// }; // x has a regular default argument now
1853 /// @endcode
1854 bool hasUnparsedDefaultArg() const {
Chandler Carruth813faed2015-12-30 02:51:00 +00001855 return ParmVarDeclBits.DefaultArgKind == DAK_Unparsed;
Douglas Gregor58354032008-12-24 00:01:03 +00001856 }
1857
Anders Carlssona5224ec2009-08-25 01:11:14 +00001858 bool hasUninstantiatedDefaultArg() const {
Chandler Carruth813faed2015-12-30 02:51:00 +00001859 return ParmVarDeclBits.DefaultArgKind == DAK_Uninstantiated;
Anders Carlssona5224ec2009-08-25 01:11:14 +00001860 }
Mike Stump11289f42009-09-09 15:08:12 +00001861
James Dennettb8973efb2018-02-02 20:22:29 +00001862 /// Specify that this parameter has an unparsed default argument.
1863 /// The argument will be replaced with a real default argument via
1864 /// setDefaultArg when the class definition enclosing the function
1865 /// declaration that owns this default argument is completed.
Chandler Carruth813faed2015-12-30 02:51:00 +00001866 void setUnparsedDefaultArg() {
1867 ParmVarDeclBits.DefaultArgKind = DAK_Unparsed;
1868 }
Douglas Gregor58354032008-12-24 00:01:03 +00001869
John McCallf3cd6652010-03-12 18:31:32 +00001870 bool hasInheritedDefaultArg() const {
John McCallbeaa11c2011-05-01 02:13:58 +00001871 return ParmVarDeclBits.HasInheritedDefaultArg;
John McCallf3cd6652010-03-12 18:31:32 +00001872 }
1873
1874 void setHasInheritedDefaultArg(bool I = true) {
John McCallbeaa11c2011-05-01 02:13:58 +00001875 ParmVarDeclBits.HasInheritedDefaultArg = I;
John McCallf3cd6652010-03-12 18:31:32 +00001876 }
1877
Reid Kleckner8a365022013-06-24 17:51:48 +00001878 QualType getOriginalType() const;
Mike Stump11289f42009-09-09 15:08:12 +00001879
James Dennettb8973efb2018-02-02 20:22:29 +00001880 /// Sets the function declaration that owns this
Douglas Gregorc72e6452009-01-09 18:51:29 +00001881 /// ParmVarDecl. Since ParmVarDecls are often created before the
1882 /// FunctionDecls that own them, this routine is required to update
1883 /// the DeclContext appropriately.
1884 void setOwningFunction(DeclContext *FD) { setDeclContext(FD); }
1885
Steve Naroffef2ab6a2007-04-02 20:50:54 +00001886 // Implement isa/cast/dyncast/etc.
John McCall180ef092010-01-29 01:45:37 +00001887 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
John McCall180ef092010-01-29 01:45:37 +00001888 static bool classofKind(Kind K) { return K == ParmVar; }
David Blaikie21bfbf82011-11-09 06:07:30 +00001889
Ted Kremenek9504ae92011-10-06 04:19:35 +00001890private:
Corentin Jabotaf475172022-01-27 13:55:08 +01001891 friend class ASTDeclReader;
1892
Ted Kremenek540017e2011-10-06 05:00:56 +00001893 enum { ParameterIndexSentinel = (1 << NumParameterIndexBits) - 1 };
Corentin Jabotaf475172022-01-27 13:55:08 +01001894 SourceLocation ExplicitObjectParameterIntroducerLoc;
Ted Kremenek540017e2011-10-06 05:00:56 +00001895
Ted Kremenek9504ae92011-10-06 04:19:35 +00001896 void setParameterIndex(unsigned parameterIndex) {
Ted Kremenek540017e2011-10-06 05:00:56 +00001897 if (parameterIndex >= ParameterIndexSentinel) {
1898 setParameterIndexLarge(parameterIndex);
1899 return;
1900 }
David Blaikie21bfbf82011-11-09 06:07:30 +00001901
Ted Kremenek9504ae92011-10-06 04:19:35 +00001902 ParmVarDeclBits.ParameterIndex = parameterIndex;
1903 assert(ParmVarDeclBits.ParameterIndex == parameterIndex && "truncation!");
1904 }
Ted Kremenek540017e2011-10-06 05:00:56 +00001905 unsigned getParameterIndex() const {
1906 unsigned d = ParmVarDeclBits.ParameterIndex;
1907 return d == ParameterIndexSentinel ? getParameterIndexLarge() : d;
1908 }
David Blaikie21bfbf82011-11-09 06:07:30 +00001909
Ted Kremenek540017e2011-10-06 05:00:56 +00001910 void setParameterIndexLarge(unsigned parameterIndex);
1911 unsigned getParameterIndexLarge() const;
Chris Lattner17ed4872006-11-20 04:58:19 +00001912};
1913
Erich Keane5c0d1922018-11-28 18:34:14 +00001914enum class MultiVersionKind {
1915 None,
1916 Target,
1917 CPUSpecific,
Erich Keanefc53eb62021-11-29 06:28:02 -08001918 CPUDispatch,
Pavel Iliinfe5cf482022-12-21 11:29:53 +00001919 TargetClones,
1920 TargetVersion
Erich Keane5c0d1922018-11-28 18:34:14 +00001921};
1922
James Dennettb8973efb2018-02-02 20:22:29 +00001923/// Represents a function declaration or definition.
Douglas Gregor89f238c2008-04-21 02:02:58 +00001924///
1925/// Since a given function can be declared several times in a program,
1926/// there may be several FunctionDecls that correspond to that
1927/// function. Only one of those FunctionDecls will be found when
1928/// traversing the list of declarations in the context of the
1929/// FunctionDecl (e.g., the translation unit); this FunctionDecl
1930/// contains all of the information known about the function. Other,
1931/// previous declarations of the function are available via the
Douglas Gregorec9fd132012-01-14 16:38:05 +00001932/// getPreviousDecl() chain.
Erich Keane9c665062018-08-01 21:02:40 +00001933class FunctionDecl : public DeclaratorDecl,
1934 public DeclContext,
Argyrios Kyrtzidisfad334c2009-07-18 08:50:13 +00001935 public Redeclarable<FunctionDecl> {
Erich Keane9c665062018-08-01 21:02:40 +00001936 // This class stores some data in DeclContext::FunctionDeclBits
1937 // to save some space. Use the provided accessors to access it.
Chris Lattnera11999d2006-10-15 22:34:45 +00001938public:
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001939 /// The kind of templated function a FunctionDecl can be.
Argyrios Kyrtzidiscb6f3462010-06-22 09:54:51 +00001940 enum TemplatedKind {
Richard Smithf19a8b02019-05-02 00:49:14 +00001941 // Not templated.
Argyrios Kyrtzidiscb6f3462010-06-22 09:54:51 +00001942 TK_NonTemplate,
Richard Smithf19a8b02019-05-02 00:49:14 +00001943 // The pattern in a function template declaration.
Argyrios Kyrtzidiscb6f3462010-06-22 09:54:51 +00001944 TK_FunctionTemplate,
Richard Smithf19a8b02019-05-02 00:49:14 +00001945 // A non-template function that is an instantiation or explicit
1946 // specialization of a member of a templated class.
Argyrios Kyrtzidiscb6f3462010-06-22 09:54:51 +00001947 TK_MemberSpecialization,
Richard Smithf19a8b02019-05-02 00:49:14 +00001948 // An instantiation or explicit specialization of a function template.
1949 // Note: this might have been instantiated from a templated class if it
1950 // is a class-scope explicit specialization.
Argyrios Kyrtzidiscb6f3462010-06-22 09:54:51 +00001951 TK_FunctionTemplateSpecialization,
Richard Smithf19a8b02019-05-02 00:49:14 +00001952 // A function template specialization that hasn't yet been resolved to a
1953 // particular specialized function template.
Erich Keane3ff86f92022-07-22 12:30:47 -07001954 TK_DependentFunctionTemplateSpecialization,
1955 // A non-template function which is in a dependent scope.
1956 TK_DependentNonTemplate
1957
Argyrios Kyrtzidiscb6f3462010-06-22 09:54:51 +00001958 };
1959
Sirraideef164ce2024-04-14 12:30:01 +02001960 /// Stashed information about a defaulted/deleted function body.
1961 class DefaultedOrDeletedFunctionInfo final
1962 : llvm::TrailingObjects<DefaultedOrDeletedFunctionInfo, DeclAccessPair,
1963 StringLiteral *> {
Richard Smith848934c2019-12-05 13:37:35 -08001964 friend TrailingObjects;
1965 unsigned NumLookups;
Sirraideef164ce2024-04-14 12:30:01 +02001966 bool HasDeletedMessage;
1967
1968 size_t numTrailingObjects(OverloadToken<DeclAccessPair>) const {
1969 return NumLookups;
1970 }
Richard Smith848934c2019-12-05 13:37:35 -08001971
1972 public:
Sirraideef164ce2024-04-14 12:30:01 +02001973 static DefaultedOrDeletedFunctionInfo *
1974 Create(ASTContext &Context, ArrayRef<DeclAccessPair> Lookups,
1975 StringLiteral *DeletedMessage = nullptr);
1976
Richard Smith848934c2019-12-05 13:37:35 -08001977 /// Get the unqualified lookup results that should be used in this
1978 /// defaulted function definition.
1979 ArrayRef<DeclAccessPair> getUnqualifiedLookups() const {
1980 return {getTrailingObjects<DeclAccessPair>(), NumLookups};
1981 }
Sirraideef164ce2024-04-14 12:30:01 +02001982
1983 StringLiteral *getDeletedMessage() const {
1984 return HasDeletedMessage ? *getTrailingObjects<StringLiteral *>()
1985 : nullptr;
1986 }
1987
1988 void setDeletedMessage(StringLiteral *Message);
Richard Smith848934c2019-12-05 13:37:35 -08001989 };
1990
Mike Stump11289f42009-09-09 15:08:12 +00001991private:
James Dennettb8973efb2018-02-02 20:22:29 +00001992 /// A new[]'d array of pointers to VarDecls for the formal
Chris Lattneree1284a2008-03-16 00:16:02 +00001993 /// parameters of this function. This is null if a prototype or if there are
Douglas Gregor4adbc6d2009-06-26 00:10:03 +00001994 /// no formals.
Eugene Zelenkode0215c2017-11-13 23:01:27 +00001995 ParmVarDecl **ParamInfo = nullptr;
Mike Stump11289f42009-09-09 15:08:12 +00001996
Richard Smith848934c2019-12-05 13:37:35 -08001997 /// The active member of this union is determined by
Sirraideef164ce2024-04-14 12:30:01 +02001998 /// FunctionDeclBits.HasDefaultedOrDeletedInfo.
Richard Smith848934c2019-12-05 13:37:35 -08001999 union {
2000 /// The body of the function.
2001 LazyDeclStmtPtr Body;
2002 /// Information about a future defaulted function definition.
Sirraideef164ce2024-04-14 12:30:01 +02002003 DefaultedOrDeletedFunctionInfo *DefaultedOrDeletedInfo;
Richard Smith848934c2019-12-05 13:37:35 -08002004 };
Douglas Gregor89f238c2008-04-21 02:02:58 +00002005
Richard Trieue6caa262017-12-23 00:41:01 +00002006 unsigned ODRHash;
2007
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002008 /// End part of this FunctionDecl's source range.
Argyrios Kyrtzidis49abd4d2009-06-22 17:13:31 +00002009 ///
2010 /// We could compute the full range in getSourceRange(). However, when we're
2011 /// dealing with a function definition deserialized from a PCH/AST file,
2012 /// we can only compute the full range once the function body has been
2013 /// de-serialized, so it's far better to have the (sometimes-redundant)
2014 /// EndRangeLoc.
Argyrios Kyrtzidisa3aeb5a2009-06-20 08:09:14 +00002015 SourceLocation EndRangeLoc;
Douglas Gregor24c332b2009-05-14 21:06:31 +00002016
Nathan James1376c732022-10-04 19:38:09 +01002017 SourceLocation DefaultKWLoc;
2018
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002019 /// The template or declaration that this declaration
Douglas Gregor24c332b2009-05-14 21:06:31 +00002020 /// describes or was instantiated from, respectively.
Mike Stump11289f42009-09-09 15:08:12 +00002021 ///
Erich Keane3ff86f92022-07-22 12:30:47 -07002022 /// For non-templates this value will be NULL, unless this declaration was
2023 /// declared directly inside of a function template, in which case it will
2024 /// have a pointer to a FunctionDecl, stored in the NamedDecl. For function
2025 /// declarations that describe a function template, this will be a pointer to
2026 /// a FunctionTemplateDecl, stored in the NamedDecl. For member functions of
2027 /// class template specializations, this will be a MemberSpecializationInfo
Erich Keane258c3ae2022-07-01 11:20:16 -07002028 /// pointer containing information about the specialization.
2029 /// For function template specializations, this will be a
2030 /// FunctionTemplateSpecializationInfo, which contains information about
2031 /// the template being specialized and the template arguments involved in
2032 /// that specialization.
Erich Keane3ff86f92022-07-22 12:30:47 -07002033 llvm::PointerUnion<NamedDecl *, MemberSpecializationInfo *,
Dmitri Gribenko2948ec5c2020-01-14 15:46:13 +01002034 FunctionTemplateSpecializationInfo *,
2035 DependentFunctionTemplateSpecializationInfo *>
Erich Keane3ff86f92022-07-22 12:30:47 -07002036 TemplateOrSpecialization;
Douglas Gregor24c332b2009-05-14 21:06:31 +00002037
Erich Keane7670b4b2017-12-15 16:37:14 +00002038 /// Provides source/type location info for the declaration name embedded in
2039 /// the DeclaratorDecl base class.
Abramo Bagnarad6d2f182010-08-11 22:01:17 +00002040 DeclarationNameLoc DNLoc;
2041
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002042 /// Specify that this function declaration is actually a function
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +00002043 /// template specialization.
2044 ///
2045 /// \param C the ASTContext.
2046 ///
2047 /// \param Template the function template that this function template
2048 /// specialization specializes.
2049 ///
2050 /// \param TemplateArgs the template arguments that produced this
2051 /// function template specialization from the template.
2052 ///
2053 /// \param InsertPos If non-NULL, the position in the function template
2054 /// specialization set where the function template specialization data will
2055 /// be inserted.
2056 ///
2057 /// \param TSK the kind of template specialization this is.
2058 ///
2059 /// \param TemplateArgsAsWritten location info of template arguments.
2060 ///
2061 /// \param PointOfInstantiation point at which the function template
David Blaikie21bfbf82011-11-09 06:07:30 +00002062 /// specialization was first instantiated.
Vlad Serebrennikov6677aef2024-05-17 17:49:50 +04002063 void setFunctionTemplateSpecialization(
2064 ASTContext &C, FunctionTemplateDecl *Template,
2065 TemplateArgumentList *TemplateArgs, void *InsertPos,
2066 TemplateSpecializationKind TSK,
2067 const TemplateArgumentListInfo *TemplateArgsAsWritten,
2068 SourceLocation PointOfInstantiation);
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +00002069
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002070 /// Specify that this record is an instantiation of the
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +00002071 /// member function FD.
2072 void setInstantiationOfMemberFunction(ASTContext &C, FunctionDecl *FD,
2073 TemplateSpecializationKind TSK);
2074
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002075 void setParams(ASTContext &C, ArrayRef<ParmVarDecl *> NewParamInfo);
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +00002076
Erich Keane9c665062018-08-01 21:02:40 +00002077 // This is unfortunately needed because ASTDeclWriter::VisitFunctionDecl
2078 // need to access this bit but we want to avoid making ASTDeclWriter
2079 // a friend of FunctionDeclBitfields just for this.
2080 bool isDeletedBit() const { return FunctionDeclBits.IsDeleted; }
2081
2082 /// Whether an ODRHash has been stored.
2083 bool hasODRHash() const { return FunctionDeclBits.HasODRHash; }
2084
2085 /// State that an ODRHash has been stored.
2086 void setHasODRHash(bool B = true) { FunctionDeclBits.HasODRHash = B; }
2087
Argyrios Kyrtzidis2951e142008-06-09 21:05:31 +00002088protected:
Richard Smith053f6c62014-05-16 23:01:30 +00002089 FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
Justin Lebar2b42ccc2016-10-28 16:26:26 +00002090 const DeclarationNameInfo &NameInfo, QualType T,
Melanie Blowerbc5b5ea2021-07-29 12:02:20 -04002091 TypeSourceInfo *TInfo, StorageClass S, bool UsesFPIntrin,
2092 bool isInlineSpecified, ConstexprSpecKind ConstexprKind,
Saar Razb65b1f32020-01-09 15:07:51 +02002093 Expr *TrailingRequiresClause = nullptr);
Douglas Gregor89f238c2008-04-21 02:02:58 +00002094
Eugene Zelenkode0215c2017-11-13 23:01:27 +00002095 using redeclarable_base = Redeclarable<FunctionDecl>;
2096
Richard Smithd7af8a32014-05-10 01:17:36 +00002097 FunctionDecl *getNextRedeclarationImpl() override {
2098 return getNextRedeclaration();
2099 }
Eugene Zelenkode0215c2017-11-13 23:01:27 +00002100
Craig Toppercbce6e92014-03-11 06:22:39 +00002101 FunctionDecl *getPreviousDeclImpl() override {
Douglas Gregorec9fd132012-01-14 16:38:05 +00002102 return getPreviousDecl();
2103 }
Eugene Zelenkode0215c2017-11-13 23:01:27 +00002104
Craig Toppercbce6e92014-03-11 06:22:39 +00002105 FunctionDecl *getMostRecentDeclImpl() override {
Douglas Gregorec9fd132012-01-14 16:38:05 +00002106 return getMostRecentDecl();
2107 }
Argyrios Kyrtzidis05898da2009-07-18 08:50:35 +00002108
Chris Lattner5072bae2008-03-15 21:24:04 +00002109public:
Eugene Zelenkode0215c2017-11-13 23:01:27 +00002110 friend class ASTDeclReader;
2111 friend class ASTDeclWriter;
2112
2113 using redecl_range = redeclarable_base::redecl_range;
2114 using redecl_iterator = redeclarable_base::redecl_iterator;
2115
Aaron Ballman211cd8c2014-03-07 00:10:58 +00002116 using redeclarable_base::redecls_begin;
2117 using redeclarable_base::redecls_end;
Aaron Ballman86c93902014-03-06 23:45:36 +00002118 using redeclarable_base::redecls;
Douglas Gregorec9fd132012-01-14 16:38:05 +00002119 using redeclarable_base::getPreviousDecl;
2120 using redeclarable_base::getMostRecentDecl;
Rafael Espindola3f9e4442013-10-19 02:13:21 +00002121 using redeclarable_base::isFirstDecl;
Douglas Gregor0bc8a212012-01-14 15:55:47 +00002122
Gauthier Harnisch796ed032019-06-14 08:56:20 +00002123 static FunctionDecl *
2124 Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
2125 SourceLocation NLoc, DeclarationName N, QualType T,
Melanie Blowerbc5b5ea2021-07-29 12:02:20 -04002126 TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin = false,
2127 bool isInlineSpecified = false, bool hasWrittenPrototype = true,
Thorsten41b65f12020-11-16 14:08:33 -05002128 ConstexprSpecKind ConstexprKind = ConstexprSpecKind::Unspecified,
Saar Razb65b1f32020-01-09 15:07:51 +02002129 Expr *TrailingRequiresClause = nullptr) {
Abramo Bagnaradff19302011-03-08 08:55:46 +00002130 DeclarationNameInfo NameInfo(N, NLoc);
Gauthier Harnisch796ed032019-06-14 08:56:20 +00002131 return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo, SC,
Melanie Blowerbc5b5ea2021-07-29 12:02:20 -04002132 UsesFPIntrin, isInlineSpecified,
2133 hasWrittenPrototype, ConstexprKind,
2134 TrailingRequiresClause);
Abramo Bagnarad6d2f182010-08-11 22:01:17 +00002135 }
2136
Melanie Blowerbc5b5ea2021-07-29 12:02:20 -04002137 static FunctionDecl *
2138 Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
2139 const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
2140 StorageClass SC, bool UsesFPIntrin, bool isInlineSpecified,
2141 bool hasWrittenPrototype, ConstexprSpecKind ConstexprKind,
2142 Expr *TrailingRequiresClause);
Argyrios Kyrtzidisa3aeb5a2009-06-20 08:09:14 +00002143
Chuanqi Xud86cc732024-04-25 11:43:13 +08002144 static FunctionDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
Fangrui Song6907ce22018-07-30 19:24:48 +00002145
Abramo Bagnarad6d2f182010-08-11 22:01:17 +00002146 DeclarationNameInfo getNameInfo() const {
2147 return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
2148 }
2149
Craig Toppercbce6e92014-03-11 06:22:39 +00002150 void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
2151 bool Qualified) const override;
Douglas Gregorb11aad82011-02-19 18:51:44 +00002152
Abramo Bagnaraea947882011-03-08 16:41:52 +00002153 void setRangeEnd(SourceLocation E) { EndRangeLoc = E; }
2154
Balazs Benics919df9d2024-05-22 17:41:31 +02002155 void setDeclarationNameLoc(DeclarationNameLoc L) { DNLoc = L; }
2156
Nicolas Manichoncc3c9352019-12-03 08:21:55 -05002157 /// Returns the location of the ellipsis of a variadic function.
2158 SourceLocation getEllipsisLoc() const {
2159 const auto *FPT = getType()->getAs<FunctionProtoType>();
2160 if (FPT && FPT->isVariadic())
2161 return FPT->getEllipsisLoc();
2162 return SourceLocation();
2163 }
2164
Craig Toppercbce6e92014-03-11 06:22:39 +00002165 SourceRange getSourceRange() const override LLVM_READONLY;
Steve Naroff22315692008-10-03 00:02:03 +00002166
Serge Pavlove6e534c2018-03-01 07:04:11 +00002167 // Function definitions.
2168 //
2169 // A function declaration may be:
2170 // - a non defining declaration,
2171 // - a definition. A function may be defined because:
2172 // - it has a body, or will have it in the case of late parsing.
2173 // - it has an uninstantiated body. The body does not exist because the
2174 // function is not used yet, but the declaration is considered a
2175 // definition and does not allow other definition of this function.
2176 // - it does not have a user specified body, but it does not allow
2177 // redefinition, because it is deleted/defaulted or is defined through
2178 // some other mechanism (alias, ifunc).
2179
2180 /// Returns true if the function has a body.
2181 ///
2182 /// The function body might be in any of the (re-)declarations of this
2183 /// function. The variant that accepts a FunctionDecl pointer will set that
2184 /// function declaration to the actual declaration containing the body (if
2185 /// there is one).
Argyrios Kyrtzidis36ea3222010-07-07 11:31:19 +00002186 bool hasBody(const FunctionDecl *&Definition) const;
2187
Craig Toppercbce6e92014-03-11 06:22:39 +00002188 bool hasBody() const override {
Argyrios Kyrtzidis36ea3222010-07-07 11:31:19 +00002189 const FunctionDecl* Definition;
2190 return hasBody(Definition);
2191 }
2192
Erich Keane7670b4b2017-12-15 16:37:14 +00002193 /// Returns whether the function has a trivial body that does not require any
2194 /// specific codegen.
Anders Carlsson9bd7d162011-05-14 23:26:09 +00002195 bool hasTrivialBody() const;
2196
Serge Pavlove6e534c2018-03-01 07:04:11 +00002197 /// Returns true if the function has a definition that does not need to be
2198 /// instantiated.
2199 ///
2200 /// The variant that accepts a FunctionDecl pointer will set that function
2201 /// declaration to the declaration that is a definition (if there is one).
Richard Smithdd8297b2020-10-30 18:30:56 -07002202 ///
2203 /// \param CheckForPendingFriendDefinition If \c true, also check for friend
Ayushi Shuklacc8237d2023-03-30 15:55:49 +01002204 /// declarations that were instantiated from function definitions.
Richard Smithdd8297b2020-10-30 18:30:56 -07002205 /// Such a declaration behaves as if it is a definition for the
2206 /// purpose of redefinition checking, but isn't actually a "real"
2207 /// definition until its body is instantiated.
2208 bool isDefined(const FunctionDecl *&Definition,
2209 bool CheckForPendingFriendDefinition = false) const;
Alexis Hunt4a8ea102011-05-06 20:44:56 +00002210
Reid Kleckner753a3242020-03-31 09:01:06 -07002211 bool isDefined() const {
Alexis Hunt4a8ea102011-05-06 20:44:56 +00002212 const FunctionDecl* Definition;
2213 return isDefined(Definition);
2214 }
2215
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002216 /// Get the definition for this declaration.
Yaron Keren18c3d062016-07-13 19:04:51 +00002217 FunctionDecl *getDefinition() {
2218 const FunctionDecl *Definition;
2219 if (isDefined(Definition))
2220 return const_cast<FunctionDecl *>(Definition);
2221 return nullptr;
2222 }
2223 const FunctionDecl *getDefinition() const {
2224 return const_cast<FunctionDecl *>(this)->getDefinition();
2225 }
2226
Erich Keane7670b4b2017-12-15 16:37:14 +00002227 /// Retrieve the body (definition) of the function. The function body might be
2228 /// in any of the (re-)declarations of this function. The variant that accepts
2229 /// a FunctionDecl pointer will set that function declaration to the actual
2230 /// declaration containing the body (if there is one).
Argyrios Kyrtzidis36ea3222010-07-07 11:31:19 +00002231 /// NOTE: For checking if there is a body, use hasBody() instead, to avoid
Sebastian Redl42a0f6a2010-08-18 23:56:27 +00002232 /// unnecessary AST de-serialization of the body.
Argyrios Kyrtzidisddcd1322009-06-30 02:35:26 +00002233 Stmt *getBody(const FunctionDecl *&Definition) const;
Ted Kremeneke5b40a92008-07-31 17:32:12 +00002234
Nico Weber2a9b6aa2014-09-03 15:28:00 +00002235 Stmt *getBody() const override {
Douglas Gregor89f238c2008-04-21 02:02:58 +00002236 const FunctionDecl* Definition;
Argyrios Kyrtzidisddcd1322009-06-30 02:35:26 +00002237 return getBody(Definition);
Douglas Gregor89f238c2008-04-21 02:02:58 +00002238 }
Douglas Gregore3dcb2d2009-04-18 00:02:19 +00002239
Serge Pavlov10673c92017-06-04 12:53:12 +00002240 /// Returns whether this specific declaration of the function is also a
2241 /// definition that does not contain uninstantiated body.
2242 ///
2243 /// This does not determine whether the function has been defined (e.g., in a
2244 /// previous definition); for that information, use isDefined.
Guillaume Chatelet98f31512019-09-25 11:31:28 +02002245 ///
2246 /// Note: the function declaration does not become a definition until the
2247 /// parser reaches the definition, if called before, this function will return
2248 /// `false`.
Francois Pichet1c229c02011-04-22 22:18:13 +00002249 bool isThisDeclarationADefinition() const {
Richard Smith848934c2019-12-05 13:37:35 -08002250 return isDeletedAsWritten() || isDefaulted() ||
2251 doesThisDeclarationHaveABody() || hasSkippedBody() ||
2252 willHaveBody() || hasDefiningAttr();
Alexis Hunt4a8ea102011-05-06 20:44:56 +00002253 }
2254
Richard Smithdd8297b2020-10-30 18:30:56 -07002255 /// Determine whether this specific declaration of the function is a friend
2256 /// declaration that was instantiated from a function definition. Such
2257 /// declarations behave like definitions in some contexts.
2258 bool isThisDeclarationInstantiatedFromAFriendDefinition() const;
2259
Serge Pavlove6e534c2018-03-01 07:04:11 +00002260 /// Returns whether this specific declaration of the function has a body.
Alexis Hunt4a8ea102011-05-06 20:44:56 +00002261 bool doesThisDeclarationHaveABody() const {
Sirraideef164ce2024-04-14 12:30:01 +02002262 return (!FunctionDeclBits.HasDefaultedOrDeletedInfo && Body) ||
Richard Smith848934c2019-12-05 13:37:35 -08002263 isLateTemplateParsed();
Francois Pichet1c229c02011-04-22 22:18:13 +00002264 }
Douglas Gregor89f238c2008-04-21 02:02:58 +00002265
Argyrios Kyrtzidisa3aeb5a2009-06-20 08:09:14 +00002266 void setBody(Stmt *B);
Richard Smith848934c2019-12-05 13:37:35 -08002267 void setLazyBody(uint64_t Offset) {
Sirraideef164ce2024-04-14 12:30:01 +02002268 FunctionDeclBits.HasDefaultedOrDeletedInfo = false;
Richard Smith848934c2019-12-05 13:37:35 -08002269 Body = LazyDeclStmtPtr(Offset);
2270 }
2271
Sirraideef164ce2024-04-14 12:30:01 +02002272 void setDefaultedOrDeletedInfo(DefaultedOrDeletedFunctionInfo *Info);
2273 DefaultedOrDeletedFunctionInfo *getDefalutedOrDeletedInfo() const;
Sebastian Redl60795252009-01-09 19:57:06 +00002274
Ted Kremenek186a0742010-04-29 16:49:01 +00002275 /// Whether this function is variadic.
2276 bool isVariadic() const;
2277
Anders Carlsson0a7c01f2009-05-14 22:15:41 +00002278 /// Whether this function is marked as virtual explicitly.
Erich Keane9c665062018-08-01 21:02:40 +00002279 bool isVirtualAsWritten() const {
2280 return FunctionDeclBits.IsVirtualAsWritten;
2281 }
2282
2283 /// State that this function is marked as virtual explicitly.
2284 void setVirtualAsWritten(bool V) { FunctionDeclBits.IsVirtualAsWritten = V; }
Sebastian Redl60795252009-01-09 19:57:06 +00002285
Sebastian Redl6138f2b2009-01-09 22:29:03 +00002286 /// Whether this virtual function is pure, i.e. makes the containing class
2287 /// abstract.
cor3ntine90e43f2024-01-18 15:30:58 +01002288 bool isPureVirtual() const { return FunctionDeclBits.IsPureVirtual; }
2289 void setIsPureVirtual(bool P = true);
Sebastian Redl60795252009-01-09 19:57:06 +00002290
Francois Pichet1c229c02011-04-22 22:18:13 +00002291 /// Whether this templated function will be late parsed.
Erich Keane9c665062018-08-01 21:02:40 +00002292 bool isLateTemplateParsed() const {
2293 return FunctionDeclBits.IsLateTemplateParsed;
2294 }
2295
2296 /// State that this templated function will be late parsed.
2297 void setLateTemplateParsed(bool ILT = true) {
2298 FunctionDeclBits.IsLateTemplateParsed = ILT;
2299 }
Francois Pichet1c229c02011-04-22 22:18:13 +00002300
Matheus Izvekov346077a2025-02-05 14:12:12 -03002301 bool isInstantiatedFromMemberTemplate() const {
2302 return FunctionDeclBits.IsInstantiatedFromMemberTemplate;
2303 }
2304 void setInstantiatedFromMemberTemplate(bool Val = true) {
2305 FunctionDeclBits.IsInstantiatedFromMemberTemplate = Val;
2306 }
2307
Douglas Gregor8a273912009-07-22 18:25:24 +00002308 /// Whether this function is "trivial" in some specialized C++ senses.
2309 /// Can only be true for default constructors, copy constructors,
2310 /// copy assignment operators, and destructors. Not meaningful until
2311 /// the class has been fully built by Sema.
Erich Keane9c665062018-08-01 21:02:40 +00002312 bool isTrivial() const { return FunctionDeclBits.IsTrivial; }
2313 void setTrivial(bool IT) { FunctionDeclBits.IsTrivial = IT; }
Mike Stump11289f42009-09-09 15:08:12 +00002314
Erich Keane9c665062018-08-01 21:02:40 +00002315 bool isTrivialForCall() const { return FunctionDeclBits.IsTrivialForCall; }
2316 void setTrivialForCall(bool IT) { FunctionDeclBits.IsTrivialForCall = IT; }
Akira Hatanaka02914dc2018-02-05 20:23:22 +00002317
mydeveloperday447ea9b2020-05-20 07:22:01 +01002318 /// Whether this function is defaulted. Valid for e.g.
2319 /// special member functions, defaulted comparisions (not methods!).
Erich Keane9c665062018-08-01 21:02:40 +00002320 bool isDefaulted() const { return FunctionDeclBits.IsDefaulted; }
2321 void setDefaulted(bool D = true) { FunctionDeclBits.IsDefaulted = D; }
Alexis Hunt5dafebc2011-05-06 01:42:00 +00002322
mydeveloperday447ea9b2020-05-20 07:22:01 +01002323 /// Whether this function is explicitly defaulted.
Erich Keane9c665062018-08-01 21:02:40 +00002324 bool isExplicitlyDefaulted() const {
2325 return FunctionDeclBits.IsExplicitlyDefaulted;
2326 }
2327
mydeveloperday447ea9b2020-05-20 07:22:01 +01002328 /// State that this function is explicitly defaulted.
Erich Keane9c665062018-08-01 21:02:40 +00002329 void setExplicitlyDefaulted(bool ED = true) {
2330 FunctionDeclBits.IsExplicitlyDefaulted = ED;
2331 }
Alexis Hunt5dafebc2011-05-06 01:42:00 +00002332
Nathan James1376c732022-10-04 19:38:09 +01002333 SourceLocation getDefaultLoc() const {
2334 return isExplicitlyDefaulted() ? DefaultKWLoc : SourceLocation();
2335 }
2336
2337 void setDefaultLoc(SourceLocation NewLoc) {
Erich Keaneeed92a92022-10-04 14:33:36 -07002338 assert((NewLoc.isInvalid() || isExplicitlyDefaulted()) &&
2339 "Can't set default loc is function isn't explicitly defaulted");
Nathan James1376c732022-10-04 19:38:09 +01002340 DefaultKWLoc = NewLoc;
2341 }
2342
Richard Smithcafc7412019-12-04 15:25:27 -08002343 /// True if this method is user-declared and was not
2344 /// deleted or defaulted on its first declaration.
2345 bool isUserProvided() const {
2346 auto *DeclAsWritten = this;
2347 if (FunctionDecl *Pattern = getTemplateInstantiationPattern())
2348 DeclAsWritten = Pattern;
2349 return !(DeclAsWritten->isDeleted() ||
2350 DeclAsWritten->getCanonicalDecl()->isDefaulted());
2351 }
2352
Roy Jacobson21eb1af2022-06-16 20:52:12 +03002353 bool isIneligibleOrNotSelected() const {
2354 return FunctionDeclBits.IsIneligibleOrNotSelected;
2355 }
2356 void setIneligibleOrNotSelected(bool II) {
2357 FunctionDeclBits.IsIneligibleOrNotSelected = II;
2358 }
2359
John McCallcaa19452009-07-28 01:00:58 +00002360 /// Whether falling off this function implicitly returns null/zero.
2361 /// If a more specific implicit return value is required, front-ends
2362 /// should synthesize the appropriate return statements.
Erich Keane9c665062018-08-01 21:02:40 +00002363 bool hasImplicitReturnZero() const {
2364 return FunctionDeclBits.HasImplicitReturnZero;
2365 }
2366
2367 /// State that falling off this function implicitly returns null/zero.
2368 /// If a more specific implicit return value is required, front-ends
2369 /// should synthesize the appropriate return statements.
2370 void setHasImplicitReturnZero(bool IRZ) {
2371 FunctionDeclBits.HasImplicitReturnZero = IRZ;
2372 }
John McCallcaa19452009-07-28 01:00:58 +00002373
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002374 /// Whether this function has a prototype, either because one
Douglas Gregor739ef0c2009-02-25 16:33:18 +00002375 /// was explicitly written or because it was "inherited" by merging
2376 /// a declaration without a prototype with a declaration that has a
2377 /// prototype.
Mike Stump11289f42009-09-09 15:08:12 +00002378 bool hasPrototype() const {
Erich Keane9c665062018-08-01 21:02:40 +00002379 return hasWrittenPrototype() || hasInheritedPrototype();
Anders Carlssone0dd1d52009-05-14 21:46:00 +00002380 }
Mike Stump11289f42009-09-09 15:08:12 +00002381
Erich Keane9c665062018-08-01 21:02:40 +00002382 /// Whether this function has a written prototype.
2383 bool hasWrittenPrototype() const {
2384 return FunctionDeclBits.HasWrittenPrototype;
2385 }
2386
2387 /// State that this function has a written prototype.
2388 void setHasWrittenPrototype(bool P = true) {
2389 FunctionDeclBits.HasWrittenPrototype = P;
2390 }
Douglas Gregor739ef0c2009-02-25 16:33:18 +00002391
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002392 /// Whether this function inherited its prototype from a
Douglas Gregorbcbf8632009-02-16 18:20:44 +00002393 /// previous declaration.
Erich Keane9c665062018-08-01 21:02:40 +00002394 bool hasInheritedPrototype() const {
2395 return FunctionDeclBits.HasInheritedPrototype;
2396 }
2397
2398 /// State that this function inherited its prototype from a
2399 /// previous declaration.
2400 void setHasInheritedPrototype(bool P = true) {
2401 FunctionDeclBits.HasInheritedPrototype = P;
2402 }
Douglas Gregorbcbf8632009-02-16 18:20:44 +00002403
Richard Smith12f247f2012-06-08 21:09:22 +00002404 /// Whether this is a (C++11) constexpr function or constexpr constructor.
Gauthier Harnisch796ed032019-06-14 08:56:20 +00002405 bool isConstexpr() const {
Thorsten41b65f12020-11-16 14:08:33 -05002406 return getConstexprKind() != ConstexprSpecKind::Unspecified;
Gauthier Harnisch796ed032019-06-14 08:56:20 +00002407 }
2408 void setConstexprKind(ConstexprSpecKind CSK) {
Thorsten41b65f12020-11-16 14:08:33 -05002409 FunctionDeclBits.ConstexprKind = static_cast<uint64_t>(CSK);
Gauthier Harnisch796ed032019-06-14 08:56:20 +00002410 }
2411 ConstexprSpecKind getConstexprKind() const {
2412 return static_cast<ConstexprSpecKind>(FunctionDeclBits.ConstexprKind);
2413 }
2414 bool isConstexprSpecified() const {
Thorsten41b65f12020-11-16 14:08:33 -05002415 return getConstexprKind() == ConstexprSpecKind::Constexpr;
Gauthier Harnisch796ed032019-06-14 08:56:20 +00002416 }
2417 bool isConsteval() const {
Thorsten41b65f12020-11-16 14:08:33 -05002418 return getConstexprKind() == ConstexprSpecKind::Consteval;
Gauthier Harnisch796ed032019-06-14 08:56:20 +00002419 }
Richard Smitha77a0a62011-08-15 21:04:07 +00002420
Corentin Jabot46768852023-05-08 12:18:43 +02002421 void setBodyContainsImmediateEscalatingExpressions(bool Set) {
2422 FunctionDeclBits.BodyContainsImmediateEscalatingExpression = Set;
2423 }
2424
2425 bool BodyContainsImmediateEscalatingExpressions() const {
2426 return FunctionDeclBits.BodyContainsImmediateEscalatingExpression;
2427 }
2428
2429 bool isImmediateEscalating() const;
2430
2431 // The function is a C++ immediate function.
2432 // This can be either a consteval function, or an immediate escalating
2433 // function containing an immediate escalating expression.
2434 bool isImmediateFunction() const;
2435
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002436 /// Whether the instantiation of this function is pending.
Sunil Srivastava15ed2922017-06-20 22:08:44 +00002437 /// This bit is set when the decision to instantiate this function is made
2438 /// and unset if and when the function body is created. That leaves out
2439 /// cases where instantiation did not happen because the template definition
2440 /// was not seen in this TU. This bit remains set in those cases, under the
2441 /// assumption that the instantiation will happen in some other TU.
Erich Keane9c665062018-08-01 21:02:40 +00002442 bool instantiationIsPending() const {
2443 return FunctionDeclBits.InstantiationIsPending;
2444 }
2445
2446 /// State that the instantiation of this function is pending.
2447 /// (see instantiationIsPending)
2448 void setInstantiationIsPending(bool IC) {
2449 FunctionDeclBits.InstantiationIsPending = IC;
2450 }
Sunil Srivastava15ed2922017-06-20 22:08:44 +00002451
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002452 /// Indicates the function uses __try.
Erich Keane9c665062018-08-01 21:02:40 +00002453 bool usesSEHTry() const { return FunctionDeclBits.UsesSEHTry; }
2454 void setUsesSEHTry(bool UST) { FunctionDeclBits.UsesSEHTry = UST; }
Reid Klecknerdeeddec2015-02-05 18:56:03 +00002455
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002456 /// Whether this function has been deleted.
Douglas Gregor171c45a2009-02-18 21:56:37 +00002457 ///
2458 /// A function that is "deleted" (via the C++0x "= delete" syntax)
2459 /// acts like a normal function, except that it cannot actually be
2460 /// called or have its address taken. Deleted functions are
2461 /// typically used in C++ overload resolution to attract arguments
2462 /// whose type or lvalue/rvalue-ness would permit the use of a
2463 /// different overload that would behave incorrectly. For example,
2464 /// one might use deleted functions to ban implicit conversion from
2465 /// a floating-point number to an Integer type:
2466 ///
2467 /// @code
2468 /// struct Integer {
2469 /// Integer(long); // construct from a long
2470 /// Integer(double) = delete; // no construction from float or double
2471 /// Integer(long double) = delete; // no construction from long double
2472 /// };
2473 /// @endcode
Alexis Hunt4a8ea102011-05-06 20:44:56 +00002474 // If a function is deleted, its first declaration must be.
Erich Keane9c665062018-08-01 21:02:40 +00002475 bool isDeleted() const {
2476 return getCanonicalDecl()->FunctionDeclBits.IsDeleted;
2477 }
2478
2479 bool isDeletedAsWritten() const {
2480 return FunctionDeclBits.IsDeleted && !isDefaulted();
2481 }
2482
Sirraideef164ce2024-04-14 12:30:01 +02002483 void setDeletedAsWritten(bool D = true, StringLiteral *Message = nullptr);
Douglas Gregor171c45a2009-02-18 21:56:37 +00002484
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002485 /// Determines whether this function is "main", which is the
John McCall53ffd372011-05-15 17:49:20 +00002486 /// entry point into an executable program.
Douglas Gregor16618f22009-09-12 00:17:51 +00002487 bool isMain() const;
Douglas Gregore62c0a42009-02-24 01:23:02 +00002488
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002489 /// Determines whether this function is a MSVCRT user defined entry
David Majnemerc729b0b2013-09-16 22:44:20 +00002490 /// point.
2491 bool isMSVCRTEntryPoint() const;
2492
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002493 /// Determines whether this operator new or delete is one
John McCall53ffd372011-05-15 17:49:20 +00002494 /// of the reserved global placement operators:
2495 /// void *operator new(size_t, void *);
2496 /// void *operator new[](size_t, void *);
2497 /// void operator delete(void *, void *);
2498 /// void operator delete[](void *, void *);
2499 /// These functions have special behavior under [new.delete.placement]:
2500 /// These functions are reserved, a C++ program may not define
2501 /// functions that displace the versions in the Standard C++ library.
2502 /// The provisions of [basic.stc.dynamic] do not apply to these
2503 /// reserved placement forms of operator new and operator delete.
2504 ///
2505 /// This function must be an allocation or deallocation function.
2506 bool isReservedGlobalPlacementOperator() const;
2507
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002508 /// Determines whether this function is one of the replaceable
Richard Smith8d0dc312013-07-21 23:12:18 +00002509 /// global allocation functions:
2510 /// void *operator new(size_t);
2511 /// void *operator new(size_t, const std::nothrow_t &) noexcept;
2512 /// void *operator new[](size_t);
2513 /// void *operator new[](size_t, const std::nothrow_t &) noexcept;
2514 /// void operator delete(void *) noexcept;
Richard Smith1cdec012013-09-29 04:40:38 +00002515 /// void operator delete(void *, std::size_t) noexcept; [C++1y]
Richard Smith8d0dc312013-07-21 23:12:18 +00002516 /// void operator delete(void *, const std::nothrow_t &) noexcept;
2517 /// void operator delete[](void *) noexcept;
Richard Smith1cdec012013-09-29 04:40:38 +00002518 /// void operator delete[](void *, std::size_t) noexcept; [C++1y]
Richard Smith8d0dc312013-07-21 23:12:18 +00002519 /// void operator delete[](void *, const std::nothrow_t &) noexcept;
2520 /// These functions have special behavior under C++1y [expr.new]:
2521 /// An implementation is allowed to omit a call to a replaceable global
2522 /// allocation function. [...]
Akira Hatanakacae83f72017-06-29 18:48:40 +00002523 ///
2524 /// If this function is an aligned allocation/deallocation function, return
Roman Lebedev3dd5a292020-02-26 01:37:17 +03002525 /// the parameter number of the requested alignment through AlignmentParam.
2526 ///
2527 /// If this function is an allocation/deallocation function that takes
2528 /// the `std::nothrow_t` tag, return true through IsNothrow,
2529 bool isReplaceableGlobalAllocationFunction(
Kazu Hirata6ad07882023-01-14 12:31:01 -08002530 std::optional<unsigned> *AlignmentParam = nullptr,
Roman Lebedev3dd5a292020-02-26 01:37:17 +03002531 bool *IsNothrow = nullptr) const;
Richard Smith8d0dc312013-07-21 23:12:18 +00002532
serge-sans-pailled437fba2020-01-16 19:54:38 +01002533 /// Determine if this function provides an inline implementation of a builtin.
2534 bool isInlineBuiltinDeclaration() const;
2535
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002536 /// Determine whether this is a destroying operator delete.
Richard Smith5b349582017-10-13 01:55:36 +00002537 bool isDestroyingOperatorDelete() const;
2538
Rafael Espindolaf4187652013-02-14 01:18:37 +00002539 /// Compute the language linkage.
2540 LanguageLinkage getLanguageLinkage() const;
2541
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002542 /// Determines whether this function is a function with
Rafael Espindola5bda63f2013-02-14 01:47:04 +00002543 /// external, C linkage.
Rafael Espindola0e0d0092013-03-14 03:07:35 +00002544 bool isExternC() const;
Rafael Espindola576127d2012-12-28 14:21:58 +00002545
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002546 /// Determines whether this function's context is, or is nested within,
Rafael Espindola593537a2013-05-05 20:15:21 +00002547 /// a C++ extern "C" linkage spec.
2548 bool isInExternCContext() const;
2549
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002550 /// Determines whether this function's context is, or is nested within,
Rafael Espindola593537a2013-05-05 20:15:21 +00002551 /// a C++ extern "C++" linkage spec.
2552 bool isInExternCXXContext() const;
2553
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002554 /// Determines whether this is a global function.
Douglas Gregorf1b876d2009-03-31 16:35:03 +00002555 bool isGlobal() const;
2556
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002557 /// Determines whether this function is known to be 'noreturn', through
Richard Smith10876ef2013-01-17 01:30:42 +00002558 /// an attribute on its declaration or its type.
2559 bool isNoReturn() const;
2560
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002561 /// True if the function was a definition but its body was skipped.
Erich Keane9c665062018-08-01 21:02:40 +00002562 bool hasSkippedBody() const { return FunctionDeclBits.HasSkippedBody; }
2563 void setHasSkippedBody(bool Skipped = true) {
2564 FunctionDeclBits.HasSkippedBody = Skipped;
2565 }
Argyrios Kyrtzidis1eb71a12012-12-06 18:59:10 +00002566
Justin Lebar2b42ccc2016-10-28 16:26:26 +00002567 /// True if this function will eventually have a body, once it's fully parsed.
Erich Keane9c665062018-08-01 21:02:40 +00002568 bool willHaveBody() const { return FunctionDeclBits.WillHaveBody; }
2569 void setWillHaveBody(bool V = true) { FunctionDeclBits.WillHaveBody = V; }
Justin Lebar2b42ccc2016-10-28 16:26:26 +00002570
Erich Keane281d20b2018-01-08 21:34:17 +00002571 /// True if this function is considered a multiversioned function.
Erich Keane9c665062018-08-01 21:02:40 +00002572 bool isMultiVersion() const {
2573 return getCanonicalDecl()->FunctionDeclBits.IsMultiVersion;
2574 }
Erich Keane281d20b2018-01-08 21:34:17 +00002575
2576 /// Sets the multiversion state for this declaration and all of its
2577 /// redeclarations.
2578 void setIsMultiVersion(bool V = true) {
Erich Keane9c665062018-08-01 21:02:40 +00002579 getCanonicalDecl()->FunctionDeclBits.IsMultiVersion = V;
Erich Keane281d20b2018-01-08 21:34:17 +00002580 }
2581
Erich Keanebabdef22022-08-19 13:57:45 -07002582 // Sets that this is a constrained friend where the constraint refers to an
2583 // enclosing template.
2584 void setFriendConstraintRefersToEnclosingTemplate(bool V = true) {
2585 getCanonicalDecl()
2586 ->FunctionDeclBits.FriendConstraintRefersToEnclosingTemplate = V;
2587 }
2588 // Indicates this function is a constrained friend, where the constraint
2589 // refers to an enclosing template for hte purposes of [temp.friend]p9.
2590 bool FriendConstraintRefersToEnclosingTemplate() const {
2591 return getCanonicalDecl()
2592 ->FunctionDeclBits.FriendConstraintRefersToEnclosingTemplate;
2593 }
2594
Richard Smitha07abe22023-03-30 16:07:55 -07002595 /// Determine whether a function is a friend function that cannot be
2596 /// redeclared outside of its class, per C++ [temp.friend]p9.
2597 bool isMemberLikeConstrainedFriend() const;
2598
Erich Keane5c0d1922018-11-28 18:34:14 +00002599 /// Gets the kind of multiversioning attribute this declaration has. Note that
2600 /// this can return a value even if the function is not multiversion, such as
2601 /// the case of 'target'.
2602 MultiVersionKind getMultiVersionKind() const;
2603
2604
Erich Keane3efe0022018-07-20 14:13:28 +00002605 /// True if this function is a multiversioned dispatch function as a part of
2606 /// the cpu_specific/cpu_dispatch functionality.
2607 bool isCPUDispatchMultiVersion() const;
2608 /// True if this function is a multiversioned processor specific function as a
2609 /// part of the cpu_specific/cpu_dispatch functionality.
2610 bool isCPUSpecificMultiVersion() const;
2611
Erich Keane19a8adc2018-10-25 18:57:19 +00002612 /// True if this function is a multiversioned dispatch function as a part of
2613 /// the target functionality.
2614 bool isTargetMultiVersion() const;
2615
Jon Roelofs20956552024-02-09 08:14:09 -08002616 /// True if this function is the default version of a multiversioned dispatch
2617 /// function as a part of the target functionality.
2618 bool isTargetMultiVersionDefault() const;
2619
Erich Keanefc53eb62021-11-29 06:28:02 -08002620 /// True if this function is a multiversioned dispatch function as a part of
2621 /// the target-clones functionality.
2622 bool isTargetClonesMultiVersion() const;
2623
Jon Roelofs99d74332024-02-09 08:13:15 -08002624 /// True if this function is a multiversioned dispatch function as a part of
2625 /// the target-version functionality.
2626 bool isTargetVersionMultiVersion() const;
2627
Saar Razb65b1f32020-01-09 15:07:51 +02002628 /// \brief Get the associated-constraints of this function declaration.
2629 /// Currently, this will either be a vector of size 1 containing the
2630 /// trailing-requires-clause or an empty vector.
2631 ///
2632 /// Use this instead of getTrailingRequiresClause for concepts APIs that
2633 /// accept an ArrayRef of constraint expressions.
2634 void getAssociatedConstraints(SmallVectorImpl<const Expr *> &AC) const {
2635 if (auto *TRC = getTrailingRequiresClause())
2636 AC.push_back(TRC);
2637 }
2638
Sirraideef164ce2024-04-14 12:30:01 +02002639 /// Get the message that indicates why this function was deleted.
2640 StringLiteral *getDeletedMessage() const {
2641 return FunctionDeclBits.HasDefaultedOrDeletedInfo
2642 ? DefaultedOrDeletedInfo->getDeletedMessage()
2643 : nullptr;
2644 }
2645
Douglas Gregor8f5d4422009-06-29 20:59:39 +00002646 void setPreviousDeclaration(FunctionDecl * PrevDecl);
Eli Friedmanaee9e542008-05-27 05:07:37 +00002647
Craig Toppercbce6e92014-03-11 06:22:39 +00002648 FunctionDecl *getCanonicalDecl() override;
Craig Topper38227742015-05-10 18:40:12 +00002649 const FunctionDecl *getCanonicalDecl() const {
2650 return const_cast<FunctionDecl*>(this)->getCanonicalDecl();
2651 }
Argyrios Kyrtzidis02dd4f92009-07-05 22:21:56 +00002652
Erik Pilkingtonb6e16ea2019-03-18 19:23:45 +00002653 unsigned getBuiltinID(bool ConsiderWrapperFunctions = false) const;
Douglas Gregorb9063fc2009-02-13 23:20:09 +00002654
David Majnemer59f77922016-06-24 04:05:48 +00002655 // ArrayRef interface to parameters.
2656 ArrayRef<ParmVarDecl *> parameters() const {
2657 return {ParamInfo, getNumParams()};
2658 }
2659 MutableArrayRef<ParmVarDecl *> parameters() {
2660 return {ParamInfo, getNumParams()};
2661 }
2662
Chris Lattner9b65d352007-12-19 23:58:25 +00002663 // Iterator access to formal parameters.
Eugene Zelenkode0215c2017-11-13 23:01:27 +00002664 using param_iterator = MutableArrayRef<ParmVarDecl *>::iterator;
2665 using param_const_iterator = ArrayRef<ParmVarDecl *>::const_iterator;
2666
David Majnemer59f77922016-06-24 04:05:48 +00002667 bool param_empty() const { return parameters().empty(); }
2668 param_iterator param_begin() { return parameters().begin(); }
2669 param_iterator param_end() { return parameters().end(); }
2670 param_const_iterator param_begin() const { return parameters().begin(); }
2671 param_const_iterator param_end() const { return parameters().end(); }
2672 size_t param_size() const { return parameters().size(); }
Mike Stump11289f42009-09-09 15:08:12 +00002673
Erich Keane7670b4b2017-12-15 16:37:14 +00002674 /// Return the number of parameters this function must have based on its
2675 /// FunctionType. This is the length of the ParamInfo array after it has been
2676 /// created.
Chris Lattnerc5cdf4d2007-01-21 07:42:07 +00002677 unsigned getNumParams() const;
Mike Stump11289f42009-09-09 15:08:12 +00002678
Chris Lattner53621a52007-06-13 20:44:40 +00002679 const ParmVarDecl *getParamDecl(unsigned i) const {
Chris Lattner2e89ebb2007-01-21 23:09:17 +00002680 assert(i < getNumParams() && "Illegal param #");
2681 return ParamInfo[i];
2682 }
Chris Lattner53621a52007-06-13 20:44:40 +00002683 ParmVarDecl *getParamDecl(unsigned i) {
2684 assert(i < getNumParams() && "Illegal param #");
2685 return ParamInfo[i];
2686 }
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002687 void setParams(ArrayRef<ParmVarDecl *> NewParamInfo) {
David Blaikie9c70e042011-09-21 18:16:56 +00002688 setParams(getASTContext(), NewParamInfo);
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +00002689 }
Chris Lattnerb0d38442008-04-12 23:52:44 +00002690
Erich Keane7670b4b2017-12-15 16:37:14 +00002691 /// Returns the minimum number of arguments needed to call this function. This
2692 /// may be fewer than the number of function parameters, if some of the
2693 /// parameters have default arguments (in C++).
Chris Lattner58258242008-04-10 02:22:51 +00002694 unsigned getMinRequiredArguments() const;
Steve Naroff46ba1eb2007-04-03 23:13:13 +00002695
Corentin Jabotaf475172022-01-27 13:55:08 +01002696 /// Returns the minimum number of non-object arguments needed to call this
2697 /// function. This produces the same value as getMinRequiredArguments except
2698 /// it does not count the explicit object argument, if any.
2699 unsigned getMinRequiredExplicitArguments() const;
2700
2701 bool hasCXXExplicitFunctionObjectParameter() const;
2702
2703 unsigned getNumNonObjectParams() const;
2704
2705 const ParmVarDecl *getNonObjectParameter(unsigned I) const {
2706 return getParamDecl(hasCXXExplicitFunctionObjectParameter() ? I + 1 : I);
2707 }
2708
2709 ParmVarDecl *getNonObjectParameter(unsigned I) {
2710 return getParamDecl(hasCXXExplicitFunctionObjectParameter() ? I + 1 : I);
2711 }
2712
Richard Smithb5f2c4e2020-06-02 10:42:36 -07002713 /// Determine whether this function has a single parameter, or multiple
2714 /// parameters where all but the first have default arguments.
2715 ///
2716 /// This notion is used in the definition of copy/move constructors and
2717 /// initializer list constructors. Note that, unlike getMinRequiredArguments,
2718 /// parameter packs are not treated specially here.
2719 bool hasOneParamOrDefaultArgs() const;
2720
Richard Smithd052a5782019-10-22 17:44:08 -07002721 /// Find the source location information for how the type of this function
2722 /// was written. May be absent (for example if the function was declared via
2723 /// a typedef) and may contain a different type from that of the function
2724 /// (for example if the function type was adjusted by an attribute).
2725 FunctionTypeLoc getFunctionTypeLoc() const;
2726
Alp Toker314cc812014-01-25 16:55:45 +00002727 QualType getReturnType() const {
Richard Smith4576a772018-09-10 06:35:32 +00002728 return getType()->castAs<FunctionType>()->getReturnType();
Steve Naroff9358c712007-05-27 23:58:33 +00002729 }
David Blaikie21bfbf82011-11-09 06:07:30 +00002730
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002731 /// Attempt to compute an informative source range covering the
Alp Tokerf5b10792014-07-02 12:55:58 +00002732 /// function return type. This may omit qualifiers and other information with
2733 /// limited representation in the AST.
Alp Tokerd0787eb2014-07-02 01:47:15 +00002734 SourceRange getReturnTypeSourceRange() const;
2735
Nicolas Manichoncc3c9352019-12-03 08:21:55 -05002736 /// Attempt to compute an informative source range covering the
2737 /// function parameters, including the ellipsis of a variadic function.
2738 /// The source range excludes the parentheses, and is invalid if there are
2739 /// no parameters and no ellipsis.
2740 SourceRange getParametersSourceRange() const;
2741
Richard Smith4576a772018-09-10 06:35:32 +00002742 /// Get the declared return type, which may differ from the actual return
2743 /// type if the return type is deduced.
2744 QualType getDeclaredReturnType() const {
2745 auto *TSI = getTypeSourceInfo();
2746 QualType T = TSI ? TSI->getType() : getType();
2747 return T->castAs<FunctionType>()->getReturnType();
2748 }
2749
Erich Keaned02f4a12019-05-30 17:31:54 +00002750 /// Gets the ExceptionSpecificationType as declared.
2751 ExceptionSpecificationType getExceptionSpecType() const {
2752 auto *TSI = getTypeSourceInfo();
2753 QualType T = TSI ? TSI->getType() : getType();
2754 const auto *FPT = T->getAs<FunctionProtoType>();
2755 return FPT ? FPT->getExceptionSpecType() : EST_None;
2756 }
2757
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002758 /// Attempt to compute an informative source range covering the
Malcolm Parsonsa3220ce2017-01-12 16:11:28 +00002759 /// function exception specification, if any.
2760 SourceRange getExceptionSpecSourceRange() const;
2761
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002762 /// Determine the type of an expression that calls this function.
Douglas Gregor603d81b2010-07-13 08:18:22 +00002763 QualType getCallResultType() const {
Richard Smith4576a772018-09-10 06:35:32 +00002764 return getType()->castAs<FunctionType>()->getCallResultType(
2765 getASTContext());
Douglas Gregor603d81b2010-07-13 08:18:22 +00002766 }
David Blaikie21bfbf82011-11-09 06:07:30 +00002767
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002768 /// Returns the storage class as written in the source. For the
Rafael Espindola6ae7e502013-04-03 19:27:57 +00002769 /// computed linkage of symbol, see getLinkage.
Erich Keane9c665062018-08-01 21:02:40 +00002770 StorageClass getStorageClass() const {
2771 return static_cast<StorageClass>(FunctionDeclBits.SClass);
2772 }
2773
2774 /// Sets the storage class as written in the source.
2775 void setStorageClass(StorageClass SClass) {
Thorsten Schütt2fd11e02021-01-04 23:17:45 +01002776 FunctionDeclBits.SClass = SClass;
Erich Keane9c665062018-08-01 21:02:40 +00002777 }
Douglas Gregorc4df4072010-04-19 22:54:31 +00002778
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002779 /// Determine whether the "inline" keyword was specified for this
Douglas Gregor35b57532009-10-27 21:01:01 +00002780 /// function.
Erich Keane9c665062018-08-01 21:02:40 +00002781 bool isInlineSpecified() const { return FunctionDeclBits.IsInlineSpecified; }
David Blaikie21bfbf82011-11-09 06:07:30 +00002782
Douglas Gregor35b57532009-10-27 21:01:01 +00002783 /// Set whether the "inline" keyword was specified for this function.
David Blaikie21bfbf82011-11-09 06:07:30 +00002784 void setInlineSpecified(bool I) {
Erich Keane9c665062018-08-01 21:02:40 +00002785 FunctionDeclBits.IsInlineSpecified = I;
2786 FunctionDeclBits.IsInline = I;
Douglas Gregorff76cb92010-12-09 16:59:22 +00002787 }
Douglas Gregore62c0a42009-02-24 01:23:02 +00002788
Melanie Blowerbc5b5ea2021-07-29 12:02:20 -04002789 /// Determine whether the function was declared in source context
2790 /// that requires constrained FP intrinsics
2791 bool UsesFPIntrin() const { return FunctionDeclBits.UsesFPIntrin; }
2792
2793 /// Set whether the function was declared in source context
2794 /// that requires constrained FP intrinsics
2795 void setUsesFPIntrin(bool I) { FunctionDeclBits.UsesFPIntrin = I; }
2796
John McCall357d0f32010-12-15 04:00:32 +00002797 /// Flag that this function is implicitly inline.
Erich Keane9c665062018-08-01 21:02:40 +00002798 void setImplicitlyInline(bool I = true) { FunctionDeclBits.IsInline = I; }
John McCall357d0f32010-12-15 04:00:32 +00002799
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002800 /// Determine whether this function should be inlined, because it is
Richard Smith7cd25b22011-09-30 00:45:47 +00002801 /// either marked "inline" or "constexpr" or is a member function of a class
2802 /// that was defined in the class body.
Erich Keane9c665062018-08-01 21:02:40 +00002803 bool isInlined() const { return FunctionDeclBits.IsInline; }
2804
Douglas Gregor299d76e2009-09-13 07:46:26 +00002805 bool isInlineDefinitionExternallyVisible() const;
Nick Lewycky26da4dd2011-07-18 05:26:13 +00002806
David Majnemer54e3ba52014-04-02 23:17:29 +00002807 bool isMSExternInline() const;
2808
Nick Lewycky26da4dd2011-07-18 05:26:13 +00002809 bool doesDeclarationForceExternallyVisibleDefinition() const;
David Blaikie21bfbf82011-11-09 06:07:30 +00002810
Thorsten Schütt2fd11e02021-01-04 23:17:45 +01002811 bool isStatic() const { return getStorageClass() == SC_Static; }
Djordje Todorovic0f651682019-06-27 06:44:44 +00002812
James Dennettb8973efb2018-02-02 20:22:29 +00002813 /// Whether this function declaration represents an C++ overloaded
2814 /// operator, e.g., "operator+".
Mike Stump11289f42009-09-09 15:08:12 +00002815 bool isOverloadedOperator() const {
Douglas Gregor11d0c4c2008-11-06 22:13:31 +00002816 return getOverloadedOperator() != OO_None;
Daniel Dunbare017ecc2009-12-19 17:50:07 +00002817 }
Douglas Gregor11d0c4c2008-11-06 22:13:31 +00002818
2819 OverloadedOperatorKind getOverloadedOperator() const;
2820
Alexis Huntc88db062010-01-13 09:01:02 +00002821 const IdentifierInfo *getLiteralIdentifier() const;
2822
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002823 /// If this function is an instantiation of a member function
Douglas Gregor24c332b2009-05-14 21:06:31 +00002824 /// of a class template specialization, retrieves the function from
2825 /// which it was instantiated.
2826 ///
2827 /// This routine will return non-NULL for (non-templated) member
2828 /// functions of class templates and for instantiations of function
2829 /// templates. For example, given:
2830 ///
2831 /// \code
2832 /// template<typename T>
2833 /// struct X {
2834 /// void f(T);
2835 /// };
2836 /// \endcode
2837 ///
2838 /// The declaration for X<int>::f is a (non-templated) FunctionDecl
2839 /// whose parent is the class template specialization X<int>. For
2840 /// this declaration, getInstantiatedFromFunction() will return
2841 /// the FunctionDecl X<T>::A. When a complete definition of
2842 /// X<int>::A is required, it will be instantiated from the
2843 /// declaration returned by getInstantiatedFromMemberFunction().
Douglas Gregord801b062009-10-07 23:56:10 +00002844 FunctionDecl *getInstantiatedFromMemberFunction() const;
David Blaikie21bfbf82011-11-09 06:07:30 +00002845
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002846 /// What kind of templated function this is.
Argyrios Kyrtzidiscb6f3462010-06-22 09:54:51 +00002847 TemplatedKind getTemplatedKind() const;
Douglas Gregor24c332b2009-05-14 21:06:31 +00002848
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002849 /// If this function is an instantiation of a member function of a
Douglas Gregor06db9f52009-10-12 20:18:28 +00002850 /// class template specialization, retrieves the member specialization
2851 /// information.
Chandler Carruth21c90602015-12-30 03:24:14 +00002852 MemberSpecializationInfo *getMemberSpecializationInfo() const;
David Blaikie21bfbf82011-11-09 06:07:30 +00002853
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002854 /// Specify that this record is an instantiation of the
Douglas Gregord801b062009-10-07 23:56:10 +00002855 /// member function FD.
2856 void setInstantiationOfMemberFunction(FunctionDecl *FD,
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +00002857 TemplateSpecializationKind TSK) {
2858 setInstantiationOfMemberFunction(getASTContext(), FD, TSK);
2859 }
Douglas Gregor24c332b2009-05-14 21:06:31 +00002860
Erich Keane3ff86f92022-07-22 12:30:47 -07002861 /// Specify that this function declaration was instantiated from a
2862 /// FunctionDecl FD. This is only used if this is a function declaration
2863 /// declared locally inside of a function template.
2864 void setInstantiatedFromDecl(FunctionDecl *FD);
2865
2866 FunctionDecl *getInstantiatedFromDecl() const;
2867
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002868 /// Retrieves the function template that is described by this
Douglas Gregor24c332b2009-05-14 21:06:31 +00002869 /// function declaration.
2870 ///
2871 /// Every function template is represented as a FunctionTemplateDecl
2872 /// and a FunctionDecl (or something derived from FunctionDecl). The
2873 /// former contains template properties (such as the template
2874 /// parameter lists) while the latter contains the actual
2875 /// description of the template's
2876 /// contents. FunctionTemplateDecl::getTemplatedDecl() retrieves the
2877 /// FunctionDecl that describes the function template,
2878 /// getDescribedFunctionTemplate() retrieves the
2879 /// FunctionTemplateDecl from a FunctionDecl.
Chandler Carruth21c90602015-12-30 03:24:14 +00002880 FunctionTemplateDecl *getDescribedFunctionTemplate() const;
Douglas Gregor24c332b2009-05-14 21:06:31 +00002881
Chandler Carruth21c90602015-12-30 03:24:14 +00002882 void setDescribedFunctionTemplate(FunctionTemplateDecl *Template);
Douglas Gregor24c332b2009-05-14 21:06:31 +00002883
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002884 /// Determine whether this function is a function template
Douglas Gregor3a923c2d2009-09-24 23:14:47 +00002885 /// specialization.
Krystian Stasiowski3a3b84b2023-10-07 02:55:31 -04002886 bool isFunctionTemplateSpecialization() const;
Francois Pichet00c7e6c2011-08-14 03:52:19 +00002887
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002888 /// If this function is actually a function template specialization,
David Blaikie21bfbf82011-11-09 06:07:30 +00002889 /// retrieve information about this function template specialization.
Douglas Gregor06db9f52009-10-12 20:18:28 +00002890 /// Otherwise, returns NULL.
Chandler Carruth21c90602015-12-30 03:24:14 +00002891 FunctionTemplateSpecializationInfo *getTemplateSpecializationInfo() const;
Douglas Gregorafca3b42009-10-27 20:53:28 +00002892
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002893 /// Determines whether this function is a function template
Douglas Gregorafca3b42009-10-27 20:53:28 +00002894 /// specialization or a member of a class template specialization that can
2895 /// be implicitly instantiated.
2896 bool isImplicitlyInstantiable() const;
David Blaikie21bfbf82011-11-09 06:07:30 +00002897
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002898 /// Determines if the given function was instantiated from a
Ted Kremenek85825ae2011-12-01 00:59:17 +00002899 /// function template.
2900 bool isTemplateInstantiation() const;
2901
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002902 /// Retrieve the function declaration from which this function could
Douglas Gregorafca3b42009-10-27 20:53:28 +00002903 /// be instantiated, if it is an instantiation (rather than a non-template
2904 /// or a specialization, for example).
Richard Smitha5569f02020-07-09 14:57:30 -07002905 ///
2906 /// If \p ForDefinition is \c false, explicit specializations will be treated
2907 /// as if they were implicit instantiations. This will then find the pattern
2908 /// corresponding to non-definition portions of the declaration, such as
2909 /// default arguments and the exception specification.
2910 FunctionDecl *
2911 getTemplateInstantiationPattern(bool ForDefinition = true) const;
Douglas Gregorafca3b42009-10-27 20:53:28 +00002912
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002913 /// Retrieve the primary template that this function template
Douglas Gregor4adbc6d2009-06-26 00:10:03 +00002914 /// specialization either specializes or was instantiated from.
2915 ///
2916 /// If this function declaration is not a function template specialization,
2917 /// returns NULL.
Douglas Gregor70d83e22009-06-29 17:30:29 +00002918 FunctionTemplateDecl *getPrimaryTemplate() const;
Mike Stump11289f42009-09-09 15:08:12 +00002919
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002920 /// Retrieve the template arguments used to produce this function
Douglas Gregor4adbc6d2009-06-26 00:10:03 +00002921 /// template specialization from the primary template.
2922 ///
2923 /// If this function declaration is not a function template specialization,
2924 /// returns NULL.
Mike Stump11289f42009-09-09 15:08:12 +00002925 const TemplateArgumentList *getTemplateSpecializationArgs() const;
2926
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002927 /// Retrieve the template argument list as written in the sources,
Abramo Bagnara02ccd282010-05-20 15:32:11 +00002928 /// if any.
2929 ///
2930 /// If this function declaration is not a function template specialization
2931 /// or if it had no explicit template argument list, returns NULL.
2932 /// Note that it an explicit template argument list may be written empty,
2933 /// e.g., template<> void foo<>(char* s);
Argyrios Kyrtzidise9a24432011-09-22 20:07:09 +00002934 const ASTTemplateArgumentListInfo*
Abramo Bagnara02ccd282010-05-20 15:32:11 +00002935 getTemplateSpecializationArgsAsWritten() const;
2936
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002937 /// Specify that this function declaration is actually a function
Douglas Gregor4adbc6d2009-06-26 00:10:03 +00002938 /// template specialization.
2939 ///
Douglas Gregor4adbc6d2009-06-26 00:10:03 +00002940 /// \param Template the function template that this function template
2941 /// specialization specializes.
2942 ///
2943 /// \param TemplateArgs the template arguments that produced this
2944 /// function template specialization from the template.
Douglas Gregor3a923c2d2009-09-24 23:14:47 +00002945 ///
2946 /// \param InsertPos If non-NULL, the position in the function template
2947 /// specialization set where the function template specialization data will
2948 /// be inserted.
2949 ///
2950 /// \param TSK the kind of template specialization this is.
Argyrios Kyrtzidiscb6f3462010-06-22 09:54:51 +00002951 ///
2952 /// \param TemplateArgsAsWritten location info of template arguments.
Argyrios Kyrtzidis927d8e02010-07-05 10:37:55 +00002953 ///
2954 /// \param PointOfInstantiation point at which the function template
David Blaikie21bfbf82011-11-09 06:07:30 +00002955 /// specialization was first instantiated.
Vlad Serebrennikov6677aef2024-05-17 17:49:50 +04002956 void setFunctionTemplateSpecialization(
2957 FunctionTemplateDecl *Template, TemplateArgumentList *TemplateArgs,
2958 void *InsertPos,
2959 TemplateSpecializationKind TSK = TSK_ImplicitInstantiation,
2960 TemplateArgumentListInfo *TemplateArgsAsWritten = nullptr,
2961 SourceLocation PointOfInstantiation = SourceLocation()) {
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +00002962 setFunctionTemplateSpecialization(getASTContext(), Template, TemplateArgs,
2963 InsertPos, TSK, TemplateArgsAsWritten,
2964 PointOfInstantiation);
2965 }
Argyrios Kyrtzidiscb6f3462010-06-22 09:54:51 +00002966
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002967 /// Specifies that this function declaration is actually a
John McCallb9c78482010-04-08 09:05:18 +00002968 /// dependent function template specialization.
Krystian Stasiowski3a3b84b2023-10-07 02:55:31 -04002969 void setDependentTemplateSpecialization(
2970 ASTContext &Context, const UnresolvedSetImpl &Templates,
2971 const TemplateArgumentListInfo *TemplateArgs);
John McCallb9c78482010-04-08 09:05:18 +00002972
2973 DependentFunctionTemplateSpecializationInfo *
Chandler Carruth21c90602015-12-30 03:24:14 +00002974 getDependentSpecializationInfo() const;
John McCallb9c78482010-04-08 09:05:18 +00002975
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002976 /// Determine what kind of template instantiation this function
Douglas Gregor34ec2ef2009-09-04 22:48:11 +00002977 /// represents.
2978 TemplateSpecializationKind getTemplateSpecializationKind() const;
Douglas Gregore8925db2009-06-29 22:39:32 +00002979
Richard Smithf19a8b02019-05-02 00:49:14 +00002980 /// Determine the kind of template specialization this function represents
2981 /// for the purpose of template instantiation.
2982 TemplateSpecializationKind
2983 getTemplateSpecializationKindForInstantiation() const;
2984
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002985 /// Determine what kind of template instantiation this function
Douglas Gregor34ec2ef2009-09-04 22:48:11 +00002986 /// represents.
Douglas Gregor3d7e69f2009-10-15 17:21:20 +00002987 void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
2988 SourceLocation PointOfInstantiation = SourceLocation());
2989
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002990 /// Retrieve the (first) point of instantiation of a function template
Douglas Gregor3d7e69f2009-10-15 17:21:20 +00002991 /// specialization or a member of a class template specialization.
2992 ///
David Blaikie21bfbf82011-11-09 06:07:30 +00002993 /// \returns the first point of instantiation, if this function was
2994 /// instantiated from a template; otherwise, returns an invalid source
Douglas Gregor3d7e69f2009-10-15 17:21:20 +00002995 /// location.
2996 SourceLocation getPointOfInstantiation() const;
David Blaikie21bfbf82011-11-09 06:07:30 +00002997
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002998 /// Determine whether this is or was instantiated from an out-of-line
Douglas Gregor6411b922009-09-11 20:15:17 +00002999 /// definition of a member function.
Craig Toppercbce6e92014-03-11 06:22:39 +00003000 bool isOutOfLine() const override;
David Blaikie21bfbf82011-11-09 06:07:30 +00003001
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003002 /// Identify a memory copying or setting function.
Anna Zaks22122702012-01-17 00:37:07 +00003003 /// If the given function is a memory copy or setting function, returns
3004 /// the corresponding Builtin ID. If the function is not a memory function,
3005 /// returns 0.
Anna Zaks28db7ce2012-01-18 02:45:01 +00003006 unsigned getMemoryFunctionKind() const;
Anna Zaks201d4892012-01-13 21:52:01 +00003007
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003008 /// Returns ODRHash of the function. This value is calculated and
Richard Trieue6caa262017-12-23 00:41:01 +00003009 /// stored on first call, then the stored value returned on the other calls.
3010 unsigned getODRHash();
3011
Richard Trieu27c1b1a2018-07-10 01:40:50 +00003012 /// Returns cached ODRHash of the function. This must have been previously
3013 /// computed and stored.
3014 unsigned getODRHash() const;
3015
Doug Wyattf03cb002024-06-24 00:51:31 -10003016 FunctionEffectsRef getFunctionEffects() const {
3017 // Effects may differ between declarations, but they should be propagated
3018 // from old to new on any redeclaration, so it suffices to look at
3019 // getMostRecentDecl().
3020 if (const auto *FPT =
3021 getMostRecentDecl()->getType()->getAs<FunctionProtoType>())
3022 return FPT->getFunctionEffects();
3023 return {};
3024 }
3025
Chris Lattnerda8aa7b2006-11-19 23:12:30 +00003026 // Implement isa/cast/dyncast/etc.
John McCall180ef092010-01-29 01:45:37 +00003027 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
John McCall180ef092010-01-29 01:45:37 +00003028 static bool classofKind(Kind K) {
Alexis Hunted053252010-05-30 07:21:58 +00003029 return K >= firstFunction && K <= lastFunction;
John McCall180ef092010-01-29 01:45:37 +00003030 }
Argyrios Kyrtzidis3768ad62008-10-12 16:14:48 +00003031 static DeclContext *castToDeclContext(const FunctionDecl *D) {
3032 return static_cast<DeclContext *>(const_cast<FunctionDecl*>(D));
3033 }
3034 static FunctionDecl *castFromDeclContext(const DeclContext *DC) {
3035 return static_cast<FunctionDecl *>(const_cast<DeclContext*>(DC));
3036 }
Chris Lattnera11999d2006-10-15 22:34:45 +00003037};
3038
James Dennett31a57342018-02-02 21:38:22 +00003039/// Represents a member of a struct/union/class.
Richard Smith0b87e072013-10-07 08:02:11 +00003040class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
Richard Smith32429342023-04-05 14:28:57 -07003041 /// The kinds of value we can store in StorageKind.
Richard Smith938f40b2011-06-11 17:19:42 +00003042 ///
John McCallc90c1492014-10-10 18:44:34 +00003043 /// Note that this is compatible with InClassInitStyle except for
3044 /// ISK_CapturedVLAType.
3045 enum InitStorageKind {
3046 /// If the pointer is null, there's nothing special. Otherwise,
3047 /// this is a bitfield and the pointer is the Expr* storing the
3048 /// bit-width.
Richard Smith6b8e3c02017-08-28 00:28:14 +00003049 ISK_NoInit = (unsigned) ICIS_NoInit,
John McCallc90c1492014-10-10 18:44:34 +00003050
3051 /// The pointer is an (optional due to delayed parsing) Expr*
3052 /// holding the copy-initializer.
3053 ISK_InClassCopyInit = (unsigned) ICIS_CopyInit,
3054
3055 /// The pointer is an (optional due to delayed parsing) Expr*
3056 /// holding the list-initializer.
3057 ISK_InClassListInit = (unsigned) ICIS_ListInit,
3058
3059 /// The pointer is a VariableArrayType* that's been captured;
3060 /// the enclosing context is a lambda or captured statement.
3061 ISK_CapturedVLAType,
3062 };
3063
Vlad Serebrennikovad278482023-11-06 12:17:21 +03003064 LLVM_PREFERRED_TYPE(bool)
Richard Smith32429342023-04-05 14:28:57 -07003065 unsigned BitField : 1;
Vlad Serebrennikovad278482023-11-06 12:17:21 +03003066 LLVM_PREFERRED_TYPE(bool)
Richard Smith32429342023-04-05 14:28:57 -07003067 unsigned Mutable : 1;
Vlad Serebrennikovad278482023-11-06 12:17:21 +03003068 LLVM_PREFERRED_TYPE(InitStorageKind)
Richard Smith32429342023-04-05 14:28:57 -07003069 unsigned StorageKind : 2;
3070 mutable unsigned CachedFieldIndex : 28;
3071
Richard Smith6b8e3c02017-08-28 00:28:14 +00003072 /// If this is a bitfield with a default member initializer, this
3073 /// structure is used to represent the two expressions.
Richard Smith32429342023-04-05 14:28:57 -07003074 struct InitAndBitWidthStorage {
3075 LazyDeclStmtPtr Init;
Richard Smith6b8e3c02017-08-28 00:28:14 +00003076 Expr *BitWidth;
3077 };
3078
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003079 /// Storage for either the bit-width, the in-class initializer, or
Richard Smith6b8e3c02017-08-28 00:28:14 +00003080 /// both (via InitAndBitWidth), or the captured variable length array bound.
John McCallc90c1492014-10-10 18:44:34 +00003081 ///
3082 /// If the storage kind is ISK_InClassCopyInit or
3083 /// ISK_InClassListInit, but the initializer is null, then this
Richard Smith6b8e3c02017-08-28 00:28:14 +00003084 /// field has an in-class initializer that has not yet been parsed
Richard Smith2b013182012-06-10 03:12:00 +00003085 /// and attached.
Richard Smith6b8e3c02017-08-28 00:28:14 +00003086 // FIXME: Tail-allocate this to reduce the size of FieldDecl in the
3087 // overwhelmingly common case that we have none of these things.
Richard Smith32429342023-04-05 14:28:57 -07003088 union {
3089 // Active member if ISK is not ISK_CapturedVLAType and BitField is false.
3090 LazyDeclStmtPtr Init;
3091 // Active member if ISK is ISK_NoInit and BitField is true.
3092 Expr *BitWidth;
3093 // Active member if ISK is ISK_InClass*Init and BitField is true.
3094 InitAndBitWidthStorage *InitAndBitWidth;
3095 // Active member if ISK is ISK_CapturedVLAType.
3096 const VariableArrayType *CapturedVLAType;
3097 };
Richard Smith6b8e3c02017-08-28 00:28:14 +00003098
Chris Lattnerd3f989c2008-03-15 23:04:32 +00003099protected:
Abramo Bagnaradff19302011-03-08 08:55:46 +00003100 FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
Bill Wendlingfca51912024-04-11 00:33:40 +00003101 SourceLocation IdLoc, const IdentifierInfo *Id, QualType T,
Richard Smith32429342023-04-05 14:28:57 -07003102 TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
Richard Smith2b013182012-06-10 03:12:00 +00003103 InClassInitStyle InitStyle)
Richard Smith32429342023-04-05 14:28:57 -07003104 : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), BitField(false),
3105 Mutable(Mutable), StorageKind((InitStorageKind)InitStyle),
3106 CachedFieldIndex(0), Init() {
Richard Smith6b8e3c02017-08-28 00:28:14 +00003107 if (BW)
3108 setBitWidth(BW);
Mike Stump11289f42009-09-09 15:08:12 +00003109 }
Douglas Gregor91f84212008-12-11 16:49:14 +00003110
Chris Lattneree1284a2008-03-16 00:16:02 +00003111public:
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003112 friend class ASTDeclReader;
3113 friend class ASTDeclWriter;
3114
Jay Foad39c79802011-01-12 09:06:06 +00003115 static FieldDecl *Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +00003116 SourceLocation StartLoc, SourceLocation IdLoc,
Bill Wendlingfca51912024-04-11 00:33:40 +00003117 const IdentifierInfo *Id, QualType T,
Richard Smith938f40b2011-06-11 17:19:42 +00003118 TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
Richard Smith2b013182012-06-10 03:12:00 +00003119 InClassInitStyle InitStyle);
Steve Naroff46ba1eb2007-04-03 23:13:13 +00003120
Chuanqi Xud86cc732024-04-25 11:43:13 +08003121 static FieldDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
Fangrui Song6907ce22018-07-30 19:24:48 +00003122
James Dennettb8973efb2018-02-02 20:22:29 +00003123 /// Returns the index of this field within its record,
John McCall4e819612011-01-20 07:57:12 +00003124 /// as appropriate for passing to ASTRecordLayout::getFieldOffset.
Reid Kleckner26aa20a2025-01-09 11:21:03 -08003125 unsigned getFieldIndex() const {
3126 const FieldDecl *Canonical = getCanonicalDecl();
3127 if (Canonical->CachedFieldIndex == 0) {
3128 Canonical->setCachedFieldIndex();
3129 assert(Canonical->CachedFieldIndex != 0);
3130 }
3131 return Canonical->CachedFieldIndex - 1;
3132 }
John McCall4e819612011-01-20 07:57:12 +00003133
Reid Kleckner26aa20a2025-01-09 11:21:03 -08003134private:
3135 /// Set CachedFieldIndex to the index of this field plus one.
3136 void setCachedFieldIndex() const;
3137
3138public:
James Dennettb8973efb2018-02-02 20:22:29 +00003139 /// Determines whether this field is mutable (C++ only).
Douglas Gregor91f84212008-12-11 16:49:14 +00003140 bool isMutable() const { return Mutable; }
3141
James Dennettb8973efb2018-02-02 20:22:29 +00003142 /// Determines whether this field is a bitfield.
Richard Smith6b8e3c02017-08-28 00:28:14 +00003143 bool isBitField() const { return BitField; }
Douglas Gregor91f84212008-12-11 16:49:14 +00003144
James Dennettb8973efb2018-02-02 20:22:29 +00003145 /// Determines whether this is an unnamed bitfield.
Timm Baeder3d56ea02024-04-18 07:39:29 +02003146 bool isUnnamedBitField() const { return isBitField() && !getDeclName(); }
Douglas Gregor347f7ea2009-01-28 21:54:33 +00003147
James Dennettb8973efb2018-02-02 20:22:29 +00003148 /// Determines whether this field is a
Douglas Gregorf4d33272009-01-07 19:46:03 +00003149 /// representative for an anonymous struct or union. Such fields are
3150 /// unnamed and are implicitly generated by the implementation to
3151 /// store the data for the anonymous union or struct.
3152 bool isAnonymousStructOrUnion() const;
3153
Timm Bäder05a11f32023-09-13 10:08:32 +02003154 /// Returns the expression that represents the bit width, if this field
3155 /// is a bit field. For non-bitfields, this returns \c nullptr.
Richard Smith938f40b2011-06-11 17:19:42 +00003156 Expr *getBitWidth() const {
Richard Smith6b8e3c02017-08-28 00:28:14 +00003157 if (!BitField)
3158 return nullptr;
Richard Smith32429342023-04-05 14:28:57 -07003159 return hasInClassInitializer() ? InitAndBitWidth->BitWidth : BitWidth;
Richard Smith938f40b2011-06-11 17:19:42 +00003160 }
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003161
Timm Bäder05a11f32023-09-13 10:08:32 +02003162 /// Computes the bit width of this field, if this is a bit field.
3163 /// May not be called on non-bitfields.
Timm Baedercfe26352025-01-11 07:12:37 +01003164 /// Note that in order to successfully use this function, the bitwidth
3165 /// expression must be a ConstantExpr with a valid integer result set.
3166 unsigned getBitWidthValue() const;
Richard Smith2b013182012-06-10 03:12:00 +00003167
James Dennettb8973efb2018-02-02 20:22:29 +00003168 /// Set the bit-field width for this member.
Abramo Bagnarab1cdde72012-07-02 20:35:48 +00003169 // Note: used by some clients (i.e., do not remove it).
John McCallc90c1492014-10-10 18:44:34 +00003170 void setBitWidth(Expr *Width) {
Richard Smith6b8e3c02017-08-28 00:28:14 +00003171 assert(!hasCapturedVLAType() && !BitField &&
3172 "bit width or captured type already set");
3173 assert(Width && "no bit width specified");
Richard Smith32429342023-04-05 14:28:57 -07003174 if (hasInClassInitializer())
3175 InitAndBitWidth =
3176 new (getASTContext()) InitAndBitWidthStorage{Init, Width};
3177 else
3178 BitWidth = Width;
Richard Smith6b8e3c02017-08-28 00:28:14 +00003179 BitField = true;
John McCallc90c1492014-10-10 18:44:34 +00003180 }
3181
James Dennettb8973efb2018-02-02 20:22:29 +00003182 /// Remove the bit-field width from this member.
Abramo Bagnarab1cdde72012-07-02 20:35:48 +00003183 // Note: used by some clients (i.e., do not remove it).
3184 void removeBitWidth() {
3185 assert(isBitField() && "no bitfield width to remove");
Richard Smith32429342023-04-05 14:28:57 -07003186 if (hasInClassInitializer()) {
3187 // Read the old initializer before we change the active union member.
3188 auto ExistingInit = InitAndBitWidth->Init;
3189 Init = ExistingInit;
3190 }
Richard Smith6b8e3c02017-08-28 00:28:14 +00003191 BitField = false;
Abramo Bagnarab1cdde72012-07-02 20:35:48 +00003192 }
3193
Richard Smith866dee42018-04-02 18:29:43 +00003194 /// Is this a zero-length bit-field? Such bit-fields aren't really bit-fields
3195 /// at all and instead act as a separator between contiguous runs of other
3196 /// bit-fields.
Timm Baedercfe26352025-01-11 07:12:37 +01003197 bool isZeroLengthBitField() const;
Richard Smith866dee42018-04-02 18:29:43 +00003198
Richard Smith78b239e2019-06-20 20:44:45 +00003199 /// Determine if this field is a subobject of zero size, that is, either a
3200 /// zero-length bit-field or a field of empty class type with the
3201 /// [[no_unique_address]] attribute.
3202 bool isZeroSize(const ASTContext &Ctx) const;
3203
Vladislav Dzhidzhoevaf6c0b6d2023-01-14 02:38:10 +03003204 /// Determine if this field is of potentially-overlapping class type, that
3205 /// is, subobject with the [[no_unique_address]] attribute
3206 bool isPotentiallyOverlapping() const;
3207
Richard Smith6b8e3c02017-08-28 00:28:14 +00003208 /// Get the kind of (C++11) default member initializer that this field has.
Richard Smith2b013182012-06-10 03:12:00 +00003209 InClassInitStyle getInClassInitStyle() const {
Richard Smith32429342023-04-05 14:28:57 -07003210 return (StorageKind == ISK_CapturedVLAType ? ICIS_NoInit
3211 : (InClassInitStyle)StorageKind);
Abramo Bagnara612f6dc2011-07-11 08:43:20 +00003212 }
Richard Smith938f40b2011-06-11 17:19:42 +00003213
Richard Smith6b8e3c02017-08-28 00:28:14 +00003214 /// Determine whether this member has a C++11 default member initializer.
Richard Smith938f40b2011-06-11 17:19:42 +00003215 bool hasInClassInitializer() const {
Richard Smith2b013182012-06-10 03:12:00 +00003216 return getInClassInitStyle() != ICIS_NoInit;
Richard Smith938f40b2011-06-11 17:19:42 +00003217 }
John McCallc90c1492014-10-10 18:44:34 +00003218
Richard Smith32429342023-04-05 14:28:57 -07003219 /// Determine whether getInClassInitializer() would return a non-null pointer
3220 /// without deserializing the initializer.
3221 bool hasNonNullInClassInitializer() const {
3222 return hasInClassInitializer() && (BitField ? InitAndBitWidth->Init : Init);
3223 }
3224
Richard Smith6b8e3c02017-08-28 00:28:14 +00003225 /// Get the C++11 default member initializer for this member, or null if one
3226 /// has not been set. If a valid declaration has a default member initializer,
3227 /// but this returns null, then we have not parsed and attached it yet.
Richard Smith32429342023-04-05 14:28:57 -07003228 Expr *getInClassInitializer() const;
John McCallc90c1492014-10-10 18:44:34 +00003229
James Dennettb8973efb2018-02-02 20:22:29 +00003230 /// Set the C++11 in-class initializer for this member.
Richard Smith32429342023-04-05 14:28:57 -07003231 void setInClassInitializer(Expr *NewInit);
John McCallc90c1492014-10-10 18:44:34 +00003232
Bill Wendling94b8b112024-08-15 05:27:19 +00003233 /// Find the FieldDecl specified in a FAM's "counted_by" attribute. Returns
3234 /// \p nullptr if either the attribute or the field doesn't exist.
3235 const FieldDecl *findCountedByField() const;
3236
Richard Smith32429342023-04-05 14:28:57 -07003237private:
3238 void setLazyInClassInitializer(LazyDeclStmtPtr NewInit);
3239
3240public:
James Dennettb8973efb2018-02-02 20:22:29 +00003241 /// Remove the C++11 in-class initializer from this member.
Richard Smith938f40b2011-06-11 17:19:42 +00003242 void removeInClassInitializer() {
Richard Smith2b013182012-06-10 03:12:00 +00003243 assert(hasInClassInitializer() && "no initializer to remove");
Richard Smith32429342023-04-05 14:28:57 -07003244 StorageKind = ISK_NoInit;
3245 if (BitField) {
3246 // Read the bit width before we change the active union member.
3247 Expr *ExistingBitWidth = InitAndBitWidth->BitWidth;
3248 BitWidth = ExistingBitWidth;
3249 }
Richard Smith938f40b2011-06-11 17:19:42 +00003250 }
Douglas Gregorfeb84b02009-04-14 21:18:50 +00003251
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003252 /// Determine whether this member captures the variable length array
Alexey Bataev39c81e22014-08-28 04:28:19 +00003253 /// type.
John McCallc90c1492014-10-10 18:44:34 +00003254 bool hasCapturedVLAType() const {
Richard Smith32429342023-04-05 14:28:57 -07003255 return StorageKind == ISK_CapturedVLAType;
John McCallc90c1492014-10-10 18:44:34 +00003256 }
3257
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003258 /// Get the captured variable length array type.
Alexey Bataev39c81e22014-08-28 04:28:19 +00003259 const VariableArrayType *getCapturedVLAType() const {
Richard Smith32429342023-04-05 14:28:57 -07003260 return hasCapturedVLAType() ? CapturedVLAType : nullptr;
Alexey Bataev39c81e22014-08-28 04:28:19 +00003261 }
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003262
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003263 /// Set the captured variable length array type for this field.
Alexey Bataev39c81e22014-08-28 04:28:19 +00003264 void setCapturedVLAType(const VariableArrayType *VLAType);
3265
James Dennettb8973efb2018-02-02 20:22:29 +00003266 /// Returns the parent of this field declaration, which
Malcolm Parsons2eac1d82017-05-08 16:43:29 +00003267 /// is the struct in which this field is defined.
Haojian Wufcf07642020-05-19 15:26:42 +02003268 ///
3269 /// Returns null if this is not a normal class/struct field declaration, e.g.
3270 /// ObjCAtDefsFieldDecl, ObjCIvarDecl.
Anders Carlsson5d8645b2010-01-29 05:05:36 +00003271 const RecordDecl *getParent() const {
Haojian Wufcf07642020-05-19 15:26:42 +02003272 return dyn_cast<RecordDecl>(getDeclContext());
Anders Carlsson5d8645b2010-01-29 05:05:36 +00003273 }
3274
3275 RecordDecl *getParent() {
Haojian Wufcf07642020-05-19 15:26:42 +02003276 return dyn_cast<RecordDecl>(getDeclContext());
Anders Carlsson5d8645b2010-01-29 05:05:36 +00003277 }
Abramo Bagnara20c9e242011-03-08 11:07:11 +00003278
Craig Toppercbce6e92014-03-11 06:22:39 +00003279 SourceRange getSourceRange() const override LLVM_READONLY;
Abramo Bagnara20c9e242011-03-08 11:07:11 +00003280
Richard Smith0b87e072013-10-07 08:02:11 +00003281 /// Retrieves the canonical declaration of this field.
Craig Toppercbce6e92014-03-11 06:22:39 +00003282 FieldDecl *getCanonicalDecl() override { return getFirstDecl(); }
Rafael Espindola8db352d2013-10-17 15:37:26 +00003283 const FieldDecl *getCanonicalDecl() const { return getFirstDecl(); }
Richard Smith0b87e072013-10-07 08:02:11 +00003284
Chris Lattnerce3a7022007-01-24 02:10:37 +00003285 // Implement isa/cast/dyncast/etc.
John McCall180ef092010-01-29 01:45:37 +00003286 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
Alexis Hunted053252010-05-30 07:21:58 +00003287 static bool classofKind(Kind K) { return K >= firstField && K <= lastField; }
Podchishchaeva, Mariyaf4c886b2023-08-24 06:27:02 -07003288
3289 void printName(raw_ostream &OS, const PrintingPolicy &Policy) const override;
Chris Lattner1300fb92007-01-23 23:42:53 +00003290};
3291
James Dennettb8973efb2018-02-02 20:22:29 +00003292/// An instance of this object exists for each enum constant
Chris Lattnerc1915e22007-01-25 07:29:02 +00003293/// that is defined. For example, in "enum X {a,b}", each of a/b are
3294/// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a
Steve Narofff1e53692007-03-23 22:27:02 +00003295/// TagType for the X EnumDecl.
Craig Topper142f2702024-01-16 12:49:11 -08003296class EnumConstantDecl : public ValueDecl,
3297 public Mergeable<EnumConstantDecl>,
3298 public APIntStorage {
Ted Kremenek85956682008-05-30 16:14:41 +00003299 Stmt *Init; // an integer constant expression
Craig Topper142f2702024-01-16 12:49:11 -08003300 bool IsUnsigned;
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003301
Chris Lattnera7b32872008-03-15 06:12:44 +00003302protected:
Craig Topper142f2702024-01-16 12:49:11 -08003303 EnumConstantDecl(const ASTContext &C, DeclContext *DC, SourceLocation L,
Chris Lattnerc5ffed42008-04-04 06:12:32 +00003304 IdentifierInfo *Id, QualType T, Expr *E,
Craig Topper142f2702024-01-16 12:49:11 -08003305 const llvm::APSInt &V);
Ted Kremenekce20e8f2008-05-20 00:43:19 +00003306
Chris Lattnera7b32872008-03-15 06:12:44 +00003307public:
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003308 friend class StmtIteratorBase;
Steve Naroff46ba1eb2007-04-03 23:13:13 +00003309
Chris Lattnerbec41342008-04-22 18:39:57 +00003310 static EnumConstantDecl *Create(ASTContext &C, EnumDecl *DC,
Chris Lattnerc5ffed42008-04-04 06:12:32 +00003311 SourceLocation L, IdentifierInfo *Id,
3312 QualType T, Expr *E,
Douglas Gregor6e6ad602009-01-20 01:17:11 +00003313 const llvm::APSInt &V);
Chuanqi Xud86cc732024-04-25 11:43:13 +08003314 static EnumConstantDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
Fangrui Song6907ce22018-07-30 19:24:48 +00003315
Ted Kremenek85956682008-05-30 16:14:41 +00003316 const Expr *getInitExpr() const { return (const Expr*) Init; }
3317 Expr *getInitExpr() { return (Expr*) Init; }
Craig Topper142f2702024-01-16 12:49:11 -08003318 llvm::APSInt getInitVal() const {
3319 return llvm::APSInt(getValue(), IsUnsigned);
3320 }
Chris Lattner959bcdc2007-08-29 17:23:37 +00003321
Ted Kremenek85956682008-05-30 16:14:41 +00003322 void setInitExpr(Expr *E) { Init = (Stmt*) E; }
Craig Topper142f2702024-01-16 12:49:11 -08003323 void setInitVal(const ASTContext &C, const llvm::APSInt &V) {
3324 setValue(C, V);
3325 IsUnsigned = V.isUnsigned();
3326 }
Mike Stump11289f42009-09-09 15:08:12 +00003327
Craig Toppercbce6e92014-03-11 06:22:39 +00003328 SourceRange getSourceRange() const override LLVM_READONLY;
David Blaikie21bfbf82011-11-09 06:07:30 +00003329
Richard Smith01a73372013-10-15 22:02:41 +00003330 /// Retrieves the canonical declaration of this enumerator.
Craig Toppercbce6e92014-03-11 06:22:39 +00003331 EnumConstantDecl *getCanonicalDecl() override { return getFirstDecl(); }
Rafael Espindola8db352d2013-10-17 15:37:26 +00003332 const EnumConstantDecl *getCanonicalDecl() const { return getFirstDecl(); }
Richard Smith01a73372013-10-15 22:02:41 +00003333
Chris Lattnerc1915e22007-01-25 07:29:02 +00003334 // Implement isa/cast/dyncast/etc.
John McCall180ef092010-01-29 01:45:37 +00003335 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
John McCall180ef092010-01-29 01:45:37 +00003336 static bool classofKind(Kind K) { return K == EnumConstant; }
Chris Lattnerc1915e22007-01-25 07:29:02 +00003337};
3338
James Dennettb8973efb2018-02-02 20:22:29 +00003339/// Represents a field injected from an anonymous union/struct into the parent
3340/// scope. These are always implicit.
Richard Smith8cbd8952015-08-04 02:05:09 +00003341class IndirectFieldDecl : public ValueDecl,
3342 public Mergeable<IndirectFieldDecl> {
Francois Pichet783dd6e2010-11-21 06:08:52 +00003343 NamedDecl **Chaining;
Benjamin Kramer39593702010-11-21 14:11:41 +00003344 unsigned ChainingSize;
Francois Pichet783dd6e2010-11-21 06:08:52 +00003345
Richard Smith9f951822016-01-06 22:49:11 +00003346 IndirectFieldDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
Francois Pichet783dd6e2010-11-21 06:08:52 +00003347 DeclarationName N, QualType T,
David Majnemer59f77922016-06-24 04:05:48 +00003348 MutableArrayRef<NamedDecl *> CH);
Francois Pichet783dd6e2010-11-21 06:08:52 +00003349
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003350 void anchor() override;
3351
Francois Pichet783dd6e2010-11-21 06:08:52 +00003352public:
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003353 friend class ASTDeclReader;
3354
Francois Pichet783dd6e2010-11-21 06:08:52 +00003355 static IndirectFieldDecl *Create(ASTContext &C, DeclContext *DC,
Bill Wendlingfca51912024-04-11 00:33:40 +00003356 SourceLocation L, const IdentifierInfo *Id,
3357 QualType T,
3358 llvm::MutableArrayRef<NamedDecl *> CH);
David Blaikie21bfbf82011-11-09 06:07:30 +00003359
Chuanqi Xud86cc732024-04-25 11:43:13 +08003360 static IndirectFieldDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
Aaron Ballman13916082014-03-07 18:11:58 +00003361
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003362 using chain_iterator = ArrayRef<NamedDecl *>::const_iterator;
David Majnemer59f77922016-06-24 04:05:48 +00003363
3364 ArrayRef<NamedDecl *> chain() const {
serge-sans-paillea3c248d2023-01-06 16:56:23 +01003365 return llvm::ArrayRef(Chaining, ChainingSize);
Aaron Ballman13916082014-03-07 18:11:58 +00003366 }
David Majnemer59f77922016-06-24 04:05:48 +00003367 chain_iterator chain_begin() const { return chain().begin(); }
3368 chain_iterator chain_end() const { return chain().end(); }
Francois Pichet783dd6e2010-11-21 06:08:52 +00003369
Benjamin Kramer39593702010-11-21 14:11:41 +00003370 unsigned getChainingSize() const { return ChainingSize; }
Francois Pichet783dd6e2010-11-21 06:08:52 +00003371
3372 FieldDecl *getAnonField() const {
David Majnemer59f77922016-06-24 04:05:48 +00003373 assert(chain().size() >= 2);
3374 return cast<FieldDecl>(chain().back());
Francois Pichet783dd6e2010-11-21 06:08:52 +00003375 }
3376
3377 VarDecl *getVarDecl() const {
David Majnemer59f77922016-06-24 04:05:48 +00003378 assert(chain().size() >= 2);
3379 return dyn_cast<VarDecl>(chain().front());
Francois Pichet783dd6e2010-11-21 06:08:52 +00003380 }
3381
Richard Smith8cbd8952015-08-04 02:05:09 +00003382 IndirectFieldDecl *getCanonicalDecl() override { return getFirstDecl(); }
3383 const IndirectFieldDecl *getCanonicalDecl() const { return getFirstDecl(); }
3384
Francois Pichet783dd6e2010-11-21 06:08:52 +00003385 // Implement isa/cast/dyncast/etc.
3386 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
Francois Pichet783dd6e2010-11-21 06:08:52 +00003387 static bool classofKind(Kind K) { return K == IndirectField; }
Francois Pichet783dd6e2010-11-21 06:08:52 +00003388};
Chris Lattnerc1915e22007-01-25 07:29:02 +00003389
James Dennettb8973efb2018-02-02 20:22:29 +00003390/// Represents a declaration of a type.
Douglas Gregor6e6ad602009-01-20 01:17:11 +00003391class TypeDecl : public NamedDecl {
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003392 friend class ASTContext;
Chuanqi Xu55cdb3c2024-08-29 12:37:56 +08003393 friend class ASTReader;
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003394
James Dennett31a57342018-02-02 21:38:22 +00003395 /// This indicates the Type object that represents
Douglas Gregoreff93e02009-02-05 23:33:38 +00003396 /// this TypeDecl. It is a cache maintained by
3397 /// ASTContext::getTypedefType, ASTContext::getTagDeclType, and
3398 /// ASTContext::getTemplateTypeParmType, and TemplateTypeParmDecl.
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003399 mutable const Type *TypeForDecl = nullptr;
3400
James Dennett31a57342018-02-02 21:38:22 +00003401 /// The start of the source range for this declaration.
Abramo Bagnarab3185b02011-03-06 15:48:19 +00003402 SourceLocation LocStart;
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003403
3404 void anchor() override;
Douglas Gregordee1be82009-01-17 00:42:38 +00003405
Chris Lattner0659f482007-01-26 02:12:16 +00003406protected:
Bill Wendlingfca51912024-04-11 00:33:40 +00003407 TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, const IdentifierInfo *Id,
Abramo Bagnarab3185b02011-03-06 15:48:19 +00003408 SourceLocation StartL = SourceLocation())
Bill Wendlingfca51912024-04-11 00:33:40 +00003409 : NamedDecl(DK, DC, L, Id), LocStart(StartL) {}
Argyrios Kyrtzidis2951e142008-06-09 21:05:31 +00003410
Douglas Gregorf4d33272009-01-07 19:46:03 +00003411public:
Douglas Gregor4b12ba02012-07-17 23:09:36 +00003412 // Low-level accessor. If you just want the type defined by this node,
3413 // check out ASTContext::getTypeDeclType or one of
3414 // ASTContext::getTypedefType, ASTContext::getRecordType, etc. if you
3415 // already know the specific kind of node this is.
John McCall424cec92011-01-19 06:33:43 +00003416 const Type *getTypeForDecl() const { return TypeForDecl; }
3417 void setTypeForDecl(const Type *TD) { TypeForDecl = TD; }
Douglas Gregorb1fe2c92009-04-07 17:20:56 +00003418
Stephen Kelly724e9e52018-08-09 20:05:03 +00003419 SourceLocation getBeginLoc() const LLVM_READONLY { return LocStart; }
Abramo Bagnarab3185b02011-03-06 15:48:19 +00003420 void setLocStart(SourceLocation L) { LocStart = L; }
Craig Toppercbce6e92014-03-11 06:22:39 +00003421 SourceRange getSourceRange() const override LLVM_READONLY {
Abramo Bagnarab3185b02011-03-06 15:48:19 +00003422 if (LocStart.isValid())
3423 return SourceRange(LocStart, getLocation());
3424 else
3425 return SourceRange(getLocation());
3426 }
3427
Chris Lattner0659f482007-01-26 02:12:16 +00003428 // Implement isa/cast/dyncast/etc.
John McCall180ef092010-01-29 01:45:37 +00003429 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
Alexis Hunted053252010-05-30 07:21:58 +00003430 static bool classofKind(Kind K) { return K >= firstType && K <= lastType; }
Chris Lattner0659f482007-01-26 02:12:16 +00003431};
3432
Richard Smithdda56e42011-04-15 14:24:37 +00003433/// Base class for declarations which introduce a typedef-name.
3434class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> {
Richard Smith7027ffa2018-07-17 22:24:11 +00003435 struct alignas(8) ModedTInfo {
Benjamin Kramer4bb33342018-01-26 20:01:13 +00003436 TypeSourceInfo *first;
3437 QualType second;
3438 };
John McCall703a3f82009-10-24 08:00:42 +00003439
Benjamin Kramerdfb730a2018-01-26 14:14:11 +00003440 /// If int part is 0, we have not computed IsTransparentTag.
3441 /// Otherwise, IsTransparentTag is (getInt() >> 1).
3442 mutable llvm::PointerIntPair<
3443 llvm::PointerUnion<TypeSourceInfo *, ModedTInfo *>, 2>
3444 MaybeModedTInfo;
Argyrios Kyrtzidis3b25c912017-03-21 16:56:02 +00003445
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003446 void anchor() override;
3447
Douglas Gregorecd99b12010-05-25 19:53:14 +00003448protected:
Richard Smith053f6c62014-05-16 23:01:30 +00003449 TypedefNameDecl(Kind DK, ASTContext &C, DeclContext *DC,
3450 SourceLocation StartLoc, SourceLocation IdLoc,
Bill Wendlingfca51912024-04-11 00:33:40 +00003451 const IdentifierInfo *Id, TypeSourceInfo *TInfo)
Richard Smith053f6c62014-05-16 23:01:30 +00003452 : TypeDecl(DK, DC, IdLoc, Id, StartLoc), redeclarable_base(C),
Benjamin Kramerdfb730a2018-01-26 14:14:11 +00003453 MaybeModedTInfo(TInfo, 0) {}
Richard Smithdda56e42011-04-15 14:24:37 +00003454
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003455 using redeclarable_base = Redeclarable<TypedefNameDecl>;
3456
Richard Smithd7af8a32014-05-10 01:17:36 +00003457 TypedefNameDecl *getNextRedeclarationImpl() override {
3458 return getNextRedeclaration();
Richard Smithdda56e42011-04-15 14:24:37 +00003459 }
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003460
Craig Toppercbce6e92014-03-11 06:22:39 +00003461 TypedefNameDecl *getPreviousDeclImpl() override {
Douglas Gregorec9fd132012-01-14 16:38:05 +00003462 return getPreviousDecl();
3463 }
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003464
Craig Toppercbce6e92014-03-11 06:22:39 +00003465 TypedefNameDecl *getMostRecentDeclImpl() override {
Douglas Gregorec9fd132012-01-14 16:38:05 +00003466 return getMostRecentDecl();
3467 }
Douglas Gregorecd99b12010-05-25 19:53:14 +00003468
Chris Lattnera7b32872008-03-15 06:12:44 +00003469public:
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003470 using redecl_range = redeclarable_base::redecl_range;
3471 using redecl_iterator = redeclarable_base::redecl_iterator;
3472
Aaron Ballman211cd8c2014-03-07 00:10:58 +00003473 using redeclarable_base::redecls_begin;
3474 using redeclarable_base::redecls_end;
Aaron Ballman86c93902014-03-06 23:45:36 +00003475 using redeclarable_base::redecls;
Douglas Gregorec9fd132012-01-14 16:38:05 +00003476 using redeclarable_base::getPreviousDecl;
3477 using redeclarable_base::getMostRecentDecl;
Rafael Espindola3f9e4442013-10-19 02:13:21 +00003478 using redeclarable_base::isFirstDecl;
Douglas Gregor0bc8a212012-01-14 15:55:47 +00003479
Benjamin Kramerdfb730a2018-01-26 14:14:11 +00003480 bool isModed() const {
Kazu Hirata2a825cd22024-12-12 01:15:39 -08003481 return isa<ModedTInfo *>(MaybeModedTInfo.getPointer());
Benjamin Kramerdfb730a2018-01-26 14:14:11 +00003482 }
Enea Zaffanellaa86d88c2013-06-20 12:46:19 +00003483
John McCallbcd03502009-12-07 02:54:59 +00003484 TypeSourceInfo *getTypeSourceInfo() const {
Kazu Hirata2a825cd22024-12-12 01:15:39 -08003485 return isModed() ? cast<ModedTInfo *>(MaybeModedTInfo.getPointer())->first
3486 : cast<TypeSourceInfo *>(MaybeModedTInfo.getPointer());
Enea Zaffanellaa86d88c2013-06-20 12:46:19 +00003487 }
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003488
Enea Zaffanellaa86d88c2013-06-20 12:46:19 +00003489 QualType getUnderlyingType() const {
Kazu Hirata2a825cd22024-12-12 01:15:39 -08003490 return isModed() ? cast<ModedTInfo *>(MaybeModedTInfo.getPointer())->second
3491 : cast<TypeSourceInfo *>(MaybeModedTInfo.getPointer())
Benjamin Kramerdfb730a2018-01-26 14:14:11 +00003492 ->getType();
Enea Zaffanellaa86d88c2013-06-20 12:46:19 +00003493 }
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003494
Enea Zaffanellaa86d88c2013-06-20 12:46:19 +00003495 void setTypeSourceInfo(TypeSourceInfo *newType) {
Benjamin Kramerdfb730a2018-01-26 14:14:11 +00003496 MaybeModedTInfo.setPointer(newType);
Enea Zaffanellaa86d88c2013-06-20 12:46:19 +00003497 }
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003498
Enea Zaffanellaa86d88c2013-06-20 12:46:19 +00003499 void setModedTypeSourceInfo(TypeSourceInfo *unmodedTSI, QualType modedTy) {
Benjamin Kramerdfb730a2018-01-26 14:14:11 +00003500 MaybeModedTInfo.setPointer(new (getASTContext(), 8)
Benjamin Kramer4bb33342018-01-26 20:01:13 +00003501 ModedTInfo({unmodedTSI, modedTy}));
John McCall703a3f82009-10-24 08:00:42 +00003502 }
3503
Richard Smithdda56e42011-04-15 14:24:37 +00003504 /// Retrieves the canonical declaration of this typedef-name.
Craig Toppercbce6e92014-03-11 06:22:39 +00003505 TypedefNameDecl *getCanonicalDecl() override { return getFirstDecl(); }
Rafael Espindola8db352d2013-10-17 15:37:26 +00003506 const TypedefNameDecl *getCanonicalDecl() const { return getFirstDecl(); }
John McCall91f1a022009-12-30 00:31:22 +00003507
Richard Smitha5230222015-03-27 01:37:43 +00003508 /// Retrieves the tag declaration for which this is the typedef name for
3509 /// linkage purposes, if any.
Richard Smith42413142015-05-15 20:05:43 +00003510 ///
3511 /// \param AnyRedecl Look for the tag declaration in any redeclaration of
3512 /// this typedef declaration.
3513 TagDecl *getAnonDeclWithTypedefName(bool AnyRedecl = false) const;
Richard Smitha5230222015-03-27 01:37:43 +00003514
Argyrios Kyrtzidis3b25c912017-03-21 16:56:02 +00003515 /// Determines if this typedef shares a name and spelling location with its
3516 /// underlying tag type, as is the case with the NS_ENUM macro.
3517 bool isTransparentTag() const {
Benjamin Kramerdfb730a2018-01-26 14:14:11 +00003518 if (MaybeModedTInfo.getInt())
3519 return MaybeModedTInfo.getInt() & 0x2;
Argyrios Kyrtzidis3b25c912017-03-21 16:56:02 +00003520 return isTransparentTagSlow();
3521 }
3522
Richard Smithdda56e42011-04-15 14:24:37 +00003523 // Implement isa/cast/dyncast/etc.
3524 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
Richard Smithdda56e42011-04-15 14:24:37 +00003525 static bool classofKind(Kind K) {
3526 return K >= firstTypedefName && K <= lastTypedefName;
3527 }
Argyrios Kyrtzidis3b25c912017-03-21 16:56:02 +00003528
3529private:
3530 bool isTransparentTagSlow() const;
Richard Smithdda56e42011-04-15 14:24:37 +00003531};
3532
James Dennett31a57342018-02-02 21:38:22 +00003533/// Represents the declaration of a typedef-name via the 'typedef'
Richard Smithdda56e42011-04-15 14:24:37 +00003534/// type specifier.
3535class TypedefDecl : public TypedefNameDecl {
Richard Smith053f6c62014-05-16 23:01:30 +00003536 TypedefDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
Bill Wendlingfca51912024-04-11 00:33:40 +00003537 SourceLocation IdLoc, const IdentifierInfo *Id,
3538 TypeSourceInfo *TInfo)
Richard Smith053f6c62014-05-16 23:01:30 +00003539 : TypedefNameDecl(Typedef, C, DC, StartLoc, IdLoc, Id, TInfo) {}
Richard Smithdda56e42011-04-15 14:24:37 +00003540
3541public:
3542 static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
3543 SourceLocation StartLoc, SourceLocation IdLoc,
Bill Wendlingfca51912024-04-11 00:33:40 +00003544 const IdentifierInfo *Id, TypeSourceInfo *TInfo);
Chuanqi Xud86cc732024-04-25 11:43:13 +08003545 static TypedefDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
Craig Toppercbce6e92014-03-11 06:22:39 +00003546
3547 SourceRange getSourceRange() const override LLVM_READONLY;
Abramo Bagnaraea947882011-03-08 16:41:52 +00003548
Chris Lattner0659f482007-01-26 02:12:16 +00003549 // Implement isa/cast/dyncast/etc.
John McCall180ef092010-01-29 01:45:37 +00003550 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
John McCall180ef092010-01-29 01:45:37 +00003551 static bool classofKind(Kind K) { return K == Typedef; }
Chris Lattner0659f482007-01-26 02:12:16 +00003552};
3553
James Dennett31a57342018-02-02 21:38:22 +00003554/// Represents the declaration of a typedef-name via a C++11
Richard Smithdda56e42011-04-15 14:24:37 +00003555/// alias-declaration.
3556class TypeAliasDecl : public TypedefNameDecl {
Richard Smith43ccec8e2014-08-26 03:52:16 +00003557 /// The template for which this is the pattern, if any.
3558 TypeAliasTemplateDecl *Template;
3559
Richard Smith053f6c62014-05-16 23:01:30 +00003560 TypeAliasDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
Bill Wendlingfca51912024-04-11 00:33:40 +00003561 SourceLocation IdLoc, const IdentifierInfo *Id,
3562 TypeSourceInfo *TInfo)
Richard Smith43ccec8e2014-08-26 03:52:16 +00003563 : TypedefNameDecl(TypeAlias, C, DC, StartLoc, IdLoc, Id, TInfo),
3564 Template(nullptr) {}
Richard Smithdda56e42011-04-15 14:24:37 +00003565
3566public:
3567 static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC,
3568 SourceLocation StartLoc, SourceLocation IdLoc,
Bill Wendlingfca51912024-04-11 00:33:40 +00003569 const IdentifierInfo *Id, TypeSourceInfo *TInfo);
Chuanqi Xud86cc732024-04-25 11:43:13 +08003570 static TypeAliasDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
Richard Smithdda56e42011-04-15 14:24:37 +00003571
Craig Toppercbce6e92014-03-11 06:22:39 +00003572 SourceRange getSourceRange() const override LLVM_READONLY;
Richard Smithdda56e42011-04-15 14:24:37 +00003573
Richard Smith43ccec8e2014-08-26 03:52:16 +00003574 TypeAliasTemplateDecl *getDescribedAliasTemplate() const { return Template; }
3575 void setDescribedAliasTemplate(TypeAliasTemplateDecl *TAT) { Template = TAT; }
3576
Richard Smithdda56e42011-04-15 14:24:37 +00003577 // Implement isa/cast/dyncast/etc.
3578 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
Richard Smithdda56e42011-04-15 14:24:37 +00003579 static bool classofKind(Kind K) { return K == TypeAlias; }
3580};
3581
James Dennett31a57342018-02-02 21:38:22 +00003582/// Represents the declaration of a struct/union/class/enum.
Erich Keanef92f31c2018-08-01 20:48:16 +00003583class TagDecl : public TypeDecl,
3584 public DeclContext,
3585 public Redeclarable<TagDecl> {
3586 // This class stores some data in DeclContext::TagDeclBits
3587 // to save some space. Use the provided accessors to access it.
Argyrios Kyrtzidis554a07b2008-06-09 23:19:58 +00003588public:
John McCallfcc33b02009-09-05 00:15:47 +00003589 // This is really ugly.
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003590 using TagKind = TagTypeKind;
Argyrios Kyrtzidis554a07b2008-06-09 23:19:58 +00003591
3592private:
Argyrios Kyrtzidisd798c052016-07-15 18:11:33 +00003593 SourceRange BraceRange;
Argyrios Kyrtzidis575fa052009-07-14 03:17:17 +00003594
John McCall3e11ebe2010-03-15 10:12:16 +00003595 // A struct representing syntactic qualifier info,
3596 // to be used for the (uncommon) case of out-of-line declarations.
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003597 using ExtInfo = QualifierInfo;
John McCall3e11ebe2010-03-15 10:12:16 +00003598
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003599 /// If the (out-of-line) tag declaration name
John McCall3e11ebe2010-03-15 10:12:16 +00003600 /// is qualified, it points to the qualifier info (nns and range);
3601 /// otherwise, if the tag declaration is anonymous and it is part of
Richard Smithdda56e42011-04-15 14:24:37 +00003602 /// a typedef or alias, it points to the TypedefNameDecl (used for mangling);
David Majnemer50ce8352013-09-17 23:57:10 +00003603 /// otherwise, if the tag declaration is anonymous and it is used as a
3604 /// declaration specifier for variables, it points to the first VarDecl (used
3605 /// for mangling);
Richard Smithdda56e42011-04-15 14:24:37 +00003606 /// otherwise, it is a null (TypedefNameDecl) pointer.
David Majnemer00350522015-08-31 18:48:39 +00003607 llvm::PointerUnion<TypedefNameDecl *, ExtInfo *> TypedefNameDeclOrQualifier;
John McCall3e11ebe2010-03-15 10:12:16 +00003608
Kazu Hirata624cc702024-12-11 08:35:41 -08003609 bool hasExtInfo() const { return isa<ExtInfo *>(TypedefNameDeclOrQualifier); }
3610 ExtInfo *getExtInfo() { return cast<ExtInfo *>(TypedefNameDeclOrQualifier); }
John McCall3e11ebe2010-03-15 10:12:16 +00003611 const ExtInfo *getExtInfo() const {
Kazu Hirata624cc702024-12-11 08:35:41 -08003612 return cast<ExtInfo *>(TypedefNameDeclOrQualifier);
John McCall3e11ebe2010-03-15 10:12:16 +00003613 }
3614
Chris Lattner28743e22007-01-22 07:41:08 +00003615protected:
Richard Smith053f6c62014-05-16 23:01:30 +00003616 TagDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
3617 SourceLocation L, IdentifierInfo *Id, TagDecl *PrevDecl,
Erich Keanef92f31c2018-08-01 20:48:16 +00003618 SourceLocation StartL);
Mike Stump11289f42009-09-09 15:08:12 +00003619
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003620 using redeclarable_base = Redeclarable<TagDecl>;
3621
Richard Smithd7af8a32014-05-10 01:17:36 +00003622 TagDecl *getNextRedeclarationImpl() override {
3623 return getNextRedeclaration();
3624 }
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003625
Craig Toppercbce6e92014-03-11 06:22:39 +00003626 TagDecl *getPreviousDeclImpl() override {
Douglas Gregorec9fd132012-01-14 16:38:05 +00003627 return getPreviousDecl();
3628 }
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003629
Craig Toppercbce6e92014-03-11 06:22:39 +00003630 TagDecl *getMostRecentDeclImpl() override {
Douglas Gregorec9fd132012-01-14 16:38:05 +00003631 return getMostRecentDecl();
3632 }
Mike Stump11289f42009-09-09 15:08:12 +00003633
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003634 /// Completes the definition of this tag declaration.
Douglas Gregor8fb95122010-09-29 00:15:42 +00003635 ///
3636 /// This is a helper function for derived classes.
David Blaikie21bfbf82011-11-09 06:07:30 +00003637 void completeDefinition();
3638
Erich Keanef92f31c2018-08-01 20:48:16 +00003639 /// True if this decl is currently being defined.
3640 void setBeingDefined(bool V = true) { TagDeclBits.IsBeingDefined = V; }
3641
3642 /// Indicates whether it is possible for declarations of this kind
3643 /// to have an out-of-date definition.
3644 ///
3645 /// This option is only enabled when modules are enabled.
3646 void setMayHaveOutOfDateDef(bool V = true) {
3647 TagDeclBits.MayHaveOutOfDateDef = V;
3648 }
3649
Chris Lattner28743e22007-01-22 07:41:08 +00003650public:
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003651 friend class ASTDeclReader;
3652 friend class ASTDeclWriter;
3653
3654 using redecl_range = redeclarable_base::redecl_range;
3655 using redecl_iterator = redeclarable_base::redecl_iterator;
3656
Aaron Ballman211cd8c2014-03-07 00:10:58 +00003657 using redeclarable_base::redecls_begin;
3658 using redeclarable_base::redecls_end;
Aaron Ballman86c93902014-03-06 23:45:36 +00003659 using redeclarable_base::redecls;
Douglas Gregorec9fd132012-01-14 16:38:05 +00003660 using redeclarable_base::getPreviousDecl;
3661 using redeclarable_base::getMostRecentDecl;
Rafael Espindola3f9e4442013-10-19 02:13:21 +00003662 using redeclarable_base::isFirstDecl;
Douglas Gregor0bc8a212012-01-14 15:55:47 +00003663
Argyrios Kyrtzidisd798c052016-07-15 18:11:33 +00003664 SourceRange getBraceRange() const { return BraceRange; }
3665 void setBraceRange(SourceRange R) { BraceRange = R; }
Argyrios Kyrtzidis575fa052009-07-14 03:17:17 +00003666
James Dennett31a57342018-02-02 21:38:22 +00003667 /// Return SourceLocation representing start of source
Douglas Gregorec9c6ae2010-07-06 18:42:40 +00003668 /// range ignoring outer template declarations.
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003669 SourceLocation getInnerLocStart() const { return getBeginLoc(); }
Douglas Gregorec9c6ae2010-07-06 18:42:40 +00003670
James Dennett31a57342018-02-02 21:38:22 +00003671 /// Return SourceLocation representing start of source
Douglas Gregorec9c6ae2010-07-06 18:42:40 +00003672 /// range taking into account any outer template declarations.
3673 SourceLocation getOuterLocStart() const;
Craig Toppercbce6e92014-03-11 06:22:39 +00003674 SourceRange getSourceRange() const override LLVM_READONLY;
Mike Stump11289f42009-09-09 15:08:12 +00003675
Richard Smith053f6c62014-05-16 23:01:30 +00003676 TagDecl *getCanonicalDecl() override;
3677 const TagDecl *getCanonicalDecl() const {
John McCall84c16cf2009-11-12 03:15:40 +00003678 return const_cast<TagDecl*>(this)->getCanonicalDecl();
3679 }
Argyrios Kyrtzidis575fa052009-07-14 03:17:17 +00003680
James Dennett31a57342018-02-02 21:38:22 +00003681 /// Return true if this declaration is a completion definition of the type.
3682 /// Provided for consistency.
John McCallc265ad22010-08-31 22:21:26 +00003683 bool isThisDeclarationADefinition() const {
John McCallf937c022011-10-07 06:10:15 +00003684 return isCompleteDefinition();
John McCallc265ad22010-08-31 22:21:26 +00003685 }
3686
James Dennett31a57342018-02-02 21:38:22 +00003687 /// Return true if this decl has its body fully specified.
Erich Keanef92f31c2018-08-01 20:48:16 +00003688 bool isCompleteDefinition() const { return TagDeclBits.IsCompleteDefinition; }
3689
3690 /// True if this decl has its body fully specified.
3691 void setCompleteDefinition(bool V = true) {
3692 TagDeclBits.IsCompleteDefinition = V;
Chris Lattner7b9ace62007-01-23 20:11:08 +00003693 }
Douglas Gregore362cea2009-05-10 22:57:19 +00003694
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003695 /// Return true if this complete decl is
David Blaikie48ad6dc2013-07-13 21:08:14 +00003696 /// required to be complete for some existing use.
3697 bool isCompleteDefinitionRequired() const {
Erich Keanef92f31c2018-08-01 20:48:16 +00003698 return TagDeclBits.IsCompleteDefinitionRequired;
3699 }
3700
3701 /// True if this complete decl is
3702 /// required to be complete for some existing use.
3703 void setCompleteDefinitionRequired(bool V = true) {
3704 TagDeclBits.IsCompleteDefinitionRequired = V;
David Blaikie48ad6dc2013-07-13 21:08:14 +00003705 }
3706
James Dennett31a57342018-02-02 21:38:22 +00003707 /// Return true if this decl is currently being defined.
Erich Keanef92f31c2018-08-01 20:48:16 +00003708 bool isBeingDefined() const { return TagDeclBits.IsBeingDefined; }
Sebastian Redl9d8854e2010-08-02 18:27:05 +00003709
Erich Keanef92f31c2018-08-01 20:48:16 +00003710 /// True if this tag declaration is "embedded" (i.e., defined or declared
3711 /// for the very first time) in the syntax of a declarator.
Douglas Gregor5089c762010-02-12 17:40:34 +00003712 bool isEmbeddedInDeclarator() const {
Erich Keanef92f31c2018-08-01 20:48:16 +00003713 return TagDeclBits.IsEmbeddedInDeclarator;
Douglas Gregor586d0f92010-02-08 22:07:33 +00003714 }
3715
Erich Keanef92f31c2018-08-01 20:48:16 +00003716 /// True if this tag declaration is "embedded" (i.e., defined or declared
3717 /// for the very first time) in the syntax of a declarator.
3718 void setEmbeddedInDeclarator(bool isInDeclarator) {
3719 TagDeclBits.IsEmbeddedInDeclarator = isInDeclarator;
Argyrios Kyrtzidis201d3772011-09-30 22:11:31 +00003720 }
3721
Erich Keanef92f31c2018-08-01 20:48:16 +00003722 /// True if this tag is free standing, e.g. "struct foo;".
3723 bool isFreeStanding() const { return TagDeclBits.IsFreeStanding; }
3724
3725 /// True if this tag is free standing, e.g. "struct foo;".
3726 void setFreeStanding(bool isFreeStanding = true) {
3727 TagDeclBits.IsFreeStanding = isFreeStanding;
3728 }
3729
3730 /// Indicates whether it is possible for declarations of this kind
3731 /// to have an out-of-date definition.
3732 ///
3733 /// This option is only enabled when modules are enabled.
3734 bool mayHaveOutOfDateDef() const { return TagDeclBits.MayHaveOutOfDateDef; }
3735
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003736 /// Whether this declaration declares a type that is
Douglas Gregore362cea2009-05-10 22:57:19 +00003737 /// dependent, i.e., a type that somehow depends on template
3738 /// parameters.
Douglas Gregor9e927ab2009-05-28 16:34:51 +00003739 bool isDependentType() const { return isDependentContext(); }
Douglas Gregore362cea2009-05-10 22:57:19 +00003740
Volodymyr Sapsaifa4a0f12022-02-01 15:03:59 -08003741 /// Whether this declaration was a definition in some module but was forced
3742 /// to be a declaration.
3743 ///
3744 /// Useful for clients checking if a module has a definition of a specific
3745 /// symbol and not interested in the final AST with deduplicated definitions.
3746 bool isThisDeclarationADemotedDefinition() const {
3747 return TagDeclBits.IsThisDeclarationADemotedDefinition;
3748 }
3749
3750 /// Mark a definition as a declaration and maintain information it _was_
3751 /// a definition.
3752 void demoteThisDefinitionToDeclaration() {
3753 assert(isCompleteDefinition() &&
3754 "Should demote definitions only, not forward declarations");
3755 setCompleteDefinition(false);
3756 TagDeclBits.IsThisDeclarationADemotedDefinition = true;
3757 }
3758
James Dennett31a57342018-02-02 21:38:22 +00003759 /// Starts the definition of this tag declaration.
Mike Stump11289f42009-09-09 15:08:12 +00003760 ///
Douglas Gregordee1be82009-01-17 00:42:38 +00003761 /// This method should be invoked at the beginning of the definition
3762 /// of this tag declaration. It will set the tag type into a state
3763 /// where it is in the process of being defined.
3764 void startDefinition();
3765
James Dennett31a57342018-02-02 21:38:22 +00003766 /// Returns the TagDecl that actually defines this
Ted Kremenek21475702008-09-05 17:16:31 +00003767 /// struct/union/class/enum. When determining whether or not a
John McCallf937c022011-10-07 06:10:15 +00003768 /// struct/union/class/enum has a definition, one should use this
3769 /// method as opposed to 'isDefinition'. 'isDefinition' indicates
3770 /// whether or not a specific TagDecl is defining declaration, not
3771 /// whether or not the struct/union/class/enum type is defined.
3772 /// This method returns NULL if there is no TagDecl that defines
3773 /// the struct/union/class/enum.
3774 TagDecl *getDefinition() const;
Mike Stump11289f42009-09-09 15:08:12 +00003775
Alp Tokera030cd02014-05-05 12:38:48 +00003776 StringRef getKindName() const {
Abramo Bagnara6150c882010-05-11 21:36:43 +00003777 return TypeWithKeyword::getTagTypeKindName(getTagKind());
Chris Lattnerfb0724632007-01-23 05:45:31 +00003778 }
Argyrios Kyrtzidis554a07b2008-06-09 23:19:58 +00003779
3780 TagKind getTagKind() const {
Erich Keanef92f31c2018-08-01 20:48:16 +00003781 return static_cast<TagKind>(TagDeclBits.TagDeclKind);
Argyrios Kyrtzidis554a07b2008-06-09 23:19:58 +00003782 }
3783
Vlad Serebrennikovedd690b2023-11-03 21:45:39 +04003784 void setTagKind(TagKind TK) {
3785 TagDeclBits.TagDeclKind = llvm::to_underlying(TK);
3786 }
Douglas Gregor1daeb692009-04-13 18:14:40 +00003787
Vlad Serebrennikovedd690b2023-11-03 21:45:39 +04003788 bool isStruct() const { return getTagKind() == TagTypeKind::Struct; }
3789 bool isInterface() const { return getTagKind() == TagTypeKind::Interface; }
3790 bool isClass() const { return getTagKind() == TagTypeKind::Class; }
3791 bool isUnion() const { return getTagKind() == TagTypeKind::Union; }
3792 bool isEnum() const { return getTagKind() == TagTypeKind::Enum; }
Mike Stump11289f42009-09-09 15:08:12 +00003793
John McCall5ea95772013-03-09 00:54:27 +00003794 /// Is this tag type named, either directly or via being defined in
3795 /// a typedef of this type?
3796 ///
3797 /// C++11 [basic.link]p8:
3798 /// A type is said to have linkage if and only if:
3799 /// - it is a class or enumeration type that is named (or has a
3800 /// name for linkage purposes) and the name has linkage; ...
3801 /// C++11 [dcl.typedef]p9:
3802 /// If the typedef declaration defines an unnamed class (or enum),
3803 /// the first typedef-name declared by the declaration to be that
3804 /// class type (or enum type) is used to denote the class type (or
3805 /// enum type) for linkage purposes only.
3806 ///
3807 /// C does not have an analogous rule, but the same concept is
3808 /// nonetheless useful in some places.
3809 bool hasNameForLinkage() const {
3810 return (getDeclName() || getTypedefNameForAnonDecl());
3811 }
3812
David Majnemer50ce8352013-09-17 23:57:10 +00003813 TypedefNameDecl *getTypedefNameForAnonDecl() const {
David Majnemer00350522015-08-31 18:48:39 +00003814 return hasExtInfo() ? nullptr
Kazu Hirata624cc702024-12-11 08:35:41 -08003815 : cast<TypedefNameDecl *>(TypedefNameDeclOrQualifier);
David Majnemer50ce8352013-09-17 23:57:10 +00003816 }
3817
Richard Smithdda56e42011-04-15 14:24:37 +00003818 void setTypedefNameForAnonDecl(TypedefNameDecl *TDD);
Abramo Bagnarada41d0c2010-06-12 08:15:14 +00003819
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003820 /// Retrieve the nested-name-specifier that qualifies the name of this
Douglas Gregor14454802011-02-25 02:25:35 +00003821 /// declaration, if it was present in the source.
John McCall3e11ebe2010-03-15 10:12:16 +00003822 NestedNameSpecifier *getQualifier() const {
Douglas Gregor14454802011-02-25 02:25:35 +00003823 return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier()
Craig Topper34b4c432014-05-06 06:48:52 +00003824 : nullptr;
John McCall3e11ebe2010-03-15 10:12:16 +00003825 }
David Blaikie21bfbf82011-11-09 06:07:30 +00003826
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003827 /// Retrieve the nested-name-specifier (with source-location
David Blaikie21bfbf82011-11-09 06:07:30 +00003828 /// information) that qualifies the name of this declaration, if it was
Douglas Gregor14454802011-02-25 02:25:35 +00003829 /// present in the source.
3830 NestedNameSpecifierLoc getQualifierLoc() const {
3831 return hasExtInfo() ? getExtInfo()->QualifierLoc
3832 : NestedNameSpecifierLoc();
John McCall3e11ebe2010-03-15 10:12:16 +00003833 }
David Blaikie21bfbf82011-11-09 06:07:30 +00003834
Douglas Gregor14454802011-02-25 02:25:35 +00003835 void setQualifierInfo(NestedNameSpecifierLoc QualifierLoc);
Mike Stump11289f42009-09-09 15:08:12 +00003836
Abramo Bagnarada41d0c2010-06-12 08:15:14 +00003837 unsigned getNumTemplateParameterLists() const {
3838 return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0;
3839 }
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003840
Abramo Bagnarada41d0c2010-06-12 08:15:14 +00003841 TemplateParameterList *getTemplateParameterList(unsigned i) const {
3842 assert(i < getNumTemplateParameterLists());
3843 return getExtInfo()->TemplParamLists[i];
3844 }
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003845
Aaron Ballman05667912023-07-08 08:30:58 -04003846 using TypeDecl::printName;
Aaron Ballman19e984e2022-10-14 08:17:16 -04003847 void printName(raw_ostream &OS, const PrintingPolicy &Policy) const override;
3848
Benjamin Kramer9cc210652015-08-05 09:40:49 +00003849 void setTemplateParameterListsInfo(ASTContext &Context,
3850 ArrayRef<TemplateParameterList *> TPLists);
Abramo Bagnarada41d0c2010-06-12 08:15:14 +00003851
Chris Lattner28743e22007-01-22 07:41:08 +00003852 // Implement isa/cast/dyncast/etc.
John McCall180ef092010-01-29 01:45:37 +00003853 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
Alexis Hunted053252010-05-30 07:21:58 +00003854 static bool classofKind(Kind K) { return K >= firstTag && K <= lastTag; }
Douglas Gregordee1be82009-01-17 00:42:38 +00003855
3856 static DeclContext *castToDeclContext(const TagDecl *D) {
3857 return static_cast<DeclContext *>(const_cast<TagDecl*>(D));
3858 }
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003859
Douglas Gregordee1be82009-01-17 00:42:38 +00003860 static TagDecl *castFromDeclContext(const DeclContext *DC) {
3861 return static_cast<TagDecl *>(const_cast<DeclContext*>(DC));
3862 }
Chris Lattner28743e22007-01-22 07:41:08 +00003863};
3864
James Dennett31a57342018-02-02 21:38:22 +00003865/// Represents an enum. In C++11, enums can be forward-declared
Richard Smith4b38ded2012-03-14 23:13:10 +00003866/// with a fixed underlying type, and in C we allow them to be forward-declared
3867/// with no underlying type as an extension.
Douglas Gregor82ac25e2009-01-08 20:45:30 +00003868class EnumDecl : public TagDecl {
Erich Keanef92f31c2018-08-01 20:48:16 +00003869 // This class stores some data in DeclContext::EnumDeclBits
3870 // to save some space. Use the provided accessors to access it.
3871
James Dennett31a57342018-02-02 21:38:22 +00003872 /// This represent the integer type that the enum corresponds
Chris Lattner1c1f9322007-08-28 18:24:31 +00003873 /// to for code generation purposes. Note that the enumerator constants may
3874 /// have a different type than this does.
Douglas Gregor0bf31402010-10-08 23:50:27 +00003875 ///
3876 /// If the underlying integer type was explicitly stated in the source
3877 /// code, this is a TypeSourceInfo* for that type. Otherwise this type
3878 /// was automatically deduced somehow, and this is a Type*.
3879 ///
3880 /// Normally if IsFixed(), this would contain a TypeSourceInfo*, but in
3881 /// some cases it won't.
3882 ///
3883 /// The underlying type of an enumeration never has any qualifiers, so
3884 /// we can get away with just storing a raw Type*, and thus save an
3885 /// extra pointer when TypeSourceInfo is needed.
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003886 llvm::PointerUnion<const Type *, TypeSourceInfo *> IntegerType;
Douglas Gregor7a749382009-05-27 17:20:35 +00003887
James Dennett31a57342018-02-02 21:38:22 +00003888 /// The integer type that values of this type should
John McCall56774992009-12-09 09:09:27 +00003889 /// promote to. In C, enumerators are generally of an integer type
3890 /// directly, but gcc-style large enumerators (and all enumerators
3891 /// in C++) are of the enum type instead.
3892 QualType PromotionType;
3893
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003894 /// If this enumeration is an instantiation of a member enumeration
Richard Smith4b38ded2012-03-14 23:13:10 +00003895 /// of a class template specialization, this is the member specialization
3896 /// information.
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003897 MemberSpecializationInfo *SpecializationInfo = nullptr;
Douglas Gregor7a749382009-05-27 17:20:35 +00003898
Richard Trieuab4d7302018-07-25 22:52:05 +00003899 /// Store the ODRHash after first calculation.
Erich Keanef92f31c2018-08-01 20:48:16 +00003900 /// The corresponding flag HasODRHash is in EnumDeclBits
3901 /// and can be accessed with the provided accessors.
Richard Trieuab4d7302018-07-25 22:52:05 +00003902 unsigned ODRHash;
3903
Richard Smith053f6c62014-05-16 23:01:30 +00003904 EnumDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
3905 SourceLocation IdLoc, IdentifierInfo *Id, EnumDecl *PrevDecl,
Erich Keanef92f31c2018-08-01 20:48:16 +00003906 bool Scoped, bool ScopedUsingClassTag, bool Fixed);
Richard Smith4b38ded2012-03-14 23:13:10 +00003907
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003908 void anchor() override;
3909
Richard Smith4b38ded2012-03-14 23:13:10 +00003910 void setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED,
3911 TemplateSpecializationKind TSK);
Erich Keanef92f31c2018-08-01 20:48:16 +00003912
3913 /// Sets the width in bits required to store all the
3914 /// non-negative enumerators of this enum.
3915 void setNumPositiveBits(unsigned Num) {
3916 EnumDeclBits.NumPositiveBits = Num;
3917 assert(EnumDeclBits.NumPositiveBits == Num && "can't store this bitcount");
3918 }
3919
3920 /// Returns the width in bits required to store all the
3921 /// negative enumerators of this enum. (see getNumNegativeBits)
3922 void setNumNegativeBits(unsigned Num) { EnumDeclBits.NumNegativeBits = Num; }
3923
Adrian Prantl2b366e752020-03-03 12:54:04 -08003924public:
Erich Keanef92f31c2018-08-01 20:48:16 +00003925 /// True if this tag declaration is a scoped enumeration. Only
3926 /// possible in C++11 mode.
3927 void setScoped(bool Scoped = true) { EnumDeclBits.IsScoped = Scoped; }
3928
3929 /// If this tag declaration is a scoped enum,
3930 /// then this is true if the scoped enum was declared using the class
3931 /// tag, false if it was declared with the struct tag. No meaning is
3932 /// associated if this tag declaration is not a scoped enum.
3933 void setScopedUsingClassTag(bool ScopedUCT = true) {
3934 EnumDeclBits.IsScopedUsingClassTag = ScopedUCT;
3935 }
3936
3937 /// True if this is an Objective-C, C++11, or
3938 /// Microsoft-style enumeration with a fixed underlying type.
3939 void setFixed(bool Fixed = true) { EnumDeclBits.IsFixed = Fixed; }
3940
Adrian Prantl2b366e752020-03-03 12:54:04 -08003941private:
Erich Keanef92f31c2018-08-01 20:48:16 +00003942 /// True if a valid hash is stored in ODRHash.
3943 bool hasODRHash() const { return EnumDeclBits.HasODRHash; }
3944 void setHasODRHash(bool Hash = true) { EnumDeclBits.HasODRHash = Hash; }
3945
Chris Lattnera7b32872008-03-15 06:12:44 +00003946public:
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003947 friend class ASTDeclReader;
3948
Craig Toppercbce6e92014-03-11 06:22:39 +00003949 EnumDecl *getCanonicalDecl() override {
John McCall59660882009-08-29 08:11:13 +00003950 return cast<EnumDecl>(TagDecl::getCanonicalDecl());
3951 }
John McCall84c16cf2009-11-12 03:15:40 +00003952 const EnumDecl *getCanonicalDecl() const {
Rafael Espindola7b56f6c2013-10-19 16:55:03 +00003953 return const_cast<EnumDecl*>(this)->getCanonicalDecl();
John McCall84c16cf2009-11-12 03:15:40 +00003954 }
John McCall59660882009-08-29 08:11:13 +00003955
Douglas Gregorec9fd132012-01-14 16:38:05 +00003956 EnumDecl *getPreviousDecl() {
Aaron Ballman5116a8e2013-11-06 22:39:46 +00003957 return cast_or_null<EnumDecl>(
3958 static_cast<TagDecl *>(this)->getPreviousDecl());
Douglas Gregorec9fd132012-01-14 16:38:05 +00003959 }
Rafael Espindola7b56f6c2013-10-19 16:55:03 +00003960 const EnumDecl *getPreviousDecl() const {
3961 return const_cast<EnumDecl*>(this)->getPreviousDecl();
Douglas Gregorec9fd132012-01-14 16:38:05 +00003962 }
Rafael Espindola7b56f6c2013-10-19 16:55:03 +00003963
Douglas Gregorec9fd132012-01-14 16:38:05 +00003964 EnumDecl *getMostRecentDecl() {
Aaron Ballman5116a8e2013-11-06 22:39:46 +00003965 return cast<EnumDecl>(static_cast<TagDecl *>(this)->getMostRecentDecl());
Argyrios Kyrtzidisb5fcdc22010-07-04 21:44:47 +00003966 }
Rafael Espindola7b56f6c2013-10-19 16:55:03 +00003967 const EnumDecl *getMostRecentDecl() const {
3968 return const_cast<EnumDecl*>(this)->getMostRecentDecl();
3969 }
Argyrios Kyrtzidisb5fcdc22010-07-04 21:44:47 +00003970
Richard Smith4b38ded2012-03-14 23:13:10 +00003971 EnumDecl *getDefinition() const {
3972 return cast_or_null<EnumDecl>(TagDecl::getDefinition());
3973 }
3974
Chris Lattnerbec41342008-04-22 18:39:57 +00003975 static EnumDecl *Create(ASTContext &C, DeclContext *DC,
Abramo Bagnara29c2d462011-03-09 14:09:51 +00003976 SourceLocation StartLoc, SourceLocation IdLoc,
3977 IdentifierInfo *Id, EnumDecl *PrevDecl,
Abramo Bagnara0e05e242010-12-03 18:54:17 +00003978 bool IsScoped, bool IsScopedUsingClassTag,
3979 bool IsFixed);
Chuanqi Xud86cc732024-04-25 11:43:13 +08003980 static EnumDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
Mike Stump11289f42009-09-09 15:08:12 +00003981
Kadir Cetinkayaffa96f02021-10-06 20:25:26 +02003982 /// Overrides to provide correct range when there's an enum-base specifier
3983 /// with forward declarations.
3984 SourceRange getSourceRange() const override LLVM_READONLY;
3985
James Dennett31a57342018-02-02 21:38:22 +00003986 /// When created, the EnumDecl corresponds to a
Douglas Gregor91f84212008-12-11 16:49:14 +00003987 /// forward-declared enum. This method is used to mark the
James Dennett31a57342018-02-02 21:38:22 +00003988 /// declaration as being defined; its enumerators have already been
Douglas Gregor91f84212008-12-11 16:49:14 +00003989 /// added (via DeclContext::addDecl). NewType is the new underlying
3990 /// type of the enumeration type.
Douglas Gregord5058122010-02-11 01:19:42 +00003991 void completeDefinition(QualType NewType,
John McCall9aa35be2010-05-06 08:49:23 +00003992 QualType PromotionType,
3993 unsigned NumPositiveBits,
3994 unsigned NumNegativeBits);
Mike Stump11289f42009-09-09 15:08:12 +00003995
James Dennett31a57342018-02-02 21:38:22 +00003996 // Iterates through the enumerators of this enumeration.
Eugene Zelenkode0215c2017-11-13 23:01:27 +00003997 using enumerator_iterator = specific_decl_iterator<EnumConstantDecl>;
3998 using enumerator_range =
3999 llvm::iterator_range<specific_decl_iterator<EnumConstantDecl>>;
Aaron Ballman23a6dcb2014-03-08 18:45:14 +00004000
4001 enumerator_range enumerators() const {
4002 return enumerator_range(enumerator_begin(), enumerator_end());
4003 }
Douglas Gregor91f84212008-12-11 16:49:14 +00004004
Mike Stump11289f42009-09-09 15:08:12 +00004005 enumerator_iterator enumerator_begin() const {
Richard Smith4b38ded2012-03-14 23:13:10 +00004006 const EnumDecl *E = getDefinition();
Douglas Gregora46d6612010-06-22 14:45:56 +00004007 if (!E)
4008 E = this;
4009 return enumerator_iterator(E->decls_begin());
Douglas Gregor91f84212008-12-11 16:49:14 +00004010 }
4011
Mike Stump11289f42009-09-09 15:08:12 +00004012 enumerator_iterator enumerator_end() const {
Richard Smith4b38ded2012-03-14 23:13:10 +00004013 const EnumDecl *E = getDefinition();
Douglas Gregora46d6612010-06-22 14:45:56 +00004014 if (!E)
4015 E = this;
4016 return enumerator_iterator(E->decls_end());
Douglas Gregor91f84212008-12-11 16:49:14 +00004017 }
4018
James Dennett31a57342018-02-02 21:38:22 +00004019 /// Return the integer type that enumerators should promote to.
John McCall56774992009-12-09 09:09:27 +00004020 QualType getPromotionType() const { return PromotionType; }
4021
James Dennett31a57342018-02-02 21:38:22 +00004022 /// Set the promotion type.
John McCall56774992009-12-09 09:09:27 +00004023 void setPromotionType(QualType T) { PromotionType = T; }
4024
James Dennett31a57342018-02-02 21:38:22 +00004025 /// Return the integer type this enum decl corresponds to.
Richard Smith8bcc0862014-01-08 01:16:19 +00004026 /// This returns a null QualType for an enum forward definition with no fixed
4027 /// underlying type.
Douglas Gregor0bf31402010-10-08 23:50:27 +00004028 QualType getIntegerType() const {
4029 if (!IntegerType)
4030 return QualType();
Kazu Hiratac9699642025-01-16 08:44:15 -08004031 if (const Type *T = dyn_cast<const Type *>(IntegerType))
Douglas Gregor0bf31402010-10-08 23:50:27 +00004032 return QualType(T, 0);
Kazu Hirata624cc702024-12-11 08:35:41 -08004033 return cast<TypeSourceInfo *>(IntegerType)->getType().getUnqualifiedType();
Douglas Gregor0bf31402010-10-08 23:50:27 +00004034 }
Douglas Gregor1daeb692009-04-13 18:14:40 +00004035
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004036 /// Set the underlying integer type.
Douglas Gregor0cdc8322010-12-10 17:03:06 +00004037 void setIntegerType(QualType T) { IntegerType = T.getTypePtrOrNull(); }
Douglas Gregor0bf31402010-10-08 23:50:27 +00004038
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004039 /// Set the underlying integer type source info.
Richard Smith8bcc0862014-01-08 01:16:19 +00004040 void setIntegerTypeSourceInfo(TypeSourceInfo *TInfo) { IntegerType = TInfo; }
Douglas Gregor0bf31402010-10-08 23:50:27 +00004041
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004042 /// Return the type source info for the underlying integer type,
Douglas Gregor0bf31402010-10-08 23:50:27 +00004043 /// if no type source info exists, return 0.
Richard Smith8bcc0862014-01-08 01:16:19 +00004044 TypeSourceInfo *getIntegerTypeSourceInfo() const {
Kazu Hirata563c7c52025-01-25 14:05:01 -08004045 return dyn_cast_if_present<TypeSourceInfo *>(IntegerType);
Douglas Gregor0bf31402010-10-08 23:50:27 +00004046 }
Douglas Gregor1daeb692009-04-13 18:14:40 +00004047
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004048 /// Retrieve the source range that covers the underlying type if
Alp Tokerb9fa5122014-01-06 11:31:18 +00004049 /// specified.
4050 SourceRange getIntegerTypeRange() const LLVM_READONLY;
4051
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004052 /// Returns the width in bits required to store all the
John McCall9aa35be2010-05-06 08:49:23 +00004053 /// non-negative enumerators of this enum.
Erich Keanef92f31c2018-08-01 20:48:16 +00004054 unsigned getNumPositiveBits() const { return EnumDeclBits.NumPositiveBits; }
John McCall9aa35be2010-05-06 08:49:23 +00004055
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004056 /// Returns the width in bits required to store all the
John McCall9aa35be2010-05-06 08:49:23 +00004057 /// negative enumerators of this enum. These widths include
4058 /// the rightmost leading 1; that is:
David Blaikie21bfbf82011-11-09 06:07:30 +00004059 ///
John McCall9aa35be2010-05-06 08:49:23 +00004060 /// MOST NEGATIVE ENUMERATOR PATTERN NUM NEGATIVE BITS
4061 /// ------------------------ ------- -----------------
4062 /// -1 1111111 1
4063 /// -10 1110110 5
4064 /// -101 1001011 8
Erich Keanef92f31c2018-08-01 20:48:16 +00004065 unsigned getNumNegativeBits() const { return EnumDeclBits.NumNegativeBits; }
John McCall9aa35be2010-05-06 08:49:23 +00004066
Shafik Yaghmourb36453532022-07-28 15:26:15 -07004067 /// Calculates the [Min,Max) values the enum can store based on the
4068 /// NumPositiveBits and NumNegativeBits. This matters for enums that do not
4069 /// have a fixed underlying type.
4070 void getValueRange(llvm::APInt &Max, llvm::APInt &Min) const;
4071
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004072 /// Returns true if this is a C++11 scoped enumeration.
Erich Keanef92f31c2018-08-01 20:48:16 +00004073 bool isScoped() const { return EnumDeclBits.IsScoped; }
Douglas Gregor0bf31402010-10-08 23:50:27 +00004074
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004075 /// Returns true if this is a C++11 scoped enumeration.
Abramo Bagnara0e05e242010-12-03 18:54:17 +00004076 bool isScopedUsingClassTag() const {
Erich Keanef92f31c2018-08-01 20:48:16 +00004077 return EnumDeclBits.IsScopedUsingClassTag;
Abramo Bagnara0e05e242010-12-03 18:54:17 +00004078 }
4079
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004080 /// Returns true if this is an Objective-C, C++11, or
Adrian Prantlc60dc712013-04-19 19:56:39 +00004081 /// Microsoft-style enumeration with a fixed underlying type.
Erich Keanef92f31c2018-08-01 20:48:16 +00004082 bool isFixed() const { return EnumDeclBits.IsFixed; }
Douglas Gregor0bf31402010-10-08 23:50:27 +00004083
Richard Trieuab4d7302018-07-25 22:52:05 +00004084 unsigned getODRHash();
4085
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004086 /// Returns true if this can be considered a complete type.
Douglas Gregor0bf31402010-10-08 23:50:27 +00004087 bool isComplete() const {
Reid Klecknerb0a17ed2018-02-12 17:37:06 +00004088 // IntegerType is set for fixed type enums and non-fixed but implicitly
4089 // int-sized Microsoft enums.
4090 return isCompleteDefinition() || IntegerType;
Douglas Gregor0bf31402010-10-08 23:50:27 +00004091 }
4092
Akira Hatanaka3c268af2017-03-21 02:23:00 +00004093 /// Returns true if this enum is either annotated with
4094 /// enum_extensibility(closed) or isn't annotated with enum_extensibility.
4095 bool isClosed() const;
4096
4097 /// Returns true if this enum is annotated with flag_enum and isn't annotated
4098 /// with enum_extensibility(open).
4099 bool isClosedFlag() const;
4100
4101 /// Returns true if this enum is annotated with neither flag_enum nor
4102 /// enum_extensibility(open).
4103 bool isClosedNonFlag() const;
4104
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004105 /// Retrieve the enum definition from which this enumeration could
Richard Smith6739a102016-05-05 00:56:12 +00004106 /// be instantiated, if it is an instantiation (rather than a non-template).
4107 EnumDecl *getTemplateInstantiationPattern() const;
4108
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004109 /// Returns the enumeration (declared within the template)
Douglas Gregor7a749382009-05-27 17:20:35 +00004110 /// from which this enumeration type was instantiated, or NULL if
4111 /// this enumeration was not instantiated from any template.
Richard Smith4b38ded2012-03-14 23:13:10 +00004112 EnumDecl *getInstantiatedFromMemberEnum() const;
4113
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004114 /// If this enumeration is a member of a specialization of a
Richard Smith7d137e32012-03-23 03:33:32 +00004115 /// templated class, determine what kind of template specialization
4116 /// or instantiation this is.
4117 TemplateSpecializationKind getTemplateSpecializationKind() const;
4118
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004119 /// For an enumeration member that was instantiated from a member
Richard Smith7d137e32012-03-23 03:33:32 +00004120 /// enumeration of a templated class, set the template specialiation kind.
4121 void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
4122 SourceLocation PointOfInstantiation = SourceLocation());
4123
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004124 /// If this enumeration is an instantiation of a member enumeration of
Richard Smith4b38ded2012-03-14 23:13:10 +00004125 /// a class template specialization, retrieves the member specialization
4126 /// information.
4127 MemberSpecializationInfo *getMemberSpecializationInfo() const {
4128 return SpecializationInfo;
Douglas Gregor7a749382009-05-27 17:20:35 +00004129 }
4130
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004131 /// Specify that this enumeration is an instantiation of the
Richard Smith4b38ded2012-03-14 23:13:10 +00004132 /// member enumeration ED.
4133 void setInstantiationOfMemberEnum(EnumDecl *ED,
4134 TemplateSpecializationKind TSK) {
4135 setInstantiationOfMemberEnum(getASTContext(), ED, TSK);
4136 }
Douglas Gregor7a749382009-05-27 17:20:35 +00004137
John McCall180ef092010-01-29 01:45:37 +00004138 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
John McCall180ef092010-01-29 01:45:37 +00004139 static bool classofKind(Kind K) { return K == Enum; }
Chris Lattner5f521502007-01-25 06:27:24 +00004140};
4141
Vlad Serebrennikov24228ae2023-11-01 19:47:06 +04004142/// Enum that represents the different ways arguments are passed to and
4143/// returned from function calls. This takes into account the target-specific
4144/// and version-specific rules along with the rules determined by the
4145/// language.
Vlad Serebrennikova8ead562023-11-01 20:38:28 +04004146enum class RecordArgPassingKind {
Vlad Serebrennikov24228ae2023-11-01 19:47:06 +04004147 /// The argument of this type can be passed directly in registers.
4148 CanPassInRegs,
4149
4150 /// The argument of this type cannot be passed directly in registers.
4151 /// Records containing this type as a subobject are not forced to be passed
4152 /// indirectly. This value is used only in C++. This value is required by
4153 /// C++ because, in uncommon situations, it is possible for a class to have
4154 /// only trivial copy/move constructors even when one of its subobjects has
4155 /// a non-trivial copy/move constructor (if e.g. the corresponding copy/move
4156 /// constructor in the derived class is deleted).
4157 CannotPassInRegs,
4158
4159 /// The argument of this type cannot be passed directly in registers.
4160 /// Records containing this type as a subobject are forced to be passed
4161 /// indirectly.
4162 CanNeverPassInRegs
4163};
4164
James Dennett31a57342018-02-02 21:38:22 +00004165/// Represents a struct/union/class. For example:
Chris Lattner90c26ba2007-09-30 08:13:22 +00004166/// struct X; // Forward declaration, no "body".
4167/// union Y { int A, B; }; // Has body with members A and B (FieldDecls).
Steve Naroffb5fc2552008-02-11 21:52:37 +00004168/// This decl will be marked invalid if *any* members are invalid.
Douglas Gregor82ac25e2009-01-08 20:45:30 +00004169class RecordDecl : public TagDecl {
Erich Keanef92f31c2018-08-01 20:48:16 +00004170 // This class stores some data in DeclContext::RecordDeclBits
4171 // to save some space. Use the provided accessors to access it.
Akira Hatanakae6313ac2018-04-09 22:48:22 +00004172public:
Erich Keanef92f31c2018-08-01 20:48:16 +00004173 friend class DeclContext;
Volodymyr Sapsai160bc162022-12-01 18:39:23 -08004174 friend class ASTDeclReader;
Akira Hatanakae6313ac2018-04-09 22:48:22 +00004175
Argyrios Kyrtzidis2951e142008-06-09 21:05:31 +00004176protected:
Richard Smith053f6c62014-05-16 23:01:30 +00004177 RecordDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
Abramo Bagnara29c2d462011-03-09 14:09:51 +00004178 SourceLocation StartLoc, SourceLocation IdLoc,
4179 IdentifierInfo *Id, RecordDecl *PrevDecl);
Argyrios Kyrtzidis6bd44af2008-08-08 14:08:55 +00004180
Chris Lattnera7b32872008-03-15 06:12:44 +00004181public:
Jay Foad39c79802011-01-12 09:06:06 +00004182 static RecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
Abramo Bagnara29c2d462011-03-09 14:09:51 +00004183 SourceLocation StartLoc, SourceLocation IdLoc,
Craig Topper34b4c432014-05-06 06:48:52 +00004184 IdentifierInfo *Id, RecordDecl* PrevDecl = nullptr);
Chuanqi Xud86cc732024-04-25 11:43:13 +08004185 static RecordDecl *CreateDeserialized(const ASTContext &C, GlobalDeclID ID);
Argyrios Kyrtzidis69bc5ba2008-08-08 22:25:06 +00004186
Douglas Gregorec9fd132012-01-14 16:38:05 +00004187 RecordDecl *getPreviousDecl() {
Aaron Ballman5116a8e2013-11-06 22:39:46 +00004188 return cast_or_null<RecordDecl>(
4189 static_cast<TagDecl *>(this)->getPreviousDecl());
Douglas Gregorec9fd132012-01-14 16:38:05 +00004190 }
Rafael Espindola7b56f6c2013-10-19 16:55:03 +00004191 const RecordDecl *getPreviousDecl() const {
4192 return const_cast<RecordDecl*>(this)->getPreviousDecl();
Douglas Gregorec9fd132012-01-14 16:38:05 +00004193 }
Rafael Espindola7b56f6c2013-10-19 16:55:03 +00004194
Douglas Gregorec9fd132012-01-14 16:38:05 +00004195 RecordDecl *getMostRecentDecl() {
Aaron Ballman5116a8e2013-11-06 22:39:46 +00004196 return cast<RecordDecl>(static_cast<TagDecl *>(this)->getMostRecentDecl());
Argyrios Kyrtzidisb5fcdc22010-07-04 21:44:47 +00004197 }
Rafael Espindola7b56f6c2013-10-19 16:55:03 +00004198 const RecordDecl *getMostRecentDecl() const {
4199 return const_cast<RecordDecl*>(this)->getMostRecentDecl();
4200 }
Argyrios Kyrtzidisb5fcdc22010-07-04 21:44:47 +00004201
Erich Keanef92f31c2018-08-01 20:48:16 +00004202 bool hasFlexibleArrayMember() const {
4203 return RecordDeclBits.HasFlexibleArrayMember;
4204 }
4205
4206 void setHasFlexibleArrayMember(bool V) {
4207 RecordDeclBits.HasFlexibleArrayMember = V;
4208 }
Douglas Gregor9ac7a072009-01-07 00:43:41 +00004209
James Dennett31a57342018-02-02 21:38:22 +00004210 /// Whether this is an anonymous struct or union. To be an anonymous
4211 /// struct or union, it must have been declared without a name and
4212 /// there must be no objects of this type declared, e.g.,
Douglas Gregor9ac7a072009-01-07 00:43:41 +00004213 /// @code
4214 /// union { int i; float f; };
Mike Stump11289f42009-09-09 15:08:12 +00004215 /// @endcode
Douglas Gregor9ac7a072009-01-07 00:43:41 +00004216 /// is an anonymous union but neither of the following are:
4217 /// @code
4218 /// union X { int i; float f; };
4219 /// union { int i; float f; } obj;
4220 /// @endcode
Erich Keanef92f31c2018-08-01 20:48:16 +00004221 bool isAnonymousStructOrUnion() const {
4222 return RecordDeclBits.AnonymousStructOrUnion;
Douglas Gregor9ac7a072009-01-07 00:43:41 +00004223 }
4224
Erich Keanef92f31c2018-08-01 20:48:16 +00004225 void setAnonymousStructOrUnion(bool Anon) {
4226 RecordDeclBits.AnonymousStructOrUnion = Anon;
4227 }
Mike Stump11289f42009-09-09 15:08:12 +00004228
Erich Keanef92f31c2018-08-01 20:48:16 +00004229 bool hasObjectMember() const { return RecordDeclBits.HasObjectMember; }
4230 void setHasObjectMember(bool val) { RecordDeclBits.HasObjectMember = val; }
4231
4232 bool hasVolatileMember() const { return RecordDeclBits.HasVolatileMember; }
4233
4234 void setHasVolatileMember(bool val) {
4235 RecordDeclBits.HasVolatileMember = val;
4236 }
Adrian Prantl354bebd2015-12-01 19:54:07 +00004237
Adrian Prantld6ec3bc2015-12-01 20:19:44 +00004238 bool hasLoadedFieldsFromExternalStorage() const {
Erich Keanef92f31c2018-08-01 20:48:16 +00004239 return RecordDeclBits.LoadedFieldsFromExternalStorage;
Adrian Prantld6ec3bc2015-12-01 20:19:44 +00004240 }
Erich Keanef92f31c2018-08-01 20:48:16 +00004241
4242 void setHasLoadedFieldsFromExternalStorage(bool val) const {
4243 RecordDeclBits.LoadedFieldsFromExternalStorage = val;
Adrian Prantld6ec3bc2015-12-01 20:19:44 +00004244 }
Adrian Prantl354bebd2015-12-01 19:54:07 +00004245
Akira Hatanaka7275da02018-02-28 07:15:55 +00004246 /// Functions to query basic properties of non-trivial C structs.
4247 bool isNonTrivialToPrimitiveDefaultInitialize() const {
Erich Keanef92f31c2018-08-01 20:48:16 +00004248 return RecordDeclBits.NonTrivialToPrimitiveDefaultInitialize;
Akira Hatanaka7275da02018-02-28 07:15:55 +00004249 }
4250
Akira Hatanaka34fb2642018-03-13 18:58:25 +00004251 void setNonTrivialToPrimitiveDefaultInitialize(bool V) {
Erich Keanef92f31c2018-08-01 20:48:16 +00004252 RecordDeclBits.NonTrivialToPrimitiveDefaultInitialize = V;
Akira Hatanaka7275da02018-02-28 07:15:55 +00004253 }
4254
4255 bool isNonTrivialToPrimitiveCopy() const {
Erich Keanef92f31c2018-08-01 20:48:16 +00004256 return RecordDeclBits.NonTrivialToPrimitiveCopy;
Akira Hatanaka7275da02018-02-28 07:15:55 +00004257 }
4258
Akira Hatanaka34fb2642018-03-13 18:58:25 +00004259 void setNonTrivialToPrimitiveCopy(bool V) {
Erich Keanef92f31c2018-08-01 20:48:16 +00004260 RecordDeclBits.NonTrivialToPrimitiveCopy = V;
Akira Hatanaka7275da02018-02-28 07:15:55 +00004261 }
4262
4263 bool isNonTrivialToPrimitiveDestroy() const {
Erich Keanef92f31c2018-08-01 20:48:16 +00004264 return RecordDeclBits.NonTrivialToPrimitiveDestroy;
Akira Hatanaka7275da02018-02-28 07:15:55 +00004265 }
4266
Akira Hatanaka34fb2642018-03-13 18:58:25 +00004267 void setNonTrivialToPrimitiveDestroy(bool V) {
Erich Keanef92f31c2018-08-01 20:48:16 +00004268 RecordDeclBits.NonTrivialToPrimitiveDestroy = V;
Akira Hatanaka7275da02018-02-28 07:15:55 +00004269 }
4270
Akira Hatanaka09051062019-09-07 00:34:43 +00004271 bool hasNonTrivialToPrimitiveDefaultInitializeCUnion() const {
4272 return RecordDeclBits.HasNonTrivialToPrimitiveDefaultInitializeCUnion;
4273 }
4274
4275 void setHasNonTrivialToPrimitiveDefaultInitializeCUnion(bool V) {
4276 RecordDeclBits.HasNonTrivialToPrimitiveDefaultInitializeCUnion = V;
4277 }
4278
4279 bool hasNonTrivialToPrimitiveDestructCUnion() const {
4280 return RecordDeclBits.HasNonTrivialToPrimitiveDestructCUnion;
4281 }
4282
4283 void setHasNonTrivialToPrimitiveDestructCUnion(bool V) {
4284 RecordDeclBits.HasNonTrivialToPrimitiveDestructCUnion = V;
4285 }
4286
4287 bool hasNonTrivialToPrimitiveCopyCUnion() const {
4288 return RecordDeclBits.HasNonTrivialToPrimitiveCopyCUnion;
4289 }
4290
4291 void setHasNonTrivialToPrimitiveCopyCUnion(bool V) {
4292 RecordDeclBits.HasNonTrivialToPrimitiveCopyCUnion = V;
4293 }
4294
higher-performance15944132025-01-14 13:31:12 -05004295 bool hasUninitializedExplicitInitFields() const {
4296 return RecordDeclBits.HasUninitializedExplicitInitFields;
4297 }
4298
4299 void setHasUninitializedExplicitInitFields(bool V) {
4300 RecordDeclBits.HasUninitializedExplicitInitFields = V;
4301 }
4302
Akira Hatanakad791e922018-03-19 17:38:40 +00004303 /// Determine whether this class can be passed in registers. In C++ mode,
4304 /// it must have at least one trivial, non-deleted copy or move constructor.
4305 /// FIXME: This should be set as part of completeDefinition.
4306 bool canPassInRegisters() const {
Vlad Serebrennikova8ead562023-11-01 20:38:28 +04004307 return getArgPassingRestrictions() == RecordArgPassingKind::CanPassInRegs;
Akira Hatanakad791e922018-03-19 17:38:40 +00004308 }
4309
Vlad Serebrennikova8ead562023-11-01 20:38:28 +04004310 RecordArgPassingKind getArgPassingRestrictions() const {
4311 return static_cast<RecordArgPassingKind>(
4312 RecordDeclBits.ArgPassingRestrictions);
Akira Hatanakae6313ac2018-04-09 22:48:22 +00004313 }
4314
Vlad Serebrennikova8ead562023-11-01 20:38:28 +04004315 void setArgPassingRestrictions(RecordArgPassingKind Kind) {
Vlad Serebrennikovb120fe82023-11-01 11:47:40 +03004316 RecordDeclBits.ArgPassingRestrictions = llvm::to_underlying(Kind);
Akira Hatanakad791e922018-03-19 17:38:40 +00004317 }
4318
Akira Hatanakafcbe17c2018-03-28 21:13:14 +00004319 bool isParamDestroyedInCallee() const {
Erich Keanef92f31c2018-08-01 20:48:16 +00004320 return RecordDeclBits.ParamDestroyedInCallee;
Akira Hatanakafcbe17c2018-03-28 21:13:14 +00004321 }
4322
4323 void setParamDestroyedInCallee(bool V) {
Erich Keanef92f31c2018-08-01 20:48:16 +00004324 RecordDeclBits.ParamDestroyedInCallee = V;
Akira Hatanakafcbe17c2018-03-28 21:13:14 +00004325 }
4326
Connor Kuehl7aa8c382022-04-08 23:36:51 -07004327 bool isRandomized() const { return RecordDeclBits.IsRandomized; }
4328
4329 void setIsRandomized(bool V) { RecordDeclBits.IsRandomized = V; }
4330
Bill Wendling463790b2022-04-28 12:00:47 -07004331 void reorderDecls(const SmallVectorImpl<Decl *> &Decls);
Connor Kuehl7aa8c382022-04-08 23:36:51 -07004332
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004333 /// Determines whether this declaration represents the
Douglas Gregordfcad112009-03-25 15:59:44 +00004334 /// injected class name.
4335 ///
4336 /// The injected class name in C++ is the name of the class that
4337 /// appears inside the class itself. For example:
4338 ///
4339 /// \code
4340 /// struct C {
4341 /// // C is implicitly declared here as a synonym for the class name.
4342 /// };
4343 ///
4344 /// C::C c; // same as "C c;"
4345 /// \endcode
4346 bool isInjectedClassName() const;
4347
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004348 /// Determine whether this record is a class describing a lambda
Alexey Bataev39c81e22014-08-28 04:28:19 +00004349 /// function object.
4350 bool isLambda() const;
4351
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004352 /// Determine whether this record is a record for captured variables in
Alexey Bataev330de032014-10-29 12:21:55 +00004353 /// CapturedStmt construct.
4354 bool isCapturedRecord() const;
Eugene Zelenkode0215c2017-11-13 23:01:27 +00004355
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004356 /// Mark the record as a record for captured variables in CapturedStmt
Alexey Bataev330de032014-10-29 12:21:55 +00004357 /// construct.
4358 void setCapturedRecord();
4359
James Dennett31a57342018-02-02 21:38:22 +00004360 /// Returns the RecordDecl that actually defines
John McCallf937c022011-10-07 06:10:15 +00004361 /// this struct/union/class. When determining whether or not a
4362 /// struct/union/class is completely defined, one should use this
4363 /// method as opposed to 'isCompleteDefinition'.
4364 /// 'isCompleteDefinition' indicates whether or not a specific
4365 /// RecordDecl is a completed definition, not whether or not the
4366 /// record type is defined. This method returns NULL if there is
4367 /// no RecordDecl that defines the struct/union/tag.
4368 RecordDecl *getDefinition() const {
Douglas Gregor0a5a2212010-02-11 01:04:33 +00004369 return cast_or_null<RecordDecl>(TagDecl::getDefinition());
Ted Kremenek21475702008-09-05 17:16:31 +00004370 }
Mike Stump11289f42009-09-09 15:08:12 +00004371
Momchil Velikov102b4102020-04-28 16:27:52 +01004372 /// Returns whether this record is a union, or contains (at any nesting level)
4373 /// a union member. This is used by CMSE to warn about possible information
4374 /// leaks.
4375 bool isOrContainsUnion() const;
4376
Douglas Gregore0295612008-12-11 17:59:21 +00004377 // Iterator access to field members. The field iterator only visits
4378 // the non-static data members of this class, ignoring any static
4379 // data members, functions, constructors, destructors, etc.
Eugene Zelenkode0215c2017-11-13 23:01:27 +00004380 using field_iterator = specific_decl_iterator<FieldDecl>;
4381 using field_range = llvm::iterator_range<specific_decl_iterator<FieldDecl>>;
Argyrios Kyrtzidiscd5f3bd2008-08-08 13:54:06 +00004382
Aaron Ballmane8a8bae2014-03-08 20:12:42 +00004383 field_range fields() const { return field_range(field_begin(), field_end()); }
Argyrios Kyrtzidis0e88a562010-10-14 20:14:34 +00004384 field_iterator field_begin() const;
4385
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +00004386 field_iterator field_end() const {
Argyrios Kyrtzidis0e88a562010-10-14 20:14:34 +00004387 return field_iterator(decl_iterator());
Argyrios Kyrtzidiscd5f3bd2008-08-08 13:54:06 +00004388 }
4389
James Dennett31a57342018-02-02 21:38:22 +00004390 // Whether there are any fields (non-static data members) in this record.
Mike Stump11289f42009-09-09 15:08:12 +00004391 bool field_empty() const {
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +00004392 return field_begin() == field_end();
Douglas Gregorbcced4e2009-04-09 21:40:53 +00004393 }
Douglas Gregor7a4fad12008-12-11 20:41:00 +00004394
James Dennett31a57342018-02-02 21:38:22 +00004395 /// Note that the definition of this type is now complete.
Douglas Gregorb11aad82011-02-19 18:51:44 +00004396 virtual void completeDefinition();
Steve Naroffcc321422007-03-26 23:09:51 +00004397
John McCall180ef092010-01-29 01:45:37 +00004398 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
John McCall180ef092010-01-29 01:45:37 +00004399 static bool classofKind(Kind K) {
Alexis Hunted053252010-05-30 07:21:58 +00004400 return K >= firstRecord && K <= lastRecord;
John McCall180ef092010-01-29 01:45:37 +00004401 }
Argyrios Kyrtzidis0e88a562010-10-14 20:14:34 +00004402
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004403 /// Get whether or not this is an ms_struct which can
Eli Friedman9ee2d0472012-10-12 23:29:20 +00004404 /// be turned on with an attribute, pragma, or -mms-bitfields
4405 /// commandline option.
4406 bool isMsStruct(const ASTContext &C) const;
4407
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004408 /// Whether we are allowed to insert extra padding between fields.
Kostya Serebryany293dc9b2014-10-16 20:54:52 +00004409 /// These padding are added to help AddressSanitizer detect
4410 /// intra-object-overflow bugs.
4411 bool mayInsertExtraPadding(bool EmitRemark = false) const;
4412
Evgeny Astigeevich665027d2014-12-12 16:17:46 +00004413 /// Finds the first data member which has a name.
4414 /// nullptr is returned if no named data member exists.
Fangrui Song6907ce22018-07-30 19:24:48 +00004415 const FieldDecl *findFirstNamedDataMember() const;
Evgeny Astigeevich665027d2014-12-12 16:17:46 +00004416
Volodymyr Sapsai160bc162022-12-01 18:39:23 -08004417 /// Get precomputed ODRHash or add a new one.
4418 unsigned getODRHash();
4419
Argyrios Kyrtzidis0e88a562010-10-14 20:14:34 +00004420private:
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004421 /// Deserialize just the fields.
Argyrios Kyrtzidis0e88a562010-10-14 20:14:34 +00004422 void LoadFieldsFromExternalStorage() const;
Volodymyr Sapsai160bc162022-12-01 18:39:23 -08004423
4424 /// True if a valid hash is stored in ODRHash.
4425 bool hasODRHash() const { return RecordDeclBits.ODRHash; }
4426 void setODRHash(unsigned Hash) { RecordDeclBits.ODRHash = Hash; }
Chris Lattner28743e22007-01-22 07:41:08 +00004427};
4428
Anders Carlsson5c6c0592008-02-08 00:33:21 +00004429class FileScopeAsmDecl : public Decl {
Anders Carlsson5c6c0592008-02-08 00:33:21 +00004430 StringLiteral *AsmString;
Abramo Bagnara348823a2011-03-03 14:20:18 +00004431 SourceLocation RParenLoc;
Eugene Zelenkode0215c2017-11-13 23:01:27 +00004432
Abramo Bagnara348823a2011-03-03 14:20:18 +00004433 FileScopeAsmDecl(DeclContext *DC, StringLiteral *asmstring,
4434 SourceLocation StartL, SourceLocation EndL)
4435 : Decl(FileScopeAsm, DC, StartL), AsmString(asmstring), RParenLoc(EndL) {}
Eugene Zelenkode0215c2017-11-13 23:01:27 +00004436
4437 virtual void anchor();
4438
Chris Lattneree1284a2008-03-16 00:16:02 +00004439public:
Douglas Gregor6e6ad602009-01-20 01:17:11 +00004440 static FileScopeAsmDecl *Create(ASTContext &C, DeclContext *DC,
Abramo Bagnara348823a2011-03-03 14:20:18 +00004441 StringLiteral *Str, SourceLocation AsmLoc,
4442 SourceLocation RParenLoc);
4443
Chuanqi Xud86cc732024-04-25 11:43:13 +08004444 static FileScopeAsmDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
Fangrui Song6907ce22018-07-30 19:24:48 +00004445
Abramo Bagnara348823a2011-03-03 14:20:18 +00004446 SourceLocation getAsmLoc() const { return getLocation(); }
4447 SourceLocation getRParenLoc() const { return RParenLoc; }
4448 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
Craig Toppercbce6e92014-03-11 06:22:39 +00004449 SourceRange getSourceRange() const override LLVM_READONLY {
Abramo Bagnara348823a2011-03-03 14:20:18 +00004450 return SourceRange(getAsmLoc(), getRParenLoc());
4451 }
Anders Carlsson5c6c0592008-02-08 00:33:21 +00004452
4453 const StringLiteral *getAsmString() const { return AsmString; }
4454 StringLiteral *getAsmString() { return AsmString; }
Douglas Gregora5414852009-04-13 22:49:25 +00004455 void setAsmString(StringLiteral *Asm) { AsmString = Asm; }
4456
John McCall180ef092010-01-29 01:45:37 +00004457 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
John McCall180ef092010-01-29 01:45:37 +00004458 static bool classofKind(Kind K) { return K == FileScopeAsm; }
Anders Carlsson5c6c0592008-02-08 00:33:21 +00004459};
Chris Lattner38376f12008-01-12 07:05:38 +00004460
Vassil Vassilevdc488932022-06-08 09:59:40 +00004461/// A declaration that models statements at global scope. This declaration
4462/// supports incremental and interactive C/C++.
4463///
4464/// \note This is used in libInterpreter, clang -cc1 -fincremental-extensions
4465/// and in tools such as clang-repl.
Stefan Gränitz4b70d172024-03-07 14:27:04 +01004466class TopLevelStmtDecl : public Decl, public DeclContext {
Vassil Vassilevdc488932022-06-08 09:59:40 +00004467 friend class ASTDeclReader;
4468 friend class ASTDeclWriter;
4469
4470 Stmt *Statement = nullptr;
Jun Zhang247fa042023-05-16 20:10:43 +08004471 bool IsSemiMissing = false;
Vassil Vassilevdc488932022-06-08 09:59:40 +00004472
4473 TopLevelStmtDecl(DeclContext *DC, SourceLocation L, Stmt *S)
Stefan Gränitz4b70d172024-03-07 14:27:04 +01004474 : Decl(TopLevelStmt, DC, L), DeclContext(TopLevelStmt), Statement(S) {}
Vassil Vassilevdc488932022-06-08 09:59:40 +00004475
4476 virtual void anchor();
4477
4478public:
4479 static TopLevelStmtDecl *Create(ASTContext &C, Stmt *Statement);
Chuanqi Xud86cc732024-04-25 11:43:13 +08004480 static TopLevelStmtDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
Vassil Vassilevdc488932022-06-08 09:59:40 +00004481
4482 SourceRange getSourceRange() const override LLVM_READONLY;
4483 Stmt *getStmt() { return Statement; }
4484 const Stmt *getStmt() const { return Statement; }
Stefan Gränitz4b70d172024-03-07 14:27:04 +01004485 void setStmt(Stmt *S);
Jun Zhang247fa042023-05-16 20:10:43 +08004486 bool isSemiMissing() const { return IsSemiMissing; }
4487 void setSemiMissing(bool Missing = true) { IsSemiMissing = Missing; }
Vassil Vassilevdc488932022-06-08 09:59:40 +00004488
4489 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
4490 static bool classofKind(Kind K) { return K == TopLevelStmt; }
Stefan Gränitz4b70d172024-03-07 14:27:04 +01004491
4492 static DeclContext *castToDeclContext(const TopLevelStmtDecl *D) {
4493 return static_cast<DeclContext *>(const_cast<TopLevelStmtDecl *>(D));
4494 }
4495 static TopLevelStmtDecl *castFromDeclContext(const DeclContext *DC) {
4496 return static_cast<TopLevelStmtDecl *>(const_cast<DeclContext *>(DC));
4497 }
Vassil Vassilevdc488932022-06-08 09:59:40 +00004498};
4499
JF Bastien09197772019-02-12 20:19:16 +00004500/// Represents a block literal declaration, which is like an
Steve Naroff415d3d52008-10-08 17:01:13 +00004501/// unnamed FunctionDecl. For example:
4502/// ^{ statement-body } or ^(int arg1, float arg2){ statement-body }
Steve Naroff415d3d52008-10-08 17:01:13 +00004503class BlockDecl : public Decl, public DeclContext {
Erich Keanec9d29902018-08-01 21:16:54 +00004504 // This class stores some data in DeclContext::BlockDeclBits
4505 // to save some space. Use the provided accessors to access it.
John McCall351762c2011-02-07 10:33:21 +00004506public:
4507 /// A class which contains all the information about a particular
4508 /// captured value.
4509 class Capture {
4510 enum {
4511 flag_isByRef = 0x1,
4512 flag_isNested = 0x2
4513 };
4514
4515 /// The variable being captured.
4516 llvm::PointerIntPair<VarDecl*, 2> VariableAndFlags;
4517
4518 /// The copy expression, expressed in terms of a DeclRef (or
4519 /// BlockDeclRef) to the captured variable. Only required if the
4520 /// variable has a C++ class type.
4521 Expr *CopyExpr;
4522
4523 public:
4524 Capture(VarDecl *variable, bool byRef, bool nested, Expr *copy)
4525 : VariableAndFlags(variable,
4526 (byRef ? flag_isByRef : 0) | (nested ? flag_isNested : 0)),
4527 CopyExpr(copy) {}
4528
4529 /// The variable being captured.
4530 VarDecl *getVariable() const { return VariableAndFlags.getPointer(); }
4531
4532 /// Whether this is a "by ref" capture, i.e. a capture of a __block
4533 /// variable.
4534 bool isByRef() const { return VariableAndFlags.getInt() & flag_isByRef; }
4535
Akira Hatanaka8e57b072018-10-01 21:51:28 +00004536 bool isEscapingByref() const {
4537 return getVariable()->isEscapingByref();
4538 }
4539
4540 bool isNonEscapingByref() const {
4541 return getVariable()->isNonEscapingByref();
4542 }
4543
John McCall351762c2011-02-07 10:33:21 +00004544 /// Whether this is a nested capture, i.e. the variable captured
4545 /// is not from outside the immediately enclosing function/block.
4546 bool isNested() const { return VariableAndFlags.getInt() & flag_isNested; }
4547
Craig Topper34b4c432014-05-06 06:48:52 +00004548 bool hasCopyExpr() const { return CopyExpr != nullptr; }
John McCall351762c2011-02-07 10:33:21 +00004549 Expr *getCopyExpr() const { return CopyExpr; }
4550 void setCopyExpr(Expr *e) { CopyExpr = e; }
4551 };
4552
4553private:
James Dennett31a57342018-02-02 21:38:22 +00004554 /// A new[]'d array of pointers to ParmVarDecls for the formal
Steve Naroffc4b30e52009-03-13 16:56:44 +00004555 /// parameters of this function. This is null if a prototype or if there are
4556 /// no formals.
Eugene Zelenkode0215c2017-11-13 23:01:27 +00004557 ParmVarDecl **ParamInfo = nullptr;
4558 unsigned NumParams = 0;
Mike Stump11289f42009-09-09 15:08:12 +00004559
Eugene Zelenkode0215c2017-11-13 23:01:27 +00004560 Stmt *Body = nullptr;
4561 TypeSourceInfo *SignatureAsWritten = nullptr;
Mike Stump11289f42009-09-09 15:08:12 +00004562
Eugene Zelenkode0215c2017-11-13 23:01:27 +00004563 const Capture *Captures = nullptr;
4564 unsigned NumCaptures = 0;
John McCallc63de662011-02-02 13:00:07 +00004565
Eugene Zelenkode0215c2017-11-13 23:01:27 +00004566 unsigned ManglingNumber = 0;
4567 Decl *ManglingContextDecl = nullptr;
Eli Friedman7e346a82013-07-01 20:22:57 +00004568
Steve Naroff415d3d52008-10-08 17:01:13 +00004569protected:
Erich Keanec9d29902018-08-01 21:16:54 +00004570 BlockDecl(DeclContext *DC, SourceLocation CaretLoc);
Ted Kremenek1f1e7562007-10-25 21:37:16 +00004571
Steve Naroff415d3d52008-10-08 17:01:13 +00004572public:
Fangrui Song6907ce22018-07-30 19:24:48 +00004573 static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L);
Chuanqi Xud86cc732024-04-25 11:43:13 +08004574 static BlockDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
Fangrui Song6907ce22018-07-30 19:24:48 +00004575
Steve Naroff415d3d52008-10-08 17:01:13 +00004576 SourceLocation getCaretLocation() const { return getLocation(); }
4577
Erich Keanec9d29902018-08-01 21:16:54 +00004578 bool isVariadic() const { return BlockDeclBits.IsVariadic; }
4579 void setIsVariadic(bool value) { BlockDeclBits.IsVariadic = value; }
Mike Stump11289f42009-09-09 15:08:12 +00004580
Argyrios Kyrtzidisddcd1322009-06-30 02:35:26 +00004581 CompoundStmt *getCompoundBody() const { return (CompoundStmt*) Body; }
Craig Toppercbce6e92014-03-11 06:22:39 +00004582 Stmt *getBody() const override { return (Stmt*) Body; }
Ted Kremenek73980592009-03-12 18:33:24 +00004583 void setBody(CompoundStmt *B) { Body = (Stmt*) B; }
Steve Naroff415d3d52008-10-08 17:01:13 +00004584
John McCalla3ccba02010-06-04 11:21:44 +00004585 void setSignatureAsWritten(TypeSourceInfo *Sig) { SignatureAsWritten = Sig; }
4586 TypeSourceInfo *getSignatureAsWritten() const { return SignatureAsWritten; }
4587
Ted Kremenek81541c52014-01-17 07:15:26 +00004588 // ArrayRef access to formal parameters.
David Majnemer59f77922016-06-24 04:05:48 +00004589 ArrayRef<ParmVarDecl *> parameters() const {
4590 return {ParamInfo, getNumParams()};
4591 }
4592 MutableArrayRef<ParmVarDecl *> parameters() {
4593 return {ParamInfo, getNumParams()};
Ted Kremenek81541c52014-01-17 07:15:26 +00004594 }
4595
David Majnemer59f77922016-06-24 04:05:48 +00004596 // Iterator access to formal parameters.
Eugene Zelenkode0215c2017-11-13 23:01:27 +00004597 using param_iterator = MutableArrayRef<ParmVarDecl *>::iterator;
4598 using param_const_iterator = ArrayRef<ParmVarDecl *>::const_iterator;
4599
David Majnemer59f77922016-06-24 04:05:48 +00004600 bool param_empty() const { return parameters().empty(); }
4601 param_iterator param_begin() { return parameters().begin(); }
4602 param_iterator param_end() { return parameters().end(); }
4603 param_const_iterator param_begin() const { return parameters().begin(); }
4604 param_const_iterator param_end() const { return parameters().end(); }
4605 size_t param_size() const { return parameters().size(); }
Mike Stump11289f42009-09-09 15:08:12 +00004606
John McCallc63de662011-02-02 13:00:07 +00004607 unsigned getNumParams() const { return NumParams; }
Eugene Zelenkode0215c2017-11-13 23:01:27 +00004608
Steve Naroffc4b30e52009-03-13 16:56:44 +00004609 const ParmVarDecl *getParamDecl(unsigned i) const {
4610 assert(i < getNumParams() && "Illegal param #");
4611 return ParamInfo[i];
4612 }
4613 ParmVarDecl *getParamDecl(unsigned i) {
4614 assert(i < getNumParams() && "Illegal param #");
4615 return ParamInfo[i];
4616 }
Eugene Zelenkode0215c2017-11-13 23:01:27 +00004617
Dmitri Gribenkof8579502013-01-12 19:30:44 +00004618 void setParams(ArrayRef<ParmVarDecl *> NewParamInfo);
Mike Stump11289f42009-09-09 15:08:12 +00004619
James Dennett31a57342018-02-02 21:38:22 +00004620 /// True if this block (or its nested blocks) captures
John McCallc63de662011-02-02 13:00:07 +00004621 /// anything of local storage from its enclosing scopes.
Erich Keanec9d29902018-08-01 21:16:54 +00004622 bool hasCaptures() const { return NumCaptures || capturesCXXThis(); }
John McCallc63de662011-02-02 13:00:07 +00004623
James Dennett31a57342018-02-02 21:38:22 +00004624 /// Returns the number of captured variables.
John McCall351762c2011-02-07 10:33:21 +00004625 /// Does not include an entry for 'this'.
4626 unsigned getNumCaptures() const { return NumCaptures; }
John McCallc63de662011-02-02 13:00:07 +00004627
Eugene Zelenkode0215c2017-11-13 23:01:27 +00004628 using capture_const_iterator = ArrayRef<Capture>::const_iterator;
Aaron Ballman9371dd22014-03-14 18:34:04 +00004629
David Majnemer59f77922016-06-24 04:05:48 +00004630 ArrayRef<Capture> captures() const { return {Captures, NumCaptures}; }
Aaron Ballman9371dd22014-03-14 18:34:04 +00004631
David Majnemer59f77922016-06-24 04:05:48 +00004632 capture_const_iterator capture_begin() const { return captures().begin(); }
4633 capture_const_iterator capture_end() const { return captures().end(); }
John McCallc63de662011-02-02 13:00:07 +00004634
Erich Keanec9d29902018-08-01 21:16:54 +00004635 bool capturesCXXThis() const { return BlockDeclBits.CapturesCXXThis; }
4636 void setCapturesCXXThis(bool B = true) { BlockDeclBits.CapturesCXXThis = B; }
John McCallc63de662011-02-02 13:00:07 +00004637
Erich Keanec9d29902018-08-01 21:16:54 +00004638 bool blockMissingReturnType() const {
4639 return BlockDeclBits.BlockMissingReturnType;
4640 }
Eli Friedman98b01ed2012-03-01 04:01:32 +00004641
Erich Keanec9d29902018-08-01 21:16:54 +00004642 void setBlockMissingReturnType(bool val = true) {
4643 BlockDeclBits.BlockMissingReturnType = val;
4644 }
4645
4646 bool isConversionFromLambda() const {
4647 return BlockDeclBits.IsConversionFromLambda;
4648 }
4649
4650 void setIsConversionFromLambda(bool val = true) {
4651 BlockDeclBits.IsConversionFromLambda = val;
4652 }
4653
4654 bool doesNotEscape() const { return BlockDeclBits.DoesNotEscape; }
4655 void setDoesNotEscape(bool B = true) { BlockDeclBits.DoesNotEscape = B; }
Akira Hatanaka627586b82018-03-02 01:53:15 +00004656
Akira Hatanakac5792aa2019-02-27 18:17:16 +00004657 bool canAvoidCopyToHeap() const {
4658 return BlockDeclBits.CanAvoidCopyToHeap;
4659 }
4660 void setCanAvoidCopyToHeap(bool B = true) {
4661 BlockDeclBits.CanAvoidCopyToHeap = B;
4662 }
4663
John McCallce45f882011-06-15 22:51:16 +00004664 bool capturesVariable(const VarDecl *var) const;
4665
Benjamin Kramerb40e4af2015-08-05 09:40:35 +00004666 void setCaptures(ASTContext &Context, ArrayRef<Capture> Captures,
4667 bool CapturesCXXThis);
John McCallc63de662011-02-02 13:00:07 +00004668
Michael Liaoc752f5b2019-10-10 04:16:52 +00004669 unsigned getBlockManglingNumber() const { return ManglingNumber; }
Eugene Zelenkode0215c2017-11-13 23:01:27 +00004670
Michael Liaoc752f5b2019-10-10 04:16:52 +00004671 Decl *getBlockManglingContextDecl() const { return ManglingContextDecl; }
Eli Friedman7e346a82013-07-01 20:22:57 +00004672
4673 void setBlockMangling(unsigned Number, Decl *Ctx) {
4674 ManglingNumber = Number;
4675 ManglingContextDecl = Ctx;
4676 }
4677
Craig Toppercbce6e92014-03-11 06:22:39 +00004678 SourceRange getSourceRange() const override LLVM_READONLY;
David Blaikie21bfbf82011-11-09 06:07:30 +00004679
Doug Wyattf03cb002024-06-24 00:51:31 -10004680 FunctionEffectsRef getFunctionEffects() const {
4681 if (const TypeSourceInfo *TSI = getSignatureAsWritten())
4682 if (const auto *FPT = TSI->getType()->getAs<FunctionProtoType>())
4683 return FPT->getFunctionEffects();
4684 return {};
4685 }
4686
Steve Naroff415d3d52008-10-08 17:01:13 +00004687 // Implement isa/cast/dyncast/etc.
John McCall180ef092010-01-29 01:45:37 +00004688 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
John McCall180ef092010-01-29 01:45:37 +00004689 static bool classofKind(Kind K) { return K == Block; }
Argyrios Kyrtzidis3768ad62008-10-12 16:14:48 +00004690 static DeclContext *castToDeclContext(const BlockDecl *D) {
4691 return static_cast<DeclContext *>(const_cast<BlockDecl*>(D));
4692 }
4693 static BlockDecl *castFromDeclContext(const DeclContext *DC) {
4694 return static_cast<BlockDecl *>(const_cast<DeclContext*>(DC));
4695 }
Steve Naroff415d3d52008-10-08 17:01:13 +00004696};
4697
Tom Honermann8fb42302025-01-22 16:39:08 -05004698/// Represents a partial function definition.
4699///
4700/// An outlined function declaration contains the parameters and body of
4701/// a function independent of other function definition concerns such
4702/// as function name, type, and calling convention. Such declarations may
4703/// be used to hold a parameterized and transformed sequence of statements
4704/// used to generate a target dependent function definition without losing
4705/// association with the original statements. See SYCLKernelCallStmt as an
4706/// example.
4707class OutlinedFunctionDecl final
4708 : public Decl,
4709 public DeclContext,
4710 private llvm::TrailingObjects<OutlinedFunctionDecl, ImplicitParamDecl *> {
4711private:
4712 /// The number of parameters to the outlined function.
4713 unsigned NumParams;
4714
4715 /// The body of the outlined function.
4716 llvm::PointerIntPair<Stmt *, 1, bool> BodyAndNothrow;
4717
4718 explicit OutlinedFunctionDecl(DeclContext *DC, unsigned NumParams);
4719
4720 ImplicitParamDecl *const *getParams() const {
4721 return getTrailingObjects<ImplicitParamDecl *>();
4722 }
4723
4724 ImplicitParamDecl **getParams() {
4725 return getTrailingObjects<ImplicitParamDecl *>();
4726 }
4727
4728public:
4729 friend class ASTDeclReader;
4730 friend class ASTDeclWriter;
4731 friend TrailingObjects;
4732
4733 static OutlinedFunctionDecl *Create(ASTContext &C, DeclContext *DC,
4734 unsigned NumParams);
4735 static OutlinedFunctionDecl *
4736 CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumParams);
4737
4738 Stmt *getBody() const override;
4739 void setBody(Stmt *B);
4740
4741 bool isNothrow() const;
4742 void setNothrow(bool Nothrow = true);
4743
4744 unsigned getNumParams() const { return NumParams; }
4745
4746 ImplicitParamDecl *getParam(unsigned i) const {
4747 assert(i < NumParams);
4748 return getParams()[i];
4749 }
4750 void setParam(unsigned i, ImplicitParamDecl *P) {
4751 assert(i < NumParams);
4752 getParams()[i] = P;
4753 }
4754
4755 // Range interface to parameters.
4756 using parameter_const_iterator = const ImplicitParamDecl *const *;
4757 using parameter_const_range = llvm::iterator_range<parameter_const_iterator>;
4758 parameter_const_range parameters() const {
4759 return {param_begin(), param_end()};
4760 }
4761 parameter_const_iterator param_begin() const { return getParams(); }
4762 parameter_const_iterator param_end() const { return getParams() + NumParams; }
4763
4764 // Implement isa/cast/dyncast/etc.
4765 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
4766 static bool classofKind(Kind K) { return K == OutlinedFunction; }
4767 static DeclContext *castToDeclContext(const OutlinedFunctionDecl *D) {
4768 return static_cast<DeclContext *>(const_cast<OutlinedFunctionDecl *>(D));
4769 }
4770 static OutlinedFunctionDecl *castFromDeclContext(const DeclContext *DC) {
4771 return static_cast<OutlinedFunctionDecl *>(const_cast<DeclContext *>(DC));
4772 }
4773};
4774
James Dennett31a57342018-02-02 21:38:22 +00004775/// Represents the body of a CapturedStmt, and serves as its DeclContext.
James Y Knight7a22b242015-08-06 20:26:32 +00004776class CapturedDecl final
4777 : public Decl,
4778 public DeclContext,
4779 private llvm::TrailingObjects<CapturedDecl, ImplicitParamDecl *> {
4780protected:
4781 size_t numTrailingObjects(OverloadToken<ImplicitParamDecl>) {
4782 return NumParams;
4783 }
4784
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004785private:
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004786 /// The number of parameters to the outlined function.
Ben Langmuir37943a72013-05-03 19:00:33 +00004787 unsigned NumParams;
Eugene Zelenkode0215c2017-11-13 23:01:27 +00004788
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004789 /// The position of context parameter in list of parameters.
Alexey Bataev9959db52014-05-06 10:08:46 +00004790 unsigned ContextParam;
Eugene Zelenkode0215c2017-11-13 23:01:27 +00004791
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004792 /// The body of the outlined function.
Alexey Bataev9959db52014-05-06 10:08:46 +00004793 llvm::PointerIntPair<Stmt *, 1, bool> BodyAndNothrow;
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004794
Chandler Carruth21c90602015-12-30 03:24:14 +00004795 explicit CapturedDecl(DeclContext *DC, unsigned NumParams);
Ben Langmuir37943a72013-05-03 19:00:33 +00004796
James Y Knight7a22b242015-08-06 20:26:32 +00004797 ImplicitParamDecl *const *getParams() const {
4798 return getTrailingObjects<ImplicitParamDecl *>();
4799 }
4800
4801 ImplicitParamDecl **getParams() {
4802 return getTrailingObjects<ImplicitParamDecl *>();
Ben Langmuir37943a72013-05-03 19:00:33 +00004803 }
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004804
4805public:
Eugene Zelenkode0215c2017-11-13 23:01:27 +00004806 friend class ASTDeclReader;
4807 friend class ASTDeclWriter;
4808 friend TrailingObjects;
4809
Alexey Bataev9959db52014-05-06 10:08:46 +00004810 static CapturedDecl *Create(ASTContext &C, DeclContext *DC,
4811 unsigned NumParams);
Chuanqi Xud86cc732024-04-25 11:43:13 +08004812 static CapturedDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID,
Ben Langmuirce914fc2013-05-03 19:20:19 +00004813 unsigned NumParams);
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004814
Chandler Carruth21c90602015-12-30 03:24:14 +00004815 Stmt *getBody() const override;
4816 void setBody(Stmt *B);
Alexey Bataev9959db52014-05-06 10:08:46 +00004817
Chandler Carruth21c90602015-12-30 03:24:14 +00004818 bool isNothrow() const;
4819 void setNothrow(bool Nothrow = true);
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004820
Ben Langmuirce914fc2013-05-03 19:20:19 +00004821 unsigned getNumParams() const { return NumParams; }
4822
Ben Langmuir37943a72013-05-03 19:00:33 +00004823 ImplicitParamDecl *getParam(unsigned i) const {
4824 assert(i < NumParams);
4825 return getParams()[i];
4826 }
4827 void setParam(unsigned i, ImplicitParamDecl *P) {
4828 assert(i < NumParams);
4829 getParams()[i] = P;
4830 }
4831
Yaron Kerenfe813632016-06-29 18:55:53 +00004832 // ArrayRef interface to parameters.
4833 ArrayRef<ImplicitParamDecl *> parameters() const {
4834 return {getParams(), getNumParams()};
4835 }
4836 MutableArrayRef<ImplicitParamDecl *> parameters() {
4837 return {getParams(), getNumParams()};
4838 }
4839
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004840 /// Retrieve the parameter containing captured variables.
Alexey Bataev9959db52014-05-06 10:08:46 +00004841 ImplicitParamDecl *getContextParam() const {
4842 assert(ContextParam < NumParams);
4843 return getParam(ContextParam);
4844 }
4845 void setContextParam(unsigned i, ImplicitParamDecl *P) {
4846 assert(i < NumParams);
4847 ContextParam = i;
4848 setParam(i, P);
4849 }
4850 unsigned getContextParamPosition() const { return ContextParam; }
Ben Langmuir37943a72013-05-03 19:00:33 +00004851
Eugene Zelenkode0215c2017-11-13 23:01:27 +00004852 using param_iterator = ImplicitParamDecl *const *;
4853 using param_range = llvm::iterator_range<param_iterator>;
Aaron Ballmane7fbde82014-03-07 16:40:17 +00004854
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004855 /// Retrieve an iterator pointing to the first parameter decl.
Ben Langmuir37943a72013-05-03 19:00:33 +00004856 param_iterator param_begin() const { return getParams(); }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004857 /// Retrieve an iterator one past the last parameter decl.
Ben Langmuir37943a72013-05-03 19:00:33 +00004858 param_iterator param_end() const { return getParams() + NumParams; }
4859
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004860 // Implement isa/cast/dyncast/etc.
4861 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
4862 static bool classofKind(Kind K) { return K == Captured; }
4863 static DeclContext *castToDeclContext(const CapturedDecl *D) {
4864 return static_cast<DeclContext *>(const_cast<CapturedDecl *>(D));
4865 }
4866 static CapturedDecl *castFromDeclContext(const DeclContext *DC) {
4867 return static_cast<CapturedDecl *>(const_cast<DeclContext *>(DC));
4868 }
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004869};
4870
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004871/// Describes a module import declaration, which makes the contents
Douglas Gregorba345522011-12-02 23:23:56 +00004872/// of the named module visible in the current translation unit.
4873///
4874/// An import declaration imports the named module (or submodule). For example:
4875/// \code
Douglas Gregorc50d4922012-12-11 22:11:52 +00004876/// @import std.vector;
Douglas Gregorba345522011-12-02 23:23:56 +00004877/// \endcode
4878///
Iain Sandoe69350e52021-02-07 01:00:33 +00004879/// A C++20 module import declaration imports the named module or partition.
4880/// Periods are permitted in C++20 module names, but have no semantic meaning.
4881/// For example:
4882/// \code
4883/// import NamedModule;
4884/// import :SomePartition; // Must be a partition of the current module.
4885/// import Names.Like.this; // Allowed.
4886/// import :and.Also.Partition.names;
4887/// \endcode
4888///
James Dennett1355bd12012-06-11 06:19:40 +00004889/// Import declarations can also be implicitly generated from
4890/// \#include/\#import directives.
James Y Knight7a22b242015-08-06 20:26:32 +00004891class ImportDecl final : public Decl,
4892 llvm::TrailingObjects<ImportDecl, SourceLocation> {
Eugene Zelenkode0215c2017-11-13 23:01:27 +00004893 friend class ASTContext;
4894 friend class ASTDeclReader;
4895 friend class ASTReader;
4896 friend TrailingObjects;
4897
Reid Klecknerc915cb92020-02-27 18:13:54 -08004898 /// The imported module.
4899 Module *ImportedModule = nullptr;
Fangrui Song6907ce22018-07-30 19:24:48 +00004900
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004901 /// The next import in the list of imports local to the translation
Douglas Gregor0f2a3602011-12-03 00:30:27 +00004902 /// unit being parsed (not loaded from an AST file).
Reid Klecknerc915cb92020-02-27 18:13:54 -08004903 ///
4904 /// Includes a bit that indicates whether we have source-location information
4905 /// for each identifier in the module name.
4906 ///
4907 /// When the bit is false, we only have a single source location for the
4908 /// end of the import declaration.
4909 llvm::PointerIntPair<ImportDecl *, 1, bool> NextLocalImportAndComplete;
Fangrui Song6907ce22018-07-30 19:24:48 +00004910
Douglas Gregor22d09742012-01-03 18:04:46 +00004911 ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported,
Douglas Gregorba345522011-12-02 23:23:56 +00004912 ArrayRef<SourceLocation> IdentifierLocs);
4913
Douglas Gregor22d09742012-01-03 18:04:46 +00004914 ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported,
Douglas Gregorba345522011-12-02 23:23:56 +00004915 SourceLocation EndLoc);
4916
Eugene Zelenkode0215c2017-11-13 23:01:27 +00004917 ImportDecl(EmptyShell Empty) : Decl(Import, Empty) {}
Fangrui Song6907ce22018-07-30 19:24:48 +00004918
Reid Klecknerc915cb92020-02-27 18:13:54 -08004919 bool isImportComplete() const { return NextLocalImportAndComplete.getInt(); }
4920
4921 void setImportComplete(bool C) { NextLocalImportAndComplete.setInt(C); }
4922
4923 /// The next import in the list of imports local to the translation
4924 /// unit being parsed (not loaded from an AST file).
4925 ImportDecl *getNextLocalImport() const {
4926 return NextLocalImportAndComplete.getPointer();
4927 }
4928
4929 void setNextLocalImport(ImportDecl *Import) {
4930 NextLocalImportAndComplete.setPointer(Import);
4931 }
4932
Douglas Gregorba345522011-12-02 23:23:56 +00004933public:
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004934 /// Create a new module import declaration.
Fangrui Song6907ce22018-07-30 19:24:48 +00004935 static ImportDecl *Create(ASTContext &C, DeclContext *DC,
Douglas Gregor22d09742012-01-03 18:04:46 +00004936 SourceLocation StartLoc, Module *Imported,
Douglas Gregorba345522011-12-02 23:23:56 +00004937 ArrayRef<SourceLocation> IdentifierLocs);
Fangrui Song6907ce22018-07-30 19:24:48 +00004938
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004939 /// Create a new module import declaration for an implicitly-generated
Douglas Gregorba345522011-12-02 23:23:56 +00004940 /// import.
Fangrui Song6907ce22018-07-30 19:24:48 +00004941 static ImportDecl *CreateImplicit(ASTContext &C, DeclContext *DC,
4942 SourceLocation StartLoc, Module *Imported,
Douglas Gregorba345522011-12-02 23:23:56 +00004943 SourceLocation EndLoc);
Fangrui Song6907ce22018-07-30 19:24:48 +00004944
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004945 /// Create a new, deserialized module import declaration.
Chuanqi Xud86cc732024-04-25 11:43:13 +08004946 static ImportDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID,
Douglas Gregor72172e92012-01-05 21:55:30 +00004947 unsigned NumLocations);
Fangrui Song6907ce22018-07-30 19:24:48 +00004948
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004949 /// Retrieve the module that was imported by the import declaration.
Reid Klecknerc915cb92020-02-27 18:13:54 -08004950 Module *getImportedModule() const { return ImportedModule; }
Fangrui Song6907ce22018-07-30 19:24:48 +00004951
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004952 /// Retrieves the locations of each of the identifiers that make up
Douglas Gregorba345522011-12-02 23:23:56 +00004953 /// the complete module name in the import declaration.
4954 ///
4955 /// This will return an empty array if the locations of the individual
4956 /// identifiers aren't available.
4957 ArrayRef<SourceLocation> getIdentifierLocs() const;
Craig Toppercbce6e92014-03-11 06:22:39 +00004958
4959 SourceRange getSourceRange() const override LLVM_READONLY;
4960
Douglas Gregorba345522011-12-02 23:23:56 +00004961 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
Douglas Gregorba345522011-12-02 23:23:56 +00004962 static bool classofKind(Kind K) { return K == Import; }
4963};
Michael Han84324352013-02-22 17:15:32 +00004964
Chuanqi Xu612f3ac2023-02-15 18:30:49 +08004965/// Represents a standard C++ module export declaration.
Richard Smith8df390f2016-09-08 23:14:54 +00004966///
4967/// For example:
4968/// \code
4969/// export void foo();
4970/// \endcode
4971class ExportDecl final : public Decl, public DeclContext {
4972 virtual void anchor();
Eugene Zelenkode0215c2017-11-13 23:01:27 +00004973
Richard Smith8df390f2016-09-08 23:14:54 +00004974private:
Eugene Zelenkode0215c2017-11-13 23:01:27 +00004975 friend class ASTDeclReader;
4976
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004977 /// The source location for the right brace (if valid).
Richard Smith8df390f2016-09-08 23:14:54 +00004978 SourceLocation RBraceLoc;
4979
4980 ExportDecl(DeclContext *DC, SourceLocation ExportLoc)
Eugene Zelenkode0215c2017-11-13 23:01:27 +00004981 : Decl(Export, DC, ExportLoc), DeclContext(Export),
4982 RBraceLoc(SourceLocation()) {}
Richard Smith8df390f2016-09-08 23:14:54 +00004983
4984public:
4985 static ExportDecl *Create(ASTContext &C, DeclContext *DC,
4986 SourceLocation ExportLoc);
Chuanqi Xud86cc732024-04-25 11:43:13 +08004987 static ExportDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
Fangrui Song6907ce22018-07-30 19:24:48 +00004988
Richard Smith8df390f2016-09-08 23:14:54 +00004989 SourceLocation getExportLoc() const { return getLocation(); }
4990 SourceLocation getRBraceLoc() const { return RBraceLoc; }
4991 void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
4992
Richard Smithe181de72019-04-22 22:50:11 +00004993 bool hasBraces() const { return RBraceLoc.isValid(); }
4994
Stephen Kelly02a67ba2018-08-09 20:05:47 +00004995 SourceLocation getEndLoc() const LLVM_READONLY {
Richard Smithe181de72019-04-22 22:50:11 +00004996 if (hasBraces())
Richard Smith8df390f2016-09-08 23:14:54 +00004997 return RBraceLoc;
4998 // No braces: get the end location of the (only) declaration in context
4999 // (if present).
Stephen Kelly1c301dc2018-08-09 21:09:38 +00005000 return decls_empty() ? getLocation() : decls_begin()->getEndLoc();
Richard Smith8df390f2016-09-08 23:14:54 +00005001 }
5002
5003 SourceRange getSourceRange() const override LLVM_READONLY {
Stephen Kelly1c301dc2018-08-09 21:09:38 +00005004 return SourceRange(getLocation(), getEndLoc());
Richard Smith8df390f2016-09-08 23:14:54 +00005005 }
5006
5007 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
5008 static bool classofKind(Kind K) { return K == Export; }
5009 static DeclContext *castToDeclContext(const ExportDecl *D) {
5010 return static_cast<DeclContext *>(const_cast<ExportDecl*>(D));
5011 }
5012 static ExportDecl *castFromDeclContext(const DeclContext *DC) {
5013 return static_cast<ExportDecl *>(const_cast<DeclContext*>(DC));
5014 }
5015};
5016
James Dennettb8973efb2018-02-02 20:22:29 +00005017/// Represents an empty-declaration.
Michael Han84324352013-02-22 17:15:32 +00005018class EmptyDecl : public Decl {
Eugene Zelenkode0215c2017-11-13 23:01:27 +00005019 EmptyDecl(DeclContext *DC, SourceLocation L) : Decl(Empty, DC, L) {}
5020
Michael Han84324352013-02-22 17:15:32 +00005021 virtual void anchor();
Michael Han84324352013-02-22 17:15:32 +00005022
5023public:
5024 static EmptyDecl *Create(ASTContext &C, DeclContext *DC,
5025 SourceLocation L);
Chuanqi Xud86cc732024-04-25 11:43:13 +08005026 static EmptyDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
Michael Han84324352013-02-22 17:15:32 +00005027
5028 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
5029 static bool classofKind(Kind K) { return K == Empty; }
5030};
Douglas Gregorba345522011-12-02 23:23:56 +00005031
Xiang Li782ac212022-07-15 10:45:57 -07005032/// HLSLBufferDecl - Represent a cbuffer or tbuffer declaration.
5033class HLSLBufferDecl final : public NamedDecl, public DeclContext {
5034 /// LBraceLoc - The ending location of the source range.
5035 SourceLocation LBraceLoc;
5036 /// RBraceLoc - The ending location of the source range.
5037 SourceLocation RBraceLoc;
5038 /// KwLoc - The location of the cbuffer or tbuffer keyword.
5039 SourceLocation KwLoc;
5040 /// IsCBuffer - Whether the buffer is a cbuffer (and not a tbuffer).
5041 bool IsCBuffer;
Helena Kotas19af8582025-02-20 10:32:14 -08005042 /// HasValidPackoffset - Whether the buffer has valid packoffset annotations
5043 // on all declarations
5044 bool HasValidPackoffset;
5045 // LayoutStruct - Layout struct for the buffer
5046 CXXRecordDecl *LayoutStruct;
Xiang Li782ac212022-07-15 10:45:57 -07005047
5048 HLSLBufferDecl(DeclContext *DC, bool CBuffer, SourceLocation KwLoc,
5049 IdentifierInfo *ID, SourceLocation IDLoc,
5050 SourceLocation LBrace);
5051
5052public:
5053 static HLSLBufferDecl *Create(ASTContext &C, DeclContext *LexicalParent,
5054 bool CBuffer, SourceLocation KwLoc,
5055 IdentifierInfo *ID, SourceLocation IDLoc,
5056 SourceLocation LBrace);
Chuanqi Xud86cc732024-04-25 11:43:13 +08005057 static HLSLBufferDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
Xiang Li782ac212022-07-15 10:45:57 -07005058
Xiang Lia7e3de22022-09-21 10:55:51 -07005059 SourceRange getSourceRange() const override LLVM_READONLY {
Xiang Li782ac212022-07-15 10:45:57 -07005060 return SourceRange(getLocStart(), RBraceLoc);
5061 }
5062 SourceLocation getLocStart() const LLVM_READONLY { return KwLoc; }
5063 SourceLocation getLBraceLoc() const { return LBraceLoc; }
5064 SourceLocation getRBraceLoc() const { return RBraceLoc; }
5065 void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
5066 bool isCBuffer() const { return IsCBuffer; }
Helena Kotas19af8582025-02-20 10:32:14 -08005067 void setHasValidPackoffset(bool PO) { HasValidPackoffset = PO; }
5068 bool hasValidPackoffset() const { return HasValidPackoffset; }
5069 const CXXRecordDecl *getLayoutStruct() const { return LayoutStruct; }
5070 void addLayoutStruct(CXXRecordDecl *LS);
Xiang Li782ac212022-07-15 10:45:57 -07005071
5072 // Implement isa/cast/dyncast/etc.
5073 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
5074 static bool classofKind(Kind K) { return K == HLSLBuffer; }
5075 static DeclContext *castToDeclContext(const HLSLBufferDecl *D) {
5076 return static_cast<DeclContext *>(const_cast<HLSLBufferDecl *>(D));
5077 }
5078 static HLSLBufferDecl *castFromDeclContext(const DeclContext *DC) {
5079 return static_cast<HLSLBufferDecl *>(const_cast<DeclContext *>(DC));
5080 }
5081
5082 friend class ASTDeclReader;
5083 friend class ASTDeclWriter;
5084};
5085
Douglas Gregor2ada0482009-02-04 17:27:36 +00005086/// Insertion operator for diagnostics. This allows sending NamedDecl's
5087/// into a diagnostic with <<.
Yaxun (Sam) Liu7e561b62020-09-23 16:16:00 -04005088inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
5089 const NamedDecl *ND) {
Arthur Eubanksafdac5f2021-10-05 13:55:31 -07005090 PD.AddTaggedVal(reinterpret_cast<uint64_t>(ND),
Benjamin Kramer7ec12c92012-02-07 22:29:24 +00005091 DiagnosticsEngine::ak_nameddecl);
5092 return PD;
5093}
Douglas Gregor2ada0482009-02-04 17:27:36 +00005094
Douglas Gregorbf62d642010-12-06 18:36:25 +00005095template<typename decl_type>
Rafael Espindola8db352d2013-10-17 15:37:26 +00005096void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) {
Douglas Gregorbf62d642010-12-06 18:36:25 +00005097 // Note: This routine is implemented here because we need both NamedDecl
5098 // and Redeclarable to be defined.
Richard Trieu87a615d2018-07-09 22:09:33 +00005099 assert(RedeclLink.isFirst() &&
Richard Smith053f6c62014-05-16 23:01:30 +00005100 "setPreviousDecl on a decl already in a redeclaration chain");
Douglas Gregorbf62d642010-12-06 18:36:25 +00005101
Douglas Gregorbf62d642010-12-06 18:36:25 +00005102 if (PrevDecl) {
5103 // Point to previous. Make sure that this is actually the most recent
5104 // redeclaration, or we can build invalid chains. If the most recent
5105 // redeclaration is invalid, it won't be PrevDecl, but we want it anyway.
Rafael Espindola8db352d2013-10-17 15:37:26 +00005106 First = PrevDecl->getFirstDecl();
Richard Trieu87a615d2018-07-09 22:09:33 +00005107 assert(First->RedeclLink.isFirst() && "Expected first");
Richard Smith053f6c62014-05-16 23:01:30 +00005108 decl_type *MostRecent = First->getNextRedeclaration();
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005109 RedeclLink = PreviousDeclLink(cast<decl_type>(MostRecent));
Richard Smith64017682013-07-17 23:53:16 +00005110
5111 // If the declaration was previously visible, a redeclaration of it remains
5112 // visible even if it wouldn't be visible by itself.
Richard Smith64017682013-07-17 23:53:16 +00005113 static_cast<decl_type*>(this)->IdentifierNamespace |=
Richard Smith541b38b2013-09-20 01:15:31 +00005114 MostRecent->getIdentifierNamespace() &
Richard Smith64017682013-07-17 23:53:16 +00005115 (Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Type);
Douglas Gregorbf62d642010-12-06 18:36:25 +00005116 } else {
5117 // Make this first.
5118 First = static_cast<decl_type*>(this);
5119 }
David Blaikie21bfbf82011-11-09 06:07:30 +00005120
Douglas Gregorbf62d642010-12-06 18:36:25 +00005121 // First one will point to this one as latest.
Richard Smith053f6c62014-05-16 23:01:30 +00005122 First->RedeclLink.setLatest(static_cast<decl_type*>(this));
5123
Chandler Carruth5aa9d792013-03-14 11:17:20 +00005124 assert(!isa<NamedDecl>(static_cast<decl_type*>(this)) ||
5125 cast<NamedDecl>(static_cast<decl_type*>(this))->isLinkageValid());
Douglas Gregorbf62d642010-12-06 18:36:25 +00005126}
5127
Daniel Dunbar49248822012-03-06 18:20:20 +00005128// Inline function definitions.
5129
James Dennettb8973efb2018-02-02 20:22:29 +00005130/// Check if the given decl is complete.
Daniel Dunbar49248822012-03-06 18:20:20 +00005131///
5132/// We use this function to break a cycle between the inline definitions in
5133/// Type.h and Decl.h.
5134inline bool IsEnumDeclComplete(EnumDecl *ED) {
5135 return ED->isComplete();
5136}
5137
James Dennettb8973efb2018-02-02 20:22:29 +00005138/// Check if the given decl is scoped.
Daniel Dunbard0437332012-03-08 02:52:18 +00005139///
5140/// We use this function to break a cycle between the inline definitions in
5141/// Type.h and Decl.h.
5142inline bool IsEnumDeclScoped(EnumDecl *ED) {
5143 return ED->isScoped();
5144}
5145
Johannes Doerfertbefb4be2020-02-25 14:04:06 -08005146/// OpenMP variants are mangled early based on their OpenMP context selector.
5147/// The new name looks likes this:
5148/// <name> + OpenMPVariantManglingSeparatorStr + <mangled OpenMP context>
5149static constexpr StringRef getOpenMPVariantManglingSeparatorStr() {
Lukas Sommer8bd7e412020-06-03 16:32:49 -04005150 return "$ompvariant";
Johannes Doerfertbefb4be2020-02-25 14:04:06 -08005151}
5152
Sander de Smalen6a6fcbf2024-05-07 15:03:26 +00005153/// Returns whether the given FunctionDecl has an __arm[_locally]_streaming
5154/// attribute.
5155bool IsArmStreamingFunction(const FunctionDecl *FD,
5156 bool IncludeLocallyStreaming);
5157
Benjamin Maxwella7f40442025-01-28 12:08:54 +00005158/// Returns whether the given FunctionDecl has Arm ZA state.
5159bool hasArmZAState(const FunctionDecl *FD);
5160
5161/// Returns whether the given FunctionDecl has Arm ZT0 state.
5162bool hasArmZT0State(const FunctionDecl *FD);
5163
Eugene Zelenkode0215c2017-11-13 23:01:27 +00005164} // namespace clang
Nate Begemanf2a6e5f2008-12-16 19:57:09 +00005165
Eugene Zelenkode0215c2017-11-13 23:01:27 +00005166#endif // LLVM_CLANG_AST_DECL_H