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