1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
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 | |
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>(Ty)) { |
34 | CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl()); |
35 | if (!Record->isDependentContext() || |
36 | Record->isCurrentInstantiation(CurContext)) |
37 | return Record; |
38 | |
39 | return nullptr; |
40 | } else if (isa<InjectedClassNameType>(Ty)) |
41 | return cast<InjectedClassNameType>(Ty)->getDecl(); |
42 | else |
43 | return nullptr; |
44 | } |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
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 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
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 | |
82 | |
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 | |
93 | NNSType = Context.getCanonicalType(NNSType); |
94 | if (const TemplateSpecializationType *SpecType |
95 | = NNSType->getAs<TemplateSpecializationType>()) { |
96 | |
97 | |
98 | |
99 | if (ClassTemplateDecl *ClassTemplate |
100 | = dyn_cast_or_null<ClassTemplateDecl>( |
101 | SpecType->getTemplateName().getAsTemplateDecl())) { |
102 | QualType ContextType |
103 | = Context.getCanonicalType(QualType(SpecType, 0)); |
104 | |
105 | |
106 | |
107 | |
108 | QualType Injected |
109 | = ClassTemplate->getInjectedClassNameSpecialization(); |
110 | if (Context.hasSameType(Injected, ContextType)) |
111 | return ClassTemplate->getTemplatedDecl(); |
112 | |
113 | |
114 | |
115 | |
116 | |
117 | if (ClassTemplatePartialSpecializationDecl *PartialSpec |
118 | = ClassTemplate->findPartialSpecialization(ContextType)) { |
119 | |
120 | |
121 | |
122 | (0) . __assert_fail ("!isSFINAEContext() && \"partial specialization scope specifier in SFINAE context?\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaCXXScopeSpec.cpp", 123, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!isSFINAEContext() && |
123 | (0) . __assert_fail ("!isSFINAEContext() && \"partial specialization scope specifier in SFINAE context?\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaCXXScopeSpec.cpp", 123, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "partial specialization scope specifier in SFINAE context?"); |
124 | if (!hasVisibleDeclaration(PartialSpec)) |
125 | diagnoseMissingImport(SS.getLastQualifierNameLoc(), PartialSpec, |
126 | MissingImportKind::PartialSpecialization, |
127 | ); |
128 | return PartialSpec; |
129 | } |
130 | } |
131 | } else if (const RecordType *RecordT = NNSType->getAs<RecordType>()) { |
132 | |
133 | return RecordT->getDecl(); |
134 | } |
135 | } |
136 | |
137 | return nullptr; |
138 | } |
139 | |
140 | switch (NNS->getKind()) { |
141 | case NestedNameSpecifier::Identifier: |
142 | llvm_unreachable("Dependent nested-name-specifier has no DeclContext"); |
143 | |
144 | case NestedNameSpecifier::Namespace: |
145 | return NNS->getAsNamespace(); |
146 | |
147 | case NestedNameSpecifier::NamespaceAlias: |
148 | return NNS->getAsNamespaceAlias()->getNamespace(); |
149 | |
150 | case NestedNameSpecifier::TypeSpec: |
151 | case NestedNameSpecifier::TypeSpecWithTemplate: { |
152 | const TagType *Tag = NNS->getAsType()->getAs<TagType>(); |
153 | (0) . __assert_fail ("Tag && \"Non-tag type in nested-name-specifier\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaCXXScopeSpec.cpp", 153, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Tag && "Non-tag type in nested-name-specifier"); |
154 | return Tag->getDecl(); |
155 | } |
156 | |
157 | case NestedNameSpecifier::Global: |
158 | return Context.getTranslationUnitDecl(); |
159 | |
160 | case NestedNameSpecifier::Super: |
161 | return NNS->getAsRecordDecl(); |
162 | } |
163 | |
164 | llvm_unreachable("Invalid NestedNameSpecifier::Kind!"); |
165 | } |
166 | |
167 | bool Sema::isDependentScopeSpecifier(const CXXScopeSpec &SS) { |
168 | if (!SS.isSet() || SS.isInvalid()) |
169 | return false; |
170 | |
171 | return SS.getScopeRep()->isDependent(); |
172 | } |
173 | |
174 | |
175 | |
176 | |
177 | |
178 | |
179 | CXXRecordDecl *Sema::getCurrentInstantiationOf(NestedNameSpecifier *NNS) { |
180 | (0) . __assert_fail ("getLangOpts().CPlusPlus && \"Only callable in C++\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaCXXScopeSpec.cpp", 180, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(getLangOpts().CPlusPlus && "Only callable in C++"); |
181 | (0) . __assert_fail ("NNS->isDependent() && \"Only dependent nested-name-specifier allowed\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaCXXScopeSpec.cpp", 181, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(NNS->isDependent() && "Only dependent nested-name-specifier allowed"); |
182 | |
183 | if (!NNS->getAsType()) |
184 | return nullptr; |
185 | |
186 | QualType T = QualType(NNS->getAsType(), 0); |
187 | return ::getCurrentInstantiationOf(T, CurContext); |
188 | } |
189 | |
190 | |
191 | |
192 | |
193 | |
194 | |
195 | |
196 | |
197 | |
198 | |
199 | bool Sema::RequireCompleteDeclContext(CXXScopeSpec &SS, |
200 | DeclContext *DC) { |
201 | (0) . __assert_fail ("DC && \"given null context\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaCXXScopeSpec.cpp", 201, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(DC && "given null context"); |
202 | |
203 | TagDecl *tag = dyn_cast<TagDecl>(DC); |
204 | |
205 | |
206 | |
207 | |
208 | if (!tag || tag->isDependentContext()) |
209 | return false; |
210 | |
211 | |
212 | QualType type = Context.getTypeDeclType(tag); |
213 | tag = type->getAsTagDecl(); |
214 | |
215 | |
216 | |
217 | if (tag->isBeingDefined()) |
218 | return false; |
219 | |
220 | SourceLocation loc = SS.getLastQualifierNameLoc(); |
221 | if (loc.isInvalid()) loc = SS.getRange().getBegin(); |
222 | |
223 | |
224 | if (RequireCompleteType(loc, type, diag::err_incomplete_nested_name_spec, |
225 | SS.getRange())) { |
226 | SS.SetInvalid(SS.getRange()); |
227 | return true; |
228 | } |
229 | |
230 | |
231 | |
232 | |
233 | auto *EnumD = dyn_cast<EnumDecl>(tag); |
234 | if (!EnumD) |
235 | return false; |
236 | if (EnumD->isCompleteDefinition()) { |
237 | |
238 | NamedDecl *SuggestedDef = nullptr; |
239 | if (!hasVisibleDefinition(EnumD, &SuggestedDef, |
240 | )) { |
241 | |
242 | |
243 | bool TreatAsComplete = !isSFINAEContext(); |
244 | diagnoseMissingImport(loc, SuggestedDef, MissingImportKind::Definition, |
245 | ); |
246 | return !TreatAsComplete; |
247 | } |
248 | return false; |
249 | } |
250 | |
251 | |
252 | |
253 | if (EnumDecl *Pattern = EnumD->getInstantiatedFromMemberEnum()) { |
254 | MemberSpecializationInfo *MSI = EnumD->getMemberSpecializationInfo(); |
255 | if (MSI->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) { |
256 | if (InstantiateEnum(loc, EnumD, Pattern, |
257 | getTemplateInstantiationArgs(EnumD), |
258 | TSK_ImplicitInstantiation)) { |
259 | SS.SetInvalid(SS.getRange()); |
260 | return true; |
261 | } |
262 | return false; |
263 | } |
264 | } |
265 | |
266 | Diag(loc, diag::err_incomplete_nested_name_spec) |
267 | << type << SS.getRange(); |
268 | SS.SetInvalid(SS.getRange()); |
269 | return true; |
270 | } |
271 | |
272 | bool Sema::ActOnCXXGlobalScopeSpecifier(SourceLocation CCLoc, |
273 | CXXScopeSpec &SS) { |
274 | SS.MakeGlobal(Context, CCLoc); |
275 | return false; |
276 | } |
277 | |
278 | bool Sema::ActOnSuperScopeSpecifier(SourceLocation SuperLoc, |
279 | SourceLocation ColonColonLoc, |
280 | CXXScopeSpec &SS) { |
281 | CXXRecordDecl *RD = nullptr; |
282 | for (Scope *S = getCurScope(); S; S = S->getParent()) { |
283 | if (S->isFunctionScope()) { |
284 | if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(S->getEntity())) |
285 | RD = MD->getParent(); |
286 | break; |
287 | } |
288 | if (S->isClassScope()) { |
289 | RD = cast<CXXRecordDecl>(S->getEntity()); |
290 | break; |
291 | } |
292 | } |
293 | |
294 | if (!RD) { |
295 | Diag(SuperLoc, diag::err_invalid_super_scope); |
296 | return true; |
297 | } else if (RD->isLambda()) { |
298 | Diag(SuperLoc, diag::err_super_in_lambda_unsupported); |
299 | return true; |
300 | } else if (RD->getNumBases() == 0) { |
301 | Diag(SuperLoc, diag::err_no_base_classes) << RD->getName(); |
302 | return true; |
303 | } |
304 | |
305 | SS.MakeSuper(Context, RD, SuperLoc, ColonColonLoc); |
306 | return false; |
307 | } |
308 | |
309 | |
310 | |
311 | |
312 | |
313 | |
314 | bool Sema::isAcceptableNestedNameSpecifier(const NamedDecl *SD, |
315 | bool *IsExtension) { |
316 | if (!SD) |
317 | return false; |
318 | |
319 | SD = SD->getUnderlyingDecl(); |
320 | |
321 | |
322 | if (isa<NamespaceDecl>(SD)) |
323 | return true; |
324 | |
325 | if (!isa<TypeDecl>(SD)) |
326 | return false; |
327 | |
328 | |
329 | |
330 | QualType T = Context.getTypeDeclType(cast<TypeDecl>(SD)); |
331 | if (T->isDependentType()) |
332 | return true; |
333 | if (const TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(SD)) { |
334 | if (TD->getUnderlyingType()->isRecordType()) |
335 | return true; |
336 | if (TD->getUnderlyingType()->isEnumeralType()) { |
337 | if (Context.getLangOpts().CPlusPlus11) |
338 | return true; |
339 | if (IsExtension) |
340 | *IsExtension = true; |
341 | } |
342 | } else if (isa<RecordDecl>(SD)) { |
343 | return true; |
344 | } else if (isa<EnumDecl>(SD)) { |
345 | if (Context.getLangOpts().CPlusPlus11) |
346 | return true; |
347 | if (IsExtension) |
348 | *IsExtension = true; |
349 | } |
350 | |
351 | return false; |
352 | } |
353 | |
354 | |
355 | |
356 | |
357 | |
358 | NamedDecl *Sema::FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS) { |
359 | if (!S || !NNS) |
360 | return nullptr; |
361 | |
362 | while (NNS->getPrefix()) |
363 | NNS = NNS->getPrefix(); |
364 | |
365 | if (NNS->getKind() != NestedNameSpecifier::Identifier) |
366 | return nullptr; |
367 | |
368 | LookupResult Found(*this, NNS->getAsIdentifier(), SourceLocation(), |
369 | LookupNestedNameSpecifierName); |
370 | LookupName(Found, S); |
371 | (0) . __assert_fail ("!Found.isAmbiguous() && \"Cannot handle ambiguities here yet\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaCXXScopeSpec.cpp", 371, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!Found.isAmbiguous() && "Cannot handle ambiguities here yet"); |
372 | |
373 | if (!Found.isSingleResult()) |
374 | return nullptr; |
375 | |
376 | NamedDecl *Result = Found.getFoundDecl(); |
377 | if (isAcceptableNestedNameSpecifier(Result)) |
378 | return Result; |
379 | |
380 | return nullptr; |
381 | } |
382 | |
383 | bool Sema::isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS, |
384 | NestedNameSpecInfo &IdInfo) { |
385 | QualType ObjectType = GetTypeFromParser(IdInfo.ObjectType); |
386 | LookupResult Found(*this, IdInfo.Identifier, IdInfo.IdentifierLoc, |
387 | LookupNestedNameSpecifierName); |
388 | |
389 | |
390 | DeclContext *LookupCtx = nullptr; |
391 | bool isDependent = false; |
392 | if (!ObjectType.isNull()) { |
393 | |
394 | |
395 | (0) . __assert_fail ("!SS.isSet() && \"ObjectType and scope specifier cannot coexist\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaCXXScopeSpec.cpp", 395, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!SS.isSet() && "ObjectType and scope specifier cannot coexist"); |
396 | LookupCtx = computeDeclContext(ObjectType); |
397 | isDependent = ObjectType->isDependentType(); |
398 | } else if (SS.isSet()) { |
399 | |
400 | |
401 | LookupCtx = computeDeclContext(SS, false); |
402 | isDependent = isDependentScopeSpecifier(SS); |
403 | Found.setContextRange(SS.getRange()); |
404 | } |
405 | |
406 | if (LookupCtx) { |
407 | |
408 | |
409 | |
410 | |
411 | |
412 | |
413 | if (!LookupCtx->isDependentContext() && |
414 | RequireCompleteDeclContext(SS, LookupCtx)) |
415 | return false; |
416 | |
417 | LookupQualifiedName(Found, LookupCtx); |
418 | } else if (isDependent) { |
419 | return false; |
420 | } else { |
421 | LookupName(Found, S); |
422 | } |
423 | Found.suppressDiagnostics(); |
424 | |
425 | return Found.getAsSingle<NamespaceDecl>(); |
426 | } |
427 | |
428 | namespace { |
429 | |
430 | |
431 | |
432 | class NestedNameSpecifierValidatorCCC final |
433 | : public CorrectionCandidateCallback { |
434 | public: |
435 | explicit NestedNameSpecifierValidatorCCC(Sema &SRef) |
436 | : SRef(SRef) {} |
437 | |
438 | bool ValidateCandidate(const TypoCorrection &candidate) override { |
439 | return SRef.isAcceptableNestedNameSpecifier(candidate.getCorrectionDecl()); |
440 | } |
441 | |
442 | std::unique_ptr<CorrectionCandidateCallback> clone() override { |
443 | return llvm::make_unique<NestedNameSpecifierValidatorCCC>(*this); |
444 | } |
445 | |
446 | private: |
447 | Sema &SRef; |
448 | }; |
449 | |
450 | } |
451 | |
452 | |
453 | |
454 | |
455 | |
456 | |
457 | |
458 | |
459 | |
460 | |
461 | |
462 | |
463 | |
464 | |
465 | |
466 | |
467 | |
468 | |
469 | |
470 | |
471 | |
472 | |
473 | |
474 | |
475 | |
476 | |
477 | |
478 | |
479 | |
480 | |
481 | |
482 | |
483 | bool Sema::BuildCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo, |
484 | bool EnteringContext, CXXScopeSpec &SS, |
485 | NamedDecl *ScopeLookupResult, |
486 | bool ErrorRecoveryLookup, |
487 | bool *IsCorrectedToColon, |
488 | bool OnlyNamespace) { |
489 | if (IdInfo.Identifier->isEditorPlaceholder()) |
490 | return true; |
491 | LookupResult Found(*this, IdInfo.Identifier, IdInfo.IdentifierLoc, |
492 | OnlyNamespace ? LookupNamespaceName |
493 | : LookupNestedNameSpecifierName); |
494 | QualType ObjectType = GetTypeFromParser(IdInfo.ObjectType); |
495 | |
496 | |
497 | DeclContext *LookupCtx = nullptr; |
498 | bool isDependent = false; |
499 | if (IsCorrectedToColon) |
500 | *IsCorrectedToColon = false; |
501 | if (!ObjectType.isNull()) { |
502 | |
503 | |
504 | (0) . __assert_fail ("!SS.isSet() && \"ObjectType and scope specifier cannot coexist\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaCXXScopeSpec.cpp", 504, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!SS.isSet() && "ObjectType and scope specifier cannot coexist"); |
505 | LookupCtx = computeDeclContext(ObjectType); |
506 | isDependent = ObjectType->isDependentType(); |
507 | } else if (SS.isSet()) { |
508 | |
509 | |
510 | LookupCtx = computeDeclContext(SS, EnteringContext); |
511 | isDependent = isDependentScopeSpecifier(SS); |
512 | Found.setContextRange(SS.getRange()); |
513 | } |
514 | |
515 | bool ObjectTypeSearchedInScope = false; |
516 | if (LookupCtx) { |
517 | |
518 | |
519 | |
520 | |
521 | |
522 | |
523 | if (!LookupCtx->isDependentContext() && |
524 | RequireCompleteDeclContext(SS, LookupCtx)) |
525 | return true; |
526 | |
527 | LookupQualifiedName(Found, LookupCtx); |
528 | |
529 | if (!ObjectType.isNull() && Found.empty()) { |
530 | |
531 | |
532 | |
533 | |
534 | |
535 | |
536 | |
537 | |
538 | |
539 | |
540 | |
541 | |
542 | |
543 | |
544 | |
545 | |
546 | |
547 | |
548 | |
549 | |
550 | if (S) |
551 | LookupName(Found, S); |
552 | else if (ScopeLookupResult) |
553 | Found.addDecl(ScopeLookupResult); |
554 | |
555 | ObjectTypeSearchedInScope = true; |
556 | } |
557 | } else if (!isDependent) { |
558 | |
559 | LookupName(Found, S); |
560 | } |
561 | |
562 | if (Found.isAmbiguous()) |
563 | return true; |
564 | |
565 | |
566 | |
567 | if (Found.empty() && isDependent && |
568 | !(LookupCtx && LookupCtx->isRecord() && |
569 | (!cast<CXXRecordDecl>(LookupCtx)->hasDefinition() || |
570 | !cast<CXXRecordDecl>(LookupCtx)->hasAnyDependentBases()))) { |
571 | |
572 | if (ErrorRecoveryLookup) |
573 | return true; |
574 | |
575 | |
576 | |
577 | |
578 | |
579 | SS.Extend(Context, IdInfo.Identifier, IdInfo.IdentifierLoc, IdInfo.CCLoc); |
580 | return false; |
581 | } |
582 | |
583 | if (Found.empty() && !ErrorRecoveryLookup) { |
584 | |
585 | |
586 | LookupResult R(*this, Found.getLookupNameInfo(), LookupOrdinaryName); |
587 | if (LookupCtx) |
588 | LookupQualifiedName(R, LookupCtx); |
589 | else if (S && !isDependent) |
590 | LookupName(R, S); |
591 | if (!R.empty()) { |
592 | |
593 | R.suppressDiagnostics(); |
594 | |
595 | |
596 | if (IsCorrectedToColon) { |
597 | *IsCorrectedToColon = true; |
598 | Diag(IdInfo.CCLoc, diag::err_nested_name_spec_is_not_class) |
599 | << IdInfo.Identifier << getLangOpts().CPlusPlus |
600 | << FixItHint::CreateReplacement(IdInfo.CCLoc, ":"); |
601 | if (NamedDecl *ND = R.getAsSingle<NamedDecl>()) |
602 | Diag(ND->getLocation(), diag::note_declared_at); |
603 | return true; |
604 | } |
605 | |
606 | Diag(R.getNameLoc(), OnlyNamespace |
607 | ? unsigned(diag::err_expected_namespace_name) |
608 | : unsigned(diag::err_expected_class_or_namespace)) |
609 | << IdInfo.Identifier << getLangOpts().CPlusPlus; |
610 | if (NamedDecl *ND = R.getAsSingle<NamedDecl>()) |
611 | Diag(ND->getLocation(), diag::note_entity_declared_at) |
612 | << IdInfo.Identifier; |
613 | return true; |
614 | } |
615 | } |
616 | |
617 | if (Found.empty() && !ErrorRecoveryLookup && !getLangOpts().MSVCCompat) { |
618 | |
619 | |
620 | DeclarationName Name = Found.getLookupName(); |
621 | Found.clear(); |
622 | NestedNameSpecifierValidatorCCC CCC(*this); |
623 | if (TypoCorrection Corrected = CorrectTypo( |
624 | Found.getLookupNameInfo(), Found.getLookupKind(), S, &SS, CCC, |
625 | CTK_ErrorRecovery, LookupCtx, EnteringContext)) { |
626 | if (LookupCtx) { |
627 | bool DroppedSpecifier = |
628 | Corrected.WillReplaceSpecifier() && |
629 | Name.getAsString() == Corrected.getAsString(getLangOpts()); |
630 | if (DroppedSpecifier) |
631 | SS.clear(); |
632 | diagnoseTypo(Corrected, PDiag(diag::err_no_member_suggest) |
633 | << Name << LookupCtx << DroppedSpecifier |
634 | << SS.getRange()); |
635 | } else |
636 | diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) |
637 | << Name); |
638 | |
639 | if (Corrected.getCorrectionSpecifier()) |
640 | SS.MakeTrivial(Context, Corrected.getCorrectionSpecifier(), |
641 | SourceRange(Found.getNameLoc())); |
642 | |
643 | if (NamedDecl *ND = Corrected.getFoundDecl()) |
644 | Found.addDecl(ND); |
645 | Found.setLookupName(Corrected.getCorrection()); |
646 | } else { |
647 | Found.setLookupName(IdInfo.Identifier); |
648 | } |
649 | } |
650 | |
651 | NamedDecl *SD = |
652 | Found.isSingleResult() ? Found.getRepresentativeDecl() : nullptr; |
653 | bool IsExtension = false; |
654 | bool AcceptSpec = isAcceptableNestedNameSpecifier(SD, &IsExtension); |
655 | if (!AcceptSpec && IsExtension) { |
656 | AcceptSpec = true; |
657 | Diag(IdInfo.IdentifierLoc, diag::ext_nested_name_spec_is_enum); |
658 | } |
659 | if (AcceptSpec) { |
660 | if (!ObjectType.isNull() && !ObjectTypeSearchedInScope && |
661 | !getLangOpts().CPlusPlus11) { |
662 | |
663 | |
664 | |
665 | |
666 | |
667 | |
668 | |
669 | |
670 | |
671 | |
672 | NamedDecl *OuterDecl; |
673 | if (S) { |
674 | LookupResult FoundOuter(*this, IdInfo.Identifier, IdInfo.IdentifierLoc, |
675 | LookupNestedNameSpecifierName); |
676 | LookupName(FoundOuter, S); |
677 | OuterDecl = FoundOuter.getAsSingle<NamedDecl>(); |
678 | } else |
679 | OuterDecl = ScopeLookupResult; |
680 | |
681 | if (isAcceptableNestedNameSpecifier(OuterDecl) && |
682 | OuterDecl->getCanonicalDecl() != SD->getCanonicalDecl() && |
683 | (!isa<TypeDecl>(OuterDecl) || !isa<TypeDecl>(SD) || |
684 | !Context.hasSameType( |
685 | Context.getTypeDeclType(cast<TypeDecl>(OuterDecl)), |
686 | Context.getTypeDeclType(cast<TypeDecl>(SD))))) { |
687 | if (ErrorRecoveryLookup) |
688 | return true; |
689 | |
690 | Diag(IdInfo.IdentifierLoc, |
691 | diag::err_nested_name_member_ref_lookup_ambiguous) |
692 | << IdInfo.Identifier; |
693 | Diag(SD->getLocation(), diag::note_ambig_member_ref_object_type) |
694 | << ObjectType; |
695 | Diag(OuterDecl->getLocation(), diag::note_ambig_member_ref_scope); |
696 | |
697 | |
698 | |
699 | } |
700 | } |
701 | |
702 | if (auto *TD = dyn_cast_or_null<TypedefNameDecl>(SD)) |
703 | MarkAnyDeclReferenced(TD->getLocation(), TD, ); |
704 | |
705 | |
706 | |
707 | if (ErrorRecoveryLookup) |
708 | return false; |
709 | |
710 | |
711 | DiagnoseUseOfDecl(SD, IdInfo.CCLoc); |
712 | |
713 | if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(SD)) { |
714 | SS.Extend(Context, Namespace, IdInfo.IdentifierLoc, IdInfo.CCLoc); |
715 | return false; |
716 | } |
717 | |
718 | if (NamespaceAliasDecl *Alias = dyn_cast<NamespaceAliasDecl>(SD)) { |
719 | SS.Extend(Context, Alias, IdInfo.IdentifierLoc, IdInfo.CCLoc); |
720 | return false; |
721 | } |
722 | |
723 | QualType T = |
724 | Context.getTypeDeclType(cast<TypeDecl>(SD->getUnderlyingDecl())); |
725 | TypeLocBuilder TLB; |
726 | if (isa<InjectedClassNameType>(T)) { |
727 | InjectedClassNameTypeLoc InjectedTL |
728 | = TLB.push<InjectedClassNameTypeLoc>(T); |
729 | InjectedTL.setNameLoc(IdInfo.IdentifierLoc); |
730 | } else if (isa<RecordType>(T)) { |
731 | RecordTypeLoc RecordTL = TLB.push<RecordTypeLoc>(T); |
732 | RecordTL.setNameLoc(IdInfo.IdentifierLoc); |
733 | } else if (isa<TypedefType>(T)) { |
734 | TypedefTypeLoc TypedefTL = TLB.push<TypedefTypeLoc>(T); |
735 | TypedefTL.setNameLoc(IdInfo.IdentifierLoc); |
736 | } else if (isa<EnumType>(T)) { |
737 | EnumTypeLoc EnumTL = TLB.push<EnumTypeLoc>(T); |
738 | EnumTL.setNameLoc(IdInfo.IdentifierLoc); |
739 | } else if (isa<TemplateTypeParmType>(T)) { |
740 | TemplateTypeParmTypeLoc TemplateTypeTL |
741 | = TLB.push<TemplateTypeParmTypeLoc>(T); |
742 | TemplateTypeTL.setNameLoc(IdInfo.IdentifierLoc); |
743 | } else if (isa<UnresolvedUsingType>(T)) { |
744 | UnresolvedUsingTypeLoc UnresolvedTL |
745 | = TLB.push<UnresolvedUsingTypeLoc>(T); |
746 | UnresolvedTL.setNameLoc(IdInfo.IdentifierLoc); |
747 | } else if (isa<SubstTemplateTypeParmType>(T)) { |
748 | SubstTemplateTypeParmTypeLoc TL |
749 | = TLB.push<SubstTemplateTypeParmTypeLoc>(T); |
750 | TL.setNameLoc(IdInfo.IdentifierLoc); |
751 | } else if (isa<SubstTemplateTypeParmPackType>(T)) { |
752 | SubstTemplateTypeParmPackTypeLoc TL |
753 | = TLB.push<SubstTemplateTypeParmPackTypeLoc>(T); |
754 | TL.setNameLoc(IdInfo.IdentifierLoc); |
755 | } else { |
756 | llvm_unreachable("Unhandled TypeDecl node in nested-name-specifier"); |
757 | } |
758 | |
759 | if (T->isEnumeralType()) |
760 | Diag(IdInfo.IdentifierLoc, diag::warn_cxx98_compat_enum_nested_name_spec); |
761 | |
762 | SS.Extend(Context, SourceLocation(), TLB.getTypeLocInContext(Context, T), |
763 | IdInfo.CCLoc); |
764 | return false; |
765 | } |
766 | |
767 | |
768 | |
769 | if (ErrorRecoveryLookup) |
770 | return true; |
771 | |
772 | |
773 | |
774 | |
775 | if (Found.empty()) { |
776 | Found.clear(LookupOrdinaryName); |
777 | LookupName(Found, S); |
778 | } |
779 | |
780 | |
781 | |
782 | |
783 | |
784 | |
785 | |
786 | |
787 | |
788 | |
789 | |
790 | |
791 | |
792 | |
793 | |
794 | |
795 | |
796 | |
797 | if (getLangOpts().MSVCCompat) { |
798 | DeclContext *DC = LookupCtx ? LookupCtx : CurContext; |
799 | if (DC->isDependentContext() && DC->isFunctionOrMethod()) { |
800 | CXXRecordDecl *ContainingClass = dyn_cast<CXXRecordDecl>(DC->getParent()); |
801 | if (ContainingClass && ContainingClass->hasAnyDependentBases()) { |
802 | Diag(IdInfo.IdentifierLoc, |
803 | diag::ext_undeclared_unqual_id_with_dependent_base) |
804 | << IdInfo.Identifier << ContainingClass; |
805 | SS.Extend(Context, IdInfo.Identifier, IdInfo.IdentifierLoc, |
806 | IdInfo.CCLoc); |
807 | return false; |
808 | } |
809 | } |
810 | } |
811 | |
812 | if (!Found.empty()) { |
813 | if (TypeDecl *TD = Found.getAsSingle<TypeDecl>()) |
814 | Diag(IdInfo.IdentifierLoc, diag::err_expected_class_or_namespace) |
815 | << Context.getTypeDeclType(TD) << getLangOpts().CPlusPlus; |
816 | else { |
817 | Diag(IdInfo.IdentifierLoc, diag::err_expected_class_or_namespace) |
818 | << IdInfo.Identifier << getLangOpts().CPlusPlus; |
819 | if (NamedDecl *ND = Found.getAsSingle<NamedDecl>()) |
820 | Diag(ND->getLocation(), diag::note_entity_declared_at) |
821 | << IdInfo.Identifier; |
822 | } |
823 | } else if (SS.isSet()) |
824 | Diag(IdInfo.IdentifierLoc, diag::err_no_member) << IdInfo.Identifier |
825 | << LookupCtx << SS.getRange(); |
826 | else |
827 | Diag(IdInfo.IdentifierLoc, diag::err_undeclared_var_use) |
828 | << IdInfo.Identifier; |
829 | |
830 | return true; |
831 | } |
832 | |
833 | bool Sema::ActOnCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo, |
834 | bool EnteringContext, CXXScopeSpec &SS, |
835 | bool ErrorRecoveryLookup, |
836 | bool *IsCorrectedToColon, |
837 | bool OnlyNamespace) { |
838 | if (SS.isInvalid()) |
839 | return true; |
840 | |
841 | return BuildCXXNestedNameSpecifier(S, IdInfo, EnteringContext, SS, |
842 | , false, |
843 | IsCorrectedToColon, OnlyNamespace); |
844 | } |
845 | |
846 | bool Sema::ActOnCXXNestedNameSpecifierDecltype(CXXScopeSpec &SS, |
847 | const DeclSpec &DS, |
848 | SourceLocation ColonColonLoc) { |
849 | if (SS.isInvalid() || DS.getTypeSpecType() == DeclSpec::TST_error) |
850 | return true; |
851 | |
852 | assert(DS.getTypeSpecType() == DeclSpec::TST_decltype); |
853 | |
854 | QualType T = BuildDecltypeType(DS.getRepAsExpr(), DS.getTypeSpecTypeLoc()); |
855 | if (T.isNull()) |
856 | return true; |
857 | |
858 | if (!T->isDependentType() && !T->getAs<TagType>()) { |
859 | Diag(DS.getTypeSpecTypeLoc(), diag::err_expected_class_or_namespace) |
860 | << T << getLangOpts().CPlusPlus; |
861 | return true; |
862 | } |
863 | |
864 | TypeLocBuilder TLB; |
865 | DecltypeTypeLoc DecltypeTL = TLB.push<DecltypeTypeLoc>(T); |
866 | DecltypeTL.setNameLoc(DS.getTypeSpecTypeLoc()); |
867 | SS.Extend(Context, SourceLocation(), TLB.getTypeLocInContext(Context, T), |
868 | ColonColonLoc); |
869 | return false; |
870 | } |
871 | |
872 | |
873 | |
874 | |
875 | |
876 | |
877 | |
878 | bool Sema::IsInvalidUnlessNestedName(Scope *S, CXXScopeSpec &SS, |
879 | NestedNameSpecInfo &IdInfo, |
880 | bool EnteringContext) { |
881 | if (SS.isInvalid()) |
882 | return false; |
883 | |
884 | return !BuildCXXNestedNameSpecifier(S, IdInfo, EnteringContext, SS, |
885 | , true); |
886 | } |
887 | |
888 | bool Sema::ActOnCXXNestedNameSpecifier(Scope *S, |
889 | CXXScopeSpec &SS, |
890 | SourceLocation TemplateKWLoc, |
891 | TemplateTy Template, |
892 | SourceLocation TemplateNameLoc, |
893 | SourceLocation LAngleLoc, |
894 | ASTTemplateArgsPtr TemplateArgsIn, |
895 | SourceLocation RAngleLoc, |
896 | SourceLocation CCLoc, |
897 | bool EnteringContext) { |
898 | if (SS.isInvalid()) |
899 | return true; |
900 | |
901 | |
902 | TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc); |
903 | translateTemplateArguments(TemplateArgsIn, TemplateArgs); |
904 | |
905 | DependentTemplateName *DTN = Template.get().getAsDependentTemplateName(); |
906 | if (DTN && DTN->isIdentifier()) { |
907 | |
908 | |
909 | getQualifier() == SS.getScopeRep()", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaCXXScopeSpec.cpp", 909, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(DTN->getQualifier() == SS.getScopeRep()); |
910 | QualType T = Context.getDependentTemplateSpecializationType(ETK_None, |
911 | DTN->getQualifier(), |
912 | DTN->getIdentifier(), |
913 | TemplateArgs); |
914 | |
915 | |
916 | TypeLocBuilder Builder; |
917 | DependentTemplateSpecializationTypeLoc SpecTL |
918 | = Builder.push<DependentTemplateSpecializationTypeLoc>(T); |
919 | SpecTL.setElaboratedKeywordLoc(SourceLocation()); |
920 | SpecTL.setQualifierLoc(SS.getWithLocInContext(Context)); |
921 | SpecTL.setTemplateKeywordLoc(TemplateKWLoc); |
922 | SpecTL.setTemplateNameLoc(TemplateNameLoc); |
923 | SpecTL.setLAngleLoc(LAngleLoc); |
924 | SpecTL.setRAngleLoc(RAngleLoc); |
925 | for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I) |
926 | SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo()); |
927 | |
928 | SS.Extend(Context, TemplateKWLoc, Builder.getTypeLocInContext(Context, T), |
929 | CCLoc); |
930 | return false; |
931 | } |
932 | |
933 | TemplateDecl *TD = Template.get().getAsTemplateDecl(); |
934 | if (Template.get().getAsOverloadedTemplate() || DTN || |
935 | isa<FunctionTemplateDecl>(TD) || isa<VarTemplateDecl>(TD)) { |
936 | SourceRange R(TemplateNameLoc, RAngleLoc); |
937 | if (SS.getRange().isValid()) |
938 | R.setBegin(SS.getRange().getBegin()); |
939 | |
940 | Diag(CCLoc, diag::err_non_type_template_in_nested_name_specifier) |
941 | << (TD && isa<VarTemplateDecl>(TD)) << Template.get() << R; |
942 | NoteAllFoundTemplates(Template.get()); |
943 | return true; |
944 | } |
945 | |
946 | |
947 | |
948 | QualType T = |
949 | CheckTemplateIdType(Template.get(), TemplateNameLoc, TemplateArgs); |
950 | if (T.isNull()) |
951 | return true; |
952 | |
953 | |
954 | |
955 | if (!T->isDependentType() && !T->getAs<TagType>()) { |
956 | Diag(TemplateNameLoc, diag::err_nested_name_spec_non_tag) << T; |
957 | NoteAllFoundTemplates(Template.get()); |
958 | return true; |
959 | } |
960 | |
961 | |
962 | TypeLocBuilder Builder; |
963 | TemplateSpecializationTypeLoc SpecTL |
964 | = Builder.push<TemplateSpecializationTypeLoc>(T); |
965 | SpecTL.setTemplateKeywordLoc(TemplateKWLoc); |
966 | SpecTL.setTemplateNameLoc(TemplateNameLoc); |
967 | SpecTL.setLAngleLoc(LAngleLoc); |
968 | SpecTL.setRAngleLoc(RAngleLoc); |
969 | for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I) |
970 | SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo()); |
971 | |
972 | |
973 | SS.Extend(Context, TemplateKWLoc, Builder.getTypeLocInContext(Context, T), |
974 | CCLoc); |
975 | return false; |
976 | } |
977 | |
978 | namespace { |
979 | |
980 | |
981 | struct NestedNameSpecifierAnnotation { |
982 | NestedNameSpecifier *NNS; |
983 | }; |
984 | } |
985 | |
986 | void *Sema::SaveNestedNameSpecifierAnnotation(CXXScopeSpec &SS) { |
987 | if (SS.isEmpty() || SS.isInvalid()) |
988 | return nullptr; |
989 | |
990 | void *Mem = Context.Allocate( |
991 | (sizeof(NestedNameSpecifierAnnotation) + SS.location_size()), |
992 | alignof(NestedNameSpecifierAnnotation)); |
993 | NestedNameSpecifierAnnotation *Annotation |
994 | = new (Mem) NestedNameSpecifierAnnotation; |
995 | Annotation->NNS = SS.getScopeRep(); |
996 | memcpy(Annotation + 1, SS.location_data(), SS.location_size()); |
997 | return Annotation; |
998 | } |
999 | |
1000 | void Sema::RestoreNestedNameSpecifierAnnotation(void *AnnotationPtr, |
1001 | SourceRange AnnotationRange, |
1002 | CXXScopeSpec &SS) { |
1003 | if (!AnnotationPtr) { |
1004 | SS.SetInvalid(AnnotationRange); |
1005 | return; |
1006 | } |
1007 | |
1008 | NestedNameSpecifierAnnotation *Annotation |
1009 | = static_cast<NestedNameSpecifierAnnotation *>(AnnotationPtr); |
1010 | SS.Adopt(NestedNameSpecifierLoc(Annotation->NNS, Annotation + 1)); |
1011 | } |
1012 | |
1013 | bool Sema::ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) { |
1014 | (0) . __assert_fail ("SS.isSet() && \"Parser passed invalid CXXScopeSpec.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaCXXScopeSpec.cpp", 1014, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(SS.isSet() && "Parser passed invalid CXXScopeSpec."); |
1015 | |
1016 | |
1017 | |
1018 | if (isa<ObjCContainerDecl>(CurContext) || isa<ObjCMethodDecl>(CurContext)) |
1019 | return false; |
1020 | |
1021 | NestedNameSpecifier *Qualifier = SS.getScopeRep(); |
1022 | |
1023 | |
1024 | |
1025 | |
1026 | |
1027 | |
1028 | |
1029 | |
1030 | |
1031 | |
1032 | |
1033 | |
1034 | |
1035 | |
1036 | |
1037 | switch (Qualifier->getKind()) { |
1038 | case NestedNameSpecifier::Global: |
1039 | case NestedNameSpecifier::Namespace: |
1040 | case NestedNameSpecifier::NamespaceAlias: |
1041 | |
1042 | |
1043 | return CurContext->getRedeclContext()->isFileContext(); |
1044 | |
1045 | case NestedNameSpecifier::Identifier: |
1046 | case NestedNameSpecifier::TypeSpec: |
1047 | case NestedNameSpecifier::TypeSpecWithTemplate: |
1048 | case NestedNameSpecifier::Super: |
1049 | |
1050 | return true; |
1051 | } |
1052 | |
1053 | llvm_unreachable("Invalid NestedNameSpecifier::Kind!"); |
1054 | } |
1055 | |
1056 | |
1057 | |
1058 | |
1059 | |
1060 | |
1061 | |
1062 | bool Sema::ActOnCXXEnterDeclaratorScope(Scope *S, CXXScopeSpec &SS) { |
1063 | (0) . __assert_fail ("SS.isSet() && \"Parser passed invalid CXXScopeSpec.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaCXXScopeSpec.cpp", 1063, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(SS.isSet() && "Parser passed invalid CXXScopeSpec."); |
1064 | |
1065 | if (SS.isInvalid()) return true; |
1066 | |
1067 | DeclContext *DC = computeDeclContext(SS, true); |
1068 | if (!DC) return true; |
1069 | |
1070 | |
1071 | |
1072 | if (!DC->isDependentContext() && RequireCompleteDeclContext(SS, DC)) |
1073 | return true; |
1074 | |
1075 | EnterDeclaratorContext(S, DC); |
1076 | |
1077 | |
1078 | if (DC->isDependentContext()) |
1079 | RebuildNestedNameSpecifierInCurrentInstantiation(SS); |
1080 | |
1081 | return false; |
1082 | } |
1083 | |
1084 | |
1085 | |
1086 | |
1087 | |
1088 | |
1089 | void Sema::ActOnCXXExitDeclaratorScope(Scope *S, const CXXScopeSpec &SS) { |
1090 | (0) . __assert_fail ("SS.isSet() && \"Parser passed invalid CXXScopeSpec.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaCXXScopeSpec.cpp", 1090, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(SS.isSet() && "Parser passed invalid CXXScopeSpec."); |
1091 | if (SS.isInvalid()) |
1092 | return; |
1093 | (0) . __assert_fail ("!SS.isInvalid() && computeDeclContext(SS, true) && \"exiting declarator scope we never really entered\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaCXXScopeSpec.cpp", 1094, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!SS.isInvalid() && computeDeclContext(SS, true) && |
1094 | (0) . __assert_fail ("!SS.isInvalid() && computeDeclContext(SS, true) && \"exiting declarator scope we never really entered\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaCXXScopeSpec.cpp", 1094, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "exiting declarator scope we never really entered"); |
1095 | ExitDeclaratorContext(S); |
1096 | } |
1097 | |