/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/AST/Decl.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- Decl.cpp - Declaration AST Node Implementation ---------------------===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | // This file implements the Decl subclasses. |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #include "clang/AST/Decl.h" |
14 | | #include "Linkage.h" |
15 | | #include "clang/AST/ASTContext.h" |
16 | | #include "clang/AST/ASTDiagnostic.h" |
17 | | #include "clang/AST/ASTLambda.h" |
18 | | #include "clang/AST/ASTMutationListener.h" |
19 | | #include "clang/AST/Attr.h" |
20 | | #include "clang/AST/CanonicalType.h" |
21 | | #include "clang/AST/DeclBase.h" |
22 | | #include "clang/AST/DeclCXX.h" |
23 | | #include "clang/AST/DeclObjC.h" |
24 | | #include "clang/AST/DeclOpenMP.h" |
25 | | #include "clang/AST/DeclTemplate.h" |
26 | | #include "clang/AST/DeclarationName.h" |
27 | | #include "clang/AST/Expr.h" |
28 | | #include "clang/AST/ExprCXX.h" |
29 | | #include "clang/AST/ExternalASTSource.h" |
30 | | #include "clang/AST/ODRHash.h" |
31 | | #include "clang/AST/PrettyDeclStackTrace.h" |
32 | | #include "clang/AST/PrettyPrinter.h" |
33 | | #include "clang/AST/Redeclarable.h" |
34 | | #include "clang/AST/Stmt.h" |
35 | | #include "clang/AST/TemplateBase.h" |
36 | | #include "clang/AST/Type.h" |
37 | | #include "clang/AST/TypeLoc.h" |
38 | | #include "clang/Basic/Builtins.h" |
39 | | #include "clang/Basic/IdentifierTable.h" |
40 | | #include "clang/Basic/LLVM.h" |
41 | | #include "clang/Basic/LangOptions.h" |
42 | | #include "clang/Basic/Linkage.h" |
43 | | #include "clang/Basic/Module.h" |
44 | | #include "clang/Basic/PartialDiagnostic.h" |
45 | | #include "clang/Basic/SanitizerBlacklist.h" |
46 | | #include "clang/Basic/Sanitizers.h" |
47 | | #include "clang/Basic/SourceLocation.h" |
48 | | #include "clang/Basic/SourceManager.h" |
49 | | #include "clang/Basic/Specifiers.h" |
50 | | #include "clang/Basic/TargetCXXABI.h" |
51 | | #include "clang/Basic/TargetInfo.h" |
52 | | #include "clang/Basic/Visibility.h" |
53 | | #include "llvm/ADT/APSInt.h" |
54 | | #include "llvm/ADT/ArrayRef.h" |
55 | | #include "llvm/ADT/None.h" |
56 | | #include "llvm/ADT/Optional.h" |
57 | | #include "llvm/ADT/STLExtras.h" |
58 | | #include "llvm/ADT/SmallVector.h" |
59 | | #include "llvm/ADT/StringRef.h" |
60 | | #include "llvm/ADT/StringSwitch.h" |
61 | | #include "llvm/ADT/Triple.h" |
62 | | #include "llvm/Support/Casting.h" |
63 | | #include "llvm/Support/ErrorHandling.h" |
64 | | #include "llvm/Support/raw_ostream.h" |
65 | | #include <algorithm> |
66 | | #include <cassert> |
67 | | #include <cstddef> |
68 | | #include <cstring> |
69 | | #include <memory> |
70 | | #include <string> |
71 | | #include <tuple> |
72 | | #include <type_traits> |
73 | | |
74 | | using namespace clang; |
75 | | |
76 | 696k | Decl *clang::getPrimaryMergedDecl(Decl *D) { |
77 | 696k | return D->getASTContext().getPrimaryMergedDecl(D); |
78 | 696k | } |
79 | | |
80 | 0 | void PrettyDeclStackTraceEntry::print(raw_ostream &OS) const { |
81 | 0 | SourceLocation Loc = this->Loc; |
82 | 0 | if (!Loc.isValid() && TheDecl) Loc = TheDecl->getLocation(); |
83 | 0 | if (Loc.isValid()) { |
84 | 0 | Loc.print(OS, Context.getSourceManager()); |
85 | 0 | OS << ": "; |
86 | 0 | } |
87 | 0 | OS << Message; |
88 | |
|
89 | 0 | if (auto *ND = dyn_cast_or_null<NamedDecl>(TheDecl)) { |
90 | 0 | OS << " '"; |
91 | 0 | ND->getNameForDiagnostic(OS, Context.getPrintingPolicy(), true); |
92 | 0 | OS << "'"; |
93 | 0 | } |
94 | |
|
95 | 0 | OS << '\n'; |
96 | 0 | } |
97 | | |
98 | | // Defined here so that it can be inlined into its direct callers. |
99 | 76.3M | bool Decl::isOutOfLine() const { |
100 | 76.3M | return !getLexicalDeclContext()->Equals(getDeclContext()); |
101 | 76.3M | } |
102 | | |
103 | | TranslationUnitDecl::TranslationUnitDecl(ASTContext &ctx) |
104 | | : Decl(TranslationUnit, nullptr, SourceLocation()), |
105 | 86.5k | DeclContext(TranslationUnit), Ctx(ctx) {} |
106 | | |
107 | | //===----------------------------------------------------------------------===// |
108 | | // NamedDecl Implementation |
109 | | //===----------------------------------------------------------------------===// |
110 | | |
111 | | // Visibility rules aren't rigorously externally specified, but here |
112 | | // are the basic principles behind what we implement: |
113 | | // |
114 | | // 1. An explicit visibility attribute is generally a direct expression |
115 | | // of the user's intent and should be honored. Only the innermost |
116 | | // visibility attribute applies. If no visibility attribute applies, |
117 | | // global visibility settings are considered. |
118 | | // |
119 | | // 2. There is one caveat to the above: on or in a template pattern, |
120 | | // an explicit visibility attribute is just a default rule, and |
121 | | // visibility can be decreased by the visibility of template |
122 | | // arguments. But this, too, has an exception: an attribute on an |
123 | | // explicit specialization or instantiation causes all the visibility |
124 | | // restrictions of the template arguments to be ignored. |
125 | | // |
126 | | // 3. A variable that does not otherwise have explicit visibility can |
127 | | // be restricted by the visibility of its type. |
128 | | // |
129 | | // 4. A visibility restriction is explicit if it comes from an |
130 | | // attribute (or something like it), not a global visibility setting. |
131 | | // When emitting a reference to an external symbol, visibility |
132 | | // restrictions are ignored unless they are explicit. |
133 | | // |
134 | | // 5. When computing the visibility of a non-type, including a |
135 | | // non-type member of a class, only non-type visibility restrictions |
136 | | // are considered: the 'visibility' attribute, global value-visibility |
137 | | // settings, and a few special cases like __private_extern. |
138 | | // |
139 | | // 6. When computing the visibility of a type, including a type member |
140 | | // of a class, only type visibility restrictions are considered: |
141 | | // the 'type_visibility' attribute and global type-visibility settings. |
142 | | // However, a 'visibility' attribute counts as a 'type_visibility' |
143 | | // attribute on any declaration that only has the former. |
144 | | // |
145 | | // The visibility of a "secondary" entity, like a template argument, |
146 | | // is computed using the kind of that entity, not the kind of the |
147 | | // primary entity for which we are computing visibility. For example, |
148 | | // the visibility of a specialization of either of these templates: |
149 | | // template <class T, bool (&compare)(T, X)> bool has_match(list<T>, X); |
150 | | // template <class T, bool (&compare)(T, X)> class matcher; |
151 | | // is restricted according to the type visibility of the argument 'T', |
152 | | // the type visibility of 'bool(&)(T,X)', and the value visibility of |
153 | | // the argument function 'compare'. That 'has_match' is a value |
154 | | // and 'matcher' is a type only matters when looking for attributes |
155 | | // and settings from the immediate context. |
156 | | |
157 | | /// Does this computation kind permit us to consider additional |
158 | | /// visibility settings from attributes and the like? |
159 | 10.0M | static bool hasExplicitVisibilityAlready(LVComputationKind computation) { |
160 | 10.0M | return computation.IgnoreExplicitVisibility; |
161 | 10.0M | } |
162 | | |
163 | | /// Given an LVComputationKind, return one of the same type/value sort |
164 | | /// that records that it already has explicit visibility. |
165 | | static LVComputationKind |
166 | 153k | withExplicitVisibilityAlready(LVComputationKind Kind) { |
167 | 153k | Kind.IgnoreExplicitVisibility = true; |
168 | 153k | return Kind; |
169 | 153k | } |
170 | | |
171 | | static Optional<Visibility> getExplicitVisibility(const NamedDecl *D, |
172 | 2.13M | LVComputationKind kind) { |
173 | 2.13M | assert(!kind.IgnoreExplicitVisibility && |
174 | 2.13M | "asking for explicit visibility when we shouldn't be"); |
175 | 2.13M | return D->getExplicitVisibility(kind.getExplicitVisibilityKind()); |
176 | 2.13M | } |
177 | | |
178 | | /// Is the given declaration a "type" or a "value" for the purposes of |
179 | | /// visibility computation? |
180 | 1.80M | static bool usesTypeVisibility(const NamedDecl *D) { |
181 | 1.80M | return isa<TypeDecl>(D) || |
182 | 1.04M | isa<ClassTemplateDecl>(D) || |
183 | 1.04M | isa<ObjCInterfaceDecl>(D); |
184 | 1.80M | } |
185 | | |
186 | | /// Does the given declaration have member specialization information, |
187 | | /// and if so, is it an explicit specialization? |
188 | | template <class T> static typename |
189 | | std::enable_if<!std::is_base_of<RedeclarableTemplateDecl, T>::value, bool>::type |
190 | 1.32M | isExplicitMemberSpecialization(const T *D) { |
191 | 1.32M | if (const MemberSpecializationInfo *member = |
192 | 566k | D->getMemberSpecializationInfo()) { |
193 | 566k | return member->isExplicitSpecialization(); |
194 | 566k | } |
195 | 756k | return false; |
196 | 756k | } Decl.cpp:std::__1::enable_if<!(std::is_base_of<clang::RedeclarableTemplateDecl, clang::CXXMethodDecl>::value), bool>::type isExplicitMemberSpecialization<clang::CXXMethodDecl>(clang::CXXMethodDecl const*) Line | Count | Source | 190 | 1.16M | isExplicitMemberSpecialization(const T *D) { | 191 | 1.16M | if (const MemberSpecializationInfo *member = | 192 | 518k | D->getMemberSpecializationInfo()) { | 193 | 518k | return member->isExplicitSpecialization(); | 194 | 518k | } | 195 | 647k | return false; | 196 | 647k | } |
Decl.cpp:std::__1::enable_if<!(std::is_base_of<clang::RedeclarableTemplateDecl, clang::CXXRecordDecl>::value), bool>::type isExplicitMemberSpecialization<clang::CXXRecordDecl>(clang::CXXRecordDecl const*) Line | Count | Source | 190 | 31.0k | isExplicitMemberSpecialization(const T *D) { | 191 | 31.0k | if (const MemberSpecializationInfo *member = | 192 | 13.8k | D->getMemberSpecializationInfo()) { | 193 | 13.8k | return member->isExplicitSpecialization(); | 194 | 13.8k | } | 195 | 17.1k | return false; | 196 | 17.1k | } |
Decl.cpp:std::__1::enable_if<!(std::is_base_of<clang::RedeclarableTemplateDecl, clang::VarDecl>::value), bool>::type isExplicitMemberSpecialization<clang::VarDecl>(clang::VarDecl const*) Line | Count | Source | 190 | 124k | isExplicitMemberSpecialization(const T *D) { | 191 | 124k | if (const MemberSpecializationInfo *member = | 192 | 33.4k | D->getMemberSpecializationInfo()) { | 193 | 33.4k | return member->isExplicitSpecialization(); | 194 | 33.4k | } | 195 | 91.4k | return false; | 196 | 91.4k | } |
|
197 | | |
198 | | /// For templates, this question is easier: a member template can't be |
199 | | /// explicitly instantiated, so there's a single bit indicating whether |
200 | | /// or not this is an explicit member specialization. |
201 | 135k | static bool isExplicitMemberSpecialization(const RedeclarableTemplateDecl *D) { |
202 | 135k | return D->isMemberSpecialization(); |
203 | 135k | } |
204 | | |
205 | | /// Given a visibility attribute, return the explicit visibility |
206 | | /// associated with it. |
207 | | template <class T> |
208 | 636k | static Visibility getVisibilityFromAttr(const T *attr) { |
209 | 636k | switch (attr->getVisibility()) { |
210 | 426k | case T::Default: |
211 | 426k | return DefaultVisibility; |
212 | 209k | case T::Hidden: |
213 | 209k | return HiddenVisibility; |
214 | 236 | case T::Protected: |
215 | 236 | return ProtectedVisibility; |
216 | 0 | } |
217 | 0 | llvm_unreachable("bad visibility kind"); |
218 | 0 | } Decl.cpp:clang::Visibility getVisibilityFromAttr<clang::TypeVisibilityAttr>(clang::TypeVisibilityAttr const*) Line | Count | Source | 208 | 351k | static Visibility getVisibilityFromAttr(const T *attr) { | 209 | 351k | switch (attr->getVisibility()) { | 210 | 351k | case T::Default: | 211 | 351k | return DefaultVisibility; | 212 | 32 | case T::Hidden: | 213 | 32 | return HiddenVisibility; | 214 | 9 | case T::Protected: | 215 | 9 | return ProtectedVisibility; | 216 | 0 | } | 217 | 0 | llvm_unreachable("bad visibility kind"); | 218 | 0 | } |
Decl.cpp:clang::Visibility getVisibilityFromAttr<clang::VisibilityAttr>(clang::VisibilityAttr const*) Line | Count | Source | 208 | 284k | static Visibility getVisibilityFromAttr(const T *attr) { | 209 | 284k | switch (attr->getVisibility()) { | 210 | 74.6k | case T::Default: | 211 | 74.6k | return DefaultVisibility; | 212 | 209k | case T::Hidden: | 213 | 209k | return HiddenVisibility; | 214 | 227 | case T::Protected: | 215 | 227 | return ProtectedVisibility; | 216 | 0 | } | 217 | 0 | llvm_unreachable("bad visibility kind"); | 218 | 0 | } |
|
219 | | |
220 | | /// Return the explicit visibility of the given declaration. |
221 | | static Optional<Visibility> getVisibilityOf(const NamedDecl *D, |
222 | 3.03M | NamedDecl::ExplicitVisibilityKind kind) { |
223 | | // If we're ultimately computing the visibility of a type, look for |
224 | | // a 'type_visibility' attribute before looking for 'visibility'. |
225 | 3.03M | if (kind == NamedDecl::VisibilityForType) { |
226 | 1.17M | if (const auto *A = D->getAttr<TypeVisibilityAttr>()) { |
227 | 351k | return getVisibilityFromAttr(A); |
228 | 351k | } |
229 | 2.68M | } |
230 | | |
231 | | // If this declaration has an explicit visibility attribute, use it. |
232 | 2.68M | if (const auto *A = D->getAttr<VisibilityAttr>()) { |
233 | 284k | return getVisibilityFromAttr(A); |
234 | 284k | } |
235 | | |
236 | 2.40M | return None; |
237 | 2.40M | } |
238 | | |
239 | | LinkageInfo LinkageComputer::getLVForType(const Type &T, |
240 | 2.12M | LVComputationKind computation) { |
241 | 2.12M | if (computation.IgnoreAllVisibility) |
242 | 746k | return LinkageInfo(T.getLinkage(), DefaultVisibility, true); |
243 | 1.37M | return getTypeLinkageAndVisibility(&T); |
244 | 1.37M | } |
245 | | |
246 | | /// Get the most restrictive linkage for the types in the given |
247 | | /// template parameter list. For visibility purposes, template |
248 | | /// parameters are part of the signature of a template. |
249 | | LinkageInfo LinkageComputer::getLVForTemplateParameterList( |
250 | 1.30M | const TemplateParameterList *Params, LVComputationKind computation) { |
251 | 1.30M | LinkageInfo LV; |
252 | 2.18M | for (const NamedDecl *P : *Params) { |
253 | | // Template type parameters are the most common and never |
254 | | // contribute to visibility, pack or not. |
255 | 2.18M | if (isa<TemplateTypeParmDecl>(P)) |
256 | 1.89M | continue; |
257 | | |
258 | | // Non-type template parameters can be restricted by the value type, e.g. |
259 | | // template <enum X> class A { ... }; |
260 | | // We have to be careful here, though, because we can be dealing with |
261 | | // dependent types. |
262 | 285k | if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) { |
263 | | // Handle the non-pack case first. |
264 | 284k | if (!NTTP->isExpandedParameterPack()) { |
265 | 283k | if (!NTTP->getType()->isDependentType()) { |
266 | 258k | LV.merge(getLVForType(*NTTP->getType(), computation)); |
267 | 258k | } |
268 | 283k | continue; |
269 | 283k | } |
270 | | |
271 | | // Look at all the types in an expanded pack. |
272 | 165 | for (unsigned i = 0, n = NTTP->getNumExpansionTypes(); 57 i != n; ++i108 ) { |
273 | 108 | QualType type = NTTP->getExpansionType(i); |
274 | 108 | if (!type->isDependentType()) |
275 | 108 | LV.merge(getTypeLinkageAndVisibility(type)); |
276 | 108 | } |
277 | 57 | continue; |
278 | 57 | } |
279 | | |
280 | | // Template template parameters can be restricted by their |
281 | | // template parameters, recursively. |
282 | 1.94k | const auto *TTP = cast<TemplateTemplateParmDecl>(P); |
283 | | |
284 | | // Handle the non-pack case first. |
285 | 1.94k | if (!TTP->isExpandedParameterPack()) { |
286 | 1.90k | LV.merge(getLVForTemplateParameterList(TTP->getTemplateParameters(), |
287 | 1.90k | computation)); |
288 | 1.90k | continue; |
289 | 1.90k | } |
290 | | |
291 | | // Look at all expansions in an expanded pack. |
292 | 38 | for (unsigned i = 0, n = TTP->getNumExpansionTemplateParameters(); |
293 | 100 | i != n; ++i62 ) { |
294 | 62 | LV.merge(getLVForTemplateParameterList( |
295 | 62 | TTP->getExpansionTemplateParameters(i), computation)); |
296 | 62 | } |
297 | 38 | } |
298 | | |
299 | 1.30M | return LV; |
300 | 1.30M | } |
301 | | |
302 | 15.3k | static const Decl *getOutermostFuncOrBlockContext(const Decl *D) { |
303 | 15.3k | const Decl *Ret = nullptr; |
304 | 15.3k | const DeclContext *DC = D->getDeclContext(); |
305 | 36.4k | while (DC->getDeclKind() != Decl::TranslationUnit) { |
306 | 21.1k | if (isa<FunctionDecl>(DC) || isa<BlockDecl>(DC)5.68k ) |
307 | 15.5k | Ret = cast<Decl>(DC); |
308 | 21.1k | DC = DC->getParent(); |
309 | 21.1k | } |
310 | 15.3k | return Ret; |
311 | 15.3k | } |
312 | | |
313 | | /// Get the most restrictive linkage for the types and |
314 | | /// declarations in the given template argument list. |
315 | | /// |
316 | | /// Note that we don't take an LVComputationKind because we always |
317 | | /// want to honor the visibility of template arguments in the same way. |
318 | | LinkageInfo |
319 | | LinkageComputer::getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args, |
320 | 1.18M | LVComputationKind computation) { |
321 | 1.18M | LinkageInfo LV; |
322 | | |
323 | 1.95M | for (const TemplateArgument &Arg : Args) { |
324 | 1.95M | switch (Arg.getKind()) { |
325 | 0 | case TemplateArgument::Null: |
326 | 243k | case TemplateArgument::Integral: |
327 | 245k | case TemplateArgument::Expression: |
328 | 245k | continue; |
329 | | |
330 | 1.63M | case TemplateArgument::Type: |
331 | 1.63M | LV.merge(getLVForType(*Arg.getAsType(), computation)); |
332 | 1.63M | continue; |
333 | | |
334 | 2.04k | case TemplateArgument::Declaration: { |
335 | 2.04k | const NamedDecl *ND = Arg.getAsDecl(); |
336 | 2.04k | assert(!usesTypeVisibility(ND)); |
337 | 2.04k | LV.merge(getLVForDecl(ND, computation)); |
338 | 2.04k | continue; |
339 | 243k | } |
340 | | |
341 | 344 | case TemplateArgument::NullPtr: |
342 | 344 | LV.merge(getTypeLinkageAndVisibility(Arg.getNullPtrType())); |
343 | 344 | continue; |
344 | | |
345 | 1.86k | case TemplateArgument::Template: |
346 | 1.86k | case TemplateArgument::TemplateExpansion: |
347 | 1.86k | if (TemplateDecl *Template = |
348 | 1.86k | Arg.getAsTemplateOrTemplatePattern().getAsTemplateDecl()) |
349 | 1.86k | LV.merge(getLVForDecl(Template, computation)); |
350 | 1.86k | continue; |
351 | | |
352 | 71.7k | case TemplateArgument::Pack: |
353 | 71.7k | LV.merge(getLVForTemplateArgumentList(Arg.getPackAsArray(), computation)); |
354 | 71.7k | continue; |
355 | 0 | } |
356 | 0 | llvm_unreachable("bad template argument kind"); |
357 | 0 | } |
358 | | |
359 | 1.18M | return LV; |
360 | 1.18M | } |
361 | | |
362 | | LinkageInfo |
363 | | LinkageComputer::getLVForTemplateArgumentList(const TemplateArgumentList &TArgs, |
364 | 1.11M | LVComputationKind computation) { |
365 | 1.11M | return getLVForTemplateArgumentList(TArgs.asArray(), computation); |
366 | 1.11M | } |
367 | | |
368 | | static bool shouldConsiderTemplateVisibility(const FunctionDecl *fn, |
369 | 248k | const FunctionTemplateSpecializationInfo *specInfo) { |
370 | | // Include visibility from the template parameters and arguments |
371 | | // only if this is not an explicit instantiation or specialization |
372 | | // with direct explicit visibility. (Implicit instantiations won't |
373 | | // have a direct attribute.) |
374 | 248k | if (!specInfo->isExplicitInstantiationOrSpecialization()) |
375 | 240k | return true; |
376 | | |
377 | 7.92k | return !fn->hasAttr<VisibilityAttr>(); |
378 | 7.92k | } |
379 | | |
380 | | /// Merge in template-related linkage and visibility for the given |
381 | | /// function template specialization. |
382 | | /// |
383 | | /// We don't need a computation kind here because we can assume |
384 | | /// LVForValue. |
385 | | /// |
386 | | /// \param[out] LV the computation to use for the parent |
387 | | void LinkageComputer::mergeTemplateLV( |
388 | | LinkageInfo &LV, const FunctionDecl *fn, |
389 | | const FunctionTemplateSpecializationInfo *specInfo, |
390 | 248k | LVComputationKind computation) { |
391 | 248k | bool considerVisibility = |
392 | 248k | shouldConsiderTemplateVisibility(fn, specInfo); |
393 | | |
394 | | // Merge information from the template parameters. |
395 | 248k | FunctionTemplateDecl *temp = specInfo->getTemplate(); |
396 | 248k | LinkageInfo tempLV = |
397 | 248k | getLVForTemplateParameterList(temp->getTemplateParameters(), computation); |
398 | 248k | LV.mergeMaybeWithVisibility(tempLV, considerVisibility); |
399 | | |
400 | | // Merge information from the template arguments. |
401 | 248k | const TemplateArgumentList &templateArgs = *specInfo->TemplateArguments; |
402 | 248k | LinkageInfo argsLV = getLVForTemplateArgumentList(templateArgs, computation); |
403 | 248k | LV.mergeMaybeWithVisibility(argsLV, considerVisibility); |
404 | 248k | } |
405 | | |
406 | | /// Does the given declaration have a direct visibility attribute |
407 | | /// that would match the given rules? |
408 | | static bool hasDirectVisibilityAttribute(const NamedDecl *D, |
409 | 54.3k | LVComputationKind computation) { |
410 | 54.3k | if (computation.IgnoreAllVisibility) |
411 | 2.84k | return false; |
412 | | |
413 | 51.4k | return (computation.isTypeVisibility() && D->hasAttr<TypeVisibilityAttr>()41.7k ) || |
414 | 11.1k | D->hasAttr<VisibilityAttr>(); |
415 | 51.4k | } |
416 | | |
417 | | /// Should we consider visibility associated with the template |
418 | | /// arguments and parameters of the given class template specialization? |
419 | | static bool shouldConsiderTemplateVisibility( |
420 | | const ClassTemplateSpecializationDecl *spec, |
421 | 865k | LVComputationKind computation) { |
422 | | // Include visibility from the template parameters and arguments |
423 | | // only if this is not an explicit instantiation or specialization |
424 | | // with direct explicit visibility (and note that implicit |
425 | | // instantiations won't have a direct attribute). |
426 | | // |
427 | | // Furthermore, we want to ignore template parameters and arguments |
428 | | // for an explicit specialization when computing the visibility of a |
429 | | // member thereof with explicit visibility. |
430 | | // |
431 | | // This is a bit complex; let's unpack it. |
432 | | // |
433 | | // An explicit class specialization is an independent, top-level |
434 | | // declaration. As such, if it or any of its members has an |
435 | | // explicit visibility attribute, that must directly express the |
436 | | // user's intent, and we should honor it. The same logic applies to |
437 | | // an explicit instantiation of a member of such a thing. |
438 | | |
439 | | // Fast path: if this is not an explicit instantiation or |
440 | | // specialization, we always want to consider template-related |
441 | | // visibility restrictions. |
442 | 865k | if (!spec->isExplicitInstantiationOrSpecialization()) |
443 | 778k | return true; |
444 | | |
445 | | // This is the 'member thereof' check. |
446 | 87.2k | if (spec->isExplicitSpecialization() && |
447 | 77.5k | hasExplicitVisibilityAlready(computation)) |
448 | 33.9k | return false; |
449 | | |
450 | 53.3k | return !hasDirectVisibilityAttribute(spec, computation); |
451 | 53.3k | } |
452 | | |
453 | | /// Merge in template-related linkage and visibility for the given |
454 | | /// class template specialization. |
455 | | void LinkageComputer::mergeTemplateLV( |
456 | | LinkageInfo &LV, const ClassTemplateSpecializationDecl *spec, |
457 | 865k | LVComputationKind computation) { |
458 | 865k | bool considerVisibility = shouldConsiderTemplateVisibility(spec, computation); |
459 | | |
460 | | // Merge information from the template parameters, but ignore |
461 | | // visibility if we're only considering template arguments. |
462 | | |
463 | 865k | ClassTemplateDecl *temp = spec->getSpecializedTemplate(); |
464 | 865k | LinkageInfo tempLV = |
465 | 865k | getLVForTemplateParameterList(temp->getTemplateParameters(), computation); |
466 | 865k | LV.mergeMaybeWithVisibility(tempLV, |
467 | 865k | considerVisibility && !hasExplicitVisibilityAlready(computation)787k ); |
468 | | |
469 | | // Merge information from the template arguments. We ignore |
470 | | // template-argument visibility if we've got an explicit |
471 | | // instantiation with a visibility attribute. |
472 | 865k | const TemplateArgumentList &templateArgs = spec->getTemplateArgs(); |
473 | 865k | LinkageInfo argsLV = getLVForTemplateArgumentList(templateArgs, computation); |
474 | 865k | if (considerVisibility) |
475 | 787k | LV.mergeVisibility(argsLV); |
476 | 865k | LV.mergeExternalVisibility(argsLV); |
477 | 865k | } |
478 | | |
479 | | /// Should we consider visibility associated with the template |
480 | | /// arguments and parameters of the given variable template |
481 | | /// specialization? As usual, follow class template specialization |
482 | | /// logic up to initialization. |
483 | | static bool shouldConsiderTemplateVisibility( |
484 | | const VarTemplateSpecializationDecl *spec, |
485 | 3.18k | LVComputationKind computation) { |
486 | | // Include visibility from the template parameters and arguments |
487 | | // only if this is not an explicit instantiation or specialization |
488 | | // with direct explicit visibility (and note that implicit |
489 | | // instantiations won't have a direct attribute). |
490 | 3.18k | if (!spec->isExplicitInstantiationOrSpecialization()) |
491 | 1.56k | return true; |
492 | | |
493 | | // An explicit variable specialization is an independent, top-level |
494 | | // declaration. As such, if it has an explicit visibility attribute, |
495 | | // that must directly express the user's intent, and we should honor |
496 | | // it. |
497 | 1.62k | if (spec->isExplicitSpecialization() && |
498 | 970 | hasExplicitVisibilityAlready(computation)) |
499 | 708 | return false; |
500 | | |
501 | 912 | return !hasDirectVisibilityAttribute(spec, computation); |
502 | 912 | } |
503 | | |
504 | | /// Merge in template-related linkage and visibility for the given |
505 | | /// variable template specialization. As usual, follow class template |
506 | | /// specialization logic up to initialization. |
507 | | void LinkageComputer::mergeTemplateLV(LinkageInfo &LV, |
508 | | const VarTemplateSpecializationDecl *spec, |
509 | 3.18k | LVComputationKind computation) { |
510 | 3.18k | bool considerVisibility = shouldConsiderTemplateVisibility(spec, computation); |
511 | | |
512 | | // Merge information from the template parameters, but ignore |
513 | | // visibility if we're only considering template arguments. |
514 | | |
515 | 3.18k | VarTemplateDecl *temp = spec->getSpecializedTemplate(); |
516 | 3.18k | LinkageInfo tempLV = |
517 | 3.18k | getLVForTemplateParameterList(temp->getTemplateParameters(), computation); |
518 | 3.18k | LV.mergeMaybeWithVisibility(tempLV, |
519 | 3.18k | considerVisibility && !hasExplicitVisibilityAlready(computation)2.47k ); |
520 | | |
521 | | // Merge information from the template arguments. We ignore |
522 | | // template-argument visibility if we've got an explicit |
523 | | // instantiation with a visibility attribute. |
524 | 3.18k | const TemplateArgumentList &templateArgs = spec->getTemplateArgs(); |
525 | 3.18k | LinkageInfo argsLV = getLVForTemplateArgumentList(templateArgs, computation); |
526 | 3.18k | if (considerVisibility) |
527 | 2.47k | LV.mergeVisibility(argsLV); |
528 | 3.18k | LV.mergeExternalVisibility(argsLV); |
529 | 3.18k | } |
530 | | |
531 | 1.14M | static bool useInlineVisibilityHidden(const NamedDecl *D) { |
532 | | // FIXME: we should warn if -fvisibility-inlines-hidden is used with c. |
533 | 1.14M | const LangOptions &Opts = D->getASTContext().getLangOpts(); |
534 | 1.14M | if (!Opts.CPlusPlus || !Opts.InlineVisibilityHidden844k ) |
535 | 1.14M | return false; |
536 | | |
537 | 327 | const auto *FD = dyn_cast<FunctionDecl>(D); |
538 | 327 | if (!FD) |
539 | 78 | return false; |
540 | | |
541 | 249 | TemplateSpecializationKind TSK = TSK_Undeclared; |
542 | 249 | if (FunctionTemplateSpecializationInfo *spec |
543 | 16 | = FD->getTemplateSpecializationInfo()) { |
544 | 16 | TSK = spec->getTemplateSpecializationKind(); |
545 | 233 | } else if (MemberSpecializationInfo *MSI = |
546 | 28 | FD->getMemberSpecializationInfo()) { |
547 | 28 | TSK = MSI->getTemplateSpecializationKind(); |
548 | 28 | } |
549 | | |
550 | 249 | const FunctionDecl *Def = nullptr; |
551 | | // InlineVisibilityHidden only applies to definitions, and |
552 | | // isInlined() only gives meaningful answers on definitions |
553 | | // anyway. |
554 | 249 | return TSK != TSK_ExplicitInstantiationDeclaration && |
555 | 245 | TSK != TSK_ExplicitInstantiationDefinition && |
556 | 237 | FD->hasBody(Def) && Def->isInlined()223 && !Def->hasAttr<GNUInlineAttr>()143 ; |
557 | 249 | } |
558 | | |
559 | 6.64M | template <typename T> static bool isFirstInExternCContext(T *D) { |
560 | 6.64M | const T *First = D->getFirstDecl(); |
561 | 6.64M | return First->isInExternCContext(); |
562 | 6.64M | } Decl.cpp:bool isFirstInExternCContext<clang::VarDecl const>(clang::VarDecl const*) Line | Count | Source | 559 | 600k | template <typename T> static bool isFirstInExternCContext(T *D) { | 560 | 600k | const T *First = D->getFirstDecl(); | 561 | 600k | return First->isInExternCContext(); | 562 | 600k | } |
Decl.cpp:bool isFirstInExternCContext<clang::FunctionDecl const>(clang::FunctionDecl const*) Line | Count | Source | 559 | 6.04M | template <typename T> static bool isFirstInExternCContext(T *D) { | 560 | 6.04M | const T *First = D->getFirstDecl(); | 561 | 6.04M | return First->isInExternCContext(); | 562 | 6.04M | } |
|
563 | | |
564 | 13.8M | static bool isSingleLineLanguageLinkage(const Decl &D) { |
565 | 13.8M | if (const auto *SD = dyn_cast<LinkageSpecDecl>(D.getDeclContext())) |
566 | 193k | if (!SD->hasBraces()) |
567 | 191k | return true; |
568 | 13.6M | return false; |
569 | 13.6M | } |
570 | | |
571 | | /// Determine whether D is declared in the purview of a named module. |
572 | 17.2M | static bool isInModulePurview(const NamedDecl *D) { |
573 | 17.2M | if (auto *M = D->getOwningModule()) |
574 | 605k | return M->isModulePurview(); |
575 | 16.6M | return false; |
576 | 16.6M | } |
577 | | |
578 | 147k | static bool isExportedFromModuleInterfaceUnit(const NamedDecl *D) { |
579 | | // FIXME: Handle isModulePrivate. |
580 | 147k | switch (D->getModuleOwnershipKind()) { |
581 | 135k | case Decl::ModuleOwnershipKind::Unowned: |
582 | 135k | case Decl::ModuleOwnershipKind::ModulePrivate: |
583 | 135k | return false; |
584 | 11.6k | case Decl::ModuleOwnershipKind::Visible: |
585 | 11.8k | case Decl::ModuleOwnershipKind::VisibleWhenImported: |
586 | 11.8k | return isInModulePurview(D); |
587 | 0 | } |
588 | 0 | llvm_unreachable("unexpected module ownership kind"); |
589 | 0 | } |
590 | | |
591 | 9.72M | static LinkageInfo getInternalLinkageFor(const NamedDecl *D) { |
592 | | // Internal linkage declarations within a module interface unit are modeled |
593 | | // as "module-internal linkage", which means that they have internal linkage |
594 | | // formally but can be indirectly accessed from outside the module via inline |
595 | | // functions and templates defined within the module. |
596 | 9.72M | if (isInModulePurview(D)) |
597 | 114 | return LinkageInfo(ModuleInternalLinkage, DefaultVisibility, false); |
598 | | |
599 | 9.72M | return LinkageInfo::internal(); |
600 | 9.72M | } |
601 | | |
602 | 7.55M | static LinkageInfo getExternalLinkageFor(const NamedDecl *D) { |
603 | | // C++ Modules TS [basic.link]/6.8: |
604 | | // - A name declared at namespace scope that does not have internal linkage |
605 | | // by the previous rules and that is introduced by a non-exported |
606 | | // declaration has module linkage. |
607 | 7.55M | if (isInModulePurview(D) && !isExportedFromModuleInterfaceUnit( |
608 | 376 | cast<NamedDecl>(D->getCanonicalDecl()))) |
609 | 204 | return LinkageInfo(ModuleLinkage, DefaultVisibility, false); |
610 | | |
611 | 7.55M | return LinkageInfo::external(); |
612 | 7.55M | } |
613 | | |
614 | 17.2M | static StorageClass getStorageClass(const Decl *D) { |
615 | 17.2M | if (auto *TD = dyn_cast<TemplateDecl>(D)) |
616 | 133k | D = TD->getTemplatedDecl(); |
617 | 17.2M | if (D) { |
618 | 17.2M | if (auto *VD = dyn_cast<VarDecl>(D)) |
619 | 1.41M | return VD->getStorageClass(); |
620 | 15.8M | if (auto *FD = dyn_cast<FunctionDecl>(D)) |
621 | 14.4M | return FD->getStorageClass(); |
622 | 1.39M | } |
623 | 1.39M | return SC_None; |
624 | 1.39M | } |
625 | | |
626 | | LinkageInfo |
627 | | LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D, |
628 | | LVComputationKind computation, |
629 | 17.2M | bool IgnoreVarTypeLinkage) { |
630 | 17.2M | assert(D->getDeclContext()->getRedeclContext()->isFileContext() && |
631 | 17.2M | "Not a name having namespace scope"); |
632 | 17.2M | ASTContext &Context = D->getASTContext(); |
633 | | |
634 | | // C++ [basic.link]p3: |
635 | | // A name having namespace scope (3.3.6) has internal linkage if it |
636 | | // is the name of |
637 | | |
638 | 17.2M | if (getStorageClass(D->getCanonicalDecl()) == SC_Static) { |
639 | | // - a variable, variable template, function, or function template |
640 | | // that is explicitly declared static; or |
641 | | // (This bullet corresponds to C99 6.2.2p3.) |
642 | 9.70M | return getInternalLinkageFor(D); |
643 | 9.70M | } |
644 | | |
645 | 7.57M | if (const auto *Var = dyn_cast<VarDecl>(D)) { |
646 | | // - a non-template variable of non-volatile const-qualified type, unless |
647 | | // - it is explicitly declared extern, or |
648 | | // - it is inline or exported, or |
649 | | // - it was previously declared and the prior declaration did not have |
650 | | // internal linkage |
651 | | // (There is no equivalent in C99.) |
652 | 1.37M | if (Context.getLangOpts().CPlusPlus && |
653 | 259k | Var->getType().isConstQualified() && |
654 | 148k | !Var->getType().isVolatileQualified() && |
655 | 148k | !Var->isInline() && |
656 | 147k | !isExportedFromModuleInterfaceUnit(Var) && |
657 | 147k | !isa<VarTemplateSpecializationDecl>(Var) && |
658 | 146k | !Var->getDescribedVarTemplate()) { |
659 | 146k | const VarDecl *PrevVar = Var->getPreviousDecl(); |
660 | 146k | if (PrevVar) |
661 | 126 | return getLVForDecl(PrevVar, computation); |
662 | | |
663 | 146k | if (Var->getStorageClass() != SC_Extern && |
664 | 60.2k | Var->getStorageClass() != SC_PrivateExtern && |
665 | 60.2k | !isSingleLineLanguageLinkage(*Var)) |
666 | 11.8k | return getInternalLinkageFor(Var); |
667 | 1.36M | } |
668 | | |
669 | 1.36M | for (const VarDecl *PrevVar = Var->getPreviousDecl(); 1.36M PrevVar; |
670 | 4.72k | PrevVar = PrevVar->getPreviousDecl()4.71k ) { |
671 | 4.72k | if (PrevVar->getStorageClass() == SC_PrivateExtern && |
672 | 22 | Var->getStorageClass() == SC_None) |
673 | 19 | return getDeclLinkageAndVisibility(PrevVar); |
674 | | // Explicitly declared static. |
675 | 4.71k | if (PrevVar->getStorageClass() == SC_Static) |
676 | 0 | return getInternalLinkageFor(Var); |
677 | 4.71k | } |
678 | 6.19M | } else if (const auto *IFD = dyn_cast<IndirectFieldDecl>(D)) { |
679 | | // - a data member of an anonymous union. |
680 | 6 | const VarDecl *VD = IFD->getVarDecl(); |
681 | 6 | assert(VD && "Expected a VarDecl in this IndirectFieldDecl!"); |
682 | 6 | return getLVForNamespaceScopeDecl(VD, computation, IgnoreVarTypeLinkage); |
683 | 6 | } |
684 | 7.55M | assert(!isa<FieldDecl>(D) && "Didn't expect a FieldDecl!"); |
685 | | |
686 | | // FIXME: This gives internal linkage to names that should have no linkage |
687 | | // (those not covered by [basic.link]p6). |
688 | 7.55M | if (D->isInAnonymousNamespace()) { |
689 | 3.15k | const auto *Var = dyn_cast<VarDecl>(D); |
690 | 3.15k | const auto *Func = dyn_cast<FunctionDecl>(D); |
691 | | // FIXME: The check for extern "C" here is not justified by the standard |
692 | | // wording, but we retain it from the pre-DR1113 model to avoid breaking |
693 | | // code. |
694 | | // |
695 | | // C++11 [basic.link]p4: |
696 | | // An unnamed namespace or a namespace declared directly or indirectly |
697 | | // within an unnamed namespace has internal linkage. |
698 | 3.15k | if ((!Var || !isFirstInExternCContext(Var)793 ) && |
699 | 3.13k | (!Func || !isFirstInExternCContext(Func)905 )) |
700 | 3.10k | return getInternalLinkageFor(D); |
701 | 7.55M | } |
702 | | |
703 | | // Set up the defaults. |
704 | | |
705 | | // C99 6.2.2p5: |
706 | | // If the declaration of an identifier for an object has file |
707 | | // scope and no storage-class specifier, its linkage is |
708 | | // external. |
709 | 7.55M | LinkageInfo LV = getExternalLinkageFor(D); |
710 | | |
711 | 7.55M | if (!hasExplicitVisibilityAlready(computation)) { |
712 | 1.39M | if (Optional<Visibility> Vis = getExplicitVisibility(D, computation)) { |
713 | 482k | LV.mergeVisibility(*Vis, true); |
714 | 911k | } else { |
715 | | // If we're declared in a namespace with a visibility attribute, |
716 | | // use that namespace's visibility, and it still counts as explicit. |
717 | 911k | for (const DeclContext *DC = D->getDeclContext(); |
718 | 1.30M | !isa<TranslationUnitDecl>(DC); |
719 | 397k | DC = DC->getParent()397k ) { |
720 | 397k | const auto *ND = dyn_cast<NamespaceDecl>(DC); |
721 | 397k | if (!ND) continue40.2k ; |
722 | 356k | if (Optional<Visibility> Vis = getExplicitVisibility(ND, computation)) { |
723 | 93 | LV.mergeVisibility(*Vis, true); |
724 | 93 | break; |
725 | 93 | } |
726 | 356k | } |
727 | 911k | } |
728 | | |
729 | | // Add in global settings if the above didn't give us direct visibility. |
730 | 1.39M | if (!LV.isVisibilityExplicit()) { |
731 | | // Use global type/value visibility as appropriate. |
732 | 911k | Visibility globalVisibility = |
733 | 911k | computation.isValueVisibility() |
734 | 741k | ? Context.getLangOpts().getValueVisibilityMode() |
735 | 169k | : Context.getLangOpts().getTypeVisibilityMode(); |
736 | 911k | LV.mergeVisibility(globalVisibility, /*explicit*/ false); |
737 | | |
738 | | // If we're paying attention to global visibility, apply |
739 | | // -finline-visibility-hidden if this is an inline method. |
740 | 911k | if (useInlineVisibilityHidden(D)) |
741 | 34 | LV.mergeVisibility(HiddenVisibility, /*visibilityExplicit=*/false); |
742 | 911k | } |
743 | 1.39M | } |
744 | | |
745 | | // C++ [basic.link]p4: |
746 | | |
747 | | // A name having namespace scope that has not been given internal linkage |
748 | | // above and that is the name of |
749 | | // [...bullets...] |
750 | | // has its linkage determined as follows: |
751 | | // - if the enclosing namespace has internal linkage, the name has |
752 | | // internal linkage; [handled above] |
753 | | // - otherwise, if the declaration of the name is attached to a named |
754 | | // module and is not exported, the name has module linkage; |
755 | | // - otherwise, the name has external linkage. |
756 | | // LV is currently set up to handle the last two bullets. |
757 | | // |
758 | | // The bullets are: |
759 | | |
760 | | // - a variable; or |
761 | 7.55M | if (const auto *Var = dyn_cast<VarDecl>(D)) { |
762 | | // GCC applies the following optimization to variables and static |
763 | | // data members, but not to functions: |
764 | | // |
765 | | // Modify the variable's LV by the LV of its type unless this is |
766 | | // C or extern "C". This follows from [basic.link]p9: |
767 | | // A type without linkage shall not be used as the type of a |
768 | | // variable or function with external linkage unless |
769 | | // - the entity has C language linkage, or |
770 | | // - the entity is declared within an unnamed namespace, or |
771 | | // - the entity is not used or is defined in the same |
772 | | // translation unit. |
773 | | // and [basic.link]p10: |
774 | | // ...the types specified by all declarations referring to a |
775 | | // given variable or function shall be identical... |
776 | | // C does not have an equivalent rule. |
777 | | // |
778 | | // Ignore this if we've got an explicit attribute; the user |
779 | | // probably knows what they're doing. |
780 | | // |
781 | | // Note that we don't want to make the variable non-external |
782 | | // because of this, but unique-external linkage suits us. |
783 | 1.36M | if (Context.getLangOpts().CPlusPlus && !isFirstInExternCContext(Var)246k && |
784 | 103k | !IgnoreVarTypeLinkage) { |
785 | 103k | LinkageInfo TypeLV = getLVForType(*Var->getType(), computation); |
786 | 103k | if (!isExternallyVisible(TypeLV.getLinkage())) |
787 | 922 | return LinkageInfo::uniqueExternal(); |
788 | 102k | if (!LV.isVisibilityExplicit()) |
789 | 102k | LV.mergeVisibility(TypeLV); |
790 | 102k | } |
791 | | |
792 | 1.36M | if (Var->getStorageClass() == SC_PrivateExtern) |
793 | 73 | LV.mergeVisibility(HiddenVisibility, true); |
794 | | |
795 | | // Note that Sema::MergeVarDecl already takes care of implementing |
796 | | // C99 6.2.2p4 and propagating the visibility attribute, so we don't have |
797 | | // to do it here. |
798 | | |
799 | | // As per function and class template specializations (below), |
800 | | // consider LV for the template and template arguments. We're at file |
801 | | // scope, so we do not need to worry about nested specializations. |
802 | 1.36M | if (const auto *spec = dyn_cast<VarTemplateSpecializationDecl>(Var)) { |
803 | 2.27k | mergeTemplateLV(LV, spec, computation); |
804 | 2.27k | } |
805 | | |
806 | | // - a function; or |
807 | 6.19M | } else if (const auto *Function = dyn_cast<FunctionDecl>(D)) { |
808 | | // In theory, we can modify the function's LV by the LV of its |
809 | | // type unless it has C linkage (see comment above about variables |
810 | | // for justification). In practice, GCC doesn't do this, so it's |
811 | | // just too painful to make work. |
812 | | |
813 | 4.69M | if (Function->getStorageClass() == SC_PrivateExtern) |
814 | 40 | LV.mergeVisibility(HiddenVisibility, true); |
815 | | |
816 | | // Note that Sema::MergeCompatibleFunctionDecls already takes care of |
817 | | // merging storage classes and visibility attributes, so we don't have to |
818 | | // look at previous decls in here. |
819 | | |
820 | | // In C++, then if the type of the function uses a type with |
821 | | // unique-external linkage, it's not legally usable from outside |
822 | | // this translation unit. However, we should use the C linkage |
823 | | // rules instead for extern "C" declarations. |
824 | 4.69M | if (Context.getLangOpts().CPlusPlus && !isFirstInExternCContext(Function)1.68M ) { |
825 | | // Only look at the type-as-written. Otherwise, deducing the return type |
826 | | // of a function could change its linkage. |
827 | 985k | QualType TypeAsWritten = Function->getType(); |
828 | 985k | if (TypeSourceInfo *TSI = Function->getTypeSourceInfo()) |
829 | 978k | TypeAsWritten = TSI->getType(); |
830 | 985k | if (!isExternallyVisible(TypeAsWritten->getLinkage())) |
831 | 3.43k | return LinkageInfo::uniqueExternal(); |
832 | 4.69M | } |
833 | | |
834 | | // Consider LV from the template and the template arguments. |
835 | | // We're at file scope, so we do not need to worry about nested |
836 | | // specializations. |
837 | 4.69M | if (FunctionTemplateSpecializationInfo *specInfo |
838 | 166k | = Function->getTemplateSpecializationInfo()) { |
839 | 166k | mergeTemplateLV(LV, Function, specInfo, computation); |
840 | 166k | } |
841 | | |
842 | | // - a named class (Clause 9), or an unnamed class defined in a |
843 | | // typedef declaration in which the class has the typedef name |
844 | | // for linkage purposes (7.1.3); or |
845 | | // - a named enumeration (7.2), or an unnamed enumeration |
846 | | // defined in a typedef declaration in which the enumeration |
847 | | // has the typedef name for linkage purposes (7.1.3); or |
848 | 1.49M | } else if (const auto *Tag = dyn_cast<TagDecl>(D)) { |
849 | | // Unnamed tags have no linkage. |
850 | 1.32M | if (!Tag->hasNameForLinkage()) |
851 | 4.56k | return LinkageInfo::none(); |
852 | | |
853 | | // If this is a class template specialization, consider the |
854 | | // linkage of the template and template arguments. We're at file |
855 | | // scope, so we do not need to worry about nested specializations. |
856 | 1.31M | if (const auto *spec = dyn_cast<ClassTemplateSpecializationDecl>(Tag)) { |
857 | 862k | mergeTemplateLV(LV, spec, computation); |
858 | 862k | } |
859 | | |
860 | | // FIXME: This is not part of the C++ standard any more. |
861 | | // - an enumerator belonging to an enumeration with external linkage; or |
862 | 174k | } else if (isa<EnumConstantDecl>(D)) { |
863 | 0 | LinkageInfo EnumLV = getLVForDecl(cast<NamedDecl>(D->getDeclContext()), |
864 | 0 | computation); |
865 | 0 | if (!isExternalFormalLinkage(EnumLV.getLinkage())) |
866 | 0 | return LinkageInfo::none(); |
867 | 0 | LV.merge(EnumLV); |
868 | | |
869 | | // - a template |
870 | 174k | } else if (const auto *temp = dyn_cast<TemplateDecl>(D)) { |
871 | 133k | bool considerVisibility = !hasExplicitVisibilityAlready(computation); |
872 | 133k | LinkageInfo tempLV = |
873 | 133k | getLVForTemplateParameterList(temp->getTemplateParameters(), computation); |
874 | 133k | LV.mergeMaybeWithVisibility(tempLV, considerVisibility); |
875 | | |
876 | | // An unnamed namespace or a namespace declared directly or indirectly |
877 | | // within an unnamed namespace has internal linkage. All other namespaces |
878 | | // have external linkage. |
879 | | // |
880 | | // We handled names in anonymous namespaces above. |
881 | 41.2k | } else if (isa<NamespaceDecl>(D)) { |
882 | 36.1k | return LV; |
883 | | |
884 | | // By extension, we assign external linkage to Objective-C |
885 | | // interfaces. |
886 | 5.17k | } else if (isa<ObjCInterfaceDecl>(D)) { |
887 | | // fallout |
888 | | |
889 | 168 | } else if (auto *TD = dyn_cast<TypedefNameDecl>(D)) { |
890 | | // A typedef declaration has linkage if it gives a type a name for |
891 | | // linkage purposes. |
892 | 55 | if (!TD->getAnonDeclWithTypedefName(/*AnyRedecl*/true)) |
893 | 0 | return LinkageInfo::none(); |
894 | | |
895 | 113 | } else if (isa<MSGuidDecl>(D)) { |
896 | | // A GUID behaves like an inline variable with external linkage. Fall |
897 | | // through. |
898 | | |
899 | | // Everything not covered here has no linkage. |
900 | 1 | } else { |
901 | 1 | return LinkageInfo::none(); |
902 | 1 | } |
903 | | |
904 | | // If we ended up with non-externally-visible linkage, visibility should |
905 | | // always be default. |
906 | 7.51M | if (!isExternallyVisible(LV.getLinkage())) |
907 | 12.3k | return LinkageInfo(LV.getLinkage(), DefaultVisibility, false); |
908 | | |
909 | | // Mark the symbols as hidden when compiling for the device. |
910 | 7.49M | if (Context.getLangOpts().OpenMP && Context.getLangOpts().OpenMPIsDevice248k ) |
911 | 31.7k | LV.mergeVisibility(HiddenVisibility, /*newExplicit=*/false); |
912 | | |
913 | 7.49M | return LV; |
914 | 7.49M | } |
915 | | |
916 | | LinkageInfo |
917 | | LinkageComputer::getLVForClassMember(const NamedDecl *D, |
918 | | LVComputationKind computation, |
919 | 1.48M | bool IgnoreVarTypeLinkage) { |
920 | | // Only certain class members have linkage. Note that fields don't |
921 | | // really have linkage, but it's convenient to say they do for the |
922 | | // purposes of calculating linkage of pointer-to-data-member |
923 | | // template arguments. |
924 | | // |
925 | | // Templates also don't officially have linkage, but since we ignore |
926 | | // the C++ standard and look at template arguments when determining |
927 | | // linkage and visibility of a template specialization, we might hit |
928 | | // a template template argument that way. If we do, we need to |
929 | | // consider its linkage. |
930 | 1.48M | if (!(isa<CXXMethodDecl>(D) || |
931 | 220k | isa<VarDecl>(D) || |
932 | 94.9k | isa<FieldDecl>(D) || |
933 | 89.2k | isa<IndirectFieldDecl>(D) || |
934 | 89.1k | isa<TagDecl>(D) || |
935 | 53.1k | isa<TemplateDecl>(D))) |
936 | 51 | return LinkageInfo::none(); |
937 | | |
938 | 1.48M | LinkageInfo LV; |
939 | | |
940 | | // If we have an explicit visibility attribute, merge that in. |
941 | 1.48M | if (!hasExplicitVisibilityAlready(computation)) { |
942 | 387k | if (Optional<Visibility> Vis = getExplicitVisibility(D, computation)) |
943 | 153k | LV.mergeVisibility(*Vis, true); |
944 | | // If we're paying attention to global visibility, apply |
945 | | // -finline-visibility-hidden if this is an inline method. |
946 | | // |
947 | | // Note that we do this before merging information about |
948 | | // the class visibility. |
949 | 387k | if (!LV.isVisibilityExplicit() && useInlineVisibilityHidden(D)233k ) |
950 | 71 | LV.mergeVisibility(HiddenVisibility, /*visibilityExplicit=*/false); |
951 | 387k | } |
952 | | |
953 | | // If this class member has an explicit visibility attribute, the only |
954 | | // thing that can change its visibility is the template arguments, so |
955 | | // only look for them when processing the class. |
956 | 1.48M | LVComputationKind classComputation = computation; |
957 | 1.48M | if (LV.isVisibilityExplicit()) |
958 | 153k | classComputation = withExplicitVisibilityAlready(computation); |
959 | | |
960 | 1.48M | LinkageInfo classLV = |
961 | 1.48M | getLVForDecl(cast<RecordDecl>(D->getDeclContext()), classComputation); |
962 | | // The member has the same linkage as the class. If that's not externally |
963 | | // visible, we don't need to compute anything about the linkage. |
964 | | // FIXME: If we're only computing linkage, can we bail out here? |
965 | 1.48M | if (!isExternallyVisible(classLV.getLinkage())) |
966 | 20.1k | return classLV; |
967 | | |
968 | | |
969 | | // Otherwise, don't merge in classLV yet, because in certain cases |
970 | | // we need to completely ignore the visibility from it. |
971 | | |
972 | | // Specifically, if this decl exists and has an explicit attribute. |
973 | 1.46M | const NamedDecl *explicitSpecSuppressor = nullptr; |
974 | | |
975 | 1.46M | if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) { |
976 | | // Only look at the type-as-written. Otherwise, deducing the return type |
977 | | // of a function could change its linkage. |
978 | 1.25M | QualType TypeAsWritten = MD->getType(); |
979 | 1.25M | if (TypeSourceInfo *TSI = MD->getTypeSourceInfo()) |
980 | 1.16M | TypeAsWritten = TSI->getType(); |
981 | 1.25M | if (!isExternallyVisible(TypeAsWritten->getLinkage())) |
982 | 2.67k | return LinkageInfo::uniqueExternal(); |
983 | | |
984 | | // If this is a method template specialization, use the linkage for |
985 | | // the template parameters and arguments. |
986 | 1.24M | if (FunctionTemplateSpecializationInfo *spec |
987 | 81.3k | = MD->getTemplateSpecializationInfo()) { |
988 | 81.3k | mergeTemplateLV(LV, MD, spec, computation); |
989 | 81.3k | if (spec->isExplicitSpecialization()) { |
990 | 1.80k | explicitSpecSuppressor = MD; |
991 | 79.5k | } else if (isExplicitMemberSpecialization(spec->getTemplate())) { |
992 | 55 | explicitSpecSuppressor = spec->getTemplate()->getTemplatedDecl(); |
993 | 55 | } |
994 | 1.16M | } else if (isExplicitMemberSpecialization(MD)) { |
995 | 2.10k | explicitSpecSuppressor = MD; |
996 | 2.10k | } |
997 | | |
998 | 217k | } else if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) { |
999 | 34.1k | if (const auto *spec = dyn_cast<ClassTemplateSpecializationDecl>(RD)) { |
1000 | 3.13k | mergeTemplateLV(LV, spec, computation); |
1001 | 3.13k | if (spec->isExplicitSpecialization()) { |
1002 | 133 | explicitSpecSuppressor = spec; |
1003 | 2.99k | } else { |
1004 | 2.99k | const ClassTemplateDecl *temp = spec->getSpecializedTemplate(); |
1005 | 2.99k | if (isExplicitMemberSpecialization(temp)) { |
1006 | 45 | explicitSpecSuppressor = temp->getTemplatedDecl(); |
1007 | 45 | } |
1008 | 2.99k | } |
1009 | 31.0k | } else if (isExplicitMemberSpecialization(RD)) { |
1010 | 73 | explicitSpecSuppressor = RD; |
1011 | 73 | } |
1012 | | |
1013 | | // Static data members. |
1014 | 183k | } else if (const auto *VD = dyn_cast<VarDecl>(D)) { |
1015 | 124k | if (const auto *spec = dyn_cast<VarTemplateSpecializationDecl>(VD)) |
1016 | 906 | mergeTemplateLV(LV, spec, computation); |
1017 | | |
1018 | | // Modify the variable's linkage by its type, but ignore the |
1019 | | // type's visibility unless it's a definition. |
1020 | 124k | if (!IgnoreVarTypeLinkage) { |
1021 | 124k | LinkageInfo typeLV = getLVForType(*VD->getType(), computation); |
1022 | | // FIXME: If the type's linkage is not externally visible, we can |
1023 | | // give this static data member UniqueExternalLinkage. |
1024 | 124k | if (!LV.isVisibilityExplicit() && !classLV.isVisibilityExplicit()124k ) |
1025 | 119k | LV.mergeVisibility(typeLV); |
1026 | 124k | LV.mergeExternalVisibility(typeLV); |
1027 | 124k | } |
1028 | | |
1029 | 124k | if (isExplicitMemberSpecialization(VD)) { |
1030 | 157 | explicitSpecSuppressor = VD; |
1031 | 157 | } |
1032 | | |
1033 | | // Template members. |
1034 | 58.3k | } else if (const auto *temp = dyn_cast<TemplateDecl>(D)) { |
1035 | 53.0k | bool considerVisibility = |
1036 | 53.0k | (!LV.isVisibilityExplicit() && |
1037 | 53.0k | !classLV.isVisibilityExplicit() && |
1038 | 50.9k | !hasExplicitVisibilityAlready(computation)); |
1039 | 53.0k | LinkageInfo tempLV = |
1040 | 53.0k | getLVForTemplateParameterList(temp->getTemplateParameters(), computation); |
1041 | 53.0k | LV.mergeMaybeWithVisibility(tempLV, considerVisibility); |
1042 | | |
1043 | 53.0k | if (const auto *redeclTemp = dyn_cast<RedeclarableTemplateDecl>(temp)) { |
1044 | 53.0k | if (isExplicitMemberSpecialization(redeclTemp)) { |
1045 | 23 | explicitSpecSuppressor = temp->getTemplatedDecl(); |
1046 | 23 | } |
1047 | 53.0k | } |
1048 | 53.0k | } |
1049 | | |
1050 | | // We should never be looking for an attribute directly on a template. |
1051 | 1.46M | assert(!explicitSpecSuppressor || !isa<TemplateDecl>(explicitSpecSuppressor)); |
1052 | | |
1053 | | // If this member is an explicit member specialization, and it has |
1054 | | // an explicit attribute, ignore visibility from the parent. |
1055 | 1.46M | bool considerClassVisibility = true; |
1056 | 1.46M | if (explicitSpecSuppressor && |
1057 | | // optimization: hasDVA() is true only with explicit visibility. |
1058 | 4.39k | LV.isVisibilityExplicit() && |
1059 | 1.52k | classLV.getVisibility() != DefaultVisibility && |
1060 | 96 | hasDirectVisibilityAttribute(explicitSpecSuppressor, computation)) { |
1061 | 96 | considerClassVisibility = false; |
1062 | 96 | } |
1063 | | |
1064 | | // Finally, merge in information from the class. |
1065 | 1.46M | LV.mergeMaybeWithVisibility(classLV, considerClassVisibility); |
1066 | 1.46M | return LV; |
1067 | 1.46M | } |
1068 | | |
1069 | 0 | void NamedDecl::anchor() {} |
1070 | | |
1071 | 9.07M | bool NamedDecl::isLinkageValid() const { |
1072 | 9.07M | if (!hasCachedLinkage()) |
1073 | 9.07M | return true; |
1074 | | |
1075 | 356 | Linkage L = LinkageComputer{} |
1076 | 356 | .computeLVForDecl(this, LVComputationKind::forLinkageOnly()) |
1077 | 356 | .getLinkage(); |
1078 | 356 | return L == getCachedLinkage(); |
1079 | 356 | } |
1080 | | |
1081 | 245k | ObjCStringFormatFamily NamedDecl::getObjCFStringFormattingFamily() const { |
1082 | 245k | StringRef name = getName(); |
1083 | 245k | if (name.empty()) return SFF_None0 ; |
1084 | | |
1085 | 245k | if (name.front() == 'C') |
1086 | 14.5k | if (name == "CFStringCreateWithFormat" || |
1087 | 14.5k | name == "CFStringCreateWithFormatAndArguments" || |
1088 | 14.4k | name == "CFStringAppendFormat" || |
1089 | 14.4k | name == "CFStringAppendFormatAndArguments") |
1090 | 24 | return SFF_CFString; |
1091 | 245k | return SFF_None; |
1092 | 245k | } |
1093 | | |
1094 | 86.4M | Linkage NamedDecl::getLinkageInternal() const { |
1095 | | // We don't care about visibility here, so ask for the cheapest |
1096 | | // possible visibility analysis. |
1097 | 86.4M | return LinkageComputer{} |
1098 | 86.4M | .getLVForDecl(this, LVComputationKind::forLinkageOnly()) |
1099 | 86.4M | .getLinkage(); |
1100 | 86.4M | } |
1101 | | |
1102 | 1.04M | LinkageInfo NamedDecl::getLinkageAndVisibility() const { |
1103 | 1.04M | return LinkageComputer{}.getDeclLinkageAndVisibility(this); |
1104 | 1.04M | } |
1105 | | |
1106 | | static Optional<Visibility> |
1107 | | getExplicitVisibilityAux(const NamedDecl *ND, |
1108 | | NamedDecl::ExplicitVisibilityKind kind, |
1109 | 2.14M | bool IsMostRecent) { |
1110 | 2.14M | assert(!IsMostRecent || ND == ND->getMostRecentDecl()); |
1111 | | |
1112 | | // Check the declaration itself first. |
1113 | 2.14M | if (Optional<Visibility> V = getVisibilityOf(ND, kind)) |
1114 | 127k | return V; |
1115 | | |
1116 | | // If this is a member class of a specialization of a class template |
1117 | | // and the corresponding decl has explicit visibility, use that. |
1118 | 2.01M | if (const auto *RD = dyn_cast<CXXRecordDecl>(ND)) { |
1119 | 694k | CXXRecordDecl *InstantiatedFrom = RD->getInstantiatedFromMemberClass(); |
1120 | 694k | if (InstantiatedFrom) |
1121 | 7.86k | return getVisibilityOf(InstantiatedFrom, kind); |
1122 | 2.00M | } |
1123 | | |
1124 | | // If there wasn't explicit visibility there, and this is a |
1125 | | // specialization of a class template, check for visibility |
1126 | | // on the pattern. |
1127 | 2.00M | if (const auto *spec = dyn_cast<ClassTemplateSpecializationDecl>(ND)) { |
1128 | | // Walk all the template decl till this point to see if there are |
1129 | | // explicit visibility attributes. |
1130 | 505k | const auto *TD = spec->getSpecializedTemplate()->getTemplatedDecl(); |
1131 | 754k | while (TD != nullptr) { |
1132 | 559k | auto Vis = getVisibilityOf(TD, kind); |
1133 | 559k | if (Vis != None) |
1134 | 311k | return Vis; |
1135 | 248k | TD = TD->getPreviousDecl(); |
1136 | 248k | } |
1137 | 194k | return None; |
1138 | 1.50M | } |
1139 | | |
1140 | | // Use the most recent declaration. |
1141 | 1.50M | if (!IsMostRecent && !isa<NamespaceDecl>(ND)1.49M ) { |
1142 | 1.14M | const NamedDecl *MostRecent = ND->getMostRecentDecl(); |
1143 | 1.14M | if (MostRecent != ND) |
1144 | 1.68k | return getExplicitVisibilityAux(MostRecent, kind, true); |
1145 | 1.49M | } |
1146 | | |
1147 | 1.49M | if (const auto *Var = dyn_cast<VarDecl>(ND)) { |
1148 | 67.4k | if (Var->isStaticDataMember()) { |
1149 | 2.53k | VarDecl *InstantiatedFrom = Var->getInstantiatedFromStaticDataMember(); |
1150 | 2.53k | if (InstantiatedFrom) |
1151 | 946 | return getVisibilityOf(InstantiatedFrom, kind); |
1152 | 66.5k | } |
1153 | | |
1154 | 66.5k | if (const auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(Var)) |
1155 | 1.06k | return getVisibilityOf(VTSD->getSpecializedTemplate()->getTemplatedDecl(), |
1156 | 1.06k | kind); |
1157 | | |
1158 | 65.4k | return None; |
1159 | 65.4k | } |
1160 | | // Also handle function template specializations. |
1161 | 1.43M | if (const auto *fn = dyn_cast<FunctionDecl>(ND)) { |
1162 | | // If the function is a specialization of a template with an |
1163 | | // explicit visibility attribute, use that. |
1164 | 886k | if (FunctionTemplateSpecializationInfo *templateInfo |
1165 | 120k | = fn->getTemplateSpecializationInfo()) |
1166 | 120k | return getVisibilityOf(templateInfo->getTemplate()->getTemplatedDecl(), |
1167 | 120k | kind); |
1168 | | |
1169 | | // If the function is a member of a specialization of a class template |
1170 | | // and the corresponding decl has explicit visibility, use that. |
1171 | 766k | FunctionDecl *InstantiatedFrom = fn->getInstantiatedFromMemberFunction(); |
1172 | 766k | if (InstantiatedFrom) |
1173 | 208k | return getVisibilityOf(InstantiatedFrom, kind); |
1174 | | |
1175 | 558k | return None; |
1176 | 558k | } |
1177 | | |
1178 | | // The visibility of a template is stored in the templated decl. |
1179 | 544k | if (const auto *TD = dyn_cast<TemplateDecl>(ND)) |
1180 | 591 | return getVisibilityOf(TD->getTemplatedDecl(), kind); |
1181 | | |
1182 | 543k | return None; |
1183 | 543k | } |
1184 | | |
1185 | | Optional<Visibility> |
1186 | 2.13M | NamedDecl::getExplicitVisibility(ExplicitVisibilityKind kind) const { |
1187 | 2.13M | return getExplicitVisibilityAux(this, kind, false); |
1188 | 2.13M | } |
1189 | | |
1190 | | LinkageInfo LinkageComputer::getLVForClosure(const DeclContext *DC, |
1191 | | Decl *ContextDecl, |
1192 | 7.08k | LVComputationKind computation) { |
1193 | | // This lambda has its linkage/visibility determined by its owner. |
1194 | 7.08k | const NamedDecl *Owner; |
1195 | 7.08k | if (!ContextDecl) |
1196 | 6.69k | Owner = dyn_cast<NamedDecl>(DC); |
1197 | 392 | else if (isa<ParmVarDecl>(ContextDecl)) |
1198 | 177 | Owner = |
1199 | 177 | dyn_cast<NamedDecl>(ContextDecl->getDeclContext()->getRedeclContext()); |
1200 | 215 | else |
1201 | 215 | Owner = cast<NamedDecl>(ContextDecl); |
1202 | | |
1203 | 7.08k | if (!Owner) |
1204 | 1.73k | return LinkageInfo::none(); |
1205 | | |
1206 | | // If the owner has a deduced type, we need to skip querying the linkage and |
1207 | | // visibility of that type, because it might involve this closure type. The |
1208 | | // only effect of this is that we might give a lambda VisibleNoLinkage rather |
1209 | | // than NoLinkage when we don't strictly need to, which is benign. |
1210 | 5.34k | auto *VD = dyn_cast<VarDecl>(Owner); |
1211 | 5.34k | LinkageInfo OwnerLV = |
1212 | 5.34k | VD && VD->getType()->getContainedDeducedType()130 |
1213 | 73 | ? computeLVForDecl(Owner, computation, /*IgnoreVarTypeLinkage*/true) |
1214 | 5.27k | : getLVForDecl(Owner, computation); |
1215 | | |
1216 | | // A lambda never formally has linkage. But if the owner is externally |
1217 | | // visible, then the lambda is too. We apply the same rules to blocks. |
1218 | 5.34k | if (!isExternallyVisible(OwnerLV.getLinkage())) |
1219 | 2.26k | return LinkageInfo::none(); |
1220 | 3.08k | return LinkageInfo(VisibleNoLinkage, OwnerLV.getVisibility(), |
1221 | 3.08k | OwnerLV.isVisibilityExplicit()); |
1222 | 3.08k | } |
1223 | | |
1224 | | LinkageInfo LinkageComputer::getLVForLocalDecl(const NamedDecl *D, |
1225 | 776k | LVComputationKind computation) { |
1226 | 776k | if (const auto *Function = dyn_cast<FunctionDecl>(D)) { |
1227 | 93 | if (Function->isInAnonymousNamespace() && |
1228 | 0 | !isFirstInExternCContext(Function)) |
1229 | 0 | return getInternalLinkageFor(Function); |
1230 | | |
1231 | | // This is a "void f();" which got merged with a file static. |
1232 | 93 | if (Function->getCanonicalDecl()->getStorageClass() == SC_Static) |
1233 | 0 | return getInternalLinkageFor(Function); |
1234 | | |
1235 | 93 | LinkageInfo LV; |
1236 | 93 | if (!hasExplicitVisibilityAlready(computation)) { |
1237 | 0 | if (Optional<Visibility> Vis = |
1238 | 0 | getExplicitVisibility(Function, computation)) |
1239 | 0 | LV.mergeVisibility(*Vis, true); |
1240 | 0 | } |
1241 | | |
1242 | | // Note that Sema::MergeCompatibleFunctionDecls already takes care of |
1243 | | // merging storage classes and visibility attributes, so we don't have to |
1244 | | // look at previous decls in here. |
1245 | | |
1246 | 93 | return LV; |
1247 | 93 | } |
1248 | | |
1249 | 776k | if (const auto *Var = dyn_cast<VarDecl>(D)) { |
1250 | 772k | if (Var->hasExternalStorage()) { |
1251 | 78 | if (Var->isInAnonymousNamespace() && !isFirstInExternCContext(Var)0 ) |
1252 | 0 | return getInternalLinkageFor(Var); |
1253 | | |
1254 | 78 | LinkageInfo LV; |
1255 | 78 | if (Var->getStorageClass() == SC_PrivateExtern) |
1256 | 24 | LV.mergeVisibility(HiddenVisibility, true); |
1257 | 54 | else if (!hasExplicitVisibilityAlready(computation)) { |
1258 | 0 | if (Optional<Visibility> Vis = getExplicitVisibility(Var, computation)) |
1259 | 0 | LV.mergeVisibility(*Vis, true); |
1260 | 0 | } |
1261 | | |
1262 | 78 | if (const VarDecl *Prev = Var->getPreviousDecl()) { |
1263 | 23 | LinkageInfo PrevLV = getLVForDecl(Prev, computation); |
1264 | 23 | if (PrevLV.getLinkage()) |
1265 | 23 | LV.setLinkage(PrevLV.getLinkage()); |
1266 | 23 | LV.mergeVisibility(PrevLV); |
1267 | 23 | } |
1268 | | |
1269 | 78 | return LV; |
1270 | 78 | } |
1271 | | |
1272 | 772k | if (!Var->isStaticLocal()) |
1273 | 759k | return LinkageInfo::none(); |
1274 | 17.3k | } |
1275 | | |
1276 | 17.3k | ASTContext &Context = D->getASTContext(); |
1277 | 17.3k | if (!Context.getLangOpts().CPlusPlus) |
1278 | 1.99k | return LinkageInfo::none(); |
1279 | | |
1280 | 15.3k | const Decl *OuterD = getOutermostFuncOrBlockContext(D); |
1281 | 15.3k | if (!OuterD || OuterD->isInvalidDecl()15.2k ) |
1282 | 111 | return LinkageInfo::none(); |
1283 | | |
1284 | 15.2k | LinkageInfo LV; |
1285 | 15.2k | if (const auto *BD = dyn_cast<BlockDecl>(OuterD)) { |
1286 | 41 | if (!BD->getBlockManglingNumber()) |
1287 | 9 | return LinkageInfo::none(); |
1288 | | |
1289 | 32 | LV = getLVForClosure(BD->getDeclContext()->getRedeclContext(), |
1290 | 32 | BD->getBlockManglingContextDecl(), computation); |
1291 | 15.2k | } else { |
1292 | 15.2k | const auto *FD = cast<FunctionDecl>(OuterD); |
1293 | 15.2k | if (!FD->isInlined() && |
1294 | 13.9k | !isTemplateInstantiation(FD->getTemplateSpecializationKind())) |
1295 | 13.6k | return LinkageInfo::none(); |
1296 | | |
1297 | | // If a function is hidden by -fvisibility-inlines-hidden option and |
1298 | | // is not explicitly attributed as a hidden function, |
1299 | | // we should not make static local variables in the function hidden. |
1300 | 1.55k | LV = getLVForDecl(FD, computation); |
1301 | 1.55k | if (isa<VarDecl>(D) && useInlineVisibilityHidden(FD)738 && |
1302 | 34 | !LV.isVisibilityExplicit() && |
1303 | 27 | !Context.getLangOpts().VisibilityInlinesHiddenStaticLocalVar) { |
1304 | 18 | assert(cast<VarDecl>(D)->isStaticLocal()); |
1305 | | // If this was an implicitly hidden inline method, check again for |
1306 | | // explicit visibility on the parent class, and use that for static locals |
1307 | | // if present. |
1308 | 18 | if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) |
1309 | 6 | LV = getLVForDecl(MD->getParent(), computation); |
1310 | 18 | if (!LV.isVisibilityExplicit()) { |
1311 | 15 | Visibility globalVisibility = |
1312 | 15 | computation.isValueVisibility() |
1313 | 15 | ? Context.getLangOpts().getValueVisibilityMode() |
1314 | 0 | : Context.getLangOpts().getTypeVisibilityMode(); |
1315 | 15 | return LinkageInfo(VisibleNoLinkage, globalVisibility, |
1316 | 15 | /*visibilityExplicit=*/false); |
1317 | 15 | } |
1318 | 1.56k | } |
1319 | 1.55k | } |
1320 | 1.56k | if (!isExternallyVisible(LV.getLinkage())) |
1321 | 247 | return LinkageInfo::none(); |
1322 | 1.32k | return LinkageInfo(VisibleNoLinkage, LV.getVisibility(), |
1323 | 1.32k | LV.isVisibilityExplicit()); |
1324 | 1.32k | } |
1325 | | |
1326 | | LinkageInfo LinkageComputer::computeLVForDecl(const NamedDecl *D, |
1327 | | LVComputationKind computation, |
1328 | 21.0M | bool IgnoreVarTypeLinkage) { |
1329 | | // Internal_linkage attribute overrides other considerations. |
1330 | 21.0M | if (D->hasAttr<InternalLinkageAttr>()) |
1331 | 0 | return getInternalLinkageFor(D); |
1332 | | |
1333 | | // Objective-C: treat all Objective-C declarations as having external |
1334 | | // linkage. |
1335 | 21.0M | switch (D->getKind()) { |
1336 | 19.0M | default: |
1337 | 19.0M | break; |
1338 | | |
1339 | | // Per C++ [basic.link]p2, only the names of objects, references, |
1340 | | // functions, types, templates, namespaces, and values ever have linkage. |
1341 | | // |
1342 | | // Note that the name of a typedef, namespace alias, using declaration, |
1343 | | // and so on are not the name of the corresponding type, namespace, or |
1344 | | // declaration, so they do *not* have linkage. |
1345 | 202k | case Decl::ImplicitParam: |
1346 | 202k | case Decl::Label: |
1347 | 202k | case Decl::NamespaceAlias: |
1348 | 1.45M | case Decl::ParmVar: |
1349 | 1.45M | case Decl::Using: |
1350 | 1.45M | case Decl::UsingShadow: |
1351 | 1.45M | case Decl::UsingDirective: |
1352 | 1.45M | return LinkageInfo::none(); |
1353 | | |
1354 | 15 | case Decl::EnumConstant: |
1355 | | // C++ [basic.link]p4: an enumerator has the linkage of its enumeration. |
1356 | 15 | if (D->getASTContext().getLangOpts().CPlusPlus) |
1357 | 14 | return getLVForDecl(cast<EnumDecl>(D->getDeclContext()), computation); |
1358 | 1 | return LinkageInfo::visible_none(); |
1359 | | |
1360 | 21.6k | case Decl::Typedef: |
1361 | 22.5k | case Decl::TypeAlias: |
1362 | | // A typedef declaration has linkage if it gives a type a name for |
1363 | | // linkage purposes. |
1364 | 22.5k | if (!cast<TypedefNameDecl>(D) |
1365 | 22.5k | ->getAnonDeclWithTypedefName(/*AnyRedecl*/true)) |
1366 | 22.4k | return LinkageInfo::none(); |
1367 | 55 | break; |
1368 | | |
1369 | 2 | case Decl::TemplateTemplateParm: // count these as external |
1370 | 2 | case Decl::NonTypeTemplateParm: |
1371 | 2 | case Decl::ObjCAtDefsField: |
1372 | 3 | case Decl::ObjCCategory: |
1373 | 3 | case Decl::ObjCCategoryImpl: |
1374 | 3 | case Decl::ObjCCompatibleAlias: |
1375 | 3 | case Decl::ObjCImplementation: |
1376 | 2.52k | case Decl::ObjCMethod: |
1377 | 2.52k | case Decl::ObjCProperty: |
1378 | 2.52k | case Decl::ObjCPropertyImpl: |
1379 | 2.52k | case Decl::ObjCProtocol: |
1380 | 2.52k | return getExternalLinkageFor(D); |
1381 | | |
1382 | 495k | case Decl::CXXRecord: { |
1383 | 495k | const auto *Record = cast<CXXRecordDecl>(D); |
1384 | 495k | if (Record->isLambda()) { |
1385 | 13.8k | if (Record->hasKnownLambdaInternalLinkage() || |
1386 | 13.6k | !Record->getLambdaManglingNumber()) { |
1387 | | // This lambda has no mangling number, so it's internal. |
1388 | 6.76k | return getInternalLinkageFor(D); |
1389 | 6.76k | } |
1390 | | |
1391 | 7.05k | return getLVForClosure( |
1392 | 7.05k | Record->getDeclContext()->getRedeclContext(), |
1393 | 7.05k | Record->getLambdaContextDecl(), computation); |
1394 | 7.05k | } |
1395 | | |
1396 | 481k | break; |
1397 | 481k | } |
1398 | | |
1399 | 651 | case Decl::TemplateParamObject: { |
1400 | | // The template parameter object can be referenced from anywhere its type |
1401 | | // and value can be referenced. |
1402 | 651 | auto *TPO = cast<TemplateParamObjectDecl>(D); |
1403 | 651 | LinkageInfo LV = getLVForType(*TPO->getType(), computation); |
1404 | 651 | LV.merge(getLVForValue(TPO->getValue(), computation)); |
1405 | 651 | return LV; |
1406 | 19.5M | } |
1407 | 19.5M | } |
1408 | | |
1409 | | // Handle linkage for namespace-scope names. |
1410 | 19.5M | if (D->getDeclContext()->getRedeclContext()->isFileContext()) |
1411 | 17.2M | return getLVForNamespaceScopeDecl(D, computation, IgnoreVarTypeLinkage); |
1412 | | |
1413 | | // C++ [basic.link]p5: |
1414 | | // In addition, a member function, static data member, a named |
1415 | | // class or enumeration of class scope, or an unnamed class or |
1416 | | // enumeration defined in a class-scope typedef declaration such |
1417 | | // that the class or enumeration has the typedef name for linkage |
1418 | | // purposes (7.1.3), has external linkage if the name of the class |
1419 | | // has external linkage. |
1420 | 2.26M | if (D->getDeclContext()->isRecord()) |
1421 | 1.48M | return getLVForClassMember(D, computation, IgnoreVarTypeLinkage); |
1422 | | |
1423 | | // C++ [basic.link]p6: |
1424 | | // The name of a function declared in block scope and the name of |
1425 | | // an object declared by a block scope extern declaration have |
1426 | | // linkage. If there is a visible declaration of an entity with |
1427 | | // linkage having the same name and type, ignoring entities |
1428 | | // declared outside the innermost enclosing namespace scope, the |
1429 | | // block scope declaration declares that same entity and receives |
1430 | | // the linkage of the previous declaration. If there is more than |
1431 | | // one such matching entity, the program is ill-formed. Otherwise, |
1432 | | // if no matching entity is found, the block scope entity receives |
1433 | | // external linkage. |
1434 | 777k | if (D->getDeclContext()->isFunctionOrMethod()) |
1435 | 776k | return getLVForLocalDecl(D, computation); |
1436 | | |
1437 | | // C++ [basic.link]p6: |
1438 | | // Names not covered by these rules have no linkage. |
1439 | 760 | return LinkageInfo::none(); |
1440 | 760 | } |
1441 | | |
1442 | | /// getLVForDecl - Get the linkage and visibility for the given declaration. |
1443 | | LinkageInfo LinkageComputer::getLVForDecl(const NamedDecl *D, |
1444 | 89.7M | LVComputationKind computation) { |
1445 | | // Internal_linkage attribute overrides other considerations. |
1446 | 89.7M | if (D->hasAttr<InternalLinkageAttr>()) |
1447 | 697 | return getInternalLinkageFor(D); |
1448 | | |
1449 | 89.7M | if (computation.IgnoreAllVisibility && D->hasCachedLinkage()87.5M ) |
1450 | 68.5M | return LinkageInfo(D->getCachedLinkage(), DefaultVisibility, false); |
1451 | | |
1452 | 21.2M | if (llvm::Optional<LinkageInfo> LI = lookup(D, computation)) |
1453 | 172k | return *LI; |
1454 | | |
1455 | 21.0M | LinkageInfo LV = computeLVForDecl(D, computation); |
1456 | 21.0M | if (D->hasCachedLinkage()) |
1457 | 21.0M | assert(D->getCachedLinkage() == LV.getLinkage()); |
1458 | | |
1459 | 21.0M | D->setCachedLinkage(LV.getLinkage()); |
1460 | 21.0M | cache(D, computation, LV); |
1461 | | |
1462 | 21.0M | #ifndef NDEBUG |
1463 | | // In C (because of gnu inline) and in c++ with microsoft extensions an |
1464 | | // static can follow an extern, so we can have two decls with different |
1465 | | // linkages. |
1466 | 21.0M | const LangOptions &Opts = D->getASTContext().getLangOpts(); |
1467 | 21.0M | if (!Opts.CPlusPlus || Opts.MicrosoftExt6.35M ) |
1468 | 14.7M | return LV; |
1469 | | |
1470 | | // We have just computed the linkage for this decl. By induction we know |
1471 | | // that all other computed linkages match, check that the one we just |
1472 | | // computed also does. |
1473 | 6.23M | NamedDecl *Old = nullptr; |
1474 | 7.65M | for (auto I : D->redecls()) { |
1475 | 7.65M | auto *T = cast<NamedDecl>(I); |
1476 | 7.65M | if (T == D) |
1477 | 6.23M | continue; |
1478 | 1.41M | if (!T->isInvalidDecl() && T->hasCachedLinkage()1.41M ) { |
1479 | 254k | Old = T; |
1480 | 254k | break; |
1481 | 254k | } |
1482 | 1.41M | } |
1483 | 6.23M | assert(!Old || Old->getCachedLinkage() == D->getCachedLinkage()); |
1484 | 6.23M | #endif |
1485 | | |
1486 | 6.23M | return LV; |
1487 | 6.23M | } |
1488 | | |
1489 | 1.79M | LinkageInfo LinkageComputer::getDeclLinkageAndVisibility(const NamedDecl *D) { |
1490 | 1.79M | return getLVForDecl(D, |
1491 | 1.79M | LVComputationKind(usesTypeVisibility(D) |
1492 | 760k | ? NamedDecl::VisibilityForType |
1493 | 1.03M | : NamedDecl::VisibilityForValue)); |
1494 | 1.79M | } |
1495 | | |
1496 | 26.2M | Module *Decl::getOwningModuleForLinkage(bool IgnoreLinkage) const { |
1497 | 26.2M | Module *M = getOwningModule(); |
1498 | 26.2M | if (!M) |
1499 | 25.4M | return nullptr; |
1500 | | |
1501 | 801k | switch (M->Kind) { |
1502 | 801k | case Module::ModuleMapModule: |
1503 | | // Module map modules have no special linkage semantics. |
1504 | 801k | return nullptr; |
1505 | | |
1506 | 476 | case Module::ModuleInterfaceUnit: |
1507 | 476 | return M; |
1508 | | |
1509 | 188 | case Module::GlobalModuleFragment: { |
1510 | | // External linkage declarations in the global module have no owning module |
1511 | | // for linkage purposes. But internal linkage declarations in the global |
1512 | | // module fragment of a particular module are owned by that module for |
1513 | | // linkage purposes. |
1514 | 188 | if (IgnoreLinkage) |
1515 | 168 | return nullptr; |
1516 | 20 | bool InternalLinkage; |
1517 | 20 | if (auto *ND = dyn_cast<NamedDecl>(this)) |
1518 | 20 | InternalLinkage = !ND->hasExternalFormalLinkage(); |
1519 | 0 | else { |
1520 | 0 | auto *NSD = dyn_cast<NamespaceDecl>(this); |
1521 | 0 | InternalLinkage = (NSD && NSD->isAnonymousNamespace()) || |
1522 | 0 | isInAnonymousNamespace(); |
1523 | 0 | } |
1524 | 10 | return InternalLinkage ? M->Parent : nullptr; |
1525 | 20 | } |
1526 | | |
1527 | 6 | case Module::PrivateModuleFragment: |
1528 | | // The private module fragment is part of its containing module for linkage |
1529 | | // purposes. |
1530 | 6 | return M->Parent; |
1531 | 0 | } |
1532 | | |
1533 | 0 | llvm_unreachable("unknown module kind"); |
1534 | 0 | } |
1535 | | |
1536 | 1.31M | void NamedDecl::printName(raw_ostream &os) const { |
1537 | 1.31M | os << Name; |
1538 | 1.31M | } |
1539 | | |
1540 | 19.3k | std::string NamedDecl::getQualifiedNameAsString() const { |
1541 | 19.3k | std::string QualName; |
1542 | 19.3k | llvm::raw_string_ostream OS(QualName); |
1543 | 19.3k | printQualifiedName(OS, getASTContext().getPrintingPolicy()); |
1544 | 19.3k | return OS.str(); |
1545 | 19.3k | } |
1546 | | |
1547 | 18.6k | void NamedDecl::printQualifiedName(raw_ostream &OS) const { |
1548 | 18.6k | printQualifiedName(OS, getASTContext().getPrintingPolicy()); |
1549 | 18.6k | } |
1550 | | |
1551 | | void NamedDecl::printQualifiedName(raw_ostream &OS, |
1552 | 362k | const PrintingPolicy &P) const { |
1553 | 362k | if (getDeclContext()->isFunctionOrMethod()) { |
1554 | | // We do not print '(anonymous)' for function parameters without name. |
1555 | 27.7k | printName(OS); |
1556 | 27.7k | return; |
1557 | 27.7k | } |
1558 | 335k | printNestedNameSpecifier(OS, P); |
1559 | 335k | if (getDeclName()) |
1560 | 333k | OS << *this; |
1561 | 1.21k | else { |
1562 | | // Give the printName override a chance to pick a different name before we |
1563 | | // fall back to "(anonymous)". |
1564 | 1.21k | SmallString<64> NameBuffer; |
1565 | 1.21k | llvm::raw_svector_ostream NameOS(NameBuffer); |
1566 | 1.21k | printName(NameOS); |
1567 | 1.21k | if (NameBuffer.empty()) |
1568 | 1.21k | OS << "(anonymous)"; |
1569 | 5 | else |
1570 | 5 | OS << NameBuffer; |
1571 | 1.21k | } |
1572 | 335k | } |
1573 | | |
1574 | 2 | void NamedDecl::printNestedNameSpecifier(raw_ostream &OS) const { |
1575 | 2 | printNestedNameSpecifier(OS, getASTContext().getPrintingPolicy()); |
1576 | 2 | } |
1577 | | |
1578 | | void NamedDecl::printNestedNameSpecifier(raw_ostream &OS, |
1579 | 335k | const PrintingPolicy &P) const { |
1580 | 335k | const DeclContext *Ctx = getDeclContext(); |
1581 | | |
1582 | | // For ObjC methods and properties, look through categories and use the |
1583 | | // interface as context. |
1584 | 335k | if (auto *MD = dyn_cast<ObjCMethodDecl>(this)) { |
1585 | 1.03k | if (auto *ID = MD->getClassInterface()) |
1586 | 1.02k | Ctx = ID; |
1587 | 334k | } else if (auto *PD = dyn_cast<ObjCPropertyDecl>(this)) { |
1588 | 21 | if (auto *MD = PD->getGetterMethodDecl()) |
1589 | 21 | if (auto *ID = MD->getClassInterface()) |
1590 | 21 | Ctx = ID; |
1591 | 334k | } else if (auto *ID = dyn_cast<ObjCIvarDecl>(this)) { |
1592 | 107 | if (auto *CI = ID->getContainingInterface()) |
1593 | 107 | Ctx = CI; |
1594 | 107 | } |
1595 | | |
1596 | 335k | if (Ctx->isFunctionOrMethod()) |
1597 | 0 | return; |
1598 | | |
1599 | 335k | using ContextsTy = SmallVector<const DeclContext *, 8>; |
1600 | 335k | ContextsTy Contexts; |
1601 | | |
1602 | | // Collect named contexts. |
1603 | 335k | DeclarationName NameInScope = getDeclName(); |
1604 | 994k | for (; Ctx; Ctx = Ctx->getParent()659k ) { |
1605 | | // Suppress anonymous namespace if requested. |
1606 | 659k | if (P.SuppressUnwrittenScope && isa<NamespaceDecl>(Ctx)64.3k && |
1607 | 1.22k | cast<NamespaceDecl>(Ctx)->isAnonymousNamespace()) |
1608 | 113 | continue; |
1609 | | |
1610 | | // Suppress inline namespace if it doesn't make the result ambiguous. |
1611 | 659k | if (P.SuppressInlineNamespace && Ctx->isInlineNamespace()122k && NameInScope250 && |
1612 | 249 | Ctx->lookup(NameInScope).size() == |
1613 | 249 | Ctx->getParent()->lookup(NameInScope).size()) |
1614 | 214 | continue; |
1615 | | |
1616 | | // Skip non-named contexts such as linkage specifications and ExportDecls. |
1617 | 658k | const NamedDecl *ND = dyn_cast<NamedDecl>(Ctx); |
1618 | 658k | if (!ND) |
1619 | 336k | continue; |
1620 | | |
1621 | 322k | Contexts.push_back(Ctx); |
1622 | 322k | NameInScope = ND->getDeclName(); |
1623 | 322k | } |
1624 | | |
1625 | 657k | for (unsigned I = Contexts.size(); I != 0; --I322k ) { |
1626 | 322k | const DeclContext *DC = Contexts[I - 1]; |
1627 | 322k | if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(DC)) { |
1628 | 65.0k | OS << Spec->getName(); |
1629 | 65.0k | const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); |
1630 | 65.0k | printTemplateArgumentList( |
1631 | 65.0k | OS, TemplateArgs.asArray(), P, |
1632 | 65.0k | Spec->getSpecializedTemplate()->getTemplateParameters()); |
1633 | 257k | } else if (const auto *ND = dyn_cast<NamespaceDecl>(DC)) { |
1634 | 201k | if (ND->isAnonymousNamespace()) { |
1635 | 0 | OS << (P.MSVCFormatting ? "`anonymous namespace\'" |
1636 | 1.26k | : "(anonymous namespace)"); |
1637 | 1.26k | } |
1638 | 200k | else |
1639 | 200k | OS << *ND; |
1640 | 55.5k | } else if (const auto *RD = dyn_cast<RecordDecl>(DC)) { |
1641 | 51.2k | if (!RD->getIdentifier()) |
1642 | 1.20k | OS << "(anonymous " << RD->getKindName() << ')'; |
1643 | 50.0k | else |
1644 | 50.0k | OS << *RD; |
1645 | 4.27k | } else if (const auto *FD = dyn_cast<FunctionDecl>(DC)) { |
1646 | 1.12k | const FunctionProtoType *FT = nullptr; |
1647 | 1.12k | if (FD->hasWrittenPrototype()) |
1648 | 1.12k | FT = dyn_cast<FunctionProtoType>(FD->getType()->castAs<FunctionType>()); |
1649 | | |
1650 | 1.12k | OS << *FD << '('; |
1651 | 1.12k | if (FT) { |
1652 | 1.12k | unsigned NumParams = FD->getNumParams(); |
1653 | 1.55k | for (unsigned i = 0; i < NumParams; ++i434 ) { |
1654 | 434 | if (i) |
1655 | 48 | OS << ", "; |
1656 | 434 | OS << FD->getParamDecl(i)->getType().stream(P); |
1657 | 434 | } |
1658 | | |
1659 | 1.12k | if (FT->isVariadic()) { |
1660 | 0 | if (NumParams > 0) |
1661 | 0 | OS << ", "; |
1662 | 0 | OS << "..."; |
1663 | 0 | } |
1664 | 1.12k | } |
1665 | 1.12k | OS << ')'; |
1666 | 3.15k | } else if (const auto *ED = dyn_cast<EnumDecl>(DC)) { |
1667 | | // C++ [dcl.enum]p10: Each enum-name and each unscoped |
1668 | | // enumerator is declared in the scope that immediately contains |
1669 | | // the enum-specifier. Each scoped enumerator is declared in the |
1670 | | // scope of the enumeration. |
1671 | | // For the case of unscoped enumerator, do not include in the qualified |
1672 | | // name any information about its enum enclosing scope, as its visibility |
1673 | | // is global. |
1674 | 1.98k | if (ED->isScoped()) |
1675 | 1.24k | OS << *ED; |
1676 | 744 | else |
1677 | 744 | continue; |
1678 | 1.16k | } else { |
1679 | 1.16k | OS << *cast<NamedDecl>(DC); |
1680 | 1.16k | } |
1681 | 321k | OS << "::"; |
1682 | 321k | } |
1683 | 335k | } |
1684 | | |
1685 | | void NamedDecl::getNameForDiagnostic(raw_ostream &OS, |
1686 | | const PrintingPolicy &Policy, |
1687 | 126k | bool Qualified) const { |
1688 | 126k | if (Qualified) |
1689 | 9.19k | printQualifiedName(OS, Policy); |
1690 | 117k | else |
1691 | 117k | printName(OS); |
1692 | 126k | } |
1693 | | |
1694 | 53.6M | template<typename T> static bool isRedeclarableImpl(Redeclarable<T> *) { |
1695 | 53.6M | return true; |
1696 | 53.6M | } Decl.cpp:bool isRedeclarableImpl<clang::NamespaceDecl>(clang::Redeclarable<clang::NamespaceDecl>*) Line | Count | Source | 1694 | 83.6k | template<typename T> static bool isRedeclarableImpl(Redeclarable<T> *) { | 1695 | 83.6k | return true; | 1696 | 83.6k | } |
Decl.cpp:bool isRedeclarableImpl<clang::NamespaceAliasDecl>(clang::Redeclarable<clang::NamespaceAliasDecl>*) Line | Count | Source | 1694 | 23 | template<typename T> static bool isRedeclarableImpl(Redeclarable<T> *) { | 1695 | 23 | return true; | 1696 | 23 | } |
Decl.cpp:bool isRedeclarableImpl<clang::ObjCInterfaceDecl>(clang::Redeclarable<clang::ObjCInterfaceDecl>*) Line | Count | Source | 1694 | 182k | template<typename T> static bool isRedeclarableImpl(Redeclarable<T> *) { | 1695 | 182k | return true; | 1696 | 182k | } |
Decl.cpp:bool isRedeclarableImpl<clang::ObjCProtocolDecl>(clang::Redeclarable<clang::ObjCProtocolDecl>*) Line | Count | Source | 1694 | 6.94k | template<typename T> static bool isRedeclarableImpl(Redeclarable<T> *) { | 1695 | 6.94k | return true; | 1696 | 6.94k | } |
Decl.cpp:bool isRedeclarableImpl<clang::RedeclarableTemplateDecl>(clang::Redeclarable<clang::RedeclarableTemplateDecl>*) Line | Count | Source | 1694 | 3.02M | template<typename T> static bool isRedeclarableImpl(Redeclarable<T> *) { | 1695 | 3.02M | return true; | 1696 | 3.02M | } |
Decl.cpp:bool isRedeclarableImpl<clang::TagDecl>(clang::Redeclarable<clang::TagDecl>*) Line | Count | Source | 1694 | 127k | template<typename T> static bool isRedeclarableImpl(Redeclarable<T> *) { | 1695 | 127k | return true; | 1696 | 127k | } |
Decl.cpp:bool isRedeclarableImpl<clang::TypedefNameDecl>(clang::Redeclarable<clang::TypedefNameDecl>*) Line | Count | Source | 1694 | 13.9k | template<typename T> static bool isRedeclarableImpl(Redeclarable<T> *) { | 1695 | 13.9k | return true; | 1696 | 13.9k | } |
Decl.cpp:bool isRedeclarableImpl<clang::UsingShadowDecl>(clang::Redeclarable<clang::UsingShadowDecl>*) Line | Count | Source | 1694 | 282k | template<typename T> static bool isRedeclarableImpl(Redeclarable<T> *) { | 1695 | 282k | return true; | 1696 | 282k | } |
Decl.cpp:bool isRedeclarableImpl<clang::FunctionDecl>(clang::Redeclarable<clang::FunctionDecl>*) Line | Count | Source | 1694 | 49.8M | template<typename T> static bool isRedeclarableImpl(Redeclarable<T> *) { | 1695 | 49.8M | return true; | 1696 | 49.8M | } |
Decl.cpp:bool isRedeclarableImpl<clang::VarDecl>(clang::Redeclarable<clang::VarDecl>*) Line | Count | Source | 1694 | 63.8k | template<typename T> static bool isRedeclarableImpl(Redeclarable<T> *) { | 1695 | 63.8k | return true; | 1696 | 63.8k | } |
|
1697 | 1.44k | static bool isRedeclarableImpl(...) { return false; } |
1698 | 53.6M | static bool isRedeclarable(Decl::Kind K) { |
1699 | 53.6M | switch (K) { |
1700 | 0 | #define DECL(Type, Base) \ |
1701 | 53.6M | case Decl::Type: \ |
1702 | 53.6M | return isRedeclarableImpl((Type##Decl *)nullptr); |
1703 | 0 | #define ABSTRACT_DECL(DECL) |
1704 | 0 | #include "clang/AST/DeclNodes.inc" |
1705 | 53.6M | } |
1706 | 53.6M | llvm_unreachable0 ("unknown decl kind"); |
1707 | 53.6M | } |
1708 | | |
1709 | 56.2M | bool NamedDecl::declarationReplaces(NamedDecl *OldD, bool IsKnownNewer) const { |
1710 | 56.2M | assert(getDeclName() == OldD->getDeclName() && "Declaration name mismatch"); |
1711 | | |
1712 | | // Never replace one imported declaration with another; we need both results |
1713 | | // when re-exporting. |
1714 | 56.2M | if (OldD->isFromASTFile() && isFromASTFile()105k ) |
1715 | 22.5k | return false; |
1716 | | |
1717 | | // A kind mismatch implies that the declaration is not replaced. |
1718 | 56.2M | if (OldD->getKind() != getKind()) |
1719 | 2.59M | return false; |
1720 | | |
1721 | | // For method declarations, we never replace. (Why?) |
1722 | 53.6M | if (isa<ObjCMethodDecl>(this)) |
1723 | 7.62k | return false; |
1724 | | |
1725 | | // For parameters, pick the newer one. This is either an error or (in |
1726 | | // Objective-C) permitted as an extension. |
1727 | 53.6M | if (isa<ParmVarDecl>(this)) |
1728 | 1 | return true; |
1729 | | |
1730 | | // Inline namespaces can give us two declarations with the same |
1731 | | // name and kind in the same scope but different contexts; we should |
1732 | | // keep both declarations in this case. |
1733 | 53.6M | if (!this->getDeclContext()->getRedeclContext()->Equals( |
1734 | 53.6M | OldD->getDeclContext()->getRedeclContext())) |
1735 | 8.72k | return false; |
1736 | | |
1737 | | // Using declarations can be replaced if they import the same name from the |
1738 | | // same context. |
1739 | 53.6M | if (auto *UD = dyn_cast<UsingDecl>(this)) { |
1740 | 6.03k | ASTContext &Context = getASTContext(); |
1741 | 6.03k | return Context.getCanonicalNestedNameSpecifier(UD->getQualifier()) == |
1742 | 6.03k | Context.getCanonicalNestedNameSpecifier( |
1743 | 6.03k | cast<UsingDecl>(OldD)->getQualifier()); |
1744 | 6.03k | } |
1745 | 53.6M | if (auto *UUVD = dyn_cast<UnresolvedUsingValueDecl>(this)) { |
1746 | 18 | ASTContext &Context = getASTContext(); |
1747 | 18 | return Context.getCanonicalNestedNameSpecifier(UUVD->getQualifier()) == |
1748 | 18 | Context.getCanonicalNestedNameSpecifier( |
1749 | 18 | cast<UnresolvedUsingValueDecl>(OldD)->getQualifier()); |
1750 | 18 | } |
1751 | | |
1752 | 53.6M | if (isRedeclarable(getKind())) { |
1753 | 53.6M | if (getCanonicalDecl() != OldD->getCanonicalDecl()) |
1754 | 52.7M | return false; |
1755 | | |
1756 | 808k | if (IsKnownNewer) |
1757 | 796k | return true; |
1758 | | |
1759 | | // Check whether this is actually newer than OldD. We want to keep the |
1760 | | // newer declaration. This loop will usually only iterate once, because |
1761 | | // OldD is usually the previous declaration. |
1762 | 17.0k | for (auto D : redecls())12.4k { |
1763 | 17.0k | if (D == OldD) |
1764 | 12.0k | break; |
1765 | | |
1766 | | // If we reach the canonical declaration, then OldD is not actually older |
1767 | | // than this one. |
1768 | | // |
1769 | | // FIXME: In this case, we should not add this decl to the lookup table. |
1770 | 5.00k | if (D->isCanonicalDecl()) |
1771 | 398 | return false; |
1772 | 5.00k | } |
1773 | | |
1774 | | // It's a newer declaration of the same kind of declaration in the same |
1775 | | // scope: we want this decl instead of the existing one. |
1776 | 12.0k | return true; |
1777 | 1.44k | } |
1778 | | |
1779 | | // In all other cases, we need to keep both declarations in case they have |
1780 | | // different visibility. Any attempt to use the name will result in an |
1781 | | // ambiguity if more than one is visible. |
1782 | 1.44k | return false; |
1783 | 1.44k | } |
1784 | | |
1785 | 1.57M | bool NamedDecl::hasLinkage() const { |
1786 | 1.57M | return getFormalLinkage() != NoLinkage; |
1787 | 1.57M | } |
1788 | | |
1789 | 1.42M | NamedDecl *NamedDecl::getUnderlyingDeclImpl() { |
1790 | 1.42M | NamedDecl *ND = this; |
1791 | 2.84M | while (auto *UD = dyn_cast<UsingShadowDecl>(ND)) |
1792 | 1.42M | ND = UD->getTargetDecl(); |
1793 | | |
1794 | 1.42M | if (auto *AD = dyn_cast<ObjCCompatibleAliasDecl>(ND)) |
1795 | 441 | return AD->getClassInterface(); |
1796 | | |
1797 | 1.42M | if (auto *AD = dyn_cast<NamespaceAliasDecl>(ND)) |
1798 | 1.62k | return AD->getNamespace(); |
1799 | | |
1800 | 1.42M | return ND; |
1801 | 1.42M | } |
1802 | | |
1803 | 5.53M | bool NamedDecl::isCXXInstanceMember() const { |
1804 | 5.53M | if (!isCXXClassMember()) |
1805 | 1.14M | return false; |
1806 | | |
1807 | 4.39M | const NamedDecl *D = this; |
1808 | 4.39M | if (isa<UsingShadowDecl>(D)) |
1809 | 91 | D = cast<UsingShadowDecl>(D)->getTargetDecl(); |
1810 | | |
1811 | 4.39M | if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D)3.59M || isa<MSPropertyDecl>(D)3.59M ) |
1812 | 797k | return true; |
1813 | 3.59M | if (const auto *MD = dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction())) |
1814 | 2.33M | return MD->isInstance(); |
1815 | 1.26M | return false; |
1816 | 1.26M | } |
1817 | | |
1818 | | //===----------------------------------------------------------------------===// |
1819 | | // DeclaratorDecl Implementation |
1820 | | //===----------------------------------------------------------------------===// |
1821 | | |
1822 | | template <typename DeclT> |
1823 | 6.70M | static SourceLocation getTemplateOrInnerLocStart(const DeclT *decl) { |
1824 | 6.70M | if (decl->getNumTemplateParameterLists() > 0) |
1825 | 68.4k | return decl->getTemplateParameterList(0)->getTemplateLoc(); |
1826 | 6.63M | else |
1827 | 6.63M | return decl->getInnerLocStart(); |
1828 | 6.70M | } Decl.cpp:clang::SourceLocation getTemplateOrInnerLocStart<clang::DeclaratorDecl>(clang::DeclaratorDecl const*) Line | Count | Source | 1823 | 6.34M | static SourceLocation getTemplateOrInnerLocStart(const DeclT *decl) { | 1824 | 6.34M | if (decl->getNumTemplateParameterLists() > 0) | 1825 | 68.4k | return decl->getTemplateParameterList(0)->getTemplateLoc(); | 1826 | 6.27M | else | 1827 | 6.27M | return decl->getInnerLocStart(); | 1828 | 6.34M | } |
Decl.cpp:clang::SourceLocation getTemplateOrInnerLocStart<clang::TagDecl>(clang::TagDecl const*) Line | Count | Source | 1823 | 353k | static SourceLocation getTemplateOrInnerLocStart(const DeclT *decl) { | 1824 | 353k | if (decl->getNumTemplateParameterLists() > 0) | 1825 | 10 | return decl->getTemplateParameterList(0)->getTemplateLoc(); | 1826 | 353k | else | 1827 | 353k | return decl->getInnerLocStart(); | 1828 | 353k | } |
|
1829 | | |
1830 | 1.99M | SourceLocation DeclaratorDecl::getTypeSpecStartLoc() const { |
1831 | 1.99M | TypeSourceInfo *TSI = getTypeSourceInfo(); |
1832 | 1.99M | if (TSI) return TSI->getTypeLoc().getBeginLoc(); |
1833 | 0 | return SourceLocation(); |
1834 | 0 | } |
1835 | | |
1836 | 167 | SourceLocation DeclaratorDecl::getTypeSpecEndLoc() const { |
1837 | 167 | TypeSourceInfo *TSI = getTypeSourceInfo(); |
1838 | 167 | if (TSI) return TSI->getTypeLoc().getEndLoc(); |
1839 | 0 | return SourceLocation(); |
1840 | 0 | } |
1841 | | |
1842 | 744k | void DeclaratorDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) { |
1843 | 744k | if (QualifierLoc) { |
1844 | | // Make sure the extended decl info is allocated. |
1845 | 273k | if (!hasExtInfo()) { |
1846 | | // Save (non-extended) type source info pointer. |
1847 | 273k | auto *savedTInfo = DeclInfo.get<TypeSourceInfo*>(); |
1848 | | // Allocate external info struct. |
1849 | 273k | DeclInfo = new (getASTContext()) ExtInfo; |
1850 | | // Restore savedTInfo into (extended) decl info. |
1851 | 273k | getExtInfo()->TInfo = savedTInfo; |
1852 | 273k | } |
1853 | | // Set qualifier info. |
1854 | 273k | getExtInfo()->QualifierLoc = QualifierLoc; |
1855 | 470k | } else if (hasExtInfo()) { |
1856 | | // Here Qualifier == 0, i.e., we are removing the qualifier (if any). |
1857 | 0 | getExtInfo()->QualifierLoc = QualifierLoc; |
1858 | 0 | } |
1859 | 744k | } |
1860 | | |
1861 | 255 | void DeclaratorDecl::setTrailingRequiresClause(Expr *TrailingRequiresClause) { |
1862 | 255 | assert(TrailingRequiresClause); |
1863 | | // Make sure the extended decl info is allocated. |
1864 | 255 | if (!hasExtInfo()) { |
1865 | | // Save (non-extended) type source info pointer. |
1866 | 203 | auto *savedTInfo = DeclInfo.get<TypeSourceInfo*>(); |
1867 | | // Allocate external info struct. |
1868 | 203 | DeclInfo = new (getASTContext()) ExtInfo; |
1869 | | // Restore savedTInfo into (extended) decl info. |
1870 | 203 | getExtInfo()->TInfo = savedTInfo; |
1871 | 203 | } |
1872 | | // Set requires clause info. |
1873 | 255 | getExtInfo()->TrailingRequiresClause = TrailingRequiresClause; |
1874 | 255 | } |
1875 | | |
1876 | | void DeclaratorDecl::setTemplateParameterListsInfo( |
1877 | 188k | ASTContext &Context, ArrayRef<TemplateParameterList *> TPLists) { |
1878 | 188k | assert(!TPLists.empty()); |
1879 | | // Make sure the extended decl info is allocated. |
1880 | 188k | if (!hasExtInfo()) { |
1881 | | // Save (non-extended) type source info pointer. |
1882 | 1.68k | auto *savedTInfo = DeclInfo.get<TypeSourceInfo*>(); |
1883 | | // Allocate external info struct. |
1884 | 1.68k | DeclInfo = new (getASTContext()) ExtInfo; |
1885 | | // Restore savedTInfo into (extended) decl info. |
1886 | 1.68k | getExtInfo()->TInfo = savedTInfo; |
1887 | 1.68k | } |
1888 | | // Set the template parameter lists info. |
1889 | 188k | getExtInfo()->setTemplateParameterListsInfo(Context, TPLists); |
1890 | 188k | } |
1891 | | |
1892 | 6.34M | SourceLocation DeclaratorDecl::getOuterLocStart() const { |
1893 | 6.34M | return getTemplateOrInnerLocStart(this); |
1894 | 6.34M | } |
1895 | | |
1896 | | // Helper function: returns true if QT is or contains a type |
1897 | | // having a postfix component. |
1898 | 194k | static bool typeIsPostfix(QualType QT) { |
1899 | 245k | while (true) { |
1900 | 245k | const Type* T = QT.getTypePtr(); |
1901 | 245k | switch (T->getTypeClass()) { |
1902 | 192k | default: |
1903 | 192k | return false; |
1904 | 11.9k | case Type::Pointer: |
1905 | 11.9k | QT = cast<PointerType>(T)->getPointeeType(); |
1906 | 11.9k | break; |
1907 | 38 | case Type::BlockPointer: |
1908 | 38 | QT = cast<BlockPointerType>(T)->getPointeeType(); |
1909 | 38 | break; |
1910 | 288 | case Type::MemberPointer: |
1911 | 288 | QT = cast<MemberPointerType>(T)->getPointeeType(); |
1912 | 288 | break; |
1913 | 24.2k | case Type::LValueReference: |
1914 | 36.3k | case Type::RValueReference: |
1915 | 36.3k | QT = cast<ReferenceType>(T)->getPointeeType(); |
1916 | 36.3k | break; |
1917 | 2.20k | case Type::PackExpansion: |
1918 | 2.20k | QT = cast<PackExpansionType>(T)->getPattern(); |
1919 | 2.20k | break; |
1920 | 784 | case Type::Paren: |
1921 | 1.95k | case Type::ConstantArray: |
1922 | 1.96k | case Type::DependentSizedArray: |
1923 | 2.33k | case Type::IncompleteArray: |
1924 | 2.35k | case Type::VariableArray: |
1925 | 2.39k | case Type::FunctionProto: |
1926 | 2.39k | case Type::FunctionNoProto: |
1927 | 2.39k | return true; |
1928 | 245k | } |
1929 | 245k | } |
1930 | 194k | } |
1931 | | |
1932 | 201k | SourceRange DeclaratorDecl::getSourceRange() const { |
1933 | 201k | SourceLocation RangeEnd = getLocation(); |
1934 | 201k | if (TypeSourceInfo *TInfo = getTypeSourceInfo()) { |
1935 | | // If the declaration has no name or the type extends past the name take the |
1936 | | // end location of the type. |
1937 | 197k | if (!getDeclName() || typeIsPostfix(TInfo->getType())188k ) |
1938 | 10.6k | RangeEnd = TInfo->getTypeLoc().getSourceRange().getEnd(); |
1939 | 197k | } |
1940 | 201k | return SourceRange(getOuterLocStart(), RangeEnd); |
1941 | 201k | } |
1942 | | |
1943 | | void QualifierInfo::setTemplateParameterListsInfo( |
1944 | 239k | ASTContext &Context, ArrayRef<TemplateParameterList *> TPLists) { |
1945 | | // Free previous template parameters (if any). |
1946 | 239k | if (NumTemplParamLists > 0) { |
1947 | 0 | Context.Deallocate(TemplParamLists); |
1948 | 0 | TemplParamLists = nullptr; |
1949 | 0 | NumTemplParamLists = 0; |
1950 | 0 | } |
1951 | | // Set info on matched template parameter lists (if any). |
1952 | 239k | if (!TPLists.empty()) { |
1953 | 239k | TemplParamLists = new (Context) TemplateParameterList *[TPLists.size()]; |
1954 | 239k | NumTemplParamLists = TPLists.size(); |
1955 | 239k | std::copy(TPLists.begin(), TPLists.end(), TemplParamLists); |
1956 | 239k | } |
1957 | 239k | } |
1958 | | |
1959 | | //===----------------------------------------------------------------------===// |
1960 | | // VarDecl Implementation |
1961 | | //===----------------------------------------------------------------------===// |
1962 | | |
1963 | 2.40k | const char *VarDecl::getStorageClassSpecifierString(StorageClass SC) { |
1964 | 2.40k | switch (SC) { |
1965 | 0 | case SC_None: break; |
1966 | 1 | case SC_Auto: return "auto"; |
1967 | 835 | case SC_Extern: return "extern"; |
1968 | 0 | case SC_PrivateExtern: return "__private_extern__"; |
1969 | 0 | case SC_Register: return "register"; |
1970 | 1.56k | case SC_Static: return "static"; |
1971 | 0 | } |
1972 | | |
1973 | 0 | llvm_unreachable("Invalid storage class"); |
1974 | 0 | } |
1975 | | |
1976 | | VarDecl::VarDecl(Kind DK, ASTContext &C, DeclContext *DC, |
1977 | | SourceLocation StartLoc, SourceLocation IdLoc, |
1978 | | IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, |
1979 | | StorageClass SC) |
1980 | | : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), |
1981 | 51.5M | redeclarable_base(C) { |
1982 | 51.5M | static_assert(sizeof(VarDeclBitfields) <= sizeof(unsigned), |
1983 | 51.5M | "VarDeclBitfields too large!"); |
1984 | 51.5M | static_assert(sizeof(ParmVarDeclBitfields) <= sizeof(unsigned), |
1985 | 51.5M | "ParmVarDeclBitfields too large!"); |
1986 | 51.5M | static_assert(sizeof(NonParmVarDeclBitfields) <= sizeof(unsigned), |
1987 | 51.5M | "NonParmVarDeclBitfields too large!"); |
1988 | 51.5M | AllBits = 0; |
1989 | 51.5M | VarDeclBits.SClass = SC; |
1990 | | // Everything else is implicitly initialized to false. |
1991 | 51.5M | } |
1992 | | |
1993 | | VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, |
1994 | | SourceLocation StartL, SourceLocation IdL, |
1995 | | IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, |
1996 | 4.06M | StorageClass S) { |
1997 | 4.06M | return new (C, DC) VarDecl(Var, C, DC, StartL, IdL, Id, T, TInfo, S); |
1998 | 4.06M | } |
1999 | | |
2000 | 228k | VarDecl *VarDecl::CreateDeserialized(ASTContext &C, unsigned ID) { |
2001 | 228k | return new (C, ID) |
2002 | 228k | VarDecl(Var, C, nullptr, SourceLocation(), SourceLocation(), nullptr, |
2003 | 228k | QualType(), nullptr, SC_None); |
2004 | 228k | } |
2005 | | |
2006 | 58.2k | void VarDecl::setStorageClass(StorageClass SC) { |
2007 | 58.2k | assert(isLegalForVariable(SC)); |
2008 | 58.2k | VarDeclBits.SClass = SC; |
2009 | 58.2k | } |
2010 | | |
2011 | 6.38M | VarDecl::TLSKind VarDecl::getTLSKind() const { |
2012 | 6.38M | switch (VarDeclBits.TSCSpec) { |
2013 | 6.37M | case TSCS_unspecified: |
2014 | 6.37M | if (!hasAttr<ThreadAttr>() && |
2015 | 6.37M | !(getASTContext().getLangOpts().OpenMPUseTLS && |
2016 | 2.45M | getASTContext().getTargetInfo().isTLSSupported() && |
2017 | 2.33M | hasAttr<OMPThreadPrivateDeclAttr>())) |
2018 | 6.37M | return TLS_None; |
2019 | 860 | return ((getASTContext().getLangOpts().isCompatibleWithMSVC( |
2020 | 860 | LangOptions::MSVC2015)) || |
2021 | 835 | hasAttr<OMPThreadPrivateDeclAttr>()) |
2022 | 725 | ? TLS_Dynamic |
2023 | 135 | : TLS_Static; |
2024 | 840 | case TSCS___thread: // Fall through. |
2025 | 911 | case TSCS__Thread_local: |
2026 | 911 | return TLS_Static; |
2027 | 3.54k | case TSCS_thread_local: |
2028 | 3.54k | return TLS_Dynamic; |
2029 | 0 | } |
2030 | 0 | llvm_unreachable("Unknown thread storage class specifier!"); |
2031 | 0 | } |
2032 | | |
2033 | 59.5k | SourceRange VarDecl::getSourceRange() const { |
2034 | 59.5k | if (const Expr *Init = getInit()) { |
2035 | 33.7k | SourceLocation InitEnd = Init->getEndLoc(); |
2036 | | // If Init is implicit, ignore its source range and fallback on |
2037 | | // DeclaratorDecl::getSourceRange() to handle postfix elements. |
2038 | 33.7k | if (InitEnd.isValid() && InitEnd != getLocation()33.7k ) |
2039 | 32.7k | return SourceRange(getOuterLocStart(), InitEnd); |
2040 | 26.7k | } |
2041 | 26.7k | return DeclaratorDecl::getSourceRange(); |
2042 | 26.7k | } |
2043 | | |
2044 | | template<typename T> |
2045 | 25.9M | static LanguageLinkage getDeclLanguageLinkage(const T &D) { |
2046 | | // C++ [dcl.link]p1: All function types, function names with external linkage, |
2047 | | // and variable names with external linkage have a language linkage. |
2048 | 25.9M | if (!D.hasExternalFormalLinkage()) |
2049 | 15.0M | return NoLanguageLinkage; |
2050 | | |
2051 | | // Language linkage is a C++ concept, but saying that everything else in C has |
2052 | | // C language linkage fits the implementation nicely. |
2053 | 10.9M | ASTContext &Context = D.getASTContext(); |
2054 | 10.9M | if (!Context.getLangOpts().CPlusPlus) |
2055 | 4.55M | return CLanguageLinkage; |
2056 | | |
2057 | | // C++ [dcl.link]p4: A C language linkage is ignored in determining the |
2058 | | // language linkage of the names of class members and the function type of |
2059 | | // class member functions. |
2060 | 6.36M | const DeclContext *DC = D.getDeclContext(); |
2061 | 6.36M | if (DC->isRecord()) |
2062 | 1.66M | return CXXLanguageLinkage; |
2063 | | |
2064 | | // If the first decl is in an extern "C" context, any other redeclaration |
2065 | | // will have C language linkage. If the first one is not in an extern "C" |
2066 | | // context, we would have reported an error for any other decl being in one. |
2067 | 4.70M | if (isFirstInExternCContext(&D)) |
2068 | 2.42M | return CLanguageLinkage; |
2069 | 2.27M | return CXXLanguageLinkage; |
2070 | 2.27M | } Decl.cpp:clang::LanguageLinkage getDeclLanguageLinkage<clang::VarDecl>(clang::VarDecl const&) Line | Count | Source | 2045 | 2.15M | static LanguageLinkage getDeclLanguageLinkage(const T &D) { | 2046 | | // C++ [dcl.link]p1: All function types, function names with external linkage, | 2047 | | // and variable names with external linkage have a language linkage. | 2048 | 2.15M | if (!D.hasExternalFormalLinkage()) | 2049 | 708k | return NoLanguageLinkage; | 2050 | | | 2051 | | // Language linkage is a C++ concept, but saying that everything else in C has | 2052 | | // C language linkage fits the implementation nicely. | 2053 | 1.44M | ASTContext &Context = D.getASTContext(); | 2054 | 1.44M | if (!Context.getLangOpts().CPlusPlus) | 2055 | 1.09M | return CLanguageLinkage; | 2056 | | | 2057 | | // C++ [dcl.link]p4: A C language linkage is ignored in determining the | 2058 | | // language linkage of the names of class members and the function type of | 2059 | | // class member functions. | 2060 | 352k | const DeclContext *DC = D.getDeclContext(); | 2061 | 352k | if (DC->isRecord()) | 2062 | 0 | return CXXLanguageLinkage; | 2063 | | | 2064 | | // If the first decl is in an extern "C" context, any other redeclaration | 2065 | | // will have C language linkage. If the first one is not in an extern "C" | 2066 | | // context, we would have reported an error for any other decl being in one. | 2067 | 352k | if (isFirstInExternCContext(&D)) | 2068 | 278k | return CLanguageLinkage; | 2069 | 73.9k | return CXXLanguageLinkage; | 2070 | 73.9k | } |
Decl.cpp:clang::LanguageLinkage getDeclLanguageLinkage<clang::FunctionDecl>(clang::FunctionDecl const&) Line | Count | Source | 2045 | 23.8M | static LanguageLinkage getDeclLanguageLinkage(const T &D) { | 2046 | | // C++ [dcl.link]p1: All function types, function names with external linkage, | 2047 | | // and variable names with external linkage have a language linkage. | 2048 | 23.8M | if (!D.hasExternalFormalLinkage()) | 2049 | 14.3M | return NoLanguageLinkage; | 2050 | | | 2051 | | // Language linkage is a C++ concept, but saying that everything else in C has | 2052 | | // C language linkage fits the implementation nicely. | 2053 | 9.47M | ASTContext &Context = D.getASTContext(); | 2054 | 9.47M | if (!Context.getLangOpts().CPlusPlus) | 2055 | 3.45M | return CLanguageLinkage; | 2056 | | | 2057 | | // C++ [dcl.link]p4: A C language linkage is ignored in determining the | 2058 | | // language linkage of the names of class members and the function type of | 2059 | | // class member functions. | 2060 | 6.01M | const DeclContext *DC = D.getDeclContext(); | 2061 | 6.01M | if (DC->isRecord()) | 2062 | 1.66M | return CXXLanguageLinkage; | 2063 | | | 2064 | | // If the first decl is in an extern "C" context, any other redeclaration | 2065 | | // will have C language linkage. If the first one is not in an extern "C" | 2066 | | // context, we would have reported an error for any other decl being in one. | 2067 | 4.35M | if (isFirstInExternCContext(&D)) | 2068 | 2.14M | return CLanguageLinkage; | 2069 | 2.20M | return CXXLanguageLinkage; | 2070 | 2.20M | } |
|
2071 | | |
2072 | | template<typename T> |
2073 | 23.9M | static bool isDeclExternC(const T &D) { |
2074 | | // Since the context is ignored for class members, they can only have C++ |
2075 | | // language linkage or no language linkage. |
2076 | 23.9M | const DeclContext *DC = D.getDeclContext(); |
2077 | 23.9M | if (DC->isRecord()) { |
2078 | 2.96M | assert(D.getASTContext().getLangOpts().CPlusPlus); |
2079 | 2.96M | return false; |
2080 | 2.96M | } |
2081 | | |
2082 | 20.9M | return D.getLanguageLinkage() == CLanguageLinkage; |
2083 | 20.9M | } Decl.cpp:bool isDeclExternC<clang::VarDecl>(clang::VarDecl const&) Line | Count | Source | 2073 | 2.25M | static bool isDeclExternC(const T &D) { | 2074 | | // Since the context is ignored for class members, they can only have C++ | 2075 | | // language linkage or no language linkage. | 2076 | 2.25M | const DeclContext *DC = D.getDeclContext(); | 2077 | 2.25M | if (DC->isRecord()) { | 2078 | 106k | assert(D.getASTContext().getLangOpts().CPlusPlus); | 2079 | 106k | return false; | 2080 | 106k | } | 2081 | | | 2082 | 2.15M | return D.getLanguageLinkage() == CLanguageLinkage; | 2083 | 2.15M | } |
Decl.cpp:bool isDeclExternC<clang::FunctionDecl>(clang::FunctionDecl const&) Line | Count | Source | 2073 | 21.7M | static bool isDeclExternC(const T &D) { | 2074 | | // Since the context is ignored for class members, they can only have C++ | 2075 | | // language linkage or no language linkage. | 2076 | 21.7M | const DeclContext *DC = D.getDeclContext(); | 2077 | 21.7M | if (DC->isRecord()) { | 2078 | 2.85M | assert(D.getASTContext().getLangOpts().CPlusPlus); | 2079 | 2.85M | return false; | 2080 | 2.85M | } | 2081 | | | 2082 | 18.8M | return D.getLanguageLinkage() == CLanguageLinkage; | 2083 | 18.8M | } |
|
2084 | | |
2085 | 2.15M | LanguageLinkage VarDecl::getLanguageLinkage() const { |
2086 | 2.15M | return getDeclLanguageLinkage(*this); |
2087 | 2.15M | } |
2088 | | |
2089 | 2.25M | bool VarDecl::isExternC() const { |
2090 | 2.25M | return isDeclExternC(*this); |
2091 | 2.25M | } |
2092 | | |
2093 | 3.11M | bool VarDecl::isInExternCContext() const { |
2094 | 3.11M | return getLexicalDeclContext()->isExternCContext(); |
2095 | 3.11M | } |
2096 | | |
2097 | 1.40k | bool VarDecl::isInExternCXXContext() const { |
2098 | 1.40k | return getLexicalDeclContext()->isExternCXXContext(); |
2099 | 1.40k | } |
2100 | | |
2101 | 126M | VarDecl *VarDecl::getCanonicalDecl() { return getFirstDecl(); } |
2102 | | |
2103 | | VarDecl::DefinitionKind |
2104 | 49.6M | VarDecl::isThisDeclarationADefinition(ASTContext &C) const { |
2105 | 49.6M | if (isThisDeclarationADemotedDefinition()) |
2106 | 103 | return DeclarationOnly; |
2107 | | |
2108 | | // C++ [basic.def]p2: |
2109 | | // A declaration is a definition unless [...] it contains the 'extern' |
2110 | | // specifier or a linkage-specification and neither an initializer [...], |
2111 | | // it declares a non-inline static data member in a class declaration [...], |
2112 | | // it declares a static data member outside a class definition and the variable |
2113 | | // was defined within the class with the constexpr specifier [...], |
2114 | | // C++1y [temp.expl.spec]p15: |
2115 | | // An explicit specialization of a static data member or an explicit |
2116 | | // specialization of a static data member template is a definition if the |
2117 | | // declaration includes an initializer; otherwise, it is a declaration. |
2118 | | // |
2119 | | // FIXME: How do you declare (but not define) a partial specialization of |
2120 | | // a static data member template outside the containing class? |
2121 | 49.6M | if (isStaticDataMember()) { |
2122 | 18.4M | if (isOutOfLine() && |
2123 | 7.83M | !(getCanonicalDecl()->isInline() && |
2124 | 4.08k | getCanonicalDecl()->isConstexpr()) && |
2125 | 7.83M | (hasInit() || |
2126 | | // If the first declaration is out-of-line, this may be an |
2127 | | // instantiation of an out-of-line partial specialization of a variable |
2128 | | // template for which we have not yet instantiated the initializer. |
2129 | 7.78M | (getFirstDecl()->isOutOfLine() |
2130 | 55.5k | ? getTemplateSpecializationKind() == TSK_Undeclared |
2131 | 7.72M | : getTemplateSpecializationKind() != |
2132 | 7.72M | TSK_ExplicitSpecialization) || |
2133 | 1.25k | isa<VarTemplatePartialSpecializationDecl>(this))) |
2134 | 7.83M | return Definition; |
2135 | 10.6M | else if (!isOutOfLine() && isInline()10.6M ) |
2136 | 185k | return Definition; |
2137 | 10.4M | else |
2138 | 10.4M | return DeclarationOnly; |
2139 | 31.2M | } |
2140 | | // C99 6.7p5: |
2141 | | // A definition of an identifier is a declaration for that identifier that |
2142 | | // [...] causes storage to be reserved for that object. |
2143 | | // Note: that applies for all non-file-scope objects. |
2144 | | // C99 6.9.2p1: |
2145 | | // If the declaration of an identifier for an object has file scope and an |
2146 | | // initializer, the declaration is an external definition for the identifier |
2147 | 31.2M | if (hasInit()) |
2148 | 13.7M | return Definition; |
2149 | | |
2150 | 17.4M | if (hasDefiningAttr()) |
2151 | 381 | return Definition; |
2152 | | |
2153 | 17.4M | if (const auto *SAA = getAttr<SelectAnyAttr>()) |
2154 | 166 | if (!SAA->isInherited()) |
2155 | 151 | return Definition; |
2156 | | |
2157 | | // A variable template specialization (other than a static data member |
2158 | | // template or an explicit specialization) is a declaration until we |
2159 | | // instantiate its initializer. |
2160 | 17.4M | if (auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(this)) { |
2161 | 7.35k | if (VTSD->getTemplateSpecializationKind() != TSK_ExplicitSpecialization && |
2162 | 5.68k | !isa<VarTemplatePartialSpecializationDecl>(VTSD) && |
2163 | 5.68k | !VTSD->IsCompleteDefinition) |
2164 | 4.44k | return DeclarationOnly; |
2165 | 17.4M | } |
2166 | | |
2167 | 17.4M | if (hasExternalStorage()) |
2168 | 3.64M | return DeclarationOnly; |
2169 | | |
2170 | | // [dcl.link] p7: |
2171 | | // A declaration directly contained in a linkage-specification is treated |
2172 | | // as if it contains the extern specifier for the purpose of determining |
2173 | | // the linkage of the declared name and whether it is a definition. |
2174 | 13.7M | if (isSingleLineLanguageLinkage(*this)) |
2175 | 143k | return DeclarationOnly; |
2176 | | |
2177 | | // C99 6.9.2p2: |
2178 | | // A declaration of an object that has file scope without an initializer, |
2179 | | // and without a storage class specifier or the scs 'static', constitutes |
2180 | | // a tentative definition. |
2181 | | // No such thing in C++. |
2182 | 13.6M | if (!C.getLangOpts().CPlusPlus && isFileVarDecl()6.64M ) |
2183 | 161k | return TentativeDefinition; |
2184 | | |
2185 | | // What's left is (in C, block-scope) declarations without initializers or |
2186 | | // external storage. These are definitions. |
2187 | 13.4M | return Definition; |
2188 | 13.4M | } |
2189 | | |
2190 | 10.9k | VarDecl *VarDecl::getActingDefinition() { |
2191 | 10.9k | DefinitionKind Kind = isThisDeclarationADefinition(); |
2192 | 10.9k | if (Kind != TentativeDefinition) |
2193 | 989 | return nullptr; |
2194 | | |
2195 | 9.94k | VarDecl *LastTentative = nullptr; |
2196 | 9.94k | VarDecl *First = getFirstDecl(); |
2197 | 10.8k | for (auto I : First->redecls()) { |
2198 | 10.8k | Kind = I->isThisDeclarationADefinition(); |
2199 | 10.8k | if (Kind == Definition) |
2200 | 38 | return nullptr; |
2201 | 10.8k | else if (Kind == TentativeDefinition) |
2202 | 10.7k | LastTentative = I; |
2203 | 10.8k | } |
2204 | 9.90k | return LastTentative; |
2205 | 9.94k | } |
2206 | | |
2207 | 11.1M | VarDecl *VarDecl::getDefinition(ASTContext &C) { |
2208 | 11.1M | VarDecl *First = getFirstDecl(); |
2209 | 14.2M | for (auto I : First->redecls()) { |
2210 | 14.2M | if (I->isThisDeclarationADefinition(C) == Definition) |
2211 | 9.55M | return I; |
2212 | 14.2M | } |
2213 | 1.57M | return nullptr; |
2214 | 11.1M | } |
2215 | | |
2216 | 8.11M | VarDecl::DefinitionKind VarDecl::hasDefinition(ASTContext &C) const { |
2217 | 8.11M | DefinitionKind Kind = DeclarationOnly; |
2218 | | |
2219 | 8.11M | const VarDecl *First = getFirstDecl(); |
2220 | 8.19M | for (auto I : First->redecls()) { |
2221 | 8.19M | Kind = std::max(Kind, I->isThisDeclarationADefinition(C)); |
2222 | 8.19M | if (Kind == Definition) |
2223 | 8.01M | break; |
2224 | 8.19M | } |
2225 | | |
2226 | 8.11M | return Kind; |
2227 | 8.11M | } |
2228 | | |
2229 | 28.3M | const Expr *VarDecl::getAnyInitializer(const VarDecl *&D) const { |
2230 | 31.8M | for (auto I : redecls()) { |
2231 | 31.8M | if (auto Expr = I->getInit()) { |
2232 | 9.41M | D = I; |
2233 | 9.41M | return Expr; |
2234 | 9.41M | } |
2235 | 31.8M | } |
2236 | 18.9M | return nullptr; |
2237 | 28.3M | } |
2238 | | |
2239 | 89.8M | bool VarDecl::hasInit() const { |
2240 | 89.8M | if (auto *P = dyn_cast<ParmVarDecl>(this)) |
2241 | 27.5M | if (P->hasUnparsedDefaultArg() || P->hasUninstantiatedDefaultArg()27.5M ) |
2242 | 27.0k | return false; |
2243 | | |
2244 | 89.8M | return !Init.isNull(); |
2245 | 89.8M | } |
2246 | | |
2247 | 43.7M | Expr *VarDecl::getInit() { |
2248 | 43.7M | if (!hasInit()) |
2249 | 27.6M | return nullptr; |
2250 | | |
2251 | 16.1M | if (auto *S = Init.dyn_cast<Stmt *>()) |
2252 | 9.26M | return cast<Expr>(S); |
2253 | | |
2254 | 6.84M | return cast_or_null<Expr>(Init.get<EvaluatedStmt *>()->Value); |
2255 | 6.84M | } |
2256 | | |
2257 | 291k | Stmt **VarDecl::getInitAddress() { |
2258 | 291k | if (auto *ES = Init.dyn_cast<EvaluatedStmt *>()) |
2259 | 10.8k | return &ES->Value; |
2260 | | |
2261 | 280k | return Init.getAddrOfPtr1(); |
2262 | 280k | } |
2263 | | |
2264 | 480 | VarDecl *VarDecl::getInitializingDeclaration() { |
2265 | 480 | VarDecl *Def = nullptr; |
2266 | 480 | for (auto I : redecls()) { |
2267 | 480 | if (I->hasInit()) |
2268 | 253 | return I; |
2269 | | |
2270 | 227 | if (I->isThisDeclarationADefinition()) { |
2271 | 40 | if (isStaticDataMember()) |
2272 | 0 | return I; |
2273 | 40 | else |
2274 | 40 | Def = I; |
2275 | 40 | } |
2276 | 227 | } |
2277 | 227 | return Def; |
2278 | 480 | } |
2279 | | |
2280 | 63.3M | bool VarDecl::isOutOfLine() const { |
2281 | 63.3M | if (Decl::isOutOfLine()) |
2282 | 8.04M | return true; |
2283 | | |
2284 | 55.2M | if (!isStaticDataMember()) |
2285 | 4.54M | return false; |
2286 | | |
2287 | | // If this static data member was instantiated from a static data member of |
2288 | | // a class template, check whether that static data member was defined |
2289 | | // out-of-line. |
2290 | 50.7M | if (VarDecl *VD = getInstantiatedFromStaticDataMember()) |
2291 | 21.1M | return VD->isOutOfLine(); |
2292 | | |
2293 | 29.6M | return false; |
2294 | 29.6M | } |
2295 | | |
2296 | 2.16M | void VarDecl::setInit(Expr *I) { |
2297 | 2.16M | if (auto *Eval = Init.dyn_cast<EvaluatedStmt *>()) { |
2298 | 0 | Eval->~EvaluatedStmt(); |
2299 | 0 | getASTContext().Deallocate(Eval); |
2300 | 0 | } |
2301 | | |
2302 | 2.16M | Init = I; |
2303 | 2.16M | } |
2304 | | |
2305 | 32.1M | bool VarDecl::mightBeUsableInConstantExpressions(const ASTContext &C) const { |
2306 | 32.1M | const LangOptions &Lang = C.getLangOpts(); |
2307 | | |
2308 | | // OpenCL permits const integral variables to be used in constant |
2309 | | // expressions, like in C++98. |
2310 | 32.1M | if (!Lang.CPlusPlus && !Lang.OpenCL10.9M ) |
2311 | 10.8M | return false; |
2312 | | |
2313 | | // Function parameters are never usable in constant expressions. |
2314 | 21.2M | if (isa<ParmVarDecl>(this)) |
2315 | 5.80M | return false; |
2316 | | |
2317 | | // The values of weak variables are never usable in constant expressions. |
2318 | 15.4M | if (isWeak()) |
2319 | 142 | return false; |
2320 | | |
2321 | | // In C++11, any variable of reference type can be used in a constant |
2322 | | // expression if it is initialized by a constant expression. |
2323 | 15.4M | if (Lang.CPlusPlus11 && getType()->isReferenceType()14.5M ) |
2324 | 211k | return true; |
2325 | | |
2326 | | // Only const objects can be used in constant expressions in C++. C++98 does |
2327 | | // not require the variable to be non-volatile, but we consider this to be a |
2328 | | // defect. |
2329 | 15.2M | if (!getType().isConstant(C) || getType().isVolatileQualified()5.99M ) |
2330 | 9.27M | return false; |
2331 | | |
2332 | | // In C++, const, non-volatile variables of integral or enumeration types |
2333 | | // can be used in constant expressions. |
2334 | 5.99M | if (getType()->isIntegralOrEnumerationType()) |
2335 | 5.79M | return true; |
2336 | | |
2337 | | // Additionally, in C++11, non-volatile constexpr variables can be used in |
2338 | | // constant expressions. |
2339 | 205k | return Lang.CPlusPlus11 && isConstexpr()192k ; |
2340 | 205k | } |
2341 | | |
2342 | 23.5M | bool VarDecl::isUsableInConstantExpressions(const ASTContext &Context) const { |
2343 | | // C++2a [expr.const]p3: |
2344 | | // A variable is usable in constant expressions after its initializing |
2345 | | // declaration is encountered... |
2346 | 23.5M | const VarDecl *DefVD = nullptr; |
2347 | 23.5M | const Expr *Init = getAnyInitializer(DefVD); |
2348 | 23.5M | if (!Init || Init->isValueDependent()4.97M || getType()->isDependentType()4.86M ) |
2349 | 18.6M | return false; |
2350 | | // ... if it is a constexpr variable, or it is of reference type or of |
2351 | | // const-qualified integral or enumeration type, ... |
2352 | 4.85M | if (!DefVD->mightBeUsableInConstantExpressions(Context)) |
2353 | 3.04M | return false; |
2354 | | // ... and its initializer is a constant initializer. |
2355 | 1.80M | if (Context.getLangOpts().CPlusPlus && !DefVD->hasConstantInitialization()1.80M ) |
2356 | 112k | return false; |
2357 | | // C++98 [expr.const]p1: |
2358 | | // An integral constant-expression can involve only [...] const variables |
2359 | | // or static data members of integral or enumeration types initialized with |
2360 | | // [integer] constant expressions (dcl.init) |
2361 | 1.69M | if ((Context.getLangOpts().CPlusPlus || Context.getLangOpts().OpenCL108 ) && |
2362 | 1.69M | !Context.getLangOpts().CPlusPlus11 && !DefVD->hasICEInitializer(Context)1.65k ) |
2363 | 6 | return false; |
2364 | 1.69M | return true; |
2365 | 1.69M | } |
2366 | | |
2367 | | /// Convert the initializer for this declaration to the elaborated EvaluatedStmt |
2368 | | /// form, which contains extra information on the evaluated value of the |
2369 | | /// initializer. |
2370 | 2.34M | EvaluatedStmt *VarDecl::ensureEvaluatedStmt() const { |
2371 | 2.34M | auto *Eval = Init.dyn_cast<EvaluatedStmt *>(); |
2372 | 2.34M | if (!Eval) { |
2373 | | // Note: EvaluatedStmt contains an APValue, which usually holds |
2374 | | // resources not allocated from the ASTContext. We need to do some |
2375 | | // work to avoid leaking those, but we do so in VarDecl::evaluateValue |
2376 | | // where we can detect whether there's anything to clean up or not. |
2377 | 466k | Eval = new (getASTContext()) EvaluatedStmt; |
2378 | 466k | Eval->Value = Init.get<Stmt *>(); |
2379 | 466k | Init = Eval; |
2380 | 466k | } |
2381 | 2.34M | return Eval; |
2382 | 2.34M | } |
2383 | | |
2384 | 7.67M | EvaluatedStmt *VarDecl::getEvaluatedStmt() const { |
2385 | 7.67M | return Init.dyn_cast<EvaluatedStmt *>(); |
2386 | 7.67M | } |
2387 | | |
2388 | 1.50M | APValue *VarDecl::evaluateValue() const { |
2389 | 1.50M | SmallVector<PartialDiagnosticAt, 8> Notes; |
2390 | 1.50M | return evaluateValueImpl(Notes, hasConstantInitialization()); |
2391 | 1.50M | } |
2392 | | |
2393 | | APValue *VarDecl::evaluateValueImpl(SmallVectorImpl<PartialDiagnosticAt> &Notes, |
2394 | 1.89M | bool IsConstantInitialization) const { |
2395 | 1.89M | EvaluatedStmt *Eval = ensureEvaluatedStmt(); |
2396 | | |
2397 | 1.89M | const auto *Init = cast<Expr>(Eval->Value); |
2398 | 1.89M | assert(!Init->isValueDependent()); |
2399 | | |
2400 | | // We only produce notes indicating why an initializer is non-constant the |
2401 | | // first time it is evaluated. FIXME: The notes won't always be emitted the |
2402 | | // first time we try evaluation, so might not be produced at all. |
2403 | 1.89M | if (Eval->WasEvaluated) |
2404 | 1.45M | return Eval->Evaluated.isAbsent() ? nullptr79.2k : &Eval->Evaluated1.37M ; |
2405 | | |
2406 | 440k | if (Eval->IsEvaluating) { |
2407 | | // FIXME: Produce a diagnostic for self-initialization. |
2408 | 2 | return nullptr; |
2409 | 2 | } |
2410 | | |
2411 | 440k | Eval->IsEvaluating = true; |
2412 | | |
2413 | 440k | ASTContext &Ctx = getASTContext(); |
2414 | 440k | bool Result = Init->EvaluateAsInitializer(Eval->Evaluated, Ctx, this, Notes, |
2415 | 440k | IsConstantInitialization); |
2416 | | |
2417 | | // In C++11, this isn't a constant initializer if we produced notes. In that |
2418 | | // case, we can't keep the result, because it may only be correct under the |
2419 | | // assumption that the initializer is a constant context. |
2420 | 440k | if (IsConstantInitialization && Ctx.getLangOpts().CPlusPlus11395k && |
2421 | 389k | !Notes.empty()) |
2422 | 55.6k | Result = false; |
2423 | | |
2424 | | // Ensure the computed APValue is cleaned up later if evaluation succeeded, |
2425 | | // or that it's empty (so that there's nothing to clean up) if evaluation |
2426 | | // failed. |
2427 | 440k | if (!Result) |
2428 | 98.9k | Eval->Evaluated = APValue(); |
2429 | 341k | else if (Eval->Evaluated.needsCleanup()) |
2430 | 19.8k | Ctx.addDestruction(&Eval->Evaluated); |
2431 | | |
2432 | 440k | Eval->IsEvaluating = false; |
2433 | 440k | Eval->WasEvaluated = true; |
2434 | | |
2435 | 341k | return Result ? &Eval->Evaluated : nullptr98.9k ; |
2436 | 440k | } |
2437 | | |
2438 | 1.33M | APValue *VarDecl::getEvaluatedValue() const { |
2439 | 1.33M | if (EvaluatedStmt *Eval = getEvaluatedStmt()) |
2440 | 1.33M | if (Eval->WasEvaluated) |
2441 | 1.33M | return &Eval->Evaluated; |
2442 | | |
2443 | 1 | return nullptr; |
2444 | 1 | } |
2445 | | |
2446 | 2.17k | bool VarDecl::hasICEInitializer(const ASTContext &Context) const { |
2447 | 2.17k | const Expr *Init = getInit(); |
2448 | 2.17k | assert(Init && "no initializer"); |
2449 | | |
2450 | 2.17k | EvaluatedStmt *Eval = ensureEvaluatedStmt(); |
2451 | 2.17k | if (!Eval->CheckedForICEInit) { |
2452 | 518 | Eval->CheckedForICEInit = true; |
2453 | 518 | Eval->HasICEInit = Init->isIntegerConstantExpr(Context); |
2454 | 518 | } |
2455 | 2.17k | return Eval->HasICEInit; |
2456 | 2.17k | } |
2457 | | |
2458 | 4.68M | bool VarDecl::hasConstantInitialization() const { |
2459 | | // In C, all globals (and only globals) have constant initialization. |
2460 | 4.68M | if (hasGlobalStorage() && !getASTContext().getLangOpts().CPlusPlus4.40M ) |
2461 | 7.92k | return true; |
2462 | | |
2463 | | // In C++, it depends on whether the evaluation at the point of definition |
2464 | | // was evaluatable as a constant initializer. |
2465 | 4.67M | if (EvaluatedStmt *Eval = getEvaluatedStmt()) |
2466 | 4.65M | return Eval->HasConstantInitialization; |
2467 | | |
2468 | 19.0k | return false; |
2469 | 19.0k | } |
2470 | | |
2471 | | bool VarDecl::checkForConstantInitialization( |
2472 | 387k | SmallVectorImpl<PartialDiagnosticAt> &Notes) const { |
2473 | 387k | EvaluatedStmt *Eval = ensureEvaluatedStmt(); |
2474 | | // If we ask for the value before we know whether we have a constant |
2475 | | // initializer, we can compute the wrong value (for example, due to |
2476 | | // std::is_constant_evaluated()). |
2477 | 387k | assert(!Eval->WasEvaluated && |
2478 | 387k | "already evaluated var value before checking for constant init"); |
2479 | 387k | assert(getASTContext().getLangOpts().CPlusPlus && "only meaningful in C++"); |
2480 | | |
2481 | 387k | assert(!cast<Expr>(Eval->Value)->isValueDependent()); |
2482 | | |
2483 | | // Evaluate the initializer to check whether it's a constant expression. |
2484 | 387k | Eval->HasConstantInitialization = |
2485 | 387k | evaluateValueImpl(Notes, true) && Notes.empty()330k ; |
2486 | | |
2487 | | // If evaluation as a constant initializer failed, allow re-evaluation as a |
2488 | | // non-constant initializer if we later find we want the value. |
2489 | 387k | if (!Eval->HasConstantInitialization) |
2490 | 57.0k | Eval->WasEvaluated = false; |
2491 | | |
2492 | 387k | return Eval->HasConstantInitialization; |
2493 | 387k | } |
2494 | | |
2495 | 81.4M | bool VarDecl::isParameterPack() const { |
2496 | 81.4M | return isa<PackExpansionType>(getType()); |
2497 | 81.4M | } |
2498 | | |
2499 | | template<typename DeclT> |
2500 | 3.35M | static DeclT *getDefinitionOrSelf(DeclT *D) { |
2501 | 3.35M | assert(D); |
2502 | 3.35M | if (auto *Def = D->getDefinition()) |
2503 | 2.86M | return Def; |
2504 | 485k | return D; |
2505 | 485k | } Decl.cpp:clang::VarDecl* getDefinitionOrSelf<clang::VarDecl>(clang::VarDecl*) Line | Count | Source | 2500 | 871k | static DeclT *getDefinitionOrSelf(DeclT *D) { | 2501 | 871k | assert(D); | 2502 | 871k | if (auto *Def = D->getDefinition()) | 2503 | 596k | return Def; | 2504 | 274k | return D; | 2505 | 274k | } |
Decl.cpp:clang::FunctionDecl* getDefinitionOrSelf<clang::FunctionDecl>(clang::FunctionDecl*) Line | Count | Source | 2500 | 2.44M | static DeclT *getDefinitionOrSelf(DeclT *D) { | 2501 | 2.44M | assert(D); | 2502 | 2.44M | if (auto *Def = D->getDefinition()) | 2503 | 2.23M | return Def; | 2504 | 210k | return D; | 2505 | 210k | } |
Decl.cpp:clang::EnumDecl* getDefinitionOrSelf<clang::EnumDecl>(clang::EnumDecl*) Line | Count | Source | 2500 | 36.1k | static DeclT *getDefinitionOrSelf(DeclT *D) { | 2501 | 36.1k | assert(D); | 2502 | 36.1k | if (auto *Def = D->getDefinition()) | 2503 | 36.1k | return Def; | 2504 | 2 | return D; | 2505 | 2 | } |
|
2506 | | |
2507 | 1.57M | bool VarDecl::isEscapingByref() const { |
2508 | 1.57M | return hasAttr<BlocksAttr>() && NonParmVarDeclBits.EscapingByref2.96k ; |
2509 | 1.57M | } |
2510 | | |
2511 | 7.36k | bool VarDecl::isNonEscapingByref() const { |
2512 | 7.36k | return hasAttr<BlocksAttr>() && !NonParmVarDeclBits.EscapingByref579 ; |
2513 | 7.36k | } |
2514 | | |
2515 | 966k | VarDecl *VarDecl::getTemplateInstantiationPattern() const { |
2516 | 966k | const VarDecl *VD = this; |
2517 | | |
2518 | | // If this is an instantiated member, walk back to the template from which |
2519 | | // it was instantiated. |
2520 | 966k | if (MemberSpecializationInfo *MSInfo = VD->getMemberSpecializationInfo()) { |
2521 | 868k | if (isTemplateInstantiation(MSInfo->getTemplateSpecializationKind())) { |
2522 | 868k | VD = VD->getInstantiatedFromStaticDataMember(); |
2523 | 868k | while (auto *NewVD = VD->getInstantiatedFromStaticDataMember()) |
2524 | 0 | VD = NewVD; |
2525 | 868k | } |
2526 | 868k | } |
2527 | | |
2528 | | // If it's an instantiated variable template specialization, find the |
2529 | | // template or partial specialization from which it was instantiated. |
2530 | 966k | if (auto *VDTemplSpec = dyn_cast<VarTemplateSpecializationDecl>(VD)) { |
2531 | 2.10k | if (isTemplateInstantiation(VDTemplSpec->getTemplateSpecializationKind())) { |
2532 | 1.98k | auto From = VDTemplSpec->getInstantiatedFrom(); |
2533 | 1.98k | if (auto *VTD = From.dyn_cast<VarTemplateDecl *>()) { |
2534 | 1.67k | while (!VTD->isMemberSpecialization()) { |
2535 | 1.66k | auto *NewVTD = VTD->getInstantiatedFromMemberTemplate(); |
2536 | 1.66k | if (!NewVTD) |
2537 | 1.51k | break; |
2538 | 147 | VTD = NewVTD; |
2539 | 147 | } |
2540 | 1.53k | return getDefinitionOrSelf(VTD->getTemplatedDecl()); |
2541 | 1.53k | } |
2542 | 450 | if (auto *VTPSD = |
2543 | 450 | From.dyn_cast<VarTemplatePartialSpecializationDecl *>()) { |
2544 | 476 | while (!VTPSD->isMemberSpecialization()) { |
2545 | 473 | auto *NewVTPSD = VTPSD->getInstantiatedFromMember(); |
2546 | 473 | if (!NewVTPSD) |
2547 | 447 | break; |
2548 | 26 | VTPSD = NewVTPSD; |
2549 | 26 | } |
2550 | 450 | return getDefinitionOrSelf<VarDecl>(VTPSD); |
2551 | 450 | } |
2552 | 964k | } |
2553 | 2.10k | } |
2554 | | |
2555 | | // If this is the pattern of a variable template, find where it was |
2556 | | // instantiated from. FIXME: Is this necessary? |
2557 | 964k | if (VarTemplateDecl *VarTemplate = VD->getDescribedVarTemplate()) { |
2558 | 363 | while (!VarTemplate->isMemberSpecialization()) { |
2559 | 358 | auto *NewVT = VarTemplate->getInstantiatedFromMemberTemplate(); |
2560 | 358 | if (!NewVT) |
2561 | 358 | break; |
2562 | 0 | VarTemplate = NewVT; |
2563 | 0 | } |
2564 | | |
2565 | 363 | return getDefinitionOrSelf(VarTemplate->getTemplatedDecl()); |
2566 | 363 | } |
2567 | | |
2568 | 964k | if (VD == this) |
2569 | 95.3k | return nullptr; |
2570 | 868k | return getDefinitionOrSelf(const_cast<VarDecl*>(VD)); |
2571 | 868k | } |
2572 | | |
2573 | 52.6M | VarDecl *VarDecl::getInstantiatedFromStaticDataMember() const { |
2574 | 52.6M | if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo()) |
2575 | 22.1M | return cast<VarDecl>(MSI->getInstantiatedFrom()); |
2576 | | |
2577 | 30.5M | return nullptr; |
2578 | 30.5M | } |
2579 | | |
2580 | 25.2M | TemplateSpecializationKind VarDecl::getTemplateSpecializationKind() const { |
2581 | 25.2M | if (const auto *Spec = dyn_cast<VarTemplateSpecializationDecl>(this)) |
2582 | 27.6k | return Spec->getSpecializationKind(); |
2583 | | |
2584 | 25.2M | if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo()) |
2585 | 8.64M | return MSI->getTemplateSpecializationKind(); |
2586 | | |
2587 | 16.5M | return TSK_Undeclared; |
2588 | 16.5M | } |
2589 | | |
2590 | | TemplateSpecializationKind |
2591 | 871k | VarDecl::getTemplateSpecializationKindForInstantiation() const { |
2592 | 871k | if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo()) |
2593 | 869k | return MSI->getTemplateSpecializationKind(); |
2594 | | |
2595 | 2.32k | if (const auto *Spec = dyn_cast<VarTemplateSpecializationDecl>(this)) |
2596 | 2.32k | return Spec->getSpecializationKind(); |
2597 | | |
2598 | 0 | return TSK_Undeclared; |
2599 | 0 | } |
2600 | | |
2601 | 14.9k | SourceLocation VarDecl::getPointOfInstantiation() const { |
2602 | 14.9k | if (const auto *Spec = dyn_cast<VarTemplateSpecializationDecl>(this)) |
2603 | 3.19k | return Spec->getPointOfInstantiation(); |
2604 | | |
2605 | 11.7k | if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo()) |
2606 | 11.7k | return MSI->getPointOfInstantiation(); |
2607 | | |
2608 | 0 | return SourceLocation(); |
2609 | 0 | } |
2610 | | |
2611 | 6.39M | VarTemplateDecl *VarDecl::getDescribedVarTemplate() const { |
2612 | 6.39M | return getASTContext().getTemplateOrSpecializationInfo(this) |
2613 | 6.39M | .dyn_cast<VarTemplateDecl *>(); |
2614 | 6.39M | } |
2615 | | |
2616 | 3.16k | void VarDecl::setDescribedVarTemplate(VarTemplateDecl *Template) { |
2617 | 3.16k | getASTContext().setTemplateOrSpecializationInfo(this, Template); |
2618 | 3.16k | } |
2619 | | |
2620 | 19 | bool VarDecl::isKnownToBeDefined() const { |
2621 | 19 | const auto &LangOpts = getASTContext().getLangOpts(); |
2622 | | // In CUDA mode without relocatable device code, variables of form 'extern |
2623 | | // __shared__ Foo foo[]' are pointers to the base of the GPU core's shared |
2624 | | // memory pool. These are never undefined variables, even if they appear |
2625 | | // inside of an anon namespace or static function. |
2626 | | // |
2627 | | // With CUDA relocatable device code enabled, these variables don't get |
2628 | | // special handling; they're treated like regular extern variables. |
2629 | 19 | if (LangOpts.CUDA && !LangOpts.GPURelocatableDeviceCode4 && |
2630 | 0 | hasExternalStorage() && hasAttr<CUDASharedAttr>() && |
2631 | 0 | isa<IncompleteArrayType>(getType())) |
2632 | 0 | return true; |
2633 | | |
2634 | 19 | return hasDefinition(); |
2635 | 19 | } |
2636 | | |
2637 | 1.45M | bool VarDecl::isNoDestroy(const ASTContext &Ctx) const { |
2638 | 1.45M | return hasGlobalStorage() && (1.21M hasAttr<NoDestroyAttr>()1.21M || |
2639 | 1.21M | (!Ctx.getLangOpts().RegisterStaticDestructors && |
2640 | 44 | !hasAttr<AlwaysDestroyAttr>())); |
2641 | 1.45M | } |
2642 | | |
2643 | | QualType::DestructionKind |
2644 | 1.42M | VarDecl::needsDestruction(const ASTContext &Ctx) const { |
2645 | 1.42M | if (EvaluatedStmt *Eval = getEvaluatedStmt()) |
2646 | 112k | if (Eval->HasConstantDestruction) |
2647 | 54 | return QualType::DK_none; |
2648 | | |
2649 | 1.42M | if (isNoDestroy(Ctx)) |
2650 | 32 | return QualType::DK_none; |
2651 | | |
2652 | 1.42M | return getType().isDestructedType(); |
2653 | 1.42M | } |
2654 | | |
2655 | 95.4M | MemberSpecializationInfo *VarDecl::getMemberSpecializationInfo() const { |
2656 | 95.4M | if (isStaticDataMember()) |
2657 | | // FIXME: Remove ? |
2658 | | // return getASTContext().getInstantiatedFromStaticDataMember(this); |
2659 | 67.1M | return getASTContext().getTemplateOrSpecializationInfo(this) |
2660 | 67.1M | .dyn_cast<MemberSpecializationInfo *>(); |
2661 | 28.2M | return nullptr; |
2662 | 28.2M | } |
2663 | | |
2664 | | void VarDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK, |
2665 | 601k | SourceLocation PointOfInstantiation) { |
2666 | 601k | assert((isa<VarTemplateSpecializationDecl>(this) || |
2667 | 601k | getMemberSpecializationInfo()) && |
2668 | 601k | "not a variable or static data member template specialization"); |
2669 | | |
2670 | 601k | if (VarTemplateSpecializationDecl *Spec = |
2671 | 3.74k | dyn_cast<VarTemplateSpecializationDecl>(this)) { |
2672 | 3.74k | Spec->setSpecializationKind(TSK); |
2673 | 3.74k | if (TSK != TSK_ExplicitSpecialization && |
2674 | 3.73k | PointOfInstantiation.isValid() && |
2675 | 3.73k | Spec->getPointOfInstantiation().isInvalid()) { |
2676 | 2.10k | Spec->setPointOfInstantiation(PointOfInstantiation); |
2677 | 2.10k | if (ASTMutationListener *L = getASTContext().getASTMutationListener()) |
2678 | 84 | L->InstantiationRequested(this); |
2679 | 2.10k | } |
2680 | 597k | } else if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo()) { |
2681 | 597k | MSI->setTemplateSpecializationKind(TSK); |
2682 | 597k | if (TSK != TSK_ExplicitSpecialization && PointOfInstantiation.isValid()597k && |
2683 | 597k | MSI->getPointOfInstantiation().isInvalid()) { |
2684 | 12.9k | MSI->setPointOfInstantiation(PointOfInstantiation); |
2685 | 12.9k | if (ASTMutationListener *L = getASTContext().getASTMutationListener()) |
2686 | 557 | L->InstantiationRequested(this); |
2687 | 12.9k | } |
2688 | 597k | } |
2689 | 601k | } |
2690 | | |
2691 | | void |
2692 | | VarDecl::setInstantiationOfStaticDataMember(VarDecl *VD, |
2693 | 222k | TemplateSpecializationKind TSK) { |
2694 | 222k | assert(getASTContext().getTemplateOrSpecializationInfo(this).isNull() && |
2695 | 222k | "Previous template or instantiation?"); |
2696 | 222k | getASTContext().setInstantiatedFromStaticDataMember(this, VD, TSK); |
2697 | 222k | } |
2698 | | |
2699 | | //===----------------------------------------------------------------------===// |
2700 | | // ParmVarDecl Implementation |
2701 | | //===----------------------------------------------------------------------===// |
2702 | | |
2703 | | ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC, |
2704 | | SourceLocation StartLoc, |
2705 | | SourceLocation IdLoc, IdentifierInfo *Id, |
2706 | | QualType T, TypeSourceInfo *TInfo, |
2707 | 40.4M | StorageClass S, Expr *DefArg) { |
2708 | 40.4M | return new (C, DC) ParmVarDecl(ParmVar, C, DC, StartLoc, IdLoc, Id, T, TInfo, |
2709 | 40.4M | S, DefArg); |
2710 | 40.4M | } |
2711 | | |
2712 | 10.9M | QualType ParmVarDecl::getOriginalType() const { |
2713 | 10.9M | TypeSourceInfo *TSI = getTypeSourceInfo(); |
2714 | 7.86M | QualType T = TSI ? TSI->getType() : getType()3.05M ; |
2715 | 10.9M | if (const auto *DT = dyn_cast<DecayedType>(T)) |
2716 | 0 | return DT->getOriginalType(); |
2717 | 10.9M | return T; |
2718 | 10.9M | } |
2719 | | |
2720 | 1.37M | ParmVarDecl *ParmVarDecl::CreateDeserialized(ASTContext &C, unsigned ID) { |
2721 | 1.37M | return new (C, ID) |
2722 | 1.37M | ParmVarDecl(ParmVar, C, nullptr, SourceLocation(), SourceLocation(), |
2723 | 1.37M | nullptr, QualType(), nullptr, SC_None, nullptr); |
2724 | 1.37M | } |
2725 | | |
2726 | 173k | SourceRange ParmVarDecl::getSourceRange() const { |
2727 | 173k | if (!hasInheritedDefaultArg()) { |
2728 | 172k | SourceRange ArgRange = getDefaultArgRange(); |
2729 | 172k | if (ArgRange.isValid()) |
2730 | 2.19k | return SourceRange(getOuterLocStart(), ArgRange.getEnd()); |
2731 | 170k | } |
2732 | | |
2733 | | // DeclaratorDecl considers the range of postfix types as overlapping with the |
2734 | | // declaration name, but this is not the case with parameters in ObjC methods. |
2735 | 170k | if (isa<ObjCMethodDecl>(getDeclContext())) |
2736 | 646 | return SourceRange(DeclaratorDecl::getBeginLoc(), getLocation()); |
2737 | | |
2738 | 170k | return DeclaratorDecl::getSourceRange(); |
2739 | 170k | } |
2740 | | |
2741 | 186 | bool ParmVarDecl::isDestroyedInCallee() const { |
2742 | 186 | if (hasAttr<NSConsumedAttr>()) |
2743 | 10 | return true; |
2744 | | |
2745 | 176 | auto *RT = getType()->getAs<RecordType>(); |
2746 | 176 | if (RT && RT->getDecl()->isParamDestroyedInCallee()23 ) |
2747 | 16 | return true; |
2748 | | |
2749 | 160 | return false; |
2750 | 160 | } |
2751 | | |
2752 | 1.89M | Expr *ParmVarDecl::getDefaultArg() { |
2753 | 1.89M | assert(!hasUnparsedDefaultArg() && "Default argument is not yet parsed!"); |
2754 | 1.89M | assert(!hasUninstantiatedDefaultArg() && |
2755 | 1.89M | "Default argument is not yet instantiated!"); |
2756 | | |
2757 | 1.89M | Expr *Arg = getInit(); |
2758 | 1.89M | if (auto *E = dyn_cast_or_null<FullExpr>(Arg)) |
2759 | 15.1k | return E->getSubExpr(); |
2760 | | |
2761 | 1.87M | return Arg; |
2762 | 1.87M | } |
2763 | | |
2764 | 41.9M | void ParmVarDecl::setDefaultArg(Expr *defarg) { |
2765 | 41.9M | ParmVarDeclBits.DefaultArgKind = DAK_Normal; |
2766 | 41.9M | Init = defarg; |
2767 | 41.9M | } |
2768 | | |
2769 | 173k | SourceRange ParmVarDecl::getDefaultArgRange() const { |
2770 | 173k | switch (ParmVarDeclBits.DefaultArgKind) { |
2771 | 0 | case DAK_None: |
2772 | 3 | case DAK_Unparsed: |
2773 | | // Nothing we can do here. |
2774 | 3 | return SourceRange(); |
2775 | |
|
2776 | 1 | case DAK_Uninstantiated: |
2777 | 1 | return getUninstantiatedDefaultArg()->getSourceRange(); |
2778 | |
|
2779 | 173k | case DAK_Normal: |
2780 | 173k | if (const Expr *E = getInit()) |
2781 | 2.33k | return E->getSourceRange(); |
2782 | | |
2783 | | // Missing an actual expression, may be invalid. |
2784 | 170k | return SourceRange(); |
2785 | 0 | } |
2786 | 0 | llvm_unreachable("Invalid default argument kind."); |
2787 | 0 | } |
2788 | | |
2789 | 113k | void ParmVarDecl::setUninstantiatedDefaultArg(Expr *arg) { |
2790 | 113k | ParmVarDeclBits.DefaultArgKind = DAK_Uninstantiated; |
2791 | 113k | Init = arg; |
2792 | 113k | } |
2793 | | |
2794 | 36.8k | Expr *ParmVarDecl::getUninstantiatedDefaultArg() { |
2795 | 36.8k | assert(hasUninstantiatedDefaultArg() && |
2796 | 36.8k | "Wrong kind of initialization expression!"); |
2797 | 36.8k | return cast_or_null<Expr>(Init.get<Stmt *>()); |
2798 | 36.8k | } |
2799 | | |
2800 | 28.8M | bool ParmVarDecl::hasDefaultArg() const { |
2801 | | // FIXME: We should just return false for DAK_None here once callers are |
2802 | | // prepared for the case that we encountered an invalid default argument and |
2803 | | // were unable to even build an invalid expression. |
2804 | 28.8M | return hasUnparsedDefaultArg() || hasUninstantiatedDefaultArg()28.8M || |
2805 | 28.3M | !Init.isNull(); |
2806 | 28.8M | } |
2807 | | |
2808 | 47 | void ParmVarDecl::setParameterIndexLarge(unsigned parameterIndex) { |
2809 | 47 | getASTContext().setParameterIndex(this, parameterIndex); |
2810 | 47 | ParmVarDeclBits.ParameterIndex = ParameterIndexSentinel; |
2811 | 47 | } |
2812 | | |
2813 | 0 | unsigned ParmVarDecl::getParameterIndexLarge() const { |
2814 | 0 | return getASTContext().getParameterIndex(this); |
2815 | 0 | } |
2816 | | |
2817 | | //===----------------------------------------------------------------------===// |
2818 | | // FunctionDecl Implementation |
2819 | | //===----------------------------------------------------------------------===// |
2820 | | |
2821 | | FunctionDecl::FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, |
2822 | | SourceLocation StartLoc, |
2823 | | const DeclarationNameInfo &NameInfo, QualType T, |
2824 | | TypeSourceInfo *TInfo, StorageClass S, |
2825 | | bool isInlineSpecified, |
2826 | | ConstexprSpecKind ConstexprKind, |
2827 | | Expr *TrailingRequiresClause) |
2828 | | : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo, |
2829 | | StartLoc), |
2830 | | DeclContext(DK), redeclarable_base(C), Body(), ODRHash(0), |
2831 | 17.6M | EndRangeLoc(NameInfo.getEndLoc()), DNLoc(NameInfo.getInfo()) { |
2832 | 17.6M | assert(T.isNull() || T->isFunctionType()); |
2833 | 17.6M | FunctionDeclBits.SClass = S; |
2834 | 17.6M | FunctionDeclBits.IsInline = isInlineSpecified; |
2835 | 17.6M | FunctionDeclBits.IsInlineSpecified = isInlineSpecified; |
2836 | 17.6M | FunctionDeclBits.IsVirtualAsWritten = false; |
2837 | 17.6M | FunctionDeclBits.IsPure = false; |
2838 | 17.6M | FunctionDeclBits.HasInheritedPrototype = false; |
2839 | 17.6M | FunctionDeclBits.HasWrittenPrototype = true; |
2840 | 17.6M | FunctionDeclBits.IsDeleted = false; |
2841 | 17.6M | FunctionDeclBits.IsTrivial = false; |
2842 | 17.6M | FunctionDeclBits.IsTrivialForCall = false; |
2843 | 17.6M | FunctionDeclBits.IsDefaulted = false; |
2844 | 17.6M | FunctionDeclBits.IsExplicitlyDefaulted = false; |
2845 | 17.6M | FunctionDeclBits.HasDefaultedFunctionInfo = false; |
2846 | 17.6M | FunctionDeclBits.HasImplicitReturnZero = false; |
2847 | 17.6M | FunctionDeclBits.IsLateTemplateParsed = false; |
2848 | 17.6M | FunctionDeclBits.ConstexprKind = static_cast<uint64_t>(ConstexprKind); |
2849 | 17.6M | FunctionDeclBits.InstantiationIsPending = false; |
2850 | 17.6M | FunctionDeclBits.UsesSEHTry = false; |
2851 | 17.6M | FunctionDeclBits.UsesFPIntrin = false; |
2852 | 17.6M | FunctionDeclBits.HasSkippedBody = false; |
2853 | 17.6M | FunctionDeclBits.WillHaveBody = false; |
2854 | 17.6M | FunctionDeclBits.IsMultiVersion = false; |
2855 | 17.6M | FunctionDeclBits.IsCopyDeductionCandidate = false; |
2856 | 17.6M | FunctionDeclBits.HasODRHash = false; |
2857 | 17.6M | if (TrailingRequiresClause) |
2858 | 203 | setTrailingRequiresClause(TrailingRequiresClause); |
2859 | 17.6M | } |
2860 | | |
2861 | | void FunctionDecl::getNameForDiagnostic( |
2862 | 11.2k | raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const { |
2863 | 11.2k | NamedDecl::getNameForDiagnostic(OS, Policy, Qualified); |
2864 | 11.2k | const TemplateArgumentList *TemplateArgs = getTemplateSpecializationArgs(); |
2865 | 11.2k | if (TemplateArgs) |
2866 | 4.16k | printTemplateArgumentList(OS, TemplateArgs->asArray(), Policy); |
2867 | 11.2k | } |
2868 | | |
2869 | 1.10M | bool FunctionDecl::isVariadic() const { |
2870 | 1.10M | if (const auto *FT = getType()->getAs<FunctionProtoType>()) |
2871 | 965k | return FT->isVariadic(); |
2872 | 134k | return false; |
2873 | 134k | } |
2874 | | |
2875 | | FunctionDecl::DefaultedFunctionInfo * |
2876 | | FunctionDecl::DefaultedFunctionInfo::Create(ASTContext &Context, |
2877 | 475 | ArrayRef<DeclAccessPair> Lookups) { |
2878 | 475 | DefaultedFunctionInfo *Info = new (Context.Allocate( |
2879 | 475 | totalSizeToAlloc<DeclAccessPair>(Lookups.size()), |
2880 | 475 | std::max(alignof(DefaultedFunctionInfo), alignof(DeclAccessPair)))) |
2881 | 475 | DefaultedFunctionInfo; |
2882 | 475 | Info->NumLookups = Lookups.size(); |
2883 | 475 | std::uninitialized_copy(Lookups.begin(), Lookups.end(), |
2884 | 475 | Info->getTrailingObjects<DeclAccessPair>()); |
2885 | 475 | return Info; |
2886 | 475 | } |
2887 | | |
2888 | 596 | void FunctionDecl::setDefaultedFunctionInfo(DefaultedFunctionInfo *Info) { |
2889 | 596 | assert(!FunctionDeclBits.HasDefaultedFunctionInfo && "already have this"); |
2890 | 596 | assert(!Body && "can't replace function body with defaulted function info"); |
2891 | | |
2892 | 596 | FunctionDeclBits.HasDefaultedFunctionInfo = true; |
2893 | 596 | DefaultedInfo = Info; |
2894 | 596 | } |
2895 | | |
2896 | | FunctionDecl::DefaultedFunctionInfo * |
2897 | 38.6k | FunctionDecl::getDefaultedFunctionInfo() const { |
2898 | 37.6k | return FunctionDeclBits.HasDefaultedFunctionInfo ? DefaultedInfo1.00k : nullptr; |
2899 | 38.6k | } |
2900 | | |
2901 | 12.8M | bool FunctionDecl::hasBody(const FunctionDecl *&Definition) const { |
2902 | 13.0M | for (auto I : redecls()) { |
2903 | 13.0M | if (I->doesThisDeclarationHaveABody()) { |
2904 | 9.41M | Definition = I; |
2905 | 9.41M | return true; |
2906 | 9.41M | } |
2907 | 13.0M | } |
2908 | | |
2909 | 3.40M | return false; |
2910 | 12.8M | } |
2911 | | |
2912 | 4.97k | bool FunctionDecl::hasTrivialBody() const { |
2913 | 4.97k | Stmt *S = getBody(); |
2914 | 4.97k | if (!S) { |
2915 | | // Since we don't have a body for this function, we don't know if it's |
2916 | | // trivial or not. |
2917 | 1.49k | return false; |
2918 | 1.49k | } |
2919 | | |
2920 | 3.47k | if (isa<CompoundStmt>(S) && cast<CompoundStmt>(S)->body_empty()3.46k ) |
2921 | 1.45k | return true; |
2922 | 2.02k | return false; |
2923 | 2.02k | } |
2924 | | |
2925 | 9.83M | bool FunctionDecl::isThisDeclarationInstantiatedFromAFriendDefinition() const { |
2926 | 9.83M | if (!getFriendObjectKind()) |
2927 | 9.80M | return false; |
2928 | | |
2929 | | // Check for a friend function instantiated from a friend function |
2930 | | // definition in a templated class. |
2931 | 32.6k | if (const FunctionDecl *InstantiatedFrom = |
2932 | 1.24k | getInstantiatedFromMemberFunction()) |
2933 | 1.24k | return InstantiatedFrom->getFriendObjectKind() && |
2934 | 1.20k | InstantiatedFrom->isThisDeclarationADefinition(); |
2935 | | |
2936 | | // Check for a friend function template instantiated from a friend |
2937 | | // function template definition in a templated class. |
2938 | 31.4k | if (const FunctionTemplateDecl *Template = getDescribedFunctionTemplate()) { |
2939 | 12.4k | if (const FunctionTemplateDecl *InstantiatedFrom = |
2940 | 11 | Template->getInstantiatedFromMemberTemplate()) |
2941 | 11 | return InstantiatedFrom->getFriendObjectKind() && |
2942 | 11 | InstantiatedFrom->isThisDeclarationADefinition(); |
2943 | 31.4k | } |
2944 | | |
2945 | 31.4k | return false; |
2946 | 31.4k | } |
2947 | | |
2948 | | bool FunctionDecl::isDefined(const FunctionDecl *&Definition, |
2949 | 15.2M | bool CheckForPendingFriendDefinition) const { |
2950 | 15.9M | for (const FunctionDecl *FD : redecls()) { |
2951 | 15.9M | if (FD->isThisDeclarationADefinition()) { |
2952 | 6.97M | Definition = FD; |
2953 | 6.97M | return true; |
2954 | 6.97M | } |
2955 | | |
2956 | | // If this is a friend function defined in a class template, it does not |
2957 | | // have a body until it is used, nevertheless it is a definition, see |
2958 | | // [temp.inst]p2: |
2959 | | // |
2960 | | // ... for the purpose of determining whether an instantiated redeclaration |
2961 | | // is valid according to [basic.def.odr] and [class.mem], a declaration that |
2962 | | // corresponds to a definition in the template is considered to be a |
2963 | | // definition. |
2964 | | // |
2965 | | // The following code must produce redefinition error: |
2966 | | // |
2967 | | // template<typename T> struct C20 { friend void func_20() {} }; |
2968 | | // C20<int> c20i; |
2969 | | // void func_20() {} |
2970 | | // |
2971 | 9.01M | if (CheckForPendingFriendDefinition && |
2972 | 6.82M | FD->isThisDeclarationInstantiatedFromAFriendDefinition()) { |
2973 | 603 | Definition = FD; |
2974 | 603 | return true; |
2975 | 603 | } |
2976 | 9.01M | } |
2977 | | |
2978 | 8.24M | return false; |
2979 | 15.2M | } |
2980 | | |
2981 | 10.0M | Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const { |
2982 | 10.0M | if (!hasBody(Definition)) |
2983 | 2.46M | return nullptr; |
2984 | | |
2985 | 7.61M | assert(!Definition->FunctionDeclBits.HasDefaultedFunctionInfo && |
2986 | 7.61M | "definition should not have a body"); |
2987 | 7.61M | if (Definition->Body) |
2988 | 7.61M | return Definition->Body.get(getASTContext().getExternalSource()); |
2989 | | |
2990 | 692 | return nullptr; |
2991 | 692 | } |
2992 | | |
2993 | 3.65M | void FunctionDecl::setBody(Stmt *B) { |
2994 | 3.65M | FunctionDeclBits.HasDefaultedFunctionInfo = false; |
2995 | 3.65M | Body = LazyDeclStmtPtr(B); |
2996 | 3.65M | if (B) |
2997 | 3.64M | EndRangeLoc = B->getEndLoc(); |
2998 | 3.65M | } |
2999 | | |
3000 | 1.30M | void FunctionDecl::setPure(bool P) { |
3001 | 1.30M | FunctionDeclBits.IsPure = P; |
3002 | 1.30M | if (P) |
3003 | 5.47k | if (auto *Parent = dyn_cast<CXXRecordDecl>(getDeclContext())) |
3004 | 5.47k | Parent->markedVirtualFunctionPure(); |
3005 | 1.30M | } |
3006 | | |
3007 | | template<std::size_t Len> |
3008 | 67.5M | static bool isNamed(const NamedDecl *ND, const char (&Str)[Len]) { |
3009 | 67.5M | IdentifierInfo *II = ND->getIdentifier(); |
3010 | 67.5M | return II && II->isStr(Str)67.4M ; |
3011 | 67.5M | } |
3012 | | |
3013 | 88.2M | bool FunctionDecl::isMain() const { |
3014 | 88.2M | const TranslationUnitDecl *tunit = |
3015 | 88.2M | dyn_cast<TranslationUnitDecl>(getDeclContext()->getRedeclContext()); |
3016 | 88.2M | return tunit && |
3017 | 72.2M | !tunit->getASTContext().getLangOpts().Freestanding && |
3018 | 67.5M | isNamed(this, "main"); |
3019 | 88.2M | } |
3020 | | |
3021 | 67.7M | bool FunctionDecl::isMSVCRTEntryPoint() const { |
3022 | 67.7M | const TranslationUnitDecl *TUnit = |
3023 | 67.7M | dyn_cast<TranslationUnitDecl>(getDeclContext()->getRedeclContext()); |
3024 | 67.7M | if (!TUnit) |
3025 | 10.4M | return false; |
3026 | | |
3027 | | // Even though we aren't really targeting MSVCRT if we are freestanding, |
3028 | | // semantic analysis for these functions remains the same. |
3029 | | |
3030 | | // MSVCRT entry points only exist on MSVCRT targets. |
3031 | 57.2M | if (!TUnit->getASTContext().getTargetInfo().getTriple().isOSMSVCRT()) |
3032 | 57.0M | return false; |
3033 | | |
3034 | | // Nameless functions like constructors cannot be entry points. |
3035 | 202k | if (!getIdentifier()) |
3036 | 963 | return false; |
3037 | | |
3038 | 201k | return llvm::StringSwitch<bool>(getName()) |
3039 | 201k | .Cases("main", // an ANSI console app |
3040 | 201k | "wmain", // a Unicode console App |
3041 | 201k | "WinMain", // an ANSI GUI app |
3042 | 201k | "wWinMain", // a Unicode GUI app |
3043 | 201k | "DllMain", // a DLL |
3044 | 201k | true) |
3045 | 201k | .Default(false); |
3046 | 201k | } |
3047 | | |
3048 | 7.49k | bool FunctionDecl::isReservedGlobalPlacementOperator() const { |
3049 | 7.49k | assert(getDeclName().getNameKind() == DeclarationName::CXXOperatorName); |
3050 | 7.49k | assert(getDeclName().getCXXOverloadedOperator() == OO_New || |
3051 | 7.49k | getDeclName().getCXXOverloadedOperator() == OO_Delete || |
3052 | 7.49k | getDeclName().getCXXOverloadedOperator() == OO_Array_New || |
3053 | 7.49k | getDeclName().getCXXOverloadedOperator() == OO_Array_Delete); |
3054 | | |
3055 | 7.49k | if (!getDeclContext()->getRedeclContext()->isTranslationUnit()) |
3056 | 314 | return false; |
3057 | | |
3058 | 7.18k | const auto *proto = getType()->castAs<FunctionProtoType>(); |
3059 | 7.18k | if (proto->getNumParams() != 2 || proto->isVariadic()3.21k ) |
3060 | 3.96k | return false; |
3061 | | |
3062 | 3.21k | ASTContext &Context = |
3063 | 3.21k | cast<TranslationUnitDecl>(getDeclContext()->getRedeclContext()) |
3064 | 3.21k | ->getASTContext(); |
3065 | | |
3066 | | // The result type and first argument type are constant across all |
3067 | | // these operators. The second argument must be exactly void*. |
3068 | 3.21k | return (proto->getParamType(1).getCanonicalType() == Context.VoidPtrTy); |
3069 | 3.21k | } |
3070 | | |
3071 | | bool FunctionDecl::isReplaceableGlobalAllocationFunction( |
3072 | 1.58M | Optional<unsigned> *AlignmentParam, bool *IsNothrow) const { |
3073 | 1.58M | if (getDeclName().getNameKind() != DeclarationName::CXXOperatorName) |
3074 | 1.44M | return false; |
3075 | 138k | if (getDeclName().getCXXOverloadedOperator() != OO_New && |
3076 | 124k | getDeclName().getCXXOverloadedOperator() != OO_Delete && |
3077 | 118k | getDeclName().getCXXOverloadedOperator() != OO_Array_New && |
3078 | 110k | getDeclName().getCXXOverloadedOperator() != OO_Array_Delete) |
3079 | 109k | return false; |
3080 | | |
3081 | 29.1k | if (isa<CXXRecordDecl>(getDeclContext())) |
3082 | 1.45k | return false; |
3083 | | |
3084 | | // This can only fail for an invalid 'operator new' declaration. |
3085 | 27.6k | if (!getDeclContext()->getRedeclContext()->isTranslationUnit()) |
3086 | 4 | return false; |
3087 | | |
3088 | 27.6k | const auto *FPT = getType()->castAs<FunctionProtoType>(); |
3089 | 27.6k | if (FPT->getNumParams() == 0 || FPT->getNumParams() > 327.6k || FPT->isVariadic()27.6k ) |
3090 | 11 | return false; |
3091 | | |
3092 | | // If this is a single-parameter function, it must be a replaceable global |
3093 | | // allocation or deallocation function. |
3094 | 27.6k | if (FPT->getNumParams() == 1) |
3095 | 19.3k | return true; |
3096 | | |
3097 | 8.30k | unsigned Params = 1; |
3098 | 8.30k | QualType Ty = FPT->getParamType(Params); |
3099 | 8.30k | ASTContext &Ctx = getASTContext(); |
3100 | | |
3101 | 2.44k | auto Consume = [&] { |
3102 | 2.44k | ++Params; |
3103 | 2.26k | Ty = Params < FPT->getNumParams() ? FPT->getParamType(Params)181 : QualType(); |
3104 | 2.44k | }; |
3105 | | |
3106 | | // In C++14, the next parameter can be a 'std::size_t' for sized delete. |
3107 | 8.30k | bool IsSizedDelete = false; |
3108 | 8.30k | if (Ctx.getLangOpts().SizedDeallocation && |
3109 | 316 | (getDeclName().getCXXOverloadedOperator() == OO_Delete || |
3110 | 219 | getDeclName().getCXXOverloadedOperator() == OO_Array_Delete) && |
3111 | 139 | Ctx.hasSameType(Ty, Ctx.getSizeType())) { |
3112 | 81 | IsSizedDelete = true; |
3113 | 81 | Consume(); |
3114 | 81 | } |
3115 | | |
3116 | | // In C++17, the next parameter can be a 'std::align_val_t' for aligned |
3117 | | // new/delete. |
3118 | 8.30k | if (Ctx.getLangOpts().AlignedAllocation && !Ty.isNull()1.32k && Ty->isAlignValT()1.32k ) { |
3119 | 1.05k | Consume(); |
3120 | 1.05k | if (AlignmentParam) |
3121 | 756 | *AlignmentParam = Params; |
3122 | 1.05k | } |
3123 | | |
3124 | | // Finally, if this is not a sized delete, the final parameter can |
3125 | | // be a 'const std::nothrow_t&'. |
3126 | 8.30k | if (!IsSizedDelete && !Ty.isNull()8.22k && Ty->isReferenceType()7.35k ) { |
3127 | 1.38k | Ty = Ty->getPointeeType(); |
3128 | 1.38k | if (Ty.getCVRQualifiers() != Qualifiers::Const) |
3129 | 6 | return false; |
3130 | 1.37k | if (Ty->isNothrowT()) { |
3131 | 1.31k | if (IsNothrow) |
3132 | 1.15k | *IsNothrow = true; |
3133 | 1.31k | Consume(); |
3134 | 1.31k | } |
3135 | 1.37k | } |
3136 | | |
3137 | 8.29k | return Params == FPT->getNumParams(); |
3138 | 8.30k | } |
3139 | | |
3140 | 345k | bool FunctionDecl::isInlineBuiltinDeclaration() const { |
3141 | 345k | if (!getBuiltinID()) |
3142 | 279k | return false; |
3143 | | |
3144 | 66.1k | const FunctionDecl *Definition; |
3145 | 66.1k | return hasBody(Definition) && Definition->isInlineSpecified()47 ; |
3146 | 66.1k | } |
3147 | | |
3148 | 27.2k | bool FunctionDecl::isDestroyingOperatorDelete() const { |
3149 | | // C++ P0722: |
3150 | | // Within a class C, a single object deallocation function with signature |
3151 | | // (T, std::destroying_delete_t, <more params>) |
3152 | | // is a destroying operator delete. |
3153 | 27.2k | if (!isa<CXXMethodDecl>(this) || getOverloadedOperator() != OO_Delete4.26k || |
3154 | 3.66k | getNumParams() < 2) |
3155 | 25.0k | return false; |
3156 | | |
3157 | 2.24k | auto *RD = getParamDecl(1)->getType()->getAsCXXRecordDecl(); |
3158 | 2.24k | return RD && RD->isInStdNamespace()799 && RD->getIdentifier()779 && |
3159 | 779 | RD->getIdentifier()->isStr("destroying_delete_t"); |
3160 | 2.24k | } |
3161 | | |
3162 | 23.8M | LanguageLinkage FunctionDecl::getLanguageLinkage() const { |
3163 | 23.8M | return getDeclLanguageLinkage(*this); |
3164 | 23.8M | } |
3165 | | |
3166 | 21.7M | bool FunctionDecl::isExternC() const { |
3167 | 21.7M | return isDeclExternC(*this); |
3168 | 21.7M | } |
3169 | | |
3170 | 12.4M | bool FunctionDecl::isInExternCContext() const { |
3171 | 12.4M | if (hasAttr<OpenCLKernelAttr>()) |
3172 | 574 | return true; |
3173 | 12.4M | return getLexicalDeclContext()->isExternCContext(); |
3174 | 12.4M | } |
3175 | | |
3176 | 11.9k | bool FunctionDecl::isInExternCXXContext() const { |
3177 | 11.9k | return getLexicalDeclContext()->isExternCXXContext(); |
3178 | 11.9k | } |
3179 | | |
3180 | 3.42M | bool FunctionDecl::isGlobal() const { |
3181 | 3.42M | if (const auto *Method = dyn_cast<CXXMethodDecl>(this)) |
3182 | 889k | return Method->isStatic(); |
3183 | | |
3184 | 2.53M | if (getCanonicalDecl()->getStorageClass() == SC_Static) |
3185 | 1.85M | return false; |
3186 | | |
3187 | 682k | for (const DeclContext *DC = getDeclContext(); |
3188 | 682k | DC->isNamespace(); |
3189 | 402k | DC = DC->getParent()0 ) { |
3190 | 402k | if (const auto *Namespace = cast<NamespaceDecl>(DC)) { |
3191 | 402k | if (!Namespace->getDeclName()) |
3192 | 250 | return false; |
3193 | 402k | break; |
3194 | 402k | } |
3195 | 402k | } |
3196 | | |
3197 | 682k | return true; |
3198 | 682k | } |
3199 | | |
3200 | 4.69M | bool FunctionDecl::isNoReturn() const { |
3201 | 4.69M | if (hasAttr<NoReturnAttr>()4.69M || hasAttr<CXX11NoReturnAttr>() || |
3202 | 4.69M | hasAttr<C11NoReturnAttr>()) |
3203 | 3.39k | return true; |
3204 | | |
3205 | 4.69M | if (auto *FnTy = getType()->getAs<FunctionType>()) |
3206 | 4.69M | return FnTy->getNoReturnAttr(); |
3207 | | |
3208 | 18.4E | return false; |
3209 | 18.4E | } |
3210 | | |
3211 | | |
3212 | 15.5M | MultiVersionKind FunctionDecl::getMultiVersionKind() const { |
3213 | 15.5M | if (hasAttr<TargetAttr>()) |
3214 | 1.09M | return MultiVersionKind::Target; |
3215 | 14.4M | if (hasAttr<CPUDispatchAttr>()) |
3216 | 60 | return MultiVersionKind::CPUDispatch; |
3217 | 14.4M | if (hasAttr<CPUSpecificAttr>()) |
3218 | 121 | return MultiVersionKind::CPUSpecific; |
3219 | 14.4M | return MultiVersionKind::None; |
3220 | 14.4M | } |
3221 | | |
3222 | 2.65M | bool FunctionDecl::isCPUDispatchMultiVersion() const { |
3223 | 2.65M | return isMultiVersion() && hasAttr<CPUDispatchAttr>()237 ; |
3224 | 2.65M | } |
3225 | | |
3226 | 2.56M | bool FunctionDecl::isCPUSpecificMultiVersion() const { |
3227 | 2.56M | return isMultiVersion() && hasAttr<CPUSpecificAttr>()193 ; |
3228 | 2.56M | } |
3229 | | |
3230 | 67 | bool FunctionDecl::isTargetMultiVersion() const { |
3231 | 67 | return isMultiVersion() && hasAttr<TargetAttr>(); |
3232 | 67 | } |
3233 | | |
3234 | | void |
3235 | 244k | FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) { |
3236 | 244k | redeclarable_base::setPreviousDecl(PrevDecl); |
3237 | | |
3238 | 244k | if (FunctionTemplateDecl *FunTmpl = getDescribedFunctionTemplate()) { |
3239 | 60.1k | FunctionTemplateDecl *PrevFunTmpl |
3240 | 60.1k | = PrevDecl? PrevDecl->getDescribedFunctionTemplate() : nullptr0 ; |
3241 | 60.1k | assert((!PrevDecl || PrevFunTmpl) && "Function/function template mismatch"); |
3242 | 60.1k | FunTmpl->setPreviousDecl(PrevFunTmpl); |
3243 | 60.1k | } |
3244 | | |
3245 | 244k | if (PrevDecl && PrevDecl->isInlined()) |
3246 | 45.1k | setImplicitlyInline(true); |
3247 | 244k | } |
3248 | | |
3249 | 383M | FunctionDecl *FunctionDecl::getCanonicalDecl() { return getFirstDecl(); } |
3250 | | |
3251 | | /// Returns a value indicating whether this function corresponds to a builtin |
3252 | | /// function. |
3253 | | /// |
3254 | | /// The function corresponds to a built-in function if it is declared at |
3255 | | /// translation scope or within an extern "C" block and its name matches with |
3256 | | /// the name of a builtin. The returned value will be 0 for functions that do |
3257 | | /// not correspond to a builtin, a value of type \c Builtin::ID if in the |
3258 | | /// target-independent range \c [1,Builtin::First), or a target-specific builtin |
3259 | | /// value. |
3260 | | /// |
3261 | | /// \param ConsiderWrapperFunctions If true, we should consider wrapper |
3262 | | /// functions as their wrapped builtins. This shouldn't be done in general, but |
3263 | | /// it's useful in Sema to diagnose calls to wrappers based on their semantics. |
3264 | 97.6M | unsigned FunctionDecl::getBuiltinID(bool ConsiderWrapperFunctions) const { |
3265 | 97.6M | unsigned BuiltinID = 0; |
3266 | | |
3267 | 97.6M | if (const auto *ABAA = getAttr<ArmBuiltinAliasAttr>()) { |
3268 | 44.1M | BuiltinID = ABAA->getBuiltinName()->getBuiltinID(); |
3269 | 53.5M | } else if (const auto *A = getAttr<BuiltinAttr>()) { |
3270 | 13.8M | BuiltinID = A->getID(); |
3271 | 13.8M | } |
3272 | | |
3273 | 97.6M | if (!BuiltinID) |
3274 | 39.6M | return 0; |
3275 | | |
3276 | | // If the function is marked "overloadable", it has a different mangled name |
3277 | | // and is not the C library function. |
3278 | 58.0M | if (!ConsiderWrapperFunctions && hasAttr<OverloadableAttr>()56.5M && |
3279 | 43.3M | !hasAttr<ArmBuiltinAliasAttr>()) |
3280 | 12.5k | return 0; |
3281 | | |
3282 | 58.0M | ASTContext &Context = getASTContext(); |
3283 | 58.0M | if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) |
3284 | 57.8M | return BuiltinID; |
3285 | | |
3286 | | // This function has the name of a known C library |
3287 | | // function. Determine whether it actually refers to the C library |
3288 | | // function or whether it just has the same name. |
3289 | | |
3290 | | // If this is a static function, it's not a builtin. |
3291 | 199k | if (!ConsiderWrapperFunctions && getStorageClass() == SC_Static190k ) |
3292 | 0 | return 0; |
3293 | | |
3294 | | // OpenCL v1.2 s6.9.f - The library functions defined in |
3295 | | // the C99 standard headers are not available. |
3296 | 199k | if (Context.getLangOpts().OpenCL && |
3297 | 0 | Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) |
3298 | 0 | return 0; |
3299 | | |
3300 | | // CUDA does not have device-side standard library. printf and malloc are the |
3301 | | // only special cases that are supported by device-side runtime. |
3302 | 199k | if (Context.getLangOpts().CUDA && hasAttr<CUDADeviceAttr>()333 && |
3303 | 302 | !hasAttr<CUDAHostAttr>() && |
3304 | 302 | !(BuiltinID == Builtin::BIprintf || BuiltinID == Builtin::BImalloc35 )) |
3305 | 35 | return 0; |
3306 | | |
3307 | | // As AMDGCN implementation of OpenMP does not have a device-side standard |
3308 | | // library, none of the predefined library functions except printf and malloc |
3309 | | // should be treated as a builtin i.e. 0 should be returned for them. |
3310 | 199k | if (Context.getTargetInfo().getTriple().isAMDGCN() && |
3311 | 133 | Context.getLangOpts().OpenMPIsDevice && |
3312 | 26 | Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID) && |
3313 | 26 | !(BuiltinID == Builtin::BIprintf || BuiltinID == Builtin::BImalloc)) |
3314 | 26 | return 0; |
3315 | | |
3316 | 199k | return BuiltinID; |
3317 | 199k | } |
3318 | | |
3319 | | /// getNumParams - Return the number of parameters this function must have |
3320 | | /// based on its FunctionType. This is the length of the ParamInfo array |
3321 | | /// after it has been created. |
3322 | 135M | unsigned FunctionDecl::getNumParams() const { |
3323 | 135M | const auto *FPT = getType()->getAs<FunctionProtoType>(); |
3324 | 135M | return FPT ? FPT->getNumParams() : 0293k ; |
3325 | 135M | } |
3326 | | |
3327 | | void FunctionDecl::setParams(ASTContext &C, |
3328 | 17.5M | ArrayRef<ParmVarDecl *> NewParamInfo) { |
3329 | 17.5M | assert(!ParamInfo && "Already has param info!"); |
3330 | 17.5M | assert(NewParamInfo.size() == getNumParams() && "Parameter count mismatch!"); |
3331 | | |
3332 | | // Zero params -> null pointer. |
3333 | 17.5M | if (!NewParamInfo.empty()) { |
3334 | 16.1M | ParamInfo = new (C) ParmVarDecl*[NewParamInfo.size()]; |
3335 | 16.1M | std::copy(NewParamInfo.begin(), NewParamInfo.end(), ParamInfo); |
3336 | 16.1M | } |
3337 | 17.5M | } |
3338 | | |
3339 | | /// getMinRequiredArguments - Returns the minimum number of arguments |
3340 | | /// needed to call this function. This may be fewer than the number of |
3341 | | /// function parameters, if some of the parameters have default |
3342 | | /// arguments (in C++) or are parameter packs (C++11). |
3343 | 20.5M | unsigned FunctionDecl::getMinRequiredArguments() const { |
3344 | 20.5M | if (!getASTContext().getLangOpts().CPlusPlus) |
3345 | 5.09M | return getNumParams(); |
3346 | | |
3347 | | // Note that it is possible for a parameter with no default argument to |
3348 | | // follow a parameter with a default argument. |
3349 | 15.4M | unsigned NumRequiredArgs = 0; |
3350 | 15.4M | unsigned MinParamsSoFar = 0; |
3351 | 20.7M | for (auto *Param : parameters()) { |
3352 | 20.7M | if (!Param->isParameterPack()) { |
3353 | 20.7M | ++MinParamsSoFar; |
3354 | 20.7M | if (!Param->hasDefaultArg()) |
3355 | 20.2M | NumRequiredArgs = MinParamsSoFar; |
3356 | 20.7M | } |
3357 | 20.7M | } |
3358 | 15.4M | return NumRequiredArgs; |
3359 | 15.4M | } |
3360 | | |
3361 | 5.00M | bool FunctionDecl::hasOneParamOrDefaultArgs() const { |
3362 | 5.00M | return getNumParams() == 1 || |
3363 | 1.67M | (getNumParams() > 1 && |
3364 | 602k | std::all_of(param_begin() + 1, param_end(), |
3365 | 608k | [](ParmVarDecl *P) { return P->hasDefaultArg(); })); |
3366 | 5.00M | } |
3367 | | |
3368 | | /// The combination of the extern and inline keywords under MSVC forces |
3369 | | /// the function to be required. |
3370 | | /// |
3371 | | /// Note: This function assumes that we will only get called when isInlined() |
3372 | | /// would return true for this FunctionDecl. |
3373 | 1.12M | bool FunctionDecl::isMSExternInline() const { |
3374 | 1.12M | assert(isInlined() && "expected to get called on an inlined function!"); |
3375 | | |
3376 | 1.12M | const ASTContext &Context = getASTContext(); |
3377 | 1.12M | if (!Context.getTargetInfo().getCXXABI().isMicrosoft() && |
3378 | 1.11M | !hasAttr<DLLExportAttr>()) |
3379 | 1.11M | return false; |
3380 | | |
3381 | 15.0k | for (const FunctionDecl *FD = getMostRecentDecl(); 6.81k FD; |
3382 | 8.23k | FD = FD->getPreviousDecl()) |
3383 | 8.32k | if (!FD->isImplicit() && FD->getStorageClass() == SC_Extern8.25k ) |
3384 | 96 | return true; |
3385 | | |
3386 | 6.71k | return false; |
3387 | 6.81k | } |
3388 | | |
3389 | 32 | static bool redeclForcesDefMSVC(const FunctionDecl *Redecl) { |
3390 | 32 | if (Redecl->getStorageClass() != SC_Extern) |
3391 | 31 | return false; |
3392 | | |
3393 | 2 | for (const FunctionDecl *FD = Redecl->getPreviousDecl(); 1 FD; |
3394 | 1 | FD = FD->getPreviousDecl()) |
3395 | 1 | if (!FD->isImplicit() && FD->getStorageClass() == SC_Extern) |
3396 | 0 | return false; |
3397 | | |
3398 | 1 | return true; |
3399 | 1 | } |
3400 | | |
3401 | 50.1k | static bool RedeclForcesDefC99(const FunctionDecl *Redecl) { |
3402 | | // Only consider file-scope declarations in this test. |
3403 | 50.1k | if (!Redecl->getLexicalDeclContext()->isTranslationUnit()) |
3404 | 0 | return false; |
3405 | | |
3406 | | // Only consider explicit declarations; the presence of a builtin for a |
3407 | | // libcall shouldn't affect whether a definition is externally visible. |
3408 | 50.1k | if (Redecl->isImplicit()) |
3409 | 7.80k | return false; |
3410 | | |
3411 | 42.3k | if (!Redecl->isInlineSpecified() || Redecl->getStorageClass() == SC_Extern39.0k ) |
3412 | 3.31k | return true; // Not an inline definition |
3413 | | |
3414 | 39.0k | return false; |
3415 | 39.0k | } |
3416 | | |
3417 | | /// For a function declaration in C or C++, determine whether this |
3418 | | /// declaration causes the definition to be externally visible. |
3419 | | /// |
3420 | | /// For instance, this determines if adding the current declaration to the set |
3421 | | /// of redeclarations of the given functions causes |
3422 | | /// isInlineDefinitionExternallyVisible to change from false to true. |
3423 | 8.34M | bool FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const { |
3424 | 8.34M | assert(!doesThisDeclarationHaveABody() && |
3425 | 8.34M | "Must have a declaration without a body."); |
3426 | | |
3427 | 8.34M | ASTContext &Context = getASTContext(); |
3428 | | |
3429 | 8.34M | if (Context.getLangOpts().MSVCCompat) { |
3430 | 2.25k | const FunctionDecl *Definition; |
3431 | 2.25k | if (hasBody(Definition) && Definition->isInlined()33 && |
3432 | 32 | redeclForcesDefMSVC(this)) |
3433 | 1 | return true; |
3434 | 8.34M | } |
3435 | | |
3436 | 8.34M | if (Context.getLangOpts().CPlusPlus) |
3437 | 770k | return false; |
3438 | | |
3439 | 7.57M | if (Context.getLangOpts().GNUInline || hasAttr<GNUInlineAttr>()7.57M ) { |
3440 | | // With GNU inlining, a declaration with 'inline' but not 'extern', forces |
3441 | | // an externally visible definition. |
3442 | | // |
3443 | | // FIXME: What happens if gnu_inline gets added on after the first |
3444 | | // declaration? |
3445 | 49 | if (!isInlineSpecified() || getStorageClass() == SC_Extern22 ) |
3446 | 43 | return false; |
3447 | | |
3448 | 6 | const FunctionDecl *Prev = this; |
3449 | 6 | bool FoundBody = false; |
3450 | 8 | while ((Prev = Prev->getPreviousDecl())) { |
3451 | 4 | FoundBody |= Prev->doesThisDeclarationHaveABody(); |
3452 | | |
3453 | 4 | if (Prev->doesThisDeclarationHaveABody()) { |
3454 | | // If it's not the case that both 'inline' and 'extern' are |
3455 | | // specified on the definition, then it is always externally visible. |
3456 | 4 | if (!Prev->isInlineSpecified() || |
3457 | 4 | Prev->getStorageClass() != SC_Extern) |
3458 | 2 | return false; |
3459 | 0 | } else if (Prev->isInlineSpecified() && |
3460 | 0 | Prev->getStorageClass() != SC_Extern) { |
3461 | 0 | return false; |
3462 | 0 | } |
3463 | 4 | } |
3464 | 4 | return FoundBody; |
3465 | 7.57M | } |
3466 | | |
3467 | | // C99 6.7.4p6: |
3468 | | // [...] If all of the file scope declarations for a function in a |
3469 | | // translation unit include the inline function specifier without extern, |
3470 | | // then the definition in that translation unit is an inline definition. |
3471 | 7.57M | if (isInlineSpecified() && getStorageClass() != SC_Extern5.64M ) |
3472 | 5.64M | return false; |
3473 | 1.92M | const FunctionDecl *Prev = this; |
3474 | 1.92M | bool FoundBody = false; |
3475 | 1.93M | while ((Prev = Prev->getPreviousDecl())) { |
3476 | 10.7k | FoundBody |= Prev->doesThisDeclarationHaveABody(); |
3477 | 10.7k | if (RedeclForcesDefC99(Prev)) |
3478 | 3.12k | return false; |
3479 | 10.7k | } |
3480 | 1.92M | return FoundBody; |
3481 | 1.92M | } |
3482 | | |
3483 | 562 | FunctionTypeLoc FunctionDecl::getFunctionTypeLoc() const { |
3484 | 562 | const TypeSourceInfo *TSI = getTypeSourceInfo(); |
3485 | 562 | return TSI ? TSI->getTypeLoc().IgnoreParens().getAs<FunctionTypeLoc>() |
3486 | 0 | : FunctionTypeLoc(); |
3487 | 562 | } |
3488 | | |
3489 | 504 | SourceRange FunctionDecl::getReturnTypeSourceRange() const { |
3490 | 504 | FunctionTypeLoc FTL = getFunctionTypeLoc(); |
3491 | 504 | if (!FTL) |
3492 | 1 | return SourceRange(); |
3493 | | |
3494 | | // Skip self-referential return types. |
3495 | 503 | const SourceManager &SM = getASTContext().getSourceManager(); |
3496 | 503 | SourceRange RTRange = FTL.getReturnLoc().getSourceRange(); |
3497 | 503 | SourceLocation Boundary = getNameInfo().getBeginLoc(); |
3498 | 503 | if (RTRange.isInvalid() || Boundary.isInvalid() || |
3499 | 503 | !SM.isBeforeInTranslationUnit(RTRange.getEnd(), Boundary)) |
3500 | 7 | return SourceRange(); |
3501 | | |
3502 | 496 | return RTRange; |
3503 | 496 | } |
3504 | | |
3505 | 14 | SourceRange FunctionDecl::getParametersSourceRange() const { |
3506 | 14 | unsigned NP = getNumParams(); |
3507 | 14 | SourceLocation EllipsisLoc = getEllipsisLoc(); |
3508 | | |
3509 | 14 | if (NP == 0 && EllipsisLoc.isInvalid()1 ) |
3510 | 0 | return SourceRange(); |
3511 | | |
3512 | 14 | SourceLocation Begin = |
3513 | 13 | NP > 0 ? ParamInfo[0]->getSourceRange().getBegin() : EllipsisLoc1 ; |
3514 | 14 | SourceLocation End = EllipsisLoc.isValid() |
3515 | 4 | ? EllipsisLoc |
3516 | 10 | : ParamInfo[NP - 1]->getSourceRange().getEnd(); |
3517 | | |
3518 | 14 | return SourceRange(Begin, End); |
3519 | 14 | } |
3520 | | |
3521 | 57 | SourceRange FunctionDecl::getExceptionSpecSourceRange() const { |
3522 | 57 | FunctionTypeLoc FTL = getFunctionTypeLoc(); |
3523 | 57 | return FTL ? FTL.getExceptionSpecRange() : SourceRange()0 ; |
3524 | 57 | } |
3525 | | |
3526 | | /// For an inline function definition in C, or for a gnu_inline function |
3527 | | /// in C++, determine whether the definition will be externally visible. |
3528 | | /// |
3529 | | /// Inline function definitions are always available for inlining optimizations. |
3530 | | /// However, depending on the language dialect, declaration specifiers, and |
3531 | | /// attributes, the definition of an inline function may or may not be |
3532 | | /// "externally" visible to other translation units in the program. |
3533 | | /// |
3534 | | /// In C99, inline definitions are not externally visible by default. However, |
3535 | | /// if even one of the global-scope declarations is marked "extern inline", the |
3536 | | /// inline definition becomes externally visible (C99 6.7.4p6). |
3537 | | /// |
3538 | | /// In GNU89 mode, or if the gnu_inline attribute is attached to the function |
3539 | | /// definition, we use the GNU semantics for inline, which are nearly the |
3540 | | /// opposite of C99 semantics. In particular, "inline" by itself will create |
3541 | | /// an externally visible symbol, but "extern inline" will not create an |
3542 | | /// externally visible symbol. |
3543 | 46.3k | bool FunctionDecl::isInlineDefinitionExternallyVisible() const { |
3544 | 46.3k | assert((doesThisDeclarationHaveABody() || willHaveBody() || |
3545 | 46.3k | hasAttr<AliasAttr>()) && |
3546 | 46.3k | "Must be a function definition"); |
3547 | 46.3k | assert(isInlined() && "Function must be inline"); |
3548 | 46.3k | ASTContext &Context = getASTContext(); |
3549 | | |
3550 | 46.3k | if (Context.getLangOpts().GNUInline || hasAttr<GNUInlineAttr>()46.0k ) { |
3551 | | // Note: If you change the logic here, please change |
3552 | | // doesDeclarationForceExternallyVisibleDefinition as well. |
3553 | | // |
3554 | | // If it's not the case that both 'inline' and 'extern' are |
3555 | | // specified on the definition, then this inline definition is |
3556 | | // externally visible. |
3557 | 17.2k | if (Context.getLangOpts().CPlusPlus) |
3558 | 96 | return false; |
3559 | 17.1k | if (!(isInlineSpecified() && getStorageClass() == SC_Extern17.1k )) |
3560 | 208 | return true; |
3561 | | |
3562 | | // If any declaration is 'inline' but not 'extern', then this definition |
3563 | | // is externally visible. |
3564 | 17.1k | for (auto Redecl : redecls())16.9k { |
3565 | 17.1k | if (Redecl->isInlineSpecified() && |
3566 | 16.9k | Redecl->getStorageClass() != SC_Extern) |
3567 | 11 | return true; |
3568 | 17.1k | } |
3569 | | |
3570 | 16.9k | return false; |
3571 | 29.1k | } |
3572 | | |
3573 | | // The rest of this function is C-only. |
3574 | 29.1k | assert(!Context.getLangOpts().CPlusPlus && |
3575 | 29.1k | "should not use C inline rules in C++"); |
3576 | | |
3577 | | // C99 6.7.4p6: |
3578 | | // [...] If all of the file scope declarations for a function in a |
3579 | | // translation unit include the inline function specifier without extern, |
3580 | | // then the definition in that translation unit is an inline definition. |
3581 | 39.3k | for (auto Redecl : redecls()) { |
3582 | 39.3k | if (RedeclForcesDefC99(Redecl)) |
3583 | 194 | return true; |
3584 | 39.3k | } |
3585 | | |
3586 | | // C99 6.7.4p6: |
3587 | | // An inline definition does not provide an external definition for the |
3588 | | // function, and does not forbid an external definition in another |
3589 | | // translation unit. |
3590 | 28.9k | return false; |
3591 | 29.1k | } |
3592 | | |
3593 | | /// getOverloadedOperator - Which C++ overloaded operator this |
3594 | | /// function represents, if any. |
3595 | 30.1M | OverloadedOperatorKind FunctionDecl::getOverloadedOperator() const { |
3596 | 30.1M | if (getDeclName().getNameKind() == DeclarationName::CXXOperatorName) |
3597 | 6.15M | return getDeclName().getCXXOverloadedOperator(); |
3598 | 23.9M | else |
3599 | 23.9M | return OO_None; |
3600 | 30.1M | } |
3601 | | |
3602 | | /// getLiteralIdentifier - The literal suffix identifier this function |
3603 | | /// represents, if any. |
3604 | 4.13M | const IdentifierInfo *FunctionDecl::getLiteralIdentifier() const { |
3605 | 4.13M | if (getDeclName().getNameKind() == DeclarationName::CXXLiteralOperatorName) |
3606 | 760 | return getDeclName().getCXXLiteralIdentifier(); |
3607 | 4.13M | else |
3608 | 4.13M | return nullptr; |
3609 | 4.13M | } |
3610 | | |
3611 | 7.32M | FunctionDecl::TemplatedKind FunctionDecl::getTemplatedKind() const { |
3612 | 7.32M | if (TemplateOrSpecialization.isNull()) |
3613 | 5.86M | return TK_NonTemplate; |
3614 | 1.45M | if (TemplateOrSpecialization.is<FunctionTemplateDecl *>()) |
3615 | 356k | return TK_FunctionTemplate; |
3616 | 1.09M | if (TemplateOrSpecialization.is<MemberSpecializationInfo *>()) |
3617 | 798k | return TK_MemberSpecialization; |
3618 | 300k | if (TemplateOrSpecialization.is<FunctionTemplateSpecializationInfo *>()) |
3619 | 299k | return TK_FunctionTemplateSpecialization; |
3620 | 827 | if (TemplateOrSpecialization.is |
3621 | 827 | <DependentFunctionTemplateSpecializationInfo*>()) |
3622 | 827 | return TK_DependentFunctionTemplateSpecialization; |
3623 | | |
3624 | 0 | llvm_unreachable("Did we miss a TemplateOrSpecialization type?"); |
3625 | 0 | } |
3626 | | |
3627 | 7.21M | FunctionDecl *FunctionDecl::getInstantiatedFromMemberFunction() const { |
3628 | 7.21M | if (MemberSpecializationInfo *Info = getMemberSpecializationInfo()) |
3629 | 930k | return cast<FunctionDecl>(Info->getInstantiatedFrom()); |
3630 | | |
3631 | 6.28M | return nullptr; |
3632 | 6.28M | } |
3633 | | |
3634 | 18.0M | MemberSpecializationInfo *FunctionDecl::getMemberSpecializationInfo() const { |
3635 | 18.0M | if (auto *MSI = |
3636 | 4.02M | TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo *>()) |
3637 | 4.02M | return MSI; |
3638 | 14.0M | if (auto *FTSI = TemplateOrSpecialization |
3639 | 570k | .dyn_cast<FunctionTemplateSpecializationInfo *>()) |
3640 | 570k | return FTSI->getMemberSpecializationInfo(); |
3641 | 13.4M | return nullptr; |
3642 | 13.4M | } |
3643 | | |
3644 | | void |
3645 | | FunctionDecl::setInstantiationOfMemberFunction(ASTContext &C, |
3646 | | FunctionDecl *FD, |
3647 | 806k | TemplateSpecializationKind TSK) { |
3648 | 806k | assert(TemplateOrSpecialization.isNull() && |
3649 | 806k | "Member function is already a specialization"); |
3650 | 806k | MemberSpecializationInfo *Info |
3651 | 806k | = new (C) MemberSpecializationInfo(FD, TSK); |
3652 | 806k | TemplateOrSpecialization = Info; |
3653 | 806k | } |
3654 | | |
3655 | 156M | FunctionTemplateDecl *FunctionDecl::getDescribedFunctionTemplate() const { |
3656 | 156M | return TemplateOrSpecialization.dyn_cast<FunctionTemplateDecl *>(); |
3657 | 156M | } |
3658 | | |
3659 | 1.12M | void FunctionDecl::setDescribedFunctionTemplate(FunctionTemplateDecl *Template) { |
3660 | 1.12M | assert(TemplateOrSpecialization.isNull() && |
3661 | 1.12M | "Member function is already a specialization"); |
3662 | 1.12M | TemplateOrSpecialization = Template; |
3663 | 1.12M | } |
3664 | | |
3665 | 3.38M | bool FunctionDecl::isImplicitlyInstantiable() const { |
3666 | | // If the function is invalid, it can't be implicitly instantiated. |
3667 | 3.38M | if (isInvalidDecl()) |
3668 | 112 | return false; |
3669 | | |
3670 | 3.38M | switch (getTemplateSpecializationKindForInstantiation()) { |
3671 | 2.98M | case TSK_Undeclared: |
3672 | 2.98M | case TSK_ExplicitInstantiationDefinition: |
3673 | 2.98M | case TSK_ExplicitSpecialization: |
3674 | 2.98M | return false; |
3675 | | |
3676 | 386k | case TSK_ImplicitInstantiation: |
3677 | 386k | return true; |
3678 | | |
3679 | 4.79k | case TSK_ExplicitInstantiationDeclaration: |
3680 | | // Handled below. |
3681 | 4.79k | break; |
3682 | 4.79k | } |
3683 | | |
3684 | | // Find the actual template from which we will instantiate. |
3685 | 4.79k | const FunctionDecl *PatternDecl = getTemplateInstantiationPattern(); |
3686 | 4.79k | bool HasPattern = false; |
3687 | 4.79k | if (PatternDecl) |
3688 | 4.79k | HasPattern = PatternDecl->hasBody(PatternDecl); |
3689 | | |
3690 | | // C++0x [temp.explicit]p9: |
3691 | | // Except for inline functions, other explicit instantiation declarations |
3692 | | // have the effect of suppressing the implicit instantiation of the entity |
3693 | | // to which they refer. |
3694 | 4.79k | if (!HasPattern || !PatternDecl4.75k ) |
3695 | 42 | return true; |
3696 | | |
3697 | 4.75k | return PatternDecl->isInlined(); |
3698 | 4.75k | } |
3699 | | |
3700 | 231k | bool FunctionDecl::isTemplateInstantiation() const { |
3701 | | // FIXME: Remove this, it's not clear what it means. (Which template |
3702 | | // specialization kind?) |
3703 | 231k | return clang::isTemplateInstantiation(getTemplateSpecializationKind()); |
3704 | 231k | } |
3705 | | |
3706 | | FunctionDecl * |
3707 | 5.98M | FunctionDecl::getTemplateInstantiationPattern(bool ForDefinition) const { |
3708 | | // If this is a generic lambda call operator specialization, its |
3709 | | // instantiation pattern is always its primary template's pattern |
3710 | | // even if its primary template was instantiated from another |
3711 | | // member template (which happens with nested generic lambdas). |
3712 | | // Since a lambda's call operator's body is transformed eagerly, |
3713 | | // we don't have to go hunting for a prototype definition template |
3714 | | // (i.e. instantiated-from-member-template) to use as an instantiation |
3715 | | // pattern. |
3716 | | |
3717 | 5.98M | if (isGenericLambdaCallOperatorSpecialization( |
3718 | 4.17k | dyn_cast<CXXMethodDecl>(this))) { |
3719 | 4.17k | assert(getPrimaryTemplate() && "not a generic lambda call operator?"); |
3720 | 4.17k | return getDefinitionOrSelf(getPrimaryTemplate()->getTemplatedDecl()); |
3721 | 4.17k | } |
3722 | | |
3723 | | // Check for a declaration of this function that was instantiated from a |
3724 | | // friend definition. |
3725 | 5.98M | const FunctionDecl *FD = nullptr; |
3726 | 5.98M | if (!isDefined(FD, /*CheckForPendingFriendDefinition=*/true)) |
3727 | 2.98M | FD = this; |
3728 | | |
3729 | 5.98M | if (MemberSpecializationInfo *Info = FD->getMemberSpecializationInfo()) { |
3730 | 2.20M | if (ForDefinition && |
3731 | 2.19M | !clang::isTemplateInstantiation(Info->getTemplateSpecializationKind())) |
3732 | 569 | return nullptr; |
3733 | 2.20M | return getDefinitionOrSelf(cast<FunctionDecl>(Info->getInstantiatedFrom())); |
3734 | 2.20M | } |
3735 | | |
3736 | 3.78M | if (ForDefinition && |
3737 | 3.77M | !clang::isTemplateInstantiation(getTemplateSpecializationKind())) |
3738 | 3.54M | return nullptr; |
3739 | | |
3740 | 242k | if (FunctionTemplateDecl *Primary = getPrimaryTemplate()) { |
3741 | | // If we hit a point where the user provided a specialization of this |
3742 | | // template, we're done looking. |
3743 | 393k | while (!ForDefinition || !Primary->isMemberSpecialization()381k ) { |
3744 | 393k | auto *NewPrimary = Primary->getInstantiatedFromMemberTemplate(); |
3745 | 393k | if (!NewPrimary) |
3746 | 242k | break; |
3747 | 151k | Primary = NewPrimary; |
3748 | 151k | } |
3749 | | |
3750 | 242k | return getDefinitionOrSelf(Primary->getTemplatedDecl()); |
3751 | 242k | } |
3752 | | |
3753 | 0 | return nullptr; |
3754 | 0 | } |
3755 | | |
3756 | 53.7M | FunctionTemplateDecl *FunctionDecl::getPrimaryTemplate() const { |
3757 | 53.7M | if (FunctionTemplateSpecializationInfo *Info |
3758 | 2.32M | = TemplateOrSpecialization |
3759 | 2.32M | .dyn_cast<FunctionTemplateSpecializationInfo*>()) { |
3760 | 2.32M | return Info->getTemplate(); |
3761 | 2.32M | } |
3762 | 51.4M | return nullptr; |
3763 | 51.4M | } |
3764 | | |
3765 | | FunctionTemplateSpecializationInfo * |
3766 | 8.06M | FunctionDecl::getTemplateSpecializationInfo() const { |
3767 | 8.06M | return TemplateOrSpecialization |
3768 | 8.06M | .dyn_cast<FunctionTemplateSpecializationInfo *>(); |
3769 | 8.06M | } |
3770 | | |
3771 | | const TemplateArgumentList * |
3772 | 1.14M | FunctionDecl::getTemplateSpecializationArgs() const { |
3773 | 1.14M | if (FunctionTemplateSpecializationInfo *Info |
3774 | 642k | = TemplateOrSpecialization |
3775 | 642k | .dyn_cast<FunctionTemplateSpecializationInfo*>()) { |
3776 | 642k | return Info->TemplateArguments; |
3777 | 642k | } |
3778 | 505k | return nullptr; |
3779 | 505k | } |
3780 | | |
3781 | | const ASTTemplateArgumentListInfo * |
3782 | 1.06M | FunctionDecl::getTemplateSpecializationArgsAsWritten() const { |
3783 | 1.06M | if (FunctionTemplateSpecializationInfo *Info |
3784 | 629 | = TemplateOrSpecialization |
3785 | 629 | .dyn_cast<FunctionTemplateSpecializationInfo*>()) { |
3786 | 629 | return Info->TemplateArgumentsAsWritten; |
3787 | 629 | } |
3788 | 1.06M | return nullptr; |
3789 | 1.06M | } |
3790 | | |
3791 | | void |
3792 | | FunctionDecl::setFunctionTemplateSpecialization(ASTContext &C, |
3793 | | FunctionTemplateDecl *Template, |
3794 | | const TemplateArgumentList *TemplateArgs, |
3795 | | void *InsertPos, |
3796 | | TemplateSpecializationKind TSK, |
3797 | | const TemplateArgumentListInfo *TemplateArgsAsWritten, |
3798 | 216k | SourceLocation PointOfInstantiation) { |
3799 | 216k | assert((TemplateOrSpecialization.isNull() || |
3800 | 216k | TemplateOrSpecialization.is<MemberSpecializationInfo *>()) && |
3801 | 216k | "Member function is already a specialization"); |
3802 | 216k | assert(TSK != TSK_Undeclared && |
3803 | 216k | "Must specify the type of function template specialization"); |
3804 | 216k | assert((TemplateOrSpecialization.isNull() || |
3805 | 216k | TSK == TSK_ExplicitSpecialization) && |
3806 | 216k | "Member specialization must be an explicit specialization"); |
3807 | 216k | FunctionTemplateSpecializationInfo *Info = |
3808 | 216k | FunctionTemplateSpecializationInfo::Create( |
3809 | 216k | C, this, Template, TSK, TemplateArgs, TemplateArgsAsWritten, |
3810 | 216k | PointOfInstantiation, |
3811 | 216k | TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo *>()); |
3812 | 216k | TemplateOrSpecialization = Info; |
3813 | 216k | Template->addSpecialization(Info, InsertPos); |
3814 | 216k | } |
3815 | | |
3816 | | void |
3817 | | FunctionDecl::setDependentTemplateSpecialization(ASTContext &Context, |
3818 | | const UnresolvedSetImpl &Templates, |
3819 | 2.13k | const TemplateArgumentListInfo &TemplateArgs) { |
3820 | 2.13k | assert(TemplateOrSpecialization.isNull()); |
3821 | 2.13k | DependentFunctionTemplateSpecializationInfo *Info = |
3822 | 2.13k | DependentFunctionTemplateSpecializationInfo::Create(Context, Templates, |
3823 | 2.13k | TemplateArgs); |
3824 | 2.13k | TemplateOrSpecialization = Info; |
3825 | 2.13k | } |
3826 | | |
3827 | | DependentFunctionTemplateSpecializationInfo * |
3828 | 1.06M | FunctionDecl::getDependentSpecializationInfo() const { |
3829 | 1.06M | return TemplateOrSpecialization |
3830 | 1.06M | .dyn_cast<DependentFunctionTemplateSpecializationInfo *>(); |
3831 | 1.06M | } |
3832 | | |
3833 | | DependentFunctionTemplateSpecializationInfo * |
3834 | | DependentFunctionTemplateSpecializationInfo::Create( |
3835 | | ASTContext &Context, const UnresolvedSetImpl &Ts, |
3836 | 2.13k | const TemplateArgumentListInfo &TArgs) { |
3837 | 2.13k | void *Buffer = Context.Allocate( |
3838 | 2.13k | totalSizeToAlloc<TemplateArgumentLoc, FunctionTemplateDecl *>( |
3839 | 2.13k | TArgs.size(), Ts.size())); |
3840 | 2.13k | return new (Buffer) DependentFunctionTemplateSpecializationInfo(Ts, TArgs); |
3841 | 2.13k | } |
3842 | | |
3843 | | DependentFunctionTemplateSpecializationInfo:: |
3844 | | DependentFunctionTemplateSpecializationInfo(const UnresolvedSetImpl &Ts, |
3845 | | const TemplateArgumentListInfo &TArgs) |
3846 | 2.13k | : AngleLocs(TArgs.getLAngleLoc(), TArgs.getRAngleLoc()) { |
3847 | 2.13k | NumTemplates = Ts.size(); |
3848 | 2.13k | NumArgs = TArgs.size(); |
3849 | | |
3850 | 2.13k | FunctionTemplateDecl **TsArray = getTrailingObjects<FunctionTemplateDecl *>(); |
3851 | 19.0k | for (unsigned I = 0, E = Ts.size(); I != E; ++I16.9k ) |
3852 | 16.9k | TsArray[I] = cast<FunctionTemplateDecl>(Ts[I]->getUnderlyingDecl()); |
3853 | | |
3854 | 2.13k | TemplateArgumentLoc *ArgsArray = getTrailingObjects<TemplateArgumentLoc>(); |
3855 | 2.14k | for (unsigned I = 0, E = TArgs.size(); I != E; ++I9 ) |
3856 | 9 | new (&ArgsArray[I]) TemplateArgumentLoc(TArgs[I]); |
3857 | 2.13k | } |
3858 | | |
3859 | 39.2M | TemplateSpecializationKind FunctionDecl::getTemplateSpecializationKind() const { |
3860 | | // For a function template specialization, query the specialization |
3861 | | // information object. |
3862 | 39.2M | if (FunctionTemplateSpecializationInfo *FTSInfo = |
3863 | 1.11M | TemplateOrSpecialization |
3864 | 1.11M | .dyn_cast<FunctionTemplateSpecializationInfo *>()) |
3865 | 1.11M | return FTSInfo->getTemplateSpecializationKind(); |
3866 | | |
3867 | 38.0M | if (MemberSpecializationInfo *MSInfo = |
3868 | 935k | TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo *>()) |
3869 | 935k | return MSInfo->getTemplateSpecializationKind(); |
3870 | | |
3871 | 37.1M | return TSK_Undeclared; |
3872 | 37.1M | } |
3873 | | |
3874 | | TemplateSpecializationKind |
3875 | 4.00M | FunctionDecl::getTemplateSpecializationKindForInstantiation() const { |
3876 | | // This is the same as getTemplateSpecializationKind(), except that for a |
3877 | | // function that is both a function template specialization and a member |
3878 | | // specialization, we prefer the member specialization information. Eg: |
3879 | | // |
3880 | | // template<typename T> struct A { |
3881 | | // template<typename U> void f() {} |
3882 | | // template<> void f<int>() {} |
3883 | | // }; |
3884 | | // |
3885 | | // For A<int>::f<int>(): |
3886 | | // * getTemplateSpecializationKind() will return TSK_ExplicitSpecialization |
3887 | | // * getTemplateSpecializationKindForInstantiation() will return |
3888 | | // TSK_ImplicitInstantiation |
3889 | | // |
3890 | | // This reflects the facts that A<int>::f<int> is an explicit specialization |
3891 | | // of A<int>::f, and that A<int>::f<int> should be implicitly instantiated |
3892 | | // from A::f<int> if a definition is needed. |
3893 | 4.00M | if (FunctionTemplateSpecializationInfo *FTSInfo = |
3894 | 492k | TemplateOrSpecialization |
3895 | 492k | .dyn_cast<FunctionTemplateSpecializationInfo *>()) { |
3896 | 492k | if (auto *MSInfo = FTSInfo->getMemberSpecializationInfo()) |
3897 | 296 | return MSInfo->getTemplateSpecializationKind(); |
3898 | 492k | return FTSInfo->getTemplateSpecializationKind(); |
3899 | 492k | } |
3900 | | |
3901 | 3.51M | if (MemberSpecializationInfo *MSInfo = |
3902 | 522k | TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo *>()) |
3903 | 522k | return MSInfo->getTemplateSpecializationKind(); |
3904 | | |
3905 | 2.98M | return TSK_Undeclared; |
3906 | 2.98M | } |
3907 | | |
3908 | | void |
3909 | | FunctionDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK, |
3910 | 165k | SourceLocation PointOfInstantiation) { |
3911 | 165k | if (FunctionTemplateSpecializationInfo *FTSInfo |
3912 | 101k | = TemplateOrSpecialization.dyn_cast< |
3913 | 101k | FunctionTemplateSpecializationInfo*>()) { |
3914 | 101k | FTSInfo->setTemplateSpecializationKind(TSK); |
3915 | 101k | if (TSK != TSK_ExplicitSpecialization && |
3916 | 101k | PointOfInstantiation.isValid() && |
3917 | 101k | FTSInfo->getPointOfInstantiation().isInvalid()) { |
3918 | 101k | FTSInfo->setPointOfInstantiation(PointOfInstantiation); |
3919 | 101k | if (ASTMutationListener *L = getASTContext().getASTMutationListener()) |
3920 | 4.47k | L->InstantiationRequested(this); |
3921 | 101k | } |
3922 | 63.4k | } else if (MemberSpecializationInfo *MSInfo |
3923 | 63.4k | = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>()) { |
3924 | 63.4k | MSInfo->setTemplateSpecializationKind(TSK); |
3925 | 63.4k | if (TSK != TSK_ExplicitSpecialization && |
3926 | 60.8k | PointOfInstantiation.isValid() && |
3927 | 60.8k | MSInfo->getPointOfInstantiation().isInvalid()) { |
3928 | 60.5k | MSInfo->setPointOfInstantiation(PointOfInstantiation); |
3929 | 60.5k | if (ASTMutationListener *L = getASTContext().getASTMutationListener()) |
3930 | 5.08k | L->InstantiationRequested(this); |
3931 | 60.5k | } |
3932 | 63.4k | } else |
3933 | 0 | llvm_unreachable("Function cannot have a template specialization kind"); |
3934 | 165k | } |
3935 | | |
3936 | 260k | SourceLocation FunctionDecl::getPointOfInstantiation() const { |
3937 | 260k | if (FunctionTemplateSpecializationInfo *FTSInfo |
3938 | 113k | = TemplateOrSpecialization.dyn_cast< |
3939 | 113k | FunctionTemplateSpecializationInfo*>()) |
3940 | 113k | return FTSInfo->getPointOfInstantiation(); |
3941 | 146k | else if (MemberSpecializationInfo *MSInfo |
3942 | 146k | = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>()) |
3943 | 146k | return MSInfo->getPointOfInstantiation(); |
3944 | | |
3945 | 0 | return SourceLocation(); |
3946 | 0 | } |
3947 | | |
3948 | 5.87M | bool FunctionDecl::isOutOfLine() const { |
3949 | 5.87M | if (Decl::isOutOfLine()) |
3950 | 394k | return true; |
3951 | | |
3952 | | // If this function was instantiated from a member function of a |
3953 | | // class template, check whether that member function was defined out-of-line. |
3954 | 5.48M | if (FunctionDecl *FD = getInstantiatedFromMemberFunction()) { |
3955 | 354k | const FunctionDecl *Definition; |
3956 | 354k | if (FD->hasBody(Definition)) |
3957 | 351k | return Definition->isOutOfLine(); |
3958 | 5.13M | } |
3959 | | |
3960 | | // If this function was instantiated from a function template, |
3961 | | // check whether that function template was defined out-of-line. |
3962 | 5.13M | if (FunctionTemplateDecl *FunTmpl = getPrimaryTemplate()) { |
3963 | 127k | const FunctionDecl *Definition; |
3964 | 127k | if (FunTmpl->getTemplatedDecl()->hasBody(Definition)) |
3965 | 17.1k | return Definition->isOutOfLine(); |
3966 | 5.11M | } |
3967 | | |
3968 | 5.11M | return false; |
3969 | 5.11M | } |
3970 | | |
3971 | 4.77M | SourceRange FunctionDecl::getSourceRange() const { |
3972 | 4.77M | return SourceRange(getOuterLocStart(), EndRangeLoc); |
3973 | 4.77M | } |
3974 | | |
3975 | 3.06M | unsigned FunctionDecl::getMemoryFunctionKind() const { |
3976 | 3.06M | IdentifierInfo *FnInfo = getIdentifier(); |
3977 | | |
3978 | 3.06M | if (!FnInfo) |
3979 | 0 | return 0; |
3980 | | |
3981 | | // Builtin handling. |
3982 | 3.06M | switch (getBuiltinID()) { |
3983 | 103 | case Builtin::BI__builtin_memset: |
3984 | 129 | case Builtin::BI__builtin___memset_chk: |
3985 | 346 | case Builtin::BImemset: |
3986 | 346 | return Builtin::BImemset; |
3987 | | |
3988 | 259 | case Builtin::BI__builtin_memcpy: |
3989 | 298 | case Builtin::BI__builtin___memcpy_chk: |
3990 | 480 | case Builtin::BImemcpy: |
3991 | 480 | return Builtin::BImemcpy; |
3992 | | |
3993 | 22 | case Builtin::BI__builtin_mempcpy: |
3994 | 46 | case Builtin::BI__builtin___mempcpy_chk: |
3995 | 68 | case Builtin::BImempcpy: |
3996 | 68 | return Builtin::BImempcpy; |
3997 | | |
3998 | 71 | case Builtin::BI__builtin_memmove: |
3999 | 84 | case Builtin::BI__builtin___memmove_chk: |
4000 | 203 | case Builtin::BImemmove: |
4001 | 203 | return Builtin::BImemmove; |
4002 | | |
4003 | 87 | case Builtin::BIstrlcpy: |
4004 | 102 | case Builtin::BI__builtin___strlcpy_chk: |
4005 | 102 | return Builtin::BIstrlcpy; |
4006 | | |
4007 | 46 | case Builtin::BIstrlcat: |
4008 | 49 | case Builtin::BI__builtin___strlcat_chk: |
4009 | 49 | return Builtin::BIstrlcat; |
4010 | | |
4011 | 708 | case Builtin::BI__builtin_memcmp: |
4012 | 753 | case Builtin::BImemcmp: |
4013 | 753 | return Builtin::BImemcmp; |
4014 | | |
4015 | 284 | case Builtin::BI__builtin_bcmp: |
4016 | 306 | case Builtin::BIbcmp: |
4017 | 306 | return Builtin::BIbcmp; |
4018 | | |
4019 | 27 | case Builtin::BI__builtin_strncpy: |
4020 | 71 | case Builtin::BI__builtin___strncpy_chk: |
4021 | 116 | case Builtin::BIstrncpy: |
4022 | 116 | return Builtin::BIstrncpy; |
4023 | | |
4024 | 188 | case Builtin::BI__builtin_strncmp: |
4025 | 272 | case Builtin::BIstrncmp: |
4026 | 272 | return Builtin::BIstrncmp; |
4027 | | |
4028 | 92 | case Builtin::BI__builtin_strncasecmp: |
4029 | 164 | case Builtin::BIstrncasecmp: |
4030 | 164 | return Builtin::BIstrncasecmp; |
4031 | | |
4032 | 56 | case Builtin::BI__builtin_strncat: |
4033 | 114 | case Builtin::BI__builtin___strncat_chk: |
4034 | 212 | case Builtin::BIstrncat: |
4035 | 212 | return Builtin::BIstrncat; |
4036 | | |
4037 | 0 | case Builtin::BI__builtin_strndup: |
4038 | 16 | case Builtin::BIstrndup: |
4039 | 16 | return Builtin::BIstrndup; |
4040 | |
|
4041 | 760 | case Builtin::BI__builtin_strlen: |
4042 | 1.20k | case Builtin::BIstrlen: |
4043 | 1.20k | return Builtin::BIstrlen; |
4044 | | |
4045 | 17 | case Builtin::BI__builtin_bzero: |
4046 | 49 | case Builtin::BIbzero: |
4047 | 49 | return Builtin::BIbzero; |
4048 | | |
4049 | 445 | case Builtin::BIfree: |
4050 | 445 | return Builtin::BIfree; |
4051 | | |
4052 | 3.06M | default: |
4053 | 3.06M | if (isExternC()) { |
4054 | 1.57M | if (FnInfo->isStr("memset")) |
4055 | 352 | return Builtin::BImemset; |
4056 | 1.57M | else if (FnInfo->isStr("memcpy")) |
4057 | 1.24k | return Builtin::BImemcpy; |
4058 | 1.57M | else if (FnInfo->isStr("mempcpy")) |
4059 | 0 | return Builtin::BImempcpy; |
4060 | 1.57M | else if (FnInfo->isStr("memmove")) |
4061 | 1.60k | return Builtin::BImemmove; |
4062 | 1.57M | else if (FnInfo->isStr("memcmp")) |
4063 | 395 | return Builtin::BImemcmp; |
4064 | 1.57M | else if (FnInfo->isStr("bcmp")) |
4065 | 2 | return Builtin::BIbcmp; |
4066 | 1.57M | else if (FnInfo->isStr("strncpy")) |
4067 | 69 | return Builtin::BIstrncpy; |
4068 | 1.57M | else if (FnInfo->isStr("strncmp")) |
4069 | 6 | return Builtin::BIstrncmp; |
4070 | 1.57M | else if (FnInfo->isStr("strncasecmp")) |
4071 | 1 | return Builtin::BIstrncasecmp; |
4072 | 1.57M | else if (FnInfo->isStr("strncat")) |
4073 | 3 | return Builtin::BIstrncat; |
4074 | 1.57M | else if (FnInfo->isStr("strndup")) |
4075 | 1 | return Builtin::BIstrndup; |
4076 | 1.57M | else if (FnInfo->isStr("strlen")) |
4077 | 1.10k | return Builtin::BIstrlen; |
4078 | 1.57M | else if (FnInfo->isStr("bzero")) |
4079 | 26 | return Builtin::BIbzero; |
4080 | 1.48M | } else if (isInStdNamespace()) { |
4081 | 163k | if (FnInfo->isStr("free")) |
4082 | 54 | return Builtin::BIfree; |
4083 | 3.05M | } |
4084 | 3.05M | break; |
4085 | 3.05M | } |
4086 | 3.05M | return 0; |
4087 | 3.05M | } |
4088 | | |
4089 | 53.6k | unsigned FunctionDecl::getODRHash() const { |
4090 | 53.6k | assert(hasODRHash()); |
4091 | 53.6k | return ODRHash; |
4092 | 53.6k | } |
4093 | | |
4094 | 599k | unsigned FunctionDecl::getODRHash() { |
4095 | 599k | if (hasODRHash()) |
4096 | 110k | return ODRHash; |
4097 | | |
4098 | 489k | if (auto *FT = getInstantiatedFromMemberFunction()) { |
4099 | 46.9k | setHasODRHash(true); |
4100 | 46.9k | ODRHash = FT->getODRHash(); |
4101 | 46.9k | return ODRHash; |
4102 | 46.9k | } |
4103 | | |
4104 | 442k | class ODRHash Hash; |
4105 | 442k | Hash.AddFunctionDecl(this); |
4106 | 442k | setHasODRHash(true); |
4107 | 442k | ODRHash = Hash.CalculateHash(); |
4108 | 442k | return ODRHash; |
4109 | 442k | } |
4110 | | |
4111 | | //===----------------------------------------------------------------------===// |
4112 | | // FieldDecl Implementation |
4113 | | //===----------------------------------------------------------------------===// |
4114 | | |
4115 | | FieldDecl *FieldDecl::Create(const ASTContext &C, DeclContext *DC, |
4116 | | SourceLocation StartLoc, SourceLocation IdLoc, |
4117 | | IdentifierInfo *Id, QualType T, |
4118 | | TypeSourceInfo *TInfo, Expr *BW, bool Mutable, |
4119 | 4.46M | InClassInitStyle InitStyle) { |
4120 | 4.46M | return new (C, DC) FieldDecl(Decl::Field, DC, StartLoc, IdLoc, Id, T, TInfo, |
4121 | 4.46M | BW, Mutable, InitStyle); |
4122 | 4.46M | } |
4123 | | |
4124 | 65.9k | FieldDecl *FieldDecl::CreateDeserialized(ASTContext &C, unsigned ID) { |
4125 | 65.9k | return new (C, ID) FieldDecl(Field, nullptr, SourceLocation(), |
4126 | 65.9k | SourceLocation(), nullptr, QualType(), nullptr, |
4127 | 65.9k | nullptr, false, ICIS_NoInit); |
4128 | 65.9k | } |
4129 | | |
4130 | 6.32M | bool FieldDecl::isAnonymousStructOrUnion() const { |
4131 | 6.32M | if (!isImplicit() || getDeclName()401k ) |
4132 | 5.92M | return false; |
4133 | | |
4134 | 401k | if (const auto *Record = getType()->getAs<RecordType>()) |
4135 | 22.4k | return Record->getDecl()->isAnonymousStructOrUnion(); |
4136 | | |
4137 | 378k | return false; |
4138 | 378k | } |
4139 | | |
4140 | 42.4k | unsigned FieldDecl::getBitWidthValue(const ASTContext &Ctx) const { |
4141 | 42.4k | assert(isBitField() && "not a bitfield"); |
4142 | 42.4k | return getBitWidth()->EvaluateKnownConstInt(Ctx).getZExtValue(); |
4143 | 42.4k | } |
4144 | | |
4145 | 2.53M | bool FieldDecl::isZeroLengthBitField(const ASTContext &Ctx) const { |
4146 | 2.53M | return isUnnamedBitfield() && !getBitWidth()->isValueDependent()2.52k && |
4147 | 2.52k | getBitWidthValue(Ctx) == 0; |
4148 | 2.53M | } |
4149 | | |
4150 | 2.48M | bool FieldDecl::isZeroSize(const ASTContext &Ctx) const { |
4151 | 2.48M | if (isZeroLengthBitField(Ctx)) |
4152 | 316 | return true; |
4153 | | |
4154 | | // C++2a [intro.object]p7: |
4155 | | // An object has nonzero size if it |
4156 | | // -- is not a potentially-overlapping subobject, or |
4157 | 2.48M | if (!hasAttr<NoUniqueAddressAttr>()) |
4158 | 2.48M | return false; |
4159 | | |
4160 | | // -- is not of class type, or |
4161 | 421 | const auto *RT = getType()->getAs<RecordType>(); |
4162 | 421 | if (!RT) |
4163 | 29 | return false; |
4164 | 392 | const RecordDecl *RD = RT->getDecl()->getDefinition(); |
4165 | 392 | if (!RD) { |
4166 | 0 | assert(isInvalidDecl() && "valid field has incomplete type"); |
4167 | 0 | return false; |
4168 | 0 | } |
4169 | | |
4170 | | // -- [has] virtual member functions or virtual base classes, or |
4171 | | // -- has subobjects of nonzero size or bit-fields of nonzero length |
4172 | 392 | const auto *CXXRD = cast<CXXRecordDecl>(RD); |
4173 | 392 | if (!CXXRD->isEmpty()) |
4174 | 64 | return false; |
4175 | | |
4176 | | // Otherwise, [...] the circumstances under which the object has zero size |
4177 | | // are implementation-defined. |
4178 | | // FIXME: This might be Itanium ABI specific; we don't yet know what the MS |
4179 | | // ABI will do. |
4180 | 328 | return true; |
4181 | 328 | } |
4182 | | |
4183 | 520k | unsigned FieldDecl::getFieldIndex() const { |
4184 | 520k | const FieldDecl *Canonical = getCanonicalDecl(); |
4185 | 520k | if (Canonical != this) |
4186 | 32 | return Canonical->getFieldIndex(); |
4187 | | |
4188 | 520k | if (CachedFieldIndex) return CachedFieldIndex - 1423k ; |
4189 | | |
4190 | 96.9k | unsigned Index = 0; |
4191 | 96.9k | const RecordDecl *RD = getParent()->getDefinition(); |
4192 | 96.9k | assert(RD && "requested index for field of struct with no definition"); |
4193 | | |
4194 | 233k | for (auto *Field : RD->fields()) { |
4195 | 233k | Field->getCanonicalDecl()->CachedFieldIndex = Index + 1; |
4196 | 233k | ++Index; |
4197 | 233k | } |
4198 | | |
4199 | 96.9k | assert(CachedFieldIndex && "failed to find field in parent"); |
4200 | 96.9k | return CachedFieldIndex - 1; |
4201 | 96.9k | } |
4202 | | |
4203 | 4.22k | SourceRange FieldDecl::getSourceRange() const { |
4204 | 4.22k | const Expr *FinalExpr = getInClassInitializer(); |
4205 | 4.22k | if (!FinalExpr) |
4206 | 4.09k | FinalExpr = getBitWidth(); |
4207 | 4.22k | if (FinalExpr) |
4208 | 314 | return SourceRange(getInnerLocStart(), FinalExpr->getEndLoc()); |
4209 | 3.90k | return DeclaratorDecl::getSourceRange(); |
4210 | 3.90k | } |
4211 | | |
4212 | 8.82k | void FieldDecl::setCapturedVLAType(const VariableArrayType *VLAType) { |
4213 | 8.82k | assert((getParent()->isLambda() || getParent()->isCapturedRecord()) && |
4214 | 8.82k | "capturing type in non-lambda or captured record."); |
4215 | 8.82k | assert(InitStorage.getInt() == ISK_NoInit && |
4216 | 8.82k | InitStorage.getPointer() == nullptr && |
4217 | 8.82k | "bit width, initializer or captured type already set"); |
4218 | 8.82k | InitStorage.setPointerAndInt(const_cast<VariableArrayType *>(VLAType), |
4219 | 8.82k | ISK_CapturedVLAType); |
4220 | 8.82k | } |
4221 | | |
4222 | | //===----------------------------------------------------------------------===// |
4223 | | // TagDecl Implementation |
4224 | | //===----------------------------------------------------------------------===// |
4225 | | |
4226 | | TagDecl::TagDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC, |
4227 | | SourceLocation L, IdentifierInfo *Id, TagDecl *PrevDecl, |
4228 | | SourceLocation StartL) |
4229 | | : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), redeclarable_base(C), |
4230 | 7.24M | TypedefNameDeclOrQualifier((TypedefNameDecl *)nullptr) { |
4231 | 7.24M | assert((DK != Enum || TK == TTK_Enum) && |
4232 | 7.24M | "EnumDecl not matched with TTK_Enum"); |
4233 | 7.24M | setPreviousDecl(PrevDecl); |
4234 | 7.24M | setTagKind(TK); |
4235 | 7.24M | setCompleteDefinition(false); |
4236 | 7.24M | setBeingDefined(false); |
4237 | 7.24M | setEmbeddedInDeclarator(false); |
4238 | 7.24M | setFreeStanding(false); |
4239 | 7.24M | setCompleteDefinitionRequired(false); |
4240 | 7.24M | } |
4241 | | |
4242 | 353k | SourceLocation TagDecl::getOuterLocStart() const { |
4243 | 353k | return getTemplateOrInnerLocStart(this); |
4244 | 353k | } |
4245 | | |
4246 | 353k | SourceRange TagDecl::getSourceRange() const { |
4247 | 353k | SourceLocation RBraceLoc = BraceRange.getEnd(); |
4248 | 242k | SourceLocation E = RBraceLoc.isValid() ? RBraceLoc : getLocation()110k ; |
4249 | 353k | return SourceRange(getOuterLocStart(), E); |
4250 | 353k | } |
4251 | | |
4252 | 42.4M | TagDecl *TagDecl::getCanonicalDecl() { return getFirstDecl(); } |
4253 | | |
4254 | 202k | void TagDecl::setTypedefNameForAnonDecl(TypedefNameDecl *TDD) { |
4255 | 202k | TypedefNameDeclOrQualifier = TDD; |
4256 | 202k | if (const Type *T = getTypeForDecl()) { |
4257 | 202k | (void)T; |
4258 | 202k | assert(T->isLinkageValid()); |
4259 | 202k | } |
4260 | 202k | assert(isLinkageValid()); |
4261 | 202k | } |
4262 | | |
4263 | 3.25M | void TagDecl::startDefinition() { |
4264 | 3.25M | setBeingDefined(true); |
4265 | | |
4266 | 3.25M | if (auto *D = dyn_cast<CXXRecordDecl>(this)) { |
4267 | 2.08M | struct CXXRecordDecl::DefinitionData *Data = |
4268 | 2.08M | new (getASTContext()) struct CXXRecordDecl::DefinitionData(D); |
4269 | 2.08M | for (auto I : redecls()) |
4270 | 2.11M | cast<CXXRecordDecl>(I)->DefinitionData = Data; |
4271 | 2.08M | } |
4272 | 3.25M | } |
4273 | | |
4274 | 3.28M | void TagDecl::completeDefinition() { |
4275 | 3.28M | assert((!isa<CXXRecordDecl>(this) || |
4276 | 3.28M | cast<CXXRecordDecl>(this)->hasDefinition()) && |
4277 | 3.28M | "definition completed but not started"); |
4278 | | |
4279 | 3.28M | setCompleteDefinition(true); |
4280 | 3.28M | setBeingDefined(false); |
4281 | | |
4282 | 3.28M | if (ASTMutationListener *L = getASTMutationListener()) |
4283 | 157k | L->CompletedTagDefinition(this); |
4284 | 3.28M | } |
4285 | | |
4286 | 244M | TagDecl *TagDecl::getDefinition() const { |
4287 | 244M | if (isCompleteDefinition()) |
4288 | 162M | return const_cast<TagDecl *>(this); |
4289 | | |
4290 | | // If it's possible for us to have an out-of-date definition, check now. |
4291 | 81.7M | if (mayHaveOutOfDateDef()) { |
4292 | 4.09M | if (IdentifierInfo *II = getIdentifier()) { |
4293 | 3.24M | if (II->isOutOfDate()) { |
4294 | 0 | updateOutOfDate(*II); |
4295 | 0 | } |
4296 | 3.24M | } |
4297 | 4.09M | } |
4298 | | |
4299 | 81.7M | if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(this)) |
4300 | 65.0M | return CXXRD->getDefinition(); |
4301 | | |
4302 | 16.6M | for (auto R : redecls()) |
4303 | 18.2M | if (R->isCompleteDefinition()) |
4304 | 10.0k | return R; |
4305 | | |
4306 | 16.6M | return nullptr; |
4307 | 16.6M | } |
4308 | | |
4309 | 141k | void TagDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) { |
4310 | 141k | if (QualifierLoc) { |
4311 | | // Make sure the extended qualifier info is allocated. |
4312 | 1.77k | if (!hasExtInfo()) |
4313 | 1.77k | TypedefNameDeclOrQualifier = new (getASTContext()) ExtInfo; |
4314 | | // Set qualifier info. |
4315 | 1.77k | getExtInfo()->QualifierLoc = QualifierLoc; |
4316 | 139k | } else { |
4317 | | // Here Qualifier == 0, i.e., we are removing the qualifier (if any). |
4318 | 139k | if (hasExtInfo()) { |
4319 | 0 | if (getExtInfo()->NumTemplParamLists == 0) { |
4320 | 0 | getASTContext().Deallocate(getExtInfo()); |
4321 | 0 | TypedefNameDeclOrQualifier = (TypedefNameDecl *)nullptr; |
4322 | 0 | } |
4323 | 0 | else |
4324 | 0 | getExtInfo()->QualifierLoc = QualifierLoc; |
4325 | 0 | } |
4326 | 139k | } |
4327 | 141k | } |
4328 | | |
4329 | | void TagDecl::setTemplateParameterListsInfo( |
4330 | 51.0k | ASTContext &Context, ArrayRef<TemplateParameterList *> TPLists) { |
4331 | 51.0k | assert(!TPLists.empty()); |
4332 | | // Make sure the extended decl info is allocated. |
4333 | 51.0k | if (!hasExtInfo()) |
4334 | | // Allocate external info struct. |
4335 | 50.3k | TypedefNameDeclOrQualifier = new (getASTContext()) ExtInfo; |
4336 | | // Set the template parameter lists info. |
4337 | 51.0k | getExtInfo()->setTemplateParameterListsInfo(Context, TPLists); |
4338 | 51.0k | } |
4339 | | |
4340 | | //===----------------------------------------------------------------------===// |
4341 | | // EnumDecl Implementation |
4342 | | //===----------------------------------------------------------------------===// |
4343 | | |
4344 | | EnumDecl::EnumDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, |
4345 | | SourceLocation IdLoc, IdentifierInfo *Id, EnumDecl *PrevDecl, |
4346 | | bool Scoped, bool ScopedUsingClassTag, bool Fixed) |
4347 | 703k | : TagDecl(Enum, TTK_Enum, C, DC, IdLoc, Id, PrevDecl, StartLoc) { |
4348 | 703k | assert(Scoped || !ScopedUsingClassTag); |
4349 | 703k | IntegerType = nullptr; |
4350 | 703k | setNumPositiveBits(0); |
4351 | 703k | setNumNegativeBits(0); |
4352 | 703k | setScoped(Scoped); |
4353 | 703k | setScopedUsingClassTag(ScopedUsingClassTag); |
4354 | 703k | setFixed(Fixed); |
4355 | 703k | setHasODRHash(false); |
4356 | 703k | ODRHash = 0; |
4357 | 703k | } |
4358 | | |
4359 | 0 | void EnumDecl::anchor() {} |
4360 | | |
4361 | | EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, |
4362 | | SourceLocation StartLoc, SourceLocation IdLoc, |
4363 | | IdentifierInfo *Id, |
4364 | | EnumDecl *PrevDecl, bool IsScoped, |
4365 | 699k | bool IsScopedUsingClassTag, bool IsFixed) { |
4366 | 699k | auto *Enum = new (C, DC) EnumDecl(C, DC, StartLoc, IdLoc, Id, PrevDecl, |
4367 | 699k | IsScoped, IsScopedUsingClassTag, IsFixed); |
4368 | 699k | Enum->setMayHaveOutOfDateDef(C.getLangOpts().Modules); |
4369 | 699k | C.getTypeDeclType(Enum, PrevDecl); |
4370 | 699k | return Enum; |
4371 | 699k | } |
4372 | | |
4373 | 4.42k | EnumDecl *EnumDecl::CreateDeserialized(ASTContext &C, unsigned ID) { |
4374 | 4.42k | EnumDecl *Enum = |
4375 | 4.42k | new (C, ID) EnumDecl(C, nullptr, SourceLocation(), SourceLocation(), |
4376 | 4.42k | nullptr, nullptr, false, false, false); |
4377 | 4.42k | Enum->setMayHaveOutOfDateDef(C.getLangOpts().Modules); |
4378 | 4.42k | return Enum; |
4379 | 4.42k | } |
4380 | | |
4381 | 30 | SourceRange EnumDecl::getIntegerTypeRange() const { |
4382 | 30 | if (const TypeSourceInfo *TI = getIntegerTypeSourceInfo()) |
4383 | 23 | return TI->getTypeLoc().getSourceRange(); |
4384 | 7 | return SourceRange(); |
4385 | 7 | } |
4386 | | |
4387 | | void EnumDecl::completeDefinition(QualType NewType, |
4388 | | QualType NewPromotionType, |
4389 | | unsigned NumPositiveBits, |
4390 | 606k | unsigned NumNegativeBits) { |
4391 | 606k | assert(!isCompleteDefinition() && "Cannot redefine enums!"); |
4392 | 606k | if (!IntegerType) |
4393 | 470k | IntegerType = NewType.getTypePtr(); |
4394 | 606k | PromotionType = NewPromotionType; |
4395 | 606k | setNumPositiveBits(NumPositiveBits); |
4396 | 606k | setNumNegativeBits(NumNegativeBits); |
4397 | 606k | TagDecl::completeDefinition(); |
4398 | 606k | } |
4399 | | |
4400 | 604k | bool EnumDecl::isClosed() const { |
4401 | 604k | if (const auto *A = getAttr<EnumExtensibilityAttr>()) |
4402 | 129k | return A->getExtensibility() == EnumExtensibilityAttr::Closed; |
4403 | 474k | return true; |
4404 | 474k | } |
4405 | | |
4406 | 602k | bool EnumDecl::isClosedFlag() const { |
4407 | 602k | return isClosed() && hasAttr<FlagEnumAttr>()474k ; |
4408 | 602k | } |
4409 | | |
4410 | 74 | bool EnumDecl::isClosedNonFlag() const { |
4411 | 74 | return isClosed() && !hasAttr<FlagEnumAttr>()70 ; |
4412 | 74 | } |
4413 | | |
4414 | 781k | TemplateSpecializationKind EnumDecl::getTemplateSpecializationKind() const { |
4415 | 781k | if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo()) |
4416 | 166 | return MSI->getTemplateSpecializationKind(); |
4417 | | |
4418 | 781k | return TSK_Undeclared; |
4419 | 781k | } |
4420 | | |
4421 | | void EnumDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK, |
4422 | 32 | SourceLocation PointOfInstantiation) { |
4423 | 32 | MemberSpecializationInfo *MSI = getMemberSpecializationInfo(); |
4424 | 32 | assert(MSI && "Not an instantiated member enumeration?"); |
4425 | 32 | MSI->setTemplateSpecializationKind(TSK); |
4426 | 32 | if (TSK != TSK_ExplicitSpecialization && |
4427 | 0 | PointOfInstantiation.isValid() && |
4428 | 0 | MSI->getPointOfInstantiation().isInvalid()) |
4429 | 0 | MSI->setPointOfInstantiation(PointOfInstantiation); |
4430 | 32 | } |
4431 | | |
4432 | 817k | EnumDecl *EnumDecl::getTemplateInstantiationPattern() const { |
4433 | 817k | if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) { |
4434 | 36.3k | if (isTemplateInstantiation(MSInfo->getTemplateSpecializationKind())) { |
4435 | 36.1k | EnumDecl *ED = getInstantiatedFromMemberEnum(); |
4436 | 36.1k | while (auto *NewED = ED->getInstantiatedFromMemberEnum()) |
4437 | 0 | ED = NewED; |
4438 | 36.1k | return getDefinitionOrSelf(ED); |
4439 | 36.1k | } |
4440 | 781k | } |
4441 | | |
4442 | 781k | assert(!isTemplateInstantiation(getTemplateSpecializationKind()) && |
4443 | 781k | "couldn't find pattern for enum instantiation"); |
4444 | 781k | return nullptr; |
4445 | 781k | } |
4446 | | |
4447 | 82.3k | EnumDecl *EnumDecl::getInstantiatedFromMemberEnum() const { |
4448 | 82.3k | if (SpecializationInfo) |
4449 | 42.8k | return cast<EnumDecl>(SpecializationInfo->getInstantiatedFrom()); |
4450 | | |
4451 | 39.4k | return nullptr; |
4452 | 39.4k | } |
4453 | | |
4454 | | void EnumDecl::setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED, |
4455 | 3.67k | TemplateSpecializationKind TSK) { |
4456 | 3.67k | assert(!SpecializationInfo && "Member enum is already a specialization"); |
4457 | 3.67k | SpecializationInfo = new (C) MemberSpecializationInfo(ED, TSK); |
4458 | 3.67k | } |
4459 | | |
4460 | 23.4k | unsigned EnumDecl::getODRHash() { |
4461 | 23.4k | if (hasODRHash()) |
4462 | 109 | return ODRHash; |
4463 | | |
4464 | 23.3k | class ODRHash Hash; |
4465 | 23.3k | Hash.AddEnumDecl(this); |
4466 | 23.3k | setHasODRHash(true); |
4467 | 23.3k | ODRHash = Hash.CalculateHash(); |
4468 | 23.3k | return ODRHash; |
4469 | 23.3k | } |
4470 | | |
4471 | | //===----------------------------------------------------------------------===// |
4472 | | // RecordDecl Implementation |
4473 | | //===----------------------------------------------------------------------===// |
4474 | | |
4475 | | RecordDecl::RecordDecl(Kind DK, TagKind TK, const ASTContext &C, |
4476 | | DeclContext *DC, SourceLocation StartLoc, |
4477 | | SourceLocation IdLoc, IdentifierInfo *Id, |
4478 | | RecordDecl *PrevDecl) |
4479 | 6.54M | : TagDecl(DK, TK, C, DC, IdLoc, Id, PrevDecl, StartLoc) { |
4480 | 6.54M | assert(classof(static_cast<Decl *>(this)) && "Invalid Kind!"); |
4481 | 6.54M | setHasFlexibleArrayMember(false); |
4482 | 6.54M | setAnonymousStructOrUnion(false); |
4483 | 6.54M | setHasObjectMember(false); |
4484 | 6.54M | setHasVolatileMember(false); |
4485 | 6.54M | setHasLoadedFieldsFromExternalStorage(false); |
4486 | 6.54M | setNonTrivialToPrimitiveDefaultInitialize(false); |
4487 | 6.54M | setNonTrivialToPrimitiveCopy(false); |
4488 | 6.54M | setNonTrivialToPrimitiveDestroy(false); |
4489 | 6.54M | setHasNonTrivialToPrimitiveDefaultInitializeCUnion(false); |
4490 | 6.54M | setHasNonTrivialToPrimitiveDestructCUnion(false); |
4491 | 6.54M | setHasNonTrivialToPrimitiveCopyCUnion(false); |
4492 | 6.54M | setParamDestroyedInCallee(false); |
4493 | 6.54M | setArgPassingRestrictions(APK_CanPassInRegs); |
4494 | 6.54M | } |
4495 | | |
4496 | | RecordDecl *RecordDecl::Create(const ASTContext &C, TagKind TK, DeclContext *DC, |
4497 | | SourceLocation StartLoc, SourceLocation IdLoc, |
4498 | 660k | IdentifierInfo *Id, RecordDecl* PrevDecl) { |
4499 | 660k | RecordDecl *R = new (C, DC) RecordDecl(Record, TK, C, DC, |
4500 | 660k | StartLoc, IdLoc, Id, PrevDecl); |
4501 | 660k | R->setMayHaveOutOfDateDef(C.getLangOpts().Modules); |
4502 | | |
4503 | 660k | C.getTypeDeclType(R, PrevDecl); |
4504 | 660k | return R; |
4505 | 660k | } |
4506 | | |
4507 | 5.25k | RecordDecl *RecordDecl::CreateDeserialized(const ASTContext &C, unsigned ID) { |
4508 | 5.25k | RecordDecl *R = |
4509 | 5.25k | new (C, ID) RecordDecl(Record, TTK_Struct, C, nullptr, SourceLocation(), |
4510 | 5.25k | SourceLocation(), nullptr, nullptr); |
4511 | 5.25k | R->setMayHaveOutOfDateDef(C.getLangOpts().Modules); |
4512 | 5.25k | return R; |
4513 | 5.25k | } |
4514 | | |
4515 | 5.96M | bool RecordDecl::isInjectedClassName() const { |
4516 | 5.96M | return isImplicit() && getDeclName()3.78M && getDeclContext()->isRecord()3.78M && |
4517 | 3.78M | cast<RecordDecl>(getDeclContext())->getDeclName() == getDeclName(); |
4518 | 5.96M | } |
4519 | | |
4520 | 117k | bool RecordDecl::isLambda() const { |
4521 | 117k | if (auto RD = dyn_cast<CXXRecordDecl>(this)) |
4522 | 116k | return RD->isLambda(); |
4523 | 548 | return false; |
4524 | 548 | } |
4525 | | |
4526 | 8.77k | bool RecordDecl::isCapturedRecord() const { |
4527 | 8.77k | return hasAttr<CapturedRecordAttr>(); |
4528 | 8.77k | } |
4529 | | |
4530 | 555k | void RecordDecl::setCapturedRecord() { |
4531 | 555k | addAttr(CapturedRecordAttr::CreateImplicit(getASTContext())); |
4532 | 555k | } |
4533 | | |
4534 | 147 | bool RecordDecl::isOrContainsUnion() const { |
4535 | 147 | if (isUnion()) |
4536 | 11 | return true; |
4537 | | |
4538 | 136 | if (const RecordDecl *Def = getDefinition()) { |
4539 | 367 | for (const FieldDecl *FD : Def->fields()) { |
4540 | 367 | const RecordType *RT = FD->getType()->getAs<RecordType>(); |
4541 | 367 | if (RT && RT->getDecl()->isOrContainsUnion()16 ) |
4542 | 1 | return true; |
4543 | 367 | } |
4544 | 136 | } |
4545 | | |
4546 | 135 | return false; |
4547 | 136 | } |
4548 | | |
4549 | 7.52M | RecordDecl::field_iterator RecordDecl::field_begin() const { |
4550 | 7.52M | if (hasExternalLexicalStorage() && !hasLoadedFieldsFromExternalStorage()120k ) |
4551 | 22.2k | LoadFieldsFromExternalStorage(); |
4552 | | |
4553 | 7.52M | return field_iterator(decl_iterator(FirstDecl)); |
4554 | 7.52M | } |
4555 | | |
4556 | | /// completeDefinition - Notes that the definition of this type is now |
4557 | | /// complete. |
4558 | 2.67M | void RecordDecl::completeDefinition() { |
4559 | 2.67M | assert(!isCompleteDefinition() && "Cannot redefine record!"); |
4560 | 2.67M | TagDecl::completeDefinition(); |
4561 | 2.67M | } |
4562 | | |
4563 | | /// isMsStruct - Get whether or not this record uses ms_struct layout. |
4564 | | /// This which can be turned on with an attribute, pragma, or the |
4565 | | /// -mms-bitfields command-line option. |
4566 | 1.74M | bool RecordDecl::isMsStruct(const ASTContext &C) const { |
4567 | 1.74M | return hasAttr<MSStructAttr>() || C.getLangOpts().MSBitfields == 11.74M ; |
4568 | 1.74M | } |
4569 | | |
4570 | 22.2k | void RecordDecl::LoadFieldsFromExternalStorage() const { |
4571 | 22.2k | ExternalASTSource *Source = getASTContext().getExternalSource(); |
4572 | 22.2k | assert(hasExternalLexicalStorage() && Source && "No external storage?"); |
4573 | | |
4574 | | // Notify that we have a RecordDecl doing some initialization. |
4575 | 22.2k | ExternalASTSource::Deserializing TheFields(Source); |
4576 | | |
4577 | 22.2k | SmallVector<Decl*, 64> Decls; |
4578 | 22.2k | setHasLoadedFieldsFromExternalStorage(true); |
4579 | 211k | Source->FindExternalLexicalDecls(this, [](Decl::Kind K) { |
4580 | 211k | return FieldDecl::classofKind(K) || IndirectFieldDecl::classofKind(K)180k ; |
4581 | 211k | }, Decls); |
4582 | | |
4583 | 22.2k | #ifndef NDEBUG |
4584 | | // Check that all decls we got were FieldDecls. |
4585 | 49.7k | for (unsigned i=0, e=Decls.size(); i != e; ++i27.5k ) |
4586 | 22.2k | assert(isa<FieldDecl>(Decls[i]) || isa<IndirectFieldDecl>(Decls[i])); |
4587 | 22.2k | #endif |
4588 | | |
4589 | 22.2k | if (Decls.empty()) |
4590 | 11.9k | return; |
4591 | | |
4592 | 10.2k | std::tie(FirstDecl, LastDecl) = BuildDeclChain(Decls, |
4593 | 10.2k | /*FieldsAlreadyLoaded=*/false); |
4594 | 10.2k | } |
4595 | | |
4596 | 369k | bool RecordDecl::mayInsertExtraPadding(bool EmitRemark) const { |
4597 | 369k | ASTContext &Context = getASTContext(); |
4598 | 369k | const SanitizerMask EnabledAsanMask = Context.getLangOpts().Sanitize.Mask & |
4599 | 369k | (SanitizerKind::Address | SanitizerKind::KernelAddress); |
4600 | 369k | if (!EnabledAsanMask || !Context.getLangOpts().SanitizeAddressFieldPadding908 ) |
4601 | 369k | return false; |
4602 | 178 | const auto &Blacklist = Context.getSanitizerBlacklist(); |
4603 | 178 | const auto *CXXRD = dyn_cast<CXXRecordDecl>(this); |
4604 | | // We may be able to relax some of these requirements. |
4605 | 178 | int ReasonToReject = -1; |
4606 | 178 | if (!CXXRD || CXXRD->isExternCContext()) |
4607 | 14 | ReasonToReject = 0; // is not C++. |
4608 | 164 | else if (CXXRD->hasAttr<PackedAttr>()) |
4609 | 14 | ReasonToReject = 1; // is packed. |
4610 | 150 | else if (CXXRD->isUnion()) |
4611 | 3 | ReasonToReject = 2; // is a union. |
4612 | 147 | else if (CXXRD->isTriviallyCopyable()) |
4613 | 27 | ReasonToReject = 3; // is trivially copyable. |
4614 | 120 | else if (CXXRD->hasTrivialDestructor()) |
4615 | 0 | ReasonToReject = 4; // has trivial destructor. |
4616 | 120 | else if (CXXRD->isStandardLayout()) |
4617 | 0 | ReasonToReject = 5; // is standard layout. |
4618 | 120 | else if (Blacklist.isBlacklistedLocation(EnabledAsanMask, getLocation(), |
4619 | 120 | "field-padding")) |
4620 | 39 | ReasonToReject = 6; // is in an excluded file. |
4621 | 81 | else if (Blacklist.isBlacklistedType(EnabledAsanMask, |
4622 | 81 | getQualifiedNameAsString(), |
4623 | 81 | "field-padding")) |
4624 | 9 | ReasonToReject = 7; // The type is excluded. |
4625 | | |
4626 | 178 | if (EmitRemark) { |
4627 | 48 | if (ReasonToReject >= 0) |
4628 | 32 | Context.getDiagnostics().Report( |
4629 | 32 | getLocation(), |
4630 | 32 | diag::remark_sanitize_address_insert_extra_padding_rejected) |
4631 | 32 | << getQualifiedNameAsString() << ReasonToReject; |
4632 | 16 | else |
4633 | 16 | Context.getDiagnostics().Report( |
4634 | 16 | getLocation(), |
4635 | 16 | diag::remark_sanitize_address_insert_extra_padding_accepted) |
4636 | 16 | << getQualifiedNameAsString(); |
4637 | 48 | } |
4638 | 178 | return ReasonToReject < 0; |
4639 | 178 | } |
4640 | | |
4641 | 52 | const FieldDecl *RecordDecl::findFirstNamedDataMember() const { |
4642 | 49 | for (const auto *I : fields()) { |
4643 | 49 | if (I->getIdentifier()) |
4644 | 41 | return I; |
4645 | | |
4646 | 8 | if (const auto *RT = I->getType()->getAs<RecordType>()) |
4647 | 6 | if (const FieldDecl *NamedDataMember = |
4648 | 3 | RT->getDecl()->findFirstNamedDataMember()) |
4649 | 3 | return NamedDataMember; |
4650 | 8 | } |
4651 | | |
4652 | | // We didn't find a named data member. |
4653 | 8 | return nullptr; |
4654 | 52 | } |
4655 | | |
4656 | | //===----------------------------------------------------------------------===// |
4657 | | // BlockDecl Implementation |
4658 | | //===----------------------------------------------------------------------===// |
4659 | | |
4660 | | BlockDecl::BlockDecl(DeclContext *DC, SourceLocation CaretLoc) |
4661 | 3.05k | : Decl(Block, DC, CaretLoc), DeclContext(Block) { |
4662 | 3.05k | setIsVariadic(false); |
4663 | 3.05k | setCapturesCXXThis(false); |
4664 | 3.05k | setBlockMissingReturnType(true); |
4665 | 3.05k | setIsConversionFromLambda(false); |
4666 | 3.05k | setDoesNotEscape(false); |
4667 | 3.05k | setCanAvoidCopyToHeap(false); |
4668 | 3.05k | } |
4669 | | |
4670 | 913 | void BlockDecl::setParams(ArrayRef<ParmVarDecl *> NewParamInfo) { |
4671 | 913 | assert(!ParamInfo && "Already has param info!"); |
4672 | | |
4673 | | // Zero params -> null pointer. |
4674 | 913 | if (!NewParamInfo.empty()) { |
4675 | 884 | NumParams = NewParamInfo.size(); |
4676 | 884 | ParamInfo = new (getASTContext()) ParmVarDecl*[NewParamInfo.size()]; |
4677 | 884 | std::copy(NewParamInfo.begin(), NewParamInfo.end(), ParamInfo); |
4678 | 884 | } |
4679 | 913 | } |
4680 | | |
4681 | | void BlockDecl::setCaptures(ASTContext &Context, ArrayRef<Capture> Captures, |
4682 | 2.82k | bool CapturesCXXThis) { |
4683 | 2.82k | this->setCapturesCXXThis(CapturesCXXThis); |
4684 | 2.82k | this->NumCaptures = Captures.size(); |
4685 | | |
4686 | 2.82k | if (Captures.empty()) { |
4687 | 1.44k | this->Captures = nullptr; |
4688 | 1.44k | return; |
4689 | 1.44k | } |
4690 | | |
4691 | 1.37k | this->Captures = Captures.copy(Context).data(); |
4692 | 1.37k | } |
4693 | | |
4694 | 121 | bool BlockDecl::capturesVariable(const VarDecl *variable) const { |
4695 | 121 | for (const auto &I : captures()) |
4696 | | // Only auto vars can be captured, so no redeclaration worries. |
4697 | 134 | if (I.getVariable() == variable) |
4698 | 80 | return true; |
4699 | | |
4700 | 41 | return false; |
4701 | 121 | } |
4702 | | |
4703 | 22.5k | SourceRange BlockDecl::getSourceRange() const { |
4704 | 22.5k | return SourceRange(getLocation(), Body ? Body->getEndLoc() : getLocation()0 ); |
4705 | 22.5k | } |
4706 | | |
4707 | | //===----------------------------------------------------------------------===// |
4708 | | // Other Decl Allocation/Deallocation Method Implementations |
4709 | | //===----------------------------------------------------------------------===// |
4710 | | |
4711 | 0 | void TranslationUnitDecl::anchor() {} |
4712 | | |
4713 | 86.5k | TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) { |
4714 | 86.5k | return new (C, (DeclContext *)nullptr) TranslationUnitDecl(C); |
4715 | 86.5k | } |
4716 | | |
4717 | 0 | void PragmaCommentDecl::anchor() {} |
4718 | | |
4719 | | PragmaCommentDecl *PragmaCommentDecl::Create(const ASTContext &C, |
4720 | | TranslationUnitDecl *DC, |
4721 | | SourceLocation CommentLoc, |
4722 | | PragmaMSCommentKind CommentKind, |
4723 | 56 | StringRef Arg) { |
4724 | 56 | PragmaCommentDecl *PCD = |
4725 | 56 | new (C, DC, additionalSizeToAlloc<char>(Arg.size() + 1)) |
4726 | 56 | PragmaCommentDecl(DC, CommentLoc, CommentKind); |
4727 | 56 | memcpy(PCD->getTrailingObjects<char>(), Arg.data(), Arg.size()); |
4728 | 56 | PCD->getTrailingObjects<char>()[Arg.size()] = '\0'; |
4729 | 56 | return PCD; |
4730 | 56 | } |
4731 | | |
4732 | | PragmaCommentDecl *PragmaCommentDecl::CreateDeserialized(ASTContext &C, |
4733 | | unsigned ID, |
4734 | 2 | unsigned ArgSize) { |
4735 | 2 | return new (C, ID, additionalSizeToAlloc<char>(ArgSize + 1)) |
4736 | 2 | PragmaCommentDecl(nullptr, SourceLocation(), PCK_Unknown); |
4737 | 2 | } |
4738 | | |
4739 | 0 | void PragmaDetectMismatchDecl::anchor() {} |
4740 | | |
4741 | | PragmaDetectMismatchDecl * |
4742 | | PragmaDetectMismatchDecl::Create(const ASTContext &C, TranslationUnitDecl *DC, |
4743 | | SourceLocation Loc, StringRef Name, |
4744 | 16 | StringRef Value) { |
4745 | 16 | size_t ValueStart = Name.size() + 1; |
4746 | 16 | PragmaDetectMismatchDecl *PDMD = |
4747 | 16 | new (C, DC, additionalSizeToAlloc<char>(ValueStart + Value.size() + 1)) |
4748 | 16 | PragmaDetectMismatchDecl(DC, Loc, ValueStart); |
4749 | 16 | memcpy(PDMD->getTrailingObjects<char>(), Name.data(), Name.size()); |
4750 | 16 | PDMD->getTrailingObjects<char>()[Name.size()] = '\0'; |
4751 | 16 | memcpy(PDMD->getTrailingObjects<char>() + ValueStart, Value.data(), |
4752 | 16 | Value.size()); |
4753 | 16 | PDMD->getTrailingObjects<char>()[ValueStart + Value.size()] = '\0'; |
4754 | 16 | return PDMD; |
4755 | 16 | } |
4756 | | |
4757 | | PragmaDetectMismatchDecl * |
4758 | | PragmaDetectMismatchDecl::CreateDeserialized(ASTContext &C, unsigned ID, |
4759 | 2 | unsigned NameValueSize) { |
4760 | 2 | return new (C, ID, additionalSizeToAlloc<char>(NameValueSize + 1)) |
4761 | 2 | PragmaDetectMismatchDecl(nullptr, SourceLocation(), 0); |
4762 | 2 | } |
4763 | | |
4764 | 0 | void ExternCContextDecl::anchor() {} |
4765 | | |
4766 | | ExternCContextDecl *ExternCContextDecl::Create(const ASTContext &C, |
4767 | 60.5k | TranslationUnitDecl *DC) { |
4768 | 60.5k | return new (C, DC) ExternCContextDecl(DC); |
4769 | 60.5k | } |
4770 | | |
4771 | 0 | void LabelDecl::anchor() {} |
4772 | | |
4773 | | LabelDecl *LabelDecl::Create(ASTContext &C, DeclContext *DC, |
4774 | 4.52k | SourceLocation IdentL, IdentifierInfo *II) { |
4775 | 4.52k | return new (C, DC) LabelDecl(DC, IdentL, II, nullptr, IdentL); |
4776 | 4.52k | } |
4777 | | |
4778 | | LabelDecl *LabelDecl::Create(ASTContext &C, DeclContext *DC, |
4779 | | SourceLocation IdentL, IdentifierInfo *II, |
4780 | 11 | SourceLocation GnuLabelL) { |
4781 | 11 | assert(GnuLabelL != IdentL && "Use this only for GNU local labels"); |
4782 | 11 | return new (C, DC) LabelDecl(DC, IdentL, II, nullptr, GnuLabelL); |
4783 | 11 | } |
4784 | | |
4785 | 82 | LabelDecl *LabelDecl::CreateDeserialized(ASTContext &C, unsigned ID) { |
4786 | 82 | return new (C, ID) LabelDecl(nullptr, SourceLocation(), nullptr, nullptr, |
4787 | 82 | SourceLocation()); |
4788 | 82 | } |
4789 | | |
4790 | 28 | void LabelDecl::setMSAsmLabel(StringRef Name) { |
4791 | 28 | char *Buffer = new (getASTContext(), 1) char[Name.size() + 1]; |
4792 | 28 | memcpy(Buffer, Name.data(), Name.size()); |
4793 | 28 | Buffer[Name.size()] = '\0'; |
4794 | 28 | MSAsmName = Buffer; |
4795 | 28 | } |
4796 | | |
4797 | 0 | void ValueDecl::anchor() {} |
4798 | | |
4799 | 16.9M | bool ValueDecl::isWeak() const { |
4800 | 16.9M | auto *MostRecent = getMostRecentDecl(); |
4801 | 16.9M | return MostRecent->hasAttr<WeakAttr>() || |
4802 | 16.9M | MostRecent->hasAttr<WeakRefAttr>() || isWeakImported()16.9M ; |
4803 | 16.9M | } |
4804 | | |
4805 | 0 | void ImplicitParamDecl::anchor() {} |
4806 | | |
4807 | | ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, DeclContext *DC, |
4808 | | SourceLocation IdLoc, |
4809 | | IdentifierInfo *Id, QualType Type, |
4810 | 5.14M | ImplicitParamKind ParamKind) { |
4811 | 5.14M | return new (C, DC) ImplicitParamDecl(C, DC, IdLoc, Id, Type, ParamKind); |
4812 | 5.14M | } |
4813 | | |
4814 | | ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, QualType Type, |
4815 | 6 | ImplicitParamKind ParamKind) { |
4816 | 6 | return new (C, nullptr) ImplicitParamDecl(C, Type, ParamKind); |
4817 | 6 | } |
4818 | | |
4819 | | ImplicitParamDecl *ImplicitParamDecl::CreateDeserialized(ASTContext &C, |
4820 | 163k | unsigned ID) { |
4821 | 163k | return new (C, ID) ImplicitParamDecl(C, QualType(), ImplicitParamKind::Other); |
4822 | 163k | } |
4823 | | |
4824 | | FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC, |
4825 | | SourceLocation StartLoc, |
4826 | | const DeclarationNameInfo &NameInfo, |
4827 | | QualType T, TypeSourceInfo *TInfo, |
4828 | | StorageClass SC, bool isInlineSpecified, |
4829 | | bool hasWrittenPrototype, |
4830 | | ConstexprSpecKind ConstexprKind, |
4831 | 13.8M | Expr *TrailingRequiresClause) { |
4832 | 13.8M | FunctionDecl *New = |
4833 | 13.8M | new (C, DC) FunctionDecl(Function, C, DC, StartLoc, NameInfo, T, TInfo, |
4834 | 13.8M | SC, isInlineSpecified, ConstexprKind, |
4835 | 13.8M | TrailingRequiresClause); |
4836 | 13.8M | New->setHasWrittenPrototype(hasWrittenPrototype); |
4837 | 13.8M | return New; |
4838 | 13.8M | } |
4839 | | |
4840 | 381k | FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, unsigned ID) { |
4841 | 381k | return new (C, ID) FunctionDecl( |
4842 | 381k | Function, C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), |
4843 | 381k | nullptr, SC_None, false, ConstexprSpecKind::Unspecified, nullptr); |
4844 | 381k | } |
4845 | | |
4846 | 2.94k | BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) { |
4847 | 2.94k | return new (C, DC) BlockDecl(DC, L); |
4848 | 2.94k | } |
4849 | | |
4850 | 114 | BlockDecl *BlockDecl::CreateDeserialized(ASTContext &C, unsigned ID) { |
4851 | 114 | return new (C, ID) BlockDecl(nullptr, SourceLocation()); |
4852 | 114 | } |
4853 | | |
4854 | | CapturedDecl::CapturedDecl(DeclContext *DC, unsigned NumParams) |
4855 | | : Decl(Captured, DC, SourceLocation()), DeclContext(Captured), |
4856 | 586k | NumParams(NumParams), ContextParam(0), BodyAndNothrow(nullptr, false) {} |
4857 | | |
4858 | | CapturedDecl *CapturedDecl::Create(ASTContext &C, DeclContext *DC, |
4859 | 556k | unsigned NumParams) { |
4860 | 556k | return new (C, DC, additionalSizeToAlloc<ImplicitParamDecl *>(NumParams)) |
4861 | 556k | CapturedDecl(DC, NumParams); |
4862 | 556k | } |
4863 | | |
4864 | | CapturedDecl *CapturedDecl::CreateDeserialized(ASTContext &C, unsigned ID, |
4865 | 30.5k | unsigned NumParams) { |
4866 | 30.5k | return new (C, ID, additionalSizeToAlloc<ImplicitParamDecl *>(NumParams)) |
4867 | 30.5k | CapturedDecl(nullptr, NumParams); |
4868 | 30.5k | } |
4869 | | |
4870 | 373k | Stmt *CapturedDecl::getBody() const { return BodyAndNothrow.getPointer(); } |
4871 | 567k | void CapturedDecl::setBody(Stmt *B) { BodyAndNothrow.setPointer(B); } |
4872 | | |
4873 | 57.9k | bool CapturedDecl::isNothrow() const { return BodyAndNothrow.getInt(); } |
4874 | 476k | void CapturedDecl::setNothrow(bool Nothrow) { BodyAndNothrow.setInt(Nothrow); } |
4875 | | |
4876 | | EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD, |
4877 | | SourceLocation L, |
4878 | | IdentifierInfo *Id, QualType T, |
4879 | 4.93M | Expr *E, const llvm::APSInt &V) { |
4880 | 4.93M | return new (C, CD) EnumConstantDecl(CD, L, Id, T, E, V); |
4881 | 4.93M | } |
4882 | | |
4883 | | EnumConstantDecl * |
4884 | 4.97k | EnumConstantDecl::CreateDeserialized(ASTContext &C, unsigned ID) { |
4885 | 4.97k | return new (C, ID) EnumConstantDecl(nullptr, SourceLocation(), nullptr, |
4886 | 4.97k | QualType(), nullptr, llvm::APSInt()); |
4887 | 4.97k | } |
4888 | | |
4889 | 0 | void IndirectFieldDecl::anchor() {} |
4890 | | |
4891 | | IndirectFieldDecl::IndirectFieldDecl(ASTContext &C, DeclContext *DC, |
4892 | | SourceLocation L, DeclarationName N, |
4893 | | QualType T, |
4894 | | MutableArrayRef<NamedDecl *> CH) |
4895 | | : ValueDecl(IndirectField, DC, L, N, T), Chaining(CH.data()), |
4896 | 8.99k | ChainingSize(CH.size()) { |
4897 | | // In C++, indirect field declarations conflict with tag declarations in the |
4898 | | // same scope, so add them to IDNS_Tag so that tag redeclaration finds them. |
4899 | 8.99k | if (C.getLangOpts().CPlusPlus) |
4900 | 8.49k | IdentifierNamespace |= IDNS_Tag; |
4901 | 8.99k | } |
4902 | | |
4903 | | IndirectFieldDecl * |
4904 | | IndirectFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, |
4905 | | IdentifierInfo *Id, QualType T, |
4906 | 8.03k | llvm::MutableArrayRef<NamedDecl *> CH) { |
4907 | 8.03k | return new (C, DC) IndirectFieldDecl(C, DC, L, Id, T, CH); |
4908 | 8.03k | } |
4909 | | |
4910 | | IndirectFieldDecl *IndirectFieldDecl::CreateDeserialized(ASTContext &C, |
4911 | 964 | unsigned ID) { |
4912 | 964 | return new (C, ID) IndirectFieldDecl(C, nullptr, SourceLocation(), |
4913 | 964 | DeclarationName(), QualType(), None); |
4914 | 964 | } |
4915 | | |
4916 | 1.18k | SourceRange EnumConstantDecl::getSourceRange() const { |
4917 | 1.18k | SourceLocation End = getLocation(); |
4918 | 1.18k | if (Init) |
4919 | 169 | End = Init->getEndLoc(); |
4920 | 1.18k | return SourceRange(getLocation(), End); |
4921 | 1.18k | } |
4922 | | |
4923 | 0 | void TypeDecl::anchor() {} |
4924 | | |
4925 | | TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC, |
4926 | | SourceLocation StartLoc, SourceLocation IdLoc, |
4927 | 3.47M | IdentifierInfo *Id, TypeSourceInfo *TInfo) { |
4928 | 3.47M | return new (C, DC) TypedefDecl(C, DC, StartLoc, IdLoc, Id, TInfo); |
4929 | 3.47M | } |
4930 | | |
4931 | 0 | void TypedefNameDecl::anchor() {} |
4932 | | |
4933 | 180k | TagDecl *TypedefNameDecl::getAnonDeclWithTypedefName(bool AnyRedecl) const { |
4934 | 180k | if (auto *TT = getTypeSourceInfo()->getType()->getAs<TagType>()) { |
4935 | 58.7k | auto *OwningTypedef = TT->getDecl()->getTypedefNameForAnonDecl(); |
4936 | 58.7k | auto *ThisTypedef = this; |
4937 | 58.7k | if (AnyRedecl && OwningTypedef7.83k ) { |
4938 | 155 | OwningTypedef = OwningTypedef->getCanonicalDecl(); |
4939 | 155 | ThisTypedef = ThisTypedef->getCanonicalDecl(); |
4940 | 155 | } |
4941 | 58.7k | if (OwningTypedef == ThisTypedef) |
4942 | 16.4k | return TT->getDecl(); |
4943 | 163k | } |
4944 | | |
4945 | 163k | return nullptr; |
4946 | 163k | } |
4947 | | |
4948 | 345 | bool TypedefNameDecl::isTransparentTagSlow() const { |
4949 | 345 | auto determineIsTransparent = [&]() { |
4950 | 345 | if (auto *TT = getUnderlyingType()->getAs<TagType>()) { |
4951 | 62 | if (auto *TD = TT->getDecl()) { |
4952 | 62 | if (TD->getName() != getName()) |
4953 | 49 | return false; |
4954 | 13 | SourceLocation TTLoc = getLocation(); |
4955 | 13 | SourceLocation TDLoc = TD->getLocation(); |
4956 | 13 | if (!TTLoc.isMacroID() || !TDLoc.isMacroID()) |
4957 | 0 | return false; |
4958 | 13 | SourceManager &SM = getASTContext().getSourceManager(); |
4959 | 13 | return SM.getSpellingLoc(TTLoc) == SM.getSpellingLoc(TDLoc); |
4960 | 13 | } |
4961 | 62 | } |
4962 | 283 | return false; |
4963 | 283 | }; |
4964 | | |
4965 | 345 | bool isTransparent = determineIsTransparent(); |
4966 | 345 | MaybeModedTInfo.setInt((isTransparent << 1) | 1); |
4967 | 345 | return isTransparent; |
4968 | 345 | } |
4969 | | |
4970 | 230k | TypedefDecl *TypedefDecl::CreateDeserialized(ASTContext &C, unsigned ID) { |
4971 | 230k | return new (C, ID) TypedefDecl(C, nullptr, SourceLocation(), SourceLocation(), |
4972 | 230k | nullptr, nullptr); |
4973 | 230k | } |
4974 | | |
4975 | | TypeAliasDecl *TypeAliasDecl::Create(ASTContext &C, DeclContext *DC, |
4976 | | SourceLocation StartLoc, |
4977 | | SourceLocation IdLoc, IdentifierInfo *Id, |
4978 | 171k | TypeSourceInfo *TInfo) { |
4979 | 171k | return new (C, DC) TypeAliasDecl(C, DC, StartLoc, IdLoc, Id, TInfo); |
4980 | 171k | } |
4981 | | |
4982 | 38.5k | TypeAliasDecl *TypeAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) { |
4983 | 38.5k | return new (C, ID) TypeAliasDecl(C, nullptr, SourceLocation(), |
4984 | 38.5k | SourceLocation(), nullptr, nullptr); |
4985 | 38.5k | } |
4986 | | |
4987 | 6.37k | SourceRange TypedefDecl::getSourceRange() const { |
4988 | 6.37k | SourceLocation RangeEnd = getLocation(); |
4989 | 6.37k | if (TypeSourceInfo *TInfo = getTypeSourceInfo()) { |
4990 | 6.37k | if (typeIsPostfix(TInfo->getType())) |
4991 | 697 | RangeEnd = TInfo->getTypeLoc().getSourceRange().getEnd(); |
4992 | 6.37k | } |
4993 | 6.37k | return SourceRange(getBeginLoc(), RangeEnd); |
4994 | 6.37k | } |
4995 | | |
4996 | 373 | SourceRange TypeAliasDecl::getSourceRange() const { |
4997 | 373 | SourceLocation RangeEnd = getBeginLoc(); |
4998 | 373 | if (TypeSourceInfo *TInfo = getTypeSourceInfo()) |
4999 | 373 | RangeEnd = TInfo->getTypeLoc().getSourceRange().getEnd(); |
5000 | 373 | return SourceRange(getBeginLoc(), RangeEnd); |
5001 | 373 | } |
5002 | | |
5003 | 0 | void FileScopeAsmDecl::anchor() {} |
5004 | | |
5005 | | FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC, |
5006 | | StringLiteral *Str, |
5007 | | SourceLocation AsmLoc, |
5008 | 97 | SourceLocation RParenLoc) { |
5009 | 97 | return new (C, DC) FileScopeAsmDecl(DC, Str, AsmLoc, RParenLoc); |
5010 | 97 | } |
5011 | | |
5012 | | FileScopeAsmDecl *FileScopeAsmDecl::CreateDeserialized(ASTContext &C, |
5013 | 113 | unsigned ID) { |
5014 | 113 | return new (C, ID) FileScopeAsmDecl(nullptr, nullptr, SourceLocation(), |
5015 | 113 | SourceLocation()); |
5016 | 113 | } |
5017 | | |
5018 | 0 | void EmptyDecl::anchor() {} |
5019 | | |
5020 | 5.40k | EmptyDecl *EmptyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) { |
5021 | 5.40k | return new (C, DC) EmptyDec
|