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