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