1 | //===--- SemaCXXScopeSpec.cpp - Semantic Analysis for C++ scope specifiers-===// |
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 C++ semantic analysis for scope specifiers. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "TypeLocBuilder.h" |
14 | #include "clang/AST/ASTContext.h" |
15 | #include "clang/AST/DeclTemplate.h" |
16 | #include "clang/AST/ExprCXX.h" |
17 | #include "clang/AST/NestedNameSpecifier.h" |
18 | #include "clang/Basic/PartialDiagnostic.h" |
19 | #include "clang/Sema/DeclSpec.h" |
20 | #include "clang/Sema/Lookup.h" |
21 | #include "clang/Sema/SemaInternal.h" |
22 | #include "clang/Sema/Template.h" |
23 | #include "llvm/ADT/STLExtras.h" |
24 | using namespace clang; |
25 | |
26 | /// Find the current instantiation that associated with the given type. |
27 | static CXXRecordDecl *getCurrentInstantiationOf(QualType T, |
28 | DeclContext *CurContext) { |
29 | if (T.isNull()) |
30 | return nullptr; |
31 | |
32 | const Type *Ty = T->getCanonicalTypeInternal().getTypePtr(); |
33 | if (const RecordType *RecordTy = dyn_cast<RecordType>(Val: Ty)) { |
34 | CXXRecordDecl *Record = cast<CXXRecordDecl>(Val: RecordTy->getDecl()); |
35 | if (!Record->isDependentContext() || |
36 | Record->isCurrentInstantiation(CurContext)) |
37 | return Record; |
38 | |
39 | return nullptr; |
40 | } else if (isa<InjectedClassNameType>(Val: Ty)) |
41 | return cast<InjectedClassNameType>(Val: Ty)->getDecl(); |
42 | else |
43 | return nullptr; |
44 | } |
45 | |
46 | /// Compute the DeclContext that is associated with the given type. |
47 | /// |
48 | /// \param T the type for which we are attempting to find a DeclContext. |
49 | /// |
50 | /// \returns the declaration context represented by the type T, |
51 | /// or NULL if the declaration context cannot be computed (e.g., because it is |
52 | /// dependent and not the current instantiation). |
53 | DeclContext *Sema::computeDeclContext(QualType T) { |
54 | if (!T->isDependentType()) |
55 | if (const TagType *Tag = T->getAs<TagType>()) |
56 | return Tag->getDecl(); |
57 | |
58 | return ::getCurrentInstantiationOf(T, CurContext); |
59 | } |
60 | |
61 | /// Compute the DeclContext that is associated with the given |
62 | /// scope specifier. |
63 | /// |
64 | /// \param SS the C++ scope specifier as it appears in the source |
65 | /// |
66 | /// \param EnteringContext when true, we will be entering the context of |
67 | /// this scope specifier, so we can retrieve the declaration context of a |
68 | /// class template or class template partial specialization even if it is |
69 | /// not the current instantiation. |
70 | /// |
71 | /// \returns the declaration context represented by the scope specifier @p SS, |
72 | /// or NULL if the declaration context cannot be computed (e.g., because it is |
73 | /// dependent and not the current instantiation). |
74 | DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS, |
75 | bool EnteringContext) { |
76 | if (!SS.isSet() || SS.isInvalid()) |
77 | return nullptr; |
78 | |
79 | NestedNameSpecifier *NNS = SS.getScopeRep(); |
80 | if (NNS->isDependent()) { |
81 | // If this nested-name-specifier refers to the current |
82 | // instantiation, return its DeclContext. |
83 | if (CXXRecordDecl *Record = getCurrentInstantiationOf(NNS)) |
84 | return Record; |
85 | |
86 | if (EnteringContext) { |
87 | const Type *NNSType = NNS->getAsType(); |
88 | if (!NNSType) { |
89 | return nullptr; |
90 | } |
91 | |
92 | // Look through type alias templates, per C++0x [temp.dep.type]p1. |
93 | NNSType = Context.getCanonicalType(T: NNSType); |
94 | if (const TemplateSpecializationType *SpecType |
95 | = NNSType->getAs<TemplateSpecializationType>()) { |
96 | // We are entering the context of the nested name specifier, so try to |
97 | // match the nested name specifier to either a primary class template |
98 | // or a class template partial specialization. |
99 | if (ClassTemplateDecl *ClassTemplate |
100 | = dyn_cast_or_null<ClassTemplateDecl>( |
101 | Val: SpecType->getTemplateName().getAsTemplateDecl())) { |
102 | QualType ContextType = |
103 | Context.getCanonicalType(T: QualType(SpecType, 0)); |
104 | |
105 | // FIXME: The fallback on the search of partial |
106 | // specialization using ContextType should be eventually removed since |
107 | // it doesn't handle the case of constrained template parameters |
108 | // correctly. Currently removing this fallback would change the |
109 | // diagnostic output for invalid code in a number of tests. |
110 | ClassTemplatePartialSpecializationDecl *PartialSpec = nullptr; |
111 | ArrayRef<TemplateParameterList *> TemplateParamLists = |
112 | SS.getTemplateParamLists(); |
113 | if (!TemplateParamLists.empty()) { |
114 | unsigned Depth = ClassTemplate->getTemplateParameters()->getDepth(); |
115 | auto L = find_if(Range&: TemplateParamLists, |
116 | P: [Depth](TemplateParameterList *TPL) { |
117 | return TPL->getDepth() == Depth; |
118 | }); |
119 | if (L != TemplateParamLists.end()) { |
120 | void *Pos = nullptr; |
121 | PartialSpec = ClassTemplate->findPartialSpecialization( |
122 | Args: SpecType->template_arguments(), TPL: *L, InsertPos&: Pos); |
123 | } |
124 | } else { |
125 | PartialSpec = ClassTemplate->findPartialSpecialization(T: ContextType); |
126 | } |
127 | |
128 | if (PartialSpec) { |
129 | // A declaration of the partial specialization must be visible. |
130 | // We can always recover here, because this only happens when we're |
131 | // entering the context, and that can't happen in a SFINAE context. |
132 | assert(!isSFINAEContext() && "partial specialization scope " |
133 | "specifier in SFINAE context?" ); |
134 | if (PartialSpec->hasDefinition() && |
135 | !hasReachableDefinition(PartialSpec)) |
136 | diagnoseMissingImport(SS.getLastQualifierNameLoc(), PartialSpec, |
137 | MissingImportKind::PartialSpecialization, |
138 | true); |
139 | return PartialSpec; |
140 | } |
141 | |
142 | // If the type of the nested name specifier is the same as the |
143 | // injected class name of the named class template, we're entering |
144 | // into that class template definition. |
145 | QualType Injected = |
146 | ClassTemplate->getInjectedClassNameSpecialization(); |
147 | if (Context.hasSameType(T1: Injected, T2: ContextType)) |
148 | return ClassTemplate->getTemplatedDecl(); |
149 | } |
150 | } else if (const RecordType *RecordT = NNSType->getAs<RecordType>()) { |
151 | // The nested name specifier refers to a member of a class template. |
152 | return RecordT->getDecl(); |
153 | } |
154 | } |
155 | |
156 | return nullptr; |
157 | } |
158 | |
159 | switch (NNS->getKind()) { |
160 | case NestedNameSpecifier::Identifier: |
161 | llvm_unreachable("Dependent nested-name-specifier has no DeclContext" ); |
162 | |
163 | case NestedNameSpecifier::Namespace: |
164 | return NNS->getAsNamespace(); |
165 | |
166 | case NestedNameSpecifier::NamespaceAlias: |
167 | return NNS->getAsNamespaceAlias()->getNamespace(); |
168 | |
169 | case NestedNameSpecifier::TypeSpec: |
170 | case NestedNameSpecifier::TypeSpecWithTemplate: { |
171 | const TagType *Tag = NNS->getAsType()->getAs<TagType>(); |
172 | assert(Tag && "Non-tag type in nested-name-specifier" ); |
173 | return Tag->getDecl(); |
174 | } |
175 | |
176 | case NestedNameSpecifier::Global: |
177 | return Context.getTranslationUnitDecl(); |
178 | |
179 | case NestedNameSpecifier::Super: |
180 | return NNS->getAsRecordDecl(); |
181 | } |
182 | |
183 | llvm_unreachable("Invalid NestedNameSpecifier::Kind!" ); |
184 | } |
185 | |
186 | bool Sema::isDependentScopeSpecifier(const CXXScopeSpec &SS) { |
187 | if (!SS.isSet() || SS.isInvalid()) |
188 | return false; |
189 | |
190 | return SS.getScopeRep()->isDependent(); |
191 | } |
192 | |
193 | /// If the given nested name specifier refers to the current |
194 | /// instantiation, return the declaration that corresponds to that |
195 | /// current instantiation (C++0x [temp.dep.type]p1). |
196 | /// |
197 | /// \param NNS a dependent nested name specifier. |
198 | CXXRecordDecl *Sema::getCurrentInstantiationOf(NestedNameSpecifier *NNS) { |
199 | assert(getLangOpts().CPlusPlus && "Only callable in C++" ); |
200 | assert(NNS->isDependent() && "Only dependent nested-name-specifier allowed" ); |
201 | |
202 | if (!NNS->getAsType()) |
203 | return nullptr; |
204 | |
205 | QualType T = QualType(NNS->getAsType(), 0); |
206 | return ::getCurrentInstantiationOf(T, CurContext); |
207 | } |
208 | |
209 | /// Require that the context specified by SS be complete. |
210 | /// |
211 | /// If SS refers to a type, this routine checks whether the type is |
212 | /// complete enough (or can be made complete enough) for name lookup |
213 | /// into the DeclContext. A type that is not yet completed can be |
214 | /// considered "complete enough" if it is a class/struct/union/enum |
215 | /// that is currently being defined. Or, if we have a type that names |
216 | /// a class template specialization that is not a complete type, we |
217 | /// will attempt to instantiate that class template. |
218 | bool Sema::RequireCompleteDeclContext(CXXScopeSpec &SS, |
219 | DeclContext *DC) { |
220 | assert(DC && "given null context" ); |
221 | |
222 | TagDecl *tag = dyn_cast<TagDecl>(Val: DC); |
223 | |
224 | // If this is a dependent type, then we consider it complete. |
225 | // FIXME: This is wrong; we should require a (visible) definition to |
226 | // exist in this case too. |
227 | if (!tag || tag->isDependentContext()) |
228 | return false; |
229 | |
230 | // Grab the tag definition, if there is one. |
231 | QualType type = Context.getTypeDeclType(tag); |
232 | tag = type->getAsTagDecl(); |
233 | |
234 | // If we're currently defining this type, then lookup into the |
235 | // type is okay: don't complain that it isn't complete yet. |
236 | if (tag->isBeingDefined()) |
237 | return false; |
238 | |
239 | SourceLocation loc = SS.getLastQualifierNameLoc(); |
240 | if (loc.isInvalid()) loc = SS.getRange().getBegin(); |
241 | |
242 | // The type must be complete. |
243 | if (RequireCompleteType(loc, type, diag::err_incomplete_nested_name_spec, |
244 | SS.getRange())) { |
245 | SS.SetInvalid(SS.getRange()); |
246 | return true; |
247 | } |
248 | |
249 | if (auto *EnumD = dyn_cast<EnumDecl>(Val: tag)) |
250 | // Fixed enum types and scoped enum instantiations are complete, but they |
251 | // aren't valid as scopes until we see or instantiate their definition. |
252 | return RequireCompleteEnumDecl(D: EnumD, L: loc, SS: &SS); |
253 | |
254 | return false; |
255 | } |
256 | |
257 | /// Require that the EnumDecl is completed with its enumerators defined or |
258 | /// instantiated. SS, if provided, is the ScopeRef parsed. |
259 | /// |
260 | bool Sema::RequireCompleteEnumDecl(EnumDecl *EnumD, SourceLocation L, |
261 | CXXScopeSpec *SS) { |
262 | if (EnumD->isCompleteDefinition()) { |
263 | // If we know about the definition but it is not visible, complain. |
264 | NamedDecl *SuggestedDef = nullptr; |
265 | if (!hasReachableDefinition(EnumD, &SuggestedDef, |
266 | /*OnlyNeedComplete*/ false)) { |
267 | // If the user is going to see an error here, recover by making the |
268 | // definition visible. |
269 | bool TreatAsComplete = !isSFINAEContext(); |
270 | diagnoseMissingImport(Loc: L, Decl: SuggestedDef, MIK: MissingImportKind::Definition, |
271 | /*Recover*/ TreatAsComplete); |
272 | return !TreatAsComplete; |
273 | } |
274 | return false; |
275 | } |
276 | |
277 | // Try to instantiate the definition, if this is a specialization of an |
278 | // enumeration temploid. |
279 | if (EnumDecl *Pattern = EnumD->getInstantiatedFromMemberEnum()) { |
280 | MemberSpecializationInfo *MSI = EnumD->getMemberSpecializationInfo(); |
281 | if (MSI->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) { |
282 | if (InstantiateEnum(PointOfInstantiation: L, Instantiation: EnumD, Pattern, |
283 | TemplateArgs: getTemplateInstantiationArgs(EnumD), |
284 | TSK: TSK_ImplicitInstantiation)) { |
285 | if (SS) |
286 | SS->SetInvalid(SS->getRange()); |
287 | return true; |
288 | } |
289 | return false; |
290 | } |
291 | } |
292 | |
293 | if (SS) { |
294 | Diag(L, diag::err_incomplete_nested_name_spec) |
295 | << QualType(EnumD->getTypeForDecl(), 0) << SS->getRange(); |
296 | SS->SetInvalid(SS->getRange()); |
297 | } else { |
298 | Diag(L, diag::err_incomplete_enum) << QualType(EnumD->getTypeForDecl(), 0); |
299 | Diag(EnumD->getLocation(), diag::note_declared_at); |
300 | } |
301 | |
302 | return true; |
303 | } |
304 | |
305 | bool Sema::ActOnCXXGlobalScopeSpecifier(SourceLocation CCLoc, |
306 | CXXScopeSpec &SS) { |
307 | SS.MakeGlobal(Context, ColonColonLoc: CCLoc); |
308 | return false; |
309 | } |
310 | |
311 | bool Sema::ActOnSuperScopeSpecifier(SourceLocation SuperLoc, |
312 | SourceLocation ColonColonLoc, |
313 | CXXScopeSpec &SS) { |
314 | if (getCurLambda()) { |
315 | Diag(SuperLoc, diag::err_super_in_lambda_unsupported); |
316 | return true; |
317 | } |
318 | |
319 | CXXRecordDecl *RD = nullptr; |
320 | for (Scope *S = getCurScope(); S; S = S->getParent()) { |
321 | if (S->isFunctionScope()) { |
322 | if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Val: S->getEntity())) |
323 | RD = MD->getParent(); |
324 | break; |
325 | } |
326 | if (S->isClassScope()) { |
327 | RD = cast<CXXRecordDecl>(Val: S->getEntity()); |
328 | break; |
329 | } |
330 | } |
331 | |
332 | if (!RD) { |
333 | Diag(SuperLoc, diag::err_invalid_super_scope); |
334 | return true; |
335 | } else if (RD->getNumBases() == 0) { |
336 | Diag(SuperLoc, diag::err_no_base_classes) << RD->getName(); |
337 | return true; |
338 | } |
339 | |
340 | SS.MakeSuper(Context, RD, SuperLoc, ColonColonLoc); |
341 | return false; |
342 | } |
343 | |
344 | /// Determines whether the given declaration is an valid acceptable |
345 | /// result for name lookup of a nested-name-specifier. |
346 | /// \param SD Declaration checked for nested-name-specifier. |
347 | /// \param IsExtension If not null and the declaration is accepted as an |
348 | /// extension, the pointed variable is assigned true. |
349 | bool Sema::isAcceptableNestedNameSpecifier(const NamedDecl *SD, |
350 | bool *IsExtension) { |
351 | if (!SD) |
352 | return false; |
353 | |
354 | SD = SD->getUnderlyingDecl(); |
355 | |
356 | // Namespace and namespace aliases are fine. |
357 | if (isa<NamespaceDecl>(Val: SD)) |
358 | return true; |
359 | |
360 | if (!isa<TypeDecl>(Val: SD)) |
361 | return false; |
362 | |
363 | // Determine whether we have a class (or, in C++11, an enum) or |
364 | // a typedef thereof. If so, build the nested-name-specifier. |
365 | QualType T = Context.getTypeDeclType(Decl: cast<TypeDecl>(Val: SD)); |
366 | if (T->isDependentType()) |
367 | return true; |
368 | if (const TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(Val: SD)) { |
369 | if (TD->getUnderlyingType()->isRecordType()) |
370 | return true; |
371 | if (TD->getUnderlyingType()->isEnumeralType()) { |
372 | if (Context.getLangOpts().CPlusPlus11) |
373 | return true; |
374 | if (IsExtension) |
375 | *IsExtension = true; |
376 | } |
377 | } else if (isa<RecordDecl>(Val: SD)) { |
378 | return true; |
379 | } else if (isa<EnumDecl>(Val: SD)) { |
380 | if (Context.getLangOpts().CPlusPlus11) |
381 | return true; |
382 | if (IsExtension) |
383 | *IsExtension = true; |
384 | } |
385 | |
386 | return false; |
387 | } |
388 | |
389 | /// If the given nested-name-specifier begins with a bare identifier |
390 | /// (e.g., Base::), perform name lookup for that identifier as a |
391 | /// nested-name-specifier within the given scope, and return the result of that |
392 | /// name lookup. |
393 | NamedDecl *Sema::FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS) { |
394 | if (!S || !NNS) |
395 | return nullptr; |
396 | |
397 | while (NNS->getPrefix()) |
398 | NNS = NNS->getPrefix(); |
399 | |
400 | if (NNS->getKind() != NestedNameSpecifier::Identifier) |
401 | return nullptr; |
402 | |
403 | LookupResult Found(*this, NNS->getAsIdentifier(), SourceLocation(), |
404 | LookupNestedNameSpecifierName); |
405 | LookupName(R&: Found, S); |
406 | assert(!Found.isAmbiguous() && "Cannot handle ambiguities here yet" ); |
407 | |
408 | if (!Found.isSingleResult()) |
409 | return nullptr; |
410 | |
411 | NamedDecl *Result = Found.getFoundDecl(); |
412 | if (isAcceptableNestedNameSpecifier(SD: Result)) |
413 | return Result; |
414 | |
415 | return nullptr; |
416 | } |
417 | |
418 | namespace { |
419 | |
420 | // Callback to only accept typo corrections that can be a valid C++ member |
421 | // initializer: either a non-static field member or a base class. |
422 | class NestedNameSpecifierValidatorCCC final |
423 | : public CorrectionCandidateCallback { |
424 | public: |
425 | explicit NestedNameSpecifierValidatorCCC(Sema &SRef) |
426 | : SRef(SRef) {} |
427 | |
428 | bool ValidateCandidate(const TypoCorrection &candidate) override { |
429 | return SRef.isAcceptableNestedNameSpecifier(SD: candidate.getCorrectionDecl()); |
430 | } |
431 | |
432 | std::unique_ptr<CorrectionCandidateCallback> clone() override { |
433 | return std::make_unique<NestedNameSpecifierValidatorCCC>(args&: *this); |
434 | } |
435 | |
436 | private: |
437 | Sema &SRef; |
438 | }; |
439 | |
440 | } |
441 | |
442 | /// Build a new nested-name-specifier for "identifier::", as described |
443 | /// by ActOnCXXNestedNameSpecifier. |
444 | /// |
445 | /// \param S Scope in which the nested-name-specifier occurs. |
446 | /// \param IdInfo Parser information about an identifier in the |
447 | /// nested-name-spec. |
448 | /// \param EnteringContext If true, enter the context specified by the |
449 | /// nested-name-specifier. |
450 | /// \param SS Optional nested name specifier preceding the identifier. |
451 | /// \param ScopeLookupResult Provides the result of name lookup within the |
452 | /// scope of the nested-name-specifier that was computed at template |
453 | /// definition time. |
454 | /// \param ErrorRecoveryLookup Specifies if the method is called to improve |
455 | /// error recovery and what kind of recovery is performed. |
456 | /// \param IsCorrectedToColon If not null, suggestion of replace '::' -> ':' |
457 | /// are allowed. The bool value pointed by this parameter is set to |
458 | /// 'true' if the identifier is treated as if it was followed by ':', |
459 | /// not '::'. |
460 | /// \param OnlyNamespace If true, only considers namespaces in lookup. |
461 | /// |
462 | /// This routine differs only slightly from ActOnCXXNestedNameSpecifier, in |
463 | /// that it contains an extra parameter \p ScopeLookupResult, which provides |
464 | /// the result of name lookup within the scope of the nested-name-specifier |
465 | /// that was computed at template definition time. |
466 | /// |
467 | /// If ErrorRecoveryLookup is true, then this call is used to improve error |
468 | /// recovery. This means that it should not emit diagnostics, it should |
469 | /// just return true on failure. It also means it should only return a valid |
470 | /// scope if it *knows* that the result is correct. It should not return in a |
471 | /// dependent context, for example. Nor will it extend \p SS with the scope |
472 | /// specifier. |
473 | bool Sema::BuildCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo, |
474 | bool EnteringContext, CXXScopeSpec &SS, |
475 | NamedDecl *ScopeLookupResult, |
476 | bool ErrorRecoveryLookup, |
477 | bool *IsCorrectedToColon, |
478 | bool OnlyNamespace) { |
479 | if (IdInfo.Identifier->isEditorPlaceholder()) |
480 | return true; |
481 | LookupResult Found(*this, IdInfo.Identifier, IdInfo.IdentifierLoc, |
482 | OnlyNamespace ? LookupNamespaceName |
483 | : LookupNestedNameSpecifierName); |
484 | QualType ObjectType = GetTypeFromParser(Ty: IdInfo.ObjectType); |
485 | |
486 | // Determine where to perform name lookup |
487 | DeclContext *LookupCtx = nullptr; |
488 | bool isDependent = false; |
489 | if (IsCorrectedToColon) |
490 | *IsCorrectedToColon = false; |
491 | if (!ObjectType.isNull()) { |
492 | // This nested-name-specifier occurs in a member access expression, e.g., |
493 | // x->B::f, and we are looking into the type of the object. |
494 | assert(!SS.isSet() && "ObjectType and scope specifier cannot coexist" ); |
495 | LookupCtx = computeDeclContext(T: ObjectType); |
496 | isDependent = ObjectType->isDependentType(); |
497 | } else if (SS.isSet()) { |
498 | // This nested-name-specifier occurs after another nested-name-specifier, |
499 | // so look into the context associated with the prior nested-name-specifier. |
500 | LookupCtx = computeDeclContext(SS, EnteringContext); |
501 | isDependent = isDependentScopeSpecifier(SS); |
502 | Found.setContextRange(SS.getRange()); |
503 | } |
504 | |
505 | bool ObjectTypeSearchedInScope = false; |
506 | if (LookupCtx) { |
507 | // Perform "qualified" name lookup into the declaration context we |
508 | // computed, which is either the type of the base of a member access |
509 | // expression or the declaration context associated with a prior |
510 | // nested-name-specifier. |
511 | |
512 | // The declaration context must be complete. |
513 | if (!LookupCtx->isDependentContext() && |
514 | RequireCompleteDeclContext(SS, DC: LookupCtx)) |
515 | return true; |
516 | |
517 | LookupQualifiedName(R&: Found, LookupCtx); |
518 | |
519 | if (!ObjectType.isNull() && Found.empty()) { |
520 | // C++ [basic.lookup.classref]p4: |
521 | // If the id-expression in a class member access is a qualified-id of |
522 | // the form |
523 | // |
524 | // class-name-or-namespace-name::... |
525 | // |
526 | // the class-name-or-namespace-name following the . or -> operator is |
527 | // looked up both in the context of the entire postfix-expression and in |
528 | // the scope of the class of the object expression. If the name is found |
529 | // only in the scope of the class of the object expression, the name |
530 | // shall refer to a class-name. If the name is found only in the |
531 | // context of the entire postfix-expression, the name shall refer to a |
532 | // class-name or namespace-name. [...] |
533 | // |
534 | // Qualified name lookup into a class will not find a namespace-name, |
535 | // so we do not need to diagnose that case specifically. However, |
536 | // this qualified name lookup may find nothing. In that case, perform |
537 | // unqualified name lookup in the given scope (if available) or |
538 | // reconstruct the result from when name lookup was performed at template |
539 | // definition time. |
540 | if (S) |
541 | LookupName(R&: Found, S); |
542 | else if (ScopeLookupResult) |
543 | Found.addDecl(D: ScopeLookupResult); |
544 | |
545 | ObjectTypeSearchedInScope = true; |
546 | } |
547 | } else if (!isDependent) { |
548 | // Perform unqualified name lookup in the current scope. |
549 | LookupName(R&: Found, S); |
550 | } |
551 | |
552 | if (Found.isAmbiguous()) |
553 | return true; |
554 | |
555 | // If we performed lookup into a dependent context and did not find anything, |
556 | // that's fine: just build a dependent nested-name-specifier. |
557 | if (Found.empty() && isDependent && |
558 | !(LookupCtx && LookupCtx->isRecord() && |
559 | (!cast<CXXRecordDecl>(Val: LookupCtx)->hasDefinition() || |
560 | !cast<CXXRecordDecl>(Val: LookupCtx)->hasAnyDependentBases()))) { |
561 | // Don't speculate if we're just trying to improve error recovery. |
562 | if (ErrorRecoveryLookup) |
563 | return true; |
564 | |
565 | // We were not able to compute the declaration context for a dependent |
566 | // base object type or prior nested-name-specifier, so this |
567 | // nested-name-specifier refers to an unknown specialization. Just build |
568 | // a dependent nested-name-specifier. |
569 | SS.Extend(Context, Identifier: IdInfo.Identifier, IdentifierLoc: IdInfo.IdentifierLoc, ColonColonLoc: IdInfo.CCLoc); |
570 | return false; |
571 | } |
572 | |
573 | if (Found.empty() && !ErrorRecoveryLookup) { |
574 | // If identifier is not found as class-name-or-namespace-name, but is found |
575 | // as other entity, don't look for typos. |
576 | LookupResult R(*this, Found.getLookupNameInfo(), LookupOrdinaryName); |
577 | if (LookupCtx) |
578 | LookupQualifiedName(R, LookupCtx); |
579 | else if (S && !isDependent) |
580 | LookupName(R, S); |
581 | if (!R.empty()) { |
582 | // Don't diagnose problems with this speculative lookup. |
583 | R.suppressDiagnostics(); |
584 | // The identifier is found in ordinary lookup. If correction to colon is |
585 | // allowed, suggest replacement to ':'. |
586 | if (IsCorrectedToColon) { |
587 | *IsCorrectedToColon = true; |
588 | Diag(IdInfo.CCLoc, diag::err_nested_name_spec_is_not_class) |
589 | << IdInfo.Identifier << getLangOpts().CPlusPlus |
590 | << FixItHint::CreateReplacement(IdInfo.CCLoc, ":" ); |
591 | if (NamedDecl *ND = R.getAsSingle<NamedDecl>()) |
592 | Diag(ND->getLocation(), diag::note_declared_at); |
593 | return true; |
594 | } |
595 | // Replacement '::' -> ':' is not allowed, just issue respective error. |
596 | Diag(R.getNameLoc(), OnlyNamespace |
597 | ? unsigned(diag::err_expected_namespace_name) |
598 | : unsigned(diag::err_expected_class_or_namespace)) |
599 | << IdInfo.Identifier << getLangOpts().CPlusPlus; |
600 | if (NamedDecl *ND = R.getAsSingle<NamedDecl>()) |
601 | Diag(ND->getLocation(), diag::note_entity_declared_at) |
602 | << IdInfo.Identifier; |
603 | return true; |
604 | } |
605 | } |
606 | |
607 | if (Found.empty() && !ErrorRecoveryLookup && !getLangOpts().MSVCCompat) { |
608 | // We haven't found anything, and we're not recovering from a |
609 | // different kind of error, so look for typos. |
610 | DeclarationName Name = Found.getLookupName(); |
611 | Found.clear(); |
612 | NestedNameSpecifierValidatorCCC CCC(*this); |
613 | if (TypoCorrection Corrected = CorrectTypo( |
614 | Typo: Found.getLookupNameInfo(), LookupKind: Found.getLookupKind(), S, SS: &SS, CCC, |
615 | Mode: CTK_ErrorRecovery, MemberContext: LookupCtx, EnteringContext)) { |
616 | if (LookupCtx) { |
617 | bool DroppedSpecifier = |
618 | Corrected.WillReplaceSpecifier() && |
619 | Name.getAsString() == Corrected.getAsString(LO: getLangOpts()); |
620 | if (DroppedSpecifier) |
621 | SS.clear(); |
622 | diagnoseTypo(Corrected, PDiag(diag::err_no_member_suggest) |
623 | << Name << LookupCtx << DroppedSpecifier |
624 | << SS.getRange()); |
625 | } else |
626 | diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) |
627 | << Name); |
628 | |
629 | if (Corrected.getCorrectionSpecifier()) |
630 | SS.MakeTrivial(Context, Qualifier: Corrected.getCorrectionSpecifier(), |
631 | R: SourceRange(Found.getNameLoc())); |
632 | |
633 | if (NamedDecl *ND = Corrected.getFoundDecl()) |
634 | Found.addDecl(D: ND); |
635 | Found.setLookupName(Corrected.getCorrection()); |
636 | } else { |
637 | Found.setLookupName(IdInfo.Identifier); |
638 | } |
639 | } |
640 | |
641 | NamedDecl *SD = |
642 | Found.isSingleResult() ? Found.getRepresentativeDecl() : nullptr; |
643 | bool IsExtension = false; |
644 | bool AcceptSpec = isAcceptableNestedNameSpecifier(SD, IsExtension: &IsExtension); |
645 | if (!AcceptSpec && IsExtension) { |
646 | AcceptSpec = true; |
647 | Diag(IdInfo.IdentifierLoc, diag::ext_nested_name_spec_is_enum); |
648 | } |
649 | if (AcceptSpec) { |
650 | if (!ObjectType.isNull() && !ObjectTypeSearchedInScope && |
651 | !getLangOpts().CPlusPlus11) { |
652 | // C++03 [basic.lookup.classref]p4: |
653 | // [...] If the name is found in both contexts, the |
654 | // class-name-or-namespace-name shall refer to the same entity. |
655 | // |
656 | // We already found the name in the scope of the object. Now, look |
657 | // into the current scope (the scope of the postfix-expression) to |
658 | // see if we can find the same name there. As above, if there is no |
659 | // scope, reconstruct the result from the template instantiation itself. |
660 | // |
661 | // Note that C++11 does *not* perform this redundant lookup. |
662 | NamedDecl *OuterDecl; |
663 | if (S) { |
664 | LookupResult FoundOuter(*this, IdInfo.Identifier, IdInfo.IdentifierLoc, |
665 | LookupNestedNameSpecifierName); |
666 | LookupName(R&: FoundOuter, S); |
667 | OuterDecl = FoundOuter.getAsSingle<NamedDecl>(); |
668 | } else |
669 | OuterDecl = ScopeLookupResult; |
670 | |
671 | if (isAcceptableNestedNameSpecifier(SD: OuterDecl) && |
672 | OuterDecl->getCanonicalDecl() != SD->getCanonicalDecl() && |
673 | (!isa<TypeDecl>(Val: OuterDecl) || !isa<TypeDecl>(Val: SD) || |
674 | !Context.hasSameType( |
675 | T1: Context.getTypeDeclType(Decl: cast<TypeDecl>(Val: OuterDecl)), |
676 | T2: Context.getTypeDeclType(Decl: cast<TypeDecl>(Val: SD))))) { |
677 | if (ErrorRecoveryLookup) |
678 | return true; |
679 | |
680 | Diag(IdInfo.IdentifierLoc, |
681 | diag::err_nested_name_member_ref_lookup_ambiguous) |
682 | << IdInfo.Identifier; |
683 | Diag(SD->getLocation(), diag::note_ambig_member_ref_object_type) |
684 | << ObjectType; |
685 | Diag(OuterDecl->getLocation(), diag::note_ambig_member_ref_scope); |
686 | |
687 | // Fall through so that we'll pick the name we found in the object |
688 | // type, since that's probably what the user wanted anyway. |
689 | } |
690 | } |
691 | |
692 | if (auto *TD = dyn_cast_or_null<TypedefNameDecl>(Val: SD)) |
693 | MarkAnyDeclReferenced(Loc: TD->getLocation(), D: TD, /*OdrUse=*/MightBeOdrUse: false); |
694 | |
695 | // If we're just performing this lookup for error-recovery purposes, |
696 | // don't extend the nested-name-specifier. Just return now. |
697 | if (ErrorRecoveryLookup) |
698 | return false; |
699 | |
700 | // The use of a nested name specifier may trigger deprecation warnings. |
701 | DiagnoseUseOfDecl(D: SD, Locs: IdInfo.CCLoc); |
702 | |
703 | if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Val: SD)) { |
704 | SS.Extend(Context, Namespace, NamespaceLoc: IdInfo.IdentifierLoc, ColonColonLoc: IdInfo.CCLoc); |
705 | return false; |
706 | } |
707 | |
708 | if (NamespaceAliasDecl *Alias = dyn_cast<NamespaceAliasDecl>(Val: SD)) { |
709 | SS.Extend(Context, Alias, AliasLoc: IdInfo.IdentifierLoc, ColonColonLoc: IdInfo.CCLoc); |
710 | return false; |
711 | } |
712 | |
713 | QualType T = |
714 | Context.getTypeDeclType(Decl: cast<TypeDecl>(Val: SD->getUnderlyingDecl())); |
715 | |
716 | if (T->isEnumeralType()) |
717 | Diag(IdInfo.IdentifierLoc, diag::warn_cxx98_compat_enum_nested_name_spec); |
718 | |
719 | TypeLocBuilder TLB; |
720 | if (const auto *USD = dyn_cast<UsingShadowDecl>(Val: SD)) { |
721 | T = Context.getUsingType(Found: USD, Underlying: T); |
722 | TLB.pushTypeSpec(T).setNameLoc(IdInfo.IdentifierLoc); |
723 | } else if (isa<InjectedClassNameType>(Val: T)) { |
724 | InjectedClassNameTypeLoc InjectedTL |
725 | = TLB.push<InjectedClassNameTypeLoc>(T); |
726 | InjectedTL.setNameLoc(IdInfo.IdentifierLoc); |
727 | } else if (isa<RecordType>(Val: T)) { |
728 | RecordTypeLoc RecordTL = TLB.push<RecordTypeLoc>(T); |
729 | RecordTL.setNameLoc(IdInfo.IdentifierLoc); |
730 | } else if (isa<TypedefType>(Val: T)) { |
731 | TypedefTypeLoc TypedefTL = TLB.push<TypedefTypeLoc>(T); |
732 | TypedefTL.setNameLoc(IdInfo.IdentifierLoc); |
733 | } else if (isa<EnumType>(Val: T)) { |
734 | EnumTypeLoc EnumTL = TLB.push<EnumTypeLoc>(T); |
735 | EnumTL.setNameLoc(IdInfo.IdentifierLoc); |
736 | } else if (isa<TemplateTypeParmType>(Val: T)) { |
737 | TemplateTypeParmTypeLoc TemplateTypeTL |
738 | = TLB.push<TemplateTypeParmTypeLoc>(T); |
739 | TemplateTypeTL.setNameLoc(IdInfo.IdentifierLoc); |
740 | } else if (isa<UnresolvedUsingType>(Val: T)) { |
741 | UnresolvedUsingTypeLoc UnresolvedTL |
742 | = TLB.push<UnresolvedUsingTypeLoc>(T); |
743 | UnresolvedTL.setNameLoc(IdInfo.IdentifierLoc); |
744 | } else if (isa<SubstTemplateTypeParmType>(Val: T)) { |
745 | SubstTemplateTypeParmTypeLoc TL |
746 | = TLB.push<SubstTemplateTypeParmTypeLoc>(T); |
747 | TL.setNameLoc(IdInfo.IdentifierLoc); |
748 | } else if (isa<SubstTemplateTypeParmPackType>(Val: T)) { |
749 | SubstTemplateTypeParmPackTypeLoc TL |
750 | = TLB.push<SubstTemplateTypeParmPackTypeLoc>(T); |
751 | TL.setNameLoc(IdInfo.IdentifierLoc); |
752 | } else { |
753 | llvm_unreachable("Unhandled TypeDecl node in nested-name-specifier" ); |
754 | } |
755 | |
756 | SS.Extend(Context, TemplateKWLoc: SourceLocation(), TL: TLB.getTypeLocInContext(Context, T), |
757 | ColonColonLoc: IdInfo.CCLoc); |
758 | return false; |
759 | } |
760 | |
761 | // Otherwise, we have an error case. If we don't want diagnostics, just |
762 | // return an error now. |
763 | if (ErrorRecoveryLookup) |
764 | return true; |
765 | |
766 | // If we didn't find anything during our lookup, try again with |
767 | // ordinary name lookup, which can help us produce better error |
768 | // messages. |
769 | if (Found.empty()) { |
770 | Found.clear(Kind: LookupOrdinaryName); |
771 | LookupName(R&: Found, S); |
772 | } |
773 | |
774 | // In Microsoft mode, if we are within a templated function and we can't |
775 | // resolve Identifier, then extend the SS with Identifier. This will have |
776 | // the effect of resolving Identifier during template instantiation. |
777 | // The goal is to be able to resolve a function call whose |
778 | // nested-name-specifier is located inside a dependent base class. |
779 | // Example: |
780 | // |
781 | // class C { |
782 | // public: |
783 | // static void foo2() { } |
784 | // }; |
785 | // template <class T> class A { public: typedef C D; }; |
786 | // |
787 | // template <class T> class B : public A<T> { |
788 | // public: |
789 | // void foo() { D::foo2(); } |
790 | // }; |
791 | if (getLangOpts().MSVCCompat) { |
792 | DeclContext *DC = LookupCtx ? LookupCtx : CurContext; |
793 | if (DC->isDependentContext() && DC->isFunctionOrMethod()) { |
794 | CXXRecordDecl *ContainingClass = dyn_cast<CXXRecordDecl>(Val: DC->getParent()); |
795 | if (ContainingClass && ContainingClass->hasAnyDependentBases()) { |
796 | Diag(IdInfo.IdentifierLoc, |
797 | diag::ext_undeclared_unqual_id_with_dependent_base) |
798 | << IdInfo.Identifier << ContainingClass; |
799 | SS.Extend(Context, Identifier: IdInfo.Identifier, IdentifierLoc: IdInfo.IdentifierLoc, |
800 | ColonColonLoc: IdInfo.CCLoc); |
801 | return false; |
802 | } |
803 | } |
804 | } |
805 | |
806 | if (!Found.empty()) { |
807 | if (TypeDecl *TD = Found.getAsSingle<TypeDecl>()) { |
808 | Diag(IdInfo.IdentifierLoc, diag::err_expected_class_or_namespace) |
809 | << Context.getTypeDeclType(TD) << getLangOpts().CPlusPlus; |
810 | } else if (Found.getAsSingle<TemplateDecl>()) { |
811 | ParsedType SuggestedType; |
812 | DiagnoseUnknownTypeName(II&: IdInfo.Identifier, IILoc: IdInfo.IdentifierLoc, S, SS: &SS, |
813 | SuggestedType); |
814 | } else { |
815 | Diag(IdInfo.IdentifierLoc, diag::err_expected_class_or_namespace) |
816 | << IdInfo.Identifier << getLangOpts().CPlusPlus; |
817 | if (NamedDecl *ND = Found.getAsSingle<NamedDecl>()) |
818 | Diag(ND->getLocation(), diag::note_entity_declared_at) |
819 | << IdInfo.Identifier; |
820 | } |
821 | } else if (SS.isSet()) |
822 | Diag(IdInfo.IdentifierLoc, diag::err_no_member) << IdInfo.Identifier |
823 | << LookupCtx << SS.getRange(); |
824 | else |
825 | Diag(IdInfo.IdentifierLoc, diag::err_undeclared_var_use) |
826 | << IdInfo.Identifier; |
827 | |
828 | return true; |
829 | } |
830 | |
831 | bool Sema::ActOnCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo, |
832 | bool EnteringContext, CXXScopeSpec &SS, |
833 | bool *IsCorrectedToColon, |
834 | bool OnlyNamespace) { |
835 | if (SS.isInvalid()) |
836 | return true; |
837 | |
838 | return BuildCXXNestedNameSpecifier(S, IdInfo, EnteringContext, SS, |
839 | /*ScopeLookupResult=*/nullptr, ErrorRecoveryLookup: false, |
840 | IsCorrectedToColon, OnlyNamespace); |
841 | } |
842 | |
843 | bool Sema::ActOnCXXNestedNameSpecifierDecltype(CXXScopeSpec &SS, |
844 | const DeclSpec &DS, |
845 | SourceLocation ColonColonLoc) { |
846 | if (SS.isInvalid() || DS.getTypeSpecType() == DeclSpec::TST_error) |
847 | return true; |
848 | |
849 | assert(DS.getTypeSpecType() == DeclSpec::TST_decltype); |
850 | |
851 | QualType T = BuildDecltypeType(E: DS.getRepAsExpr()); |
852 | if (T.isNull()) |
853 | return true; |
854 | |
855 | if (!T->isDependentType() && !T->getAs<TagType>()) { |
856 | Diag(DS.getTypeSpecTypeLoc(), diag::err_expected_class_or_namespace) |
857 | << T << getLangOpts().CPlusPlus; |
858 | return true; |
859 | } |
860 | |
861 | TypeLocBuilder TLB; |
862 | DecltypeTypeLoc DecltypeTL = TLB.push<DecltypeTypeLoc>(T); |
863 | DecltypeTL.setDecltypeLoc(DS.getTypeSpecTypeLoc()); |
864 | DecltypeTL.setRParenLoc(DS.getTypeofParensRange().getEnd()); |
865 | SS.Extend(Context, TemplateKWLoc: SourceLocation(), TL: TLB.getTypeLocInContext(Context, T), |
866 | ColonColonLoc); |
867 | return false; |
868 | } |
869 | |
870 | bool Sema::ActOnCXXNestedNameSpecifierIndexedPack(CXXScopeSpec &SS, |
871 | const DeclSpec &DS, |
872 | SourceLocation ColonColonLoc, |
873 | QualType Type) { |
874 | if (SS.isInvalid() || DS.getTypeSpecType() == DeclSpec::TST_error) |
875 | return true; |
876 | |
877 | assert(DS.getTypeSpecType() == DeclSpec::TST_typename_pack_indexing); |
878 | |
879 | if (Type.isNull()) |
880 | return true; |
881 | |
882 | TypeLocBuilder TLB; |
883 | TLB.pushTrivial(Context&: getASTContext(), |
884 | T: cast<PackIndexingType>(Val: Type.getTypePtr())->getPattern(), |
885 | Loc: DS.getBeginLoc()); |
886 | PackIndexingTypeLoc PIT = TLB.push<PackIndexingTypeLoc>(T: Type); |
887 | PIT.setEllipsisLoc(DS.getEllipsisLoc()); |
888 | SS.Extend(Context, TemplateKWLoc: SourceLocation(), TL: TLB.getTypeLocInContext(Context, T: Type), |
889 | ColonColonLoc); |
890 | return false; |
891 | } |
892 | |
893 | /// IsInvalidUnlessNestedName - This method is used for error recovery |
894 | /// purposes to determine whether the specified identifier is only valid as |
895 | /// a nested name specifier, for example a namespace name. It is |
896 | /// conservatively correct to always return false from this method. |
897 | /// |
898 | /// The arguments are the same as those passed to ActOnCXXNestedNameSpecifier. |
899 | bool Sema::IsInvalidUnlessNestedName(Scope *S, CXXScopeSpec &SS, |
900 | NestedNameSpecInfo &IdInfo, |
901 | bool EnteringContext) { |
902 | if (SS.isInvalid()) |
903 | return false; |
904 | |
905 | return !BuildCXXNestedNameSpecifier(S, IdInfo, EnteringContext, SS, |
906 | /*ScopeLookupResult=*/nullptr, ErrorRecoveryLookup: true); |
907 | } |
908 | |
909 | bool Sema::ActOnCXXNestedNameSpecifier(Scope *S, |
910 | CXXScopeSpec &SS, |
911 | SourceLocation TemplateKWLoc, |
912 | TemplateTy OpaqueTemplate, |
913 | SourceLocation TemplateNameLoc, |
914 | SourceLocation LAngleLoc, |
915 | ASTTemplateArgsPtr TemplateArgsIn, |
916 | SourceLocation RAngleLoc, |
917 | SourceLocation CCLoc, |
918 | bool EnteringContext) { |
919 | if (SS.isInvalid()) |
920 | return true; |
921 | |
922 | TemplateName Template = OpaqueTemplate.get(); |
923 | |
924 | // Translate the parser's template argument list in our AST format. |
925 | TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc); |
926 | translateTemplateArguments(In: TemplateArgsIn, Out&: TemplateArgs); |
927 | |
928 | DependentTemplateName *DTN = Template.getAsDependentTemplateName(); |
929 | if (DTN && DTN->isIdentifier()) { |
930 | // Handle a dependent template specialization for which we cannot resolve |
931 | // the template name. |
932 | assert(DTN->getQualifier() == SS.getScopeRep()); |
933 | QualType T = Context.getDependentTemplateSpecializationType( |
934 | Keyword: ElaboratedTypeKeyword::None, NNS: DTN->getQualifier(), Name: DTN->getIdentifier(), |
935 | Args: TemplateArgs.arguments()); |
936 | |
937 | // Create source-location information for this type. |
938 | TypeLocBuilder Builder; |
939 | DependentTemplateSpecializationTypeLoc SpecTL |
940 | = Builder.push<DependentTemplateSpecializationTypeLoc>(T); |
941 | SpecTL.setElaboratedKeywordLoc(SourceLocation()); |
942 | SpecTL.setQualifierLoc(SS.getWithLocInContext(Context)); |
943 | SpecTL.setTemplateKeywordLoc(TemplateKWLoc); |
944 | SpecTL.setTemplateNameLoc(TemplateNameLoc); |
945 | SpecTL.setLAngleLoc(LAngleLoc); |
946 | SpecTL.setRAngleLoc(RAngleLoc); |
947 | for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I) |
948 | SpecTL.setArgLocInfo(i: I, AI: TemplateArgs[I].getLocInfo()); |
949 | |
950 | SS.Extend(Context, TemplateKWLoc, TL: Builder.getTypeLocInContext(Context, T), |
951 | ColonColonLoc: CCLoc); |
952 | return false; |
953 | } |
954 | |
955 | // If we assumed an undeclared identifier was a template name, try to |
956 | // typo-correct it now. |
957 | if (Template.getAsAssumedTemplateName() && |
958 | resolveAssumedTemplateNameAsType(S, Name&: Template, NameLoc: TemplateNameLoc)) |
959 | return true; |
960 | |
961 | TemplateDecl *TD = Template.getAsTemplateDecl(); |
962 | if (Template.getAsOverloadedTemplate() || DTN || |
963 | isa<FunctionTemplateDecl>(Val: TD) || isa<VarTemplateDecl>(Val: TD)) { |
964 | SourceRange R(TemplateNameLoc, RAngleLoc); |
965 | if (SS.getRange().isValid()) |
966 | R.setBegin(SS.getRange().getBegin()); |
967 | |
968 | Diag(CCLoc, diag::err_non_type_template_in_nested_name_specifier) |
969 | << (TD && isa<VarTemplateDecl>(TD)) << Template << R; |
970 | NoteAllFoundTemplates(Name: Template); |
971 | return true; |
972 | } |
973 | |
974 | // We were able to resolve the template name to an actual template. |
975 | // Build an appropriate nested-name-specifier. |
976 | QualType T = CheckTemplateIdType(Template, TemplateLoc: TemplateNameLoc, TemplateArgs); |
977 | if (T.isNull()) |
978 | return true; |
979 | |
980 | // Alias template specializations can produce types which are not valid |
981 | // nested name specifiers. |
982 | if (!T->isDependentType() && !T->getAs<TagType>()) { |
983 | Diag(TemplateNameLoc, diag::err_nested_name_spec_non_tag) << T; |
984 | NoteAllFoundTemplates(Name: Template); |
985 | return true; |
986 | } |
987 | |
988 | // Provide source-location information for the template specialization type. |
989 | TypeLocBuilder Builder; |
990 | TemplateSpecializationTypeLoc SpecTL |
991 | = Builder.push<TemplateSpecializationTypeLoc>(T); |
992 | SpecTL.setTemplateKeywordLoc(TemplateKWLoc); |
993 | SpecTL.setTemplateNameLoc(TemplateNameLoc); |
994 | SpecTL.setLAngleLoc(LAngleLoc); |
995 | SpecTL.setRAngleLoc(RAngleLoc); |
996 | for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I) |
997 | SpecTL.setArgLocInfo(i: I, AI: TemplateArgs[I].getLocInfo()); |
998 | |
999 | |
1000 | SS.Extend(Context, TemplateKWLoc, TL: Builder.getTypeLocInContext(Context, T), |
1001 | ColonColonLoc: CCLoc); |
1002 | return false; |
1003 | } |
1004 | |
1005 | namespace { |
1006 | /// A structure that stores a nested-name-specifier annotation, |
1007 | /// including both the nested-name-specifier |
1008 | struct NestedNameSpecifierAnnotation { |
1009 | NestedNameSpecifier *NNS; |
1010 | }; |
1011 | } |
1012 | |
1013 | void *Sema::SaveNestedNameSpecifierAnnotation(CXXScopeSpec &SS) { |
1014 | if (SS.isEmpty() || SS.isInvalid()) |
1015 | return nullptr; |
1016 | |
1017 | void *Mem = Context.Allocate( |
1018 | Size: (sizeof(NestedNameSpecifierAnnotation) + SS.location_size()), |
1019 | Align: alignof(NestedNameSpecifierAnnotation)); |
1020 | NestedNameSpecifierAnnotation *Annotation |
1021 | = new (Mem) NestedNameSpecifierAnnotation; |
1022 | Annotation->NNS = SS.getScopeRep(); |
1023 | memcpy(dest: Annotation + 1, src: SS.location_data(), n: SS.location_size()); |
1024 | return Annotation; |
1025 | } |
1026 | |
1027 | void Sema::RestoreNestedNameSpecifierAnnotation(void *AnnotationPtr, |
1028 | SourceRange AnnotationRange, |
1029 | CXXScopeSpec &SS) { |
1030 | if (!AnnotationPtr) { |
1031 | SS.SetInvalid(AnnotationRange); |
1032 | return; |
1033 | } |
1034 | |
1035 | NestedNameSpecifierAnnotation *Annotation |
1036 | = static_cast<NestedNameSpecifierAnnotation *>(AnnotationPtr); |
1037 | SS.Adopt(Other: NestedNameSpecifierLoc(Annotation->NNS, Annotation + 1)); |
1038 | } |
1039 | |
1040 | bool Sema::ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) { |
1041 | assert(SS.isSet() && "Parser passed invalid CXXScopeSpec." ); |
1042 | |
1043 | // Don't enter a declarator context when the current context is an Objective-C |
1044 | // declaration. |
1045 | if (isa<ObjCContainerDecl>(Val: CurContext) || isa<ObjCMethodDecl>(Val: CurContext)) |
1046 | return false; |
1047 | |
1048 | NestedNameSpecifier *Qualifier = SS.getScopeRep(); |
1049 | |
1050 | // There are only two places a well-formed program may qualify a |
1051 | // declarator: first, when defining a namespace or class member |
1052 | // out-of-line, and second, when naming an explicitly-qualified |
1053 | // friend function. The latter case is governed by |
1054 | // C++03 [basic.lookup.unqual]p10: |
1055 | // In a friend declaration naming a member function, a name used |
1056 | // in the function declarator and not part of a template-argument |
1057 | // in a template-id is first looked up in the scope of the member |
1058 | // function's class. If it is not found, or if the name is part of |
1059 | // a template-argument in a template-id, the look up is as |
1060 | // described for unqualified names in the definition of the class |
1061 | // granting friendship. |
1062 | // i.e. we don't push a scope unless it's a class member. |
1063 | |
1064 | switch (Qualifier->getKind()) { |
1065 | case NestedNameSpecifier::Global: |
1066 | case NestedNameSpecifier::Namespace: |
1067 | case NestedNameSpecifier::NamespaceAlias: |
1068 | // These are always namespace scopes. We never want to enter a |
1069 | // namespace scope from anything but a file context. |
1070 | return CurContext->getRedeclContext()->isFileContext(); |
1071 | |
1072 | case NestedNameSpecifier::Identifier: |
1073 | case NestedNameSpecifier::TypeSpec: |
1074 | case NestedNameSpecifier::TypeSpecWithTemplate: |
1075 | case NestedNameSpecifier::Super: |
1076 | // These are never namespace scopes. |
1077 | return true; |
1078 | } |
1079 | |
1080 | llvm_unreachable("Invalid NestedNameSpecifier::Kind!" ); |
1081 | } |
1082 | |
1083 | /// ActOnCXXEnterDeclaratorScope - Called when a C++ scope specifier (global |
1084 | /// scope or nested-name-specifier) is parsed, part of a declarator-id. |
1085 | /// After this method is called, according to [C++ 3.4.3p3], names should be |
1086 | /// looked up in the declarator-id's scope, until the declarator is parsed and |
1087 | /// ActOnCXXExitDeclaratorScope is called. |
1088 | /// The 'SS' should be a non-empty valid CXXScopeSpec. |
1089 | bool Sema::ActOnCXXEnterDeclaratorScope(Scope *S, CXXScopeSpec &SS) { |
1090 | assert(SS.isSet() && "Parser passed invalid CXXScopeSpec." ); |
1091 | |
1092 | if (SS.isInvalid()) return true; |
1093 | |
1094 | DeclContext *DC = computeDeclContext(SS, EnteringContext: true); |
1095 | if (!DC) return true; |
1096 | |
1097 | // Before we enter a declarator's context, we need to make sure that |
1098 | // it is a complete declaration context. |
1099 | if (!DC->isDependentContext() && RequireCompleteDeclContext(SS, DC)) |
1100 | return true; |
1101 | |
1102 | EnterDeclaratorContext(S, DC); |
1103 | |
1104 | // Rebuild the nested name specifier for the new scope. |
1105 | if (DC->isDependentContext()) |
1106 | RebuildNestedNameSpecifierInCurrentInstantiation(SS); |
1107 | |
1108 | return false; |
1109 | } |
1110 | |
1111 | /// ActOnCXXExitDeclaratorScope - Called when a declarator that previously |
1112 | /// invoked ActOnCXXEnterDeclaratorScope(), is finished. 'SS' is the same |
1113 | /// CXXScopeSpec that was passed to ActOnCXXEnterDeclaratorScope as well. |
1114 | /// Used to indicate that names should revert to being looked up in the |
1115 | /// defining scope. |
1116 | void Sema::ActOnCXXExitDeclaratorScope(Scope *S, const CXXScopeSpec &SS) { |
1117 | assert(SS.isSet() && "Parser passed invalid CXXScopeSpec." ); |
1118 | if (SS.isInvalid()) |
1119 | return; |
1120 | assert(!SS.isInvalid() && computeDeclContext(SS, true) && |
1121 | "exiting declarator scope we never really entered" ); |
1122 | ExitDeclaratorContext(S); |
1123 | } |
1124 | |