24 #include "llvm/ADT/STLExtras.h"
25 #include "llvm/Support/raw_ostream.h"
26 using namespace clang;
35 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
36 CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl());
42 }
else if (isa<InjectedClassNameType>(Ty))
43 return cast<InjectedClassNameType>(Ty)->getDecl();
58 return Tag->getDecl();
77 bool EnteringContext) {
88 if (EnteringContext) {
102 = dyn_cast_or_null<ClassTemplateDecl>(
103 SpecType->getTemplateName().getAsTemplateDecl())) {
111 = ClassTemplate->getInjectedClassNameSpecialization();
113 return ClassTemplate->getTemplatedDecl();
120 = ClassTemplate->findPartialSpecialization(ContextType))
125 return RecordT->getDecl();
134 llvm_unreachable(
"Dependent nested-name-specifier has no DeclContext");
145 assert(Tag &&
"Non-tag type in nested-name-specifier");
156 llvm_unreachable(
"Invalid NestedNameSpecifier::Kind!");
173 assert(NNS->
isDependent() &&
"Only dependent nested-name-specifier allowed");
193 assert(DC &&
"given null context");
222 const EnumType *enumType = dyn_cast_or_null<EnumType>(tagType);
241 Diag(loc, diag::err_incomplete_nested_name_spec)
258 if (
S->isFunctionScope()) {
263 if (
S->isClassScope()) {
264 RD = cast<CXXRecordDecl>(
S->getEntity());
270 Diag(SuperLoc, diag::err_invalid_super_scope);
273 Diag(SuperLoc, diag::err_super_in_lambda_unsupported);
276 Diag(SuperLoc, diag::err_no_base_classes) << RD->
getName();
295 if (isa<NamespaceDecl>(SD) || isa<NamespaceAliasDecl>(SD))
298 if (!isa<TypeDecl>(SD))
307 if (TD->getUnderlyingType()->isRecordType())
309 if (TD->getUnderlyingType()->isEnumeralType()) {
315 }
else if (isa<RecordDecl>(SD)) {
317 }
else if (isa<EnumDecl>(SD)) {
344 assert(!Found.isAmbiguous() &&
"Cannot handle ambiguities here yet");
346 if (!Found.isSingleResult())
365 bool isDependent =
false;
366 if (!ObjectType.
isNull()) {
369 assert(!SS.
isSet() &&
"ObjectType and scope specifier cannot coexist");
372 }
else if (SS.
isSet()) {
392 }
else if (isDependent) {
400 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
411 explicit NestedNameSpecifierValidatorCCC(
Sema &SRef)
414 bool ValidateCandidate(
const TypoCorrection &candidate)
override {
462 bool EnteringContext,
465 bool ErrorRecoveryLookup,
466 bool *IsCorrectedToColon) {
472 bool isDependent =
false;
473 if (IsCorrectedToColon)
474 *IsCorrectedToColon =
false;
475 if (!ObjectType.
isNull()) {
478 assert(!SS.
isSet() &&
"ObjectType and scope specifier cannot coexist");
481 }
else if (SS.
isSet()) {
489 bool ObjectTypeSearchedInScope =
false;
526 else if (ScopeLookupResult)
527 Found.
addDecl(ScopeLookupResult);
529 ObjectTypeSearchedInScope =
true;
531 }
else if (!isDependent) {
538 if (Found.
empty() && isDependent &&
539 !(LookupCtx && LookupCtx->
isRecord() &&
540 (!cast<CXXRecordDecl>(LookupCtx)->hasDefinition() ||
541 !cast<CXXRecordDecl>(LookupCtx)->hasAnyDependentBases()))) {
543 if (ErrorRecoveryLookup)
556 if (Found.
empty() && !ErrorRecoveryLookup) {
562 else if (S && !isDependent)
567 if (IsCorrectedToColon) {
568 *IsCorrectedToColon =
true;
569 Diag(CCLoc, diag::err_nested_name_spec_is_not_class)
573 Diag(ND->getLocation(), diag::note_declared_at);
577 Diag(R.getNameLoc(), diag::err_expected_class_or_namespace)
580 Diag(ND->getLocation(), diag::note_entity_declared_at) << &Identifier;
592 llvm::make_unique<NestedNameSpecifierValidatorCCC>(*this),
595 bool DroppedSpecifier =
596 Corrected.WillReplaceSpecifier() &&
598 if (DroppedSpecifier)
601 << Name << LookupCtx << DroppedSpecifier
607 if (
NamedDecl *ND = Corrected.getCorrectionDecl())
616 bool IsExtension =
false;
618 if (!AcceptSpec && IsExtension) {
620 Diag(IdentifierLoc, diag::ext_nested_name_spec_is_enum);
623 if (!ObjectType.
isNull() && !ObjectTypeSearchedInScope &&
637 LookupResult FoundOuter(*
this, &Identifier, IdentifierLoc,
642 OuterDecl = ScopeLookupResult;
646 (!isa<TypeDecl>(OuterDecl) || !isa<TypeDecl>(SD) ||
650 if (ErrorRecoveryLookup)
654 diag::err_nested_name_member_ref_lookup_ambiguous)
665 if (
auto *TD = dyn_cast_or_null<TypedefNameDecl>(SD))
670 if (ErrorRecoveryLookup)
677 if (
NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(SD)) {
689 if (isa<InjectedClassNameType>(T)) {
693 }
else if (isa<RecordType>(T)) {
696 }
else if (isa<TypedefType>(T)) {
699 }
else if (isa<EnumType>(T)) {
702 }
else if (isa<TemplateTypeParmType>(T)) {
706 }
else if (isa<UnresolvedUsingType>(T)) {
710 }
else if (isa<SubstTemplateTypeParmType>(T)) {
714 }
else if (isa<SubstTemplateTypeParmPackType>(T)) {
719 llvm_unreachable(
"Unhandled TypeDecl node in nested-name-specifier");
723 Diag(IdentifierLoc, diag::warn_cxx98_compat_enum_nested_name_spec);
732 if (ErrorRecoveryLookup)
765 Diag(IdentifierLoc, diag::ext_undeclared_unqual_id_with_dependent_base)
766 << &Identifier << ContainingClass;
773 if (!Found.
empty()) {
775 Diag(IdentifierLoc, diag::err_expected_class_or_namespace)
778 Diag(IdentifierLoc, diag::err_expected_class_or_namespace)
781 Diag(ND->getLocation(), diag::note_entity_declared_at) << &Identifier;
783 }
else if (SS.
isSet())
784 Diag(IdentifierLoc, diag::err_no_member) << &Identifier << LookupCtx
787 Diag(IdentifierLoc, diag::err_undeclared_var_use) << &Identifier;
797 bool EnteringContext,
799 bool ErrorRecoveryLookup,
800 bool *IsCorrectedToColon) {
820 if (!T->isDependentType() && !T->getAs<
TagType>()) {
845 bool EnteringContext) {
864 bool EnteringContext) {
892 for (
unsigned I = 0, N = TemplateArgs.
size(); I != N; ++I)
902 isa<FunctionTemplateDecl>(TD) || isa<VarTemplateDecl>(TD)) {
907 Diag(CCLoc, diag::err_non_type_template_in_nested_name_specifier)
908 << (TD && isa<VarTemplateDecl>(TD)) << Template.
get() << R;
923 Diag(TemplateNameLoc, diag::err_nested_name_spec_non_tag) << T;
936 for (
unsigned I = 0, N = TemplateArgs.
size(); I != N; ++I)
948 struct NestedNameSpecifierAnnotation {
959 llvm::alignOf<NestedNameSpecifierAnnotation>());
960 NestedNameSpecifierAnnotation *Annotation
961 =
new (Mem) NestedNameSpecifierAnnotation;
970 if (!AnnotationPtr) {
975 NestedNameSpecifierAnnotation *Annotation
976 =
static_cast<NestedNameSpecifierAnnotation *
>(AnnotationPtr);
981 assert(SS.
isSet() &&
"Parser passed invalid CXXScopeSpec.");
999 switch (Qualifier->getKind()) {
1015 llvm_unreachable(
"Invalid NestedNameSpecifier::Kind!");
1025 assert(SS.
isSet() &&
"Parser passed invalid CXXScopeSpec.");
1030 if (!DC)
return true;
1052 assert(SS.
isSet() &&
"Parser passed invalid CXXScopeSpec.");
1056 "exiting declarator scope we never really entered");
NamedDecl * FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS)
If the given nested-name-specifier begins with a bare identifier (e.g., Base::), perform name lookup ...
Defines the clang::ASTContext interface.
Scope * getCurScope() const
Retrieve the parser's current scope.
StringRef getName() const
void MakeSuper(ASTContext &Context, CXXRecordDecl *RD, SourceLocation SuperLoc, SourceLocation ColonColonLoc)
Turns this (empty) nested-name-specifier into '__super' nested-name-specifier.
Simple class containing the result of Sema::CorrectTypo.
const LangOptions & getLangOpts() const
void setLookupName(DeclarationName Name)
Sets the name to look up.
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false)
Perform unqualified name lookup starting from a given scope.
DeclClass * getAsSingle() const
void setLAngleLoc(SourceLocation Loc)
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known...
Microsoft's '__super' specifier, stored as a CXXRecordDecl* of the class it appeared in...
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Defines the C++ template declaration subclasses.
bool RebuildNestedNameSpecifierInCurrentInstantiation(CXXScopeSpec &SS)
bool isEnumeralType() const
MemberSpecializationInfo * getMemberSpecializationInfo() const
If this enumeration is an instantiation of a member enumeration of a class template specialization...
CXXRecordDecl * getAsRecordDecl() const
Retrieve the record declaration stored in this nested name specifier.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
void setTemplateKeywordLoc(SourceLocation Loc)
NamespaceDecl - Represent a C++ namespace.
NestedNameSpecifier * getPrefix() const
Return the prefix of this nested name specifier.
Wrapper for source info for typedefs.
bool isAcceptableNestedNameSpecifier(const NamedDecl *SD, bool *CanCorrect=nullptr)
Determines whether the given declaration is an valid acceptable result for name lookup of a nested-na...
void * SaveNestedNameSpecifierAnnotation(CXXScopeSpec &SS)
Given a C++ nested-name-specifier, produce an annotation value that the parser can use later to recon...
An identifier, stored as an IdentifierInfo*.
void Adopt(NestedNameSpecifierLoc Other)
Adopt an existing nested-name-specifier (with source-range information).
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
DeclContext * computeDeclContext(QualType T)
Compute the DeclContext that is associated with the given type.
A namespace, stored as a NamespaceDecl*.
void setBegin(SourceLocation b)
void ActOnCXXExitDeclaratorScope(Scope *S, const CXXScopeSpec &SS)
Defines the clang::Expr interface and subclasses for C++ expressions.
bool isEmpty() const
No scope specifier.
const IdentifierInfo * getIdentifier() const
Returns the identifier to which this template name refers.
void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool OdrUse)
Perform marking for a reference to an arbitrary declaration. It marks the declaration referenced...
bool isDependentScopeSpecifier(const CXXScopeSpec &SS)
bool ActOnCXXNestedNameSpecifierDecltype(CXXScopeSpec &SS, const DeclSpec &DS, SourceLocation ColonColonLoc)
EnumDecl * getInstantiatedFromMemberEnum() const
Returns the enumeration (declared within the template) from which this enumeration type was instantia...
A C++ nested-name-specifier augmented with source location information.
Represents a dependent template name that cannot be resolved prior to template instantiation.
bool isIdentifier() const
Determine whether this template name refers to an identifier.
NamespaceDecl * getNamespace()
Retrieve the namespace declaration aliased by this directive.
void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI)
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
bool isCompleteDefinition() const
CXXRecordDecl * getCurrentInstantiationOf(NestedNameSpecifier *NNS)
If the given nested name specifier refers to the current instantiation, return the declaration that c...
bool ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS)
bool isBeingDefined() const
Determines whether this type is in the process of being defined.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
static const TST TST_error
Wrapper for source info for unresolved typename using decls.
SourceLocation getTypeSpecTypeLoc() const
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
void setNameLoc(SourceLocation Loc)
Represents the results of name lookup.
bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics...
void setRAngleLoc(SourceLocation Loc)
const LangOptions & getLangOpts() const
Wrapper for source info for injected class names of class templates.
unsigned location_size() const
Retrieve the size of the data associated with source-location information.
OverloadedTemplateStorage * getAsOverloadedTemplate() const
Retrieve the underlying, overloaded function template.
Wrapper for substituted template type parameters.
char * location_data() const
Retrieve the data associated with the source-location information.
Wrapper for substituted template type parameters.
void SetInvalid(SourceRange R)
Indicate that this nested-name-specifier is invalid.
bool isDependent() const
Whether this nested name specifier refers to a dependent type or not.
Represents a C++ nested-name-specifier or a global scope specifier.
NestedNameSpecifier * getQualifier() const
Return the nested name specifier that qualifies this name.
std::string getAsString() const
getNameAsString - Retrieve the human-readable string for this name.
void addDecl(NamedDecl *D)
Add a declaration to these results with its natural access. Does not test the acceptance criteria...
QualType getCanonicalTypeInternal() const
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
TyLocType push(QualType T)
EnumDecl * getDecl() const
DependentTemplateName * getAsDependentTemplateName() const
Retrieve the underlying dependent template name structure, if any.
QualType CheckTemplateIdType(TemplateName Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs)
Sema - This implements semantic analysis and AST building for C.
TST getTypeSpecType() const
const DeclarationNameInfo & getLookupNameInfo() const
Gets the name info to look up.
bool InstantiateEnum(SourceLocation PointOfInstantiation, EnumDecl *Instantiation, EnumDecl *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateSpecializationKind TSK)
Instantiate the definition of an enum from a given pattern.
void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI)
void setTemplateNameLoc(SourceLocation Loc)
QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, const TemplateArgumentListInfo &Args) const
SpecifierKind getKind() const
Determine what kind of nested name specifier is stored.
void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc)
MultiLevelTemplateArgumentList getTemplateInstantiationArgs(NamedDecl *D, const TemplateArgumentList *Innermost=nullptr, bool RelativeToPrimary=false, const FunctionDecl *Pattern=nullptr)
Retrieve the template argument list(s) that should be used to instantiate the definition of the given...
DeclarationName getLookupName() const
Gets the name to look up.
bool ActOnCXXGlobalScopeSpecifier(SourceLocation CCLoc, CXXScopeSpec &SS)
The parser has parsed a global nested-name-specifier '::'.
This file defines the classes used to store parsed information about declaration-specifiers and decla...
TranslationUnitDecl * getTranslationUnitDecl() const
void NoteAllFoundTemplates(TemplateName Name)
bool RequireCompleteType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
A namespace alias, stored as a NamespaceAliasDecl*.
Wrapper for source info for enum types.
const SourceRange & getRange() const
bool isDependentType() const
bool isFunctionOrMethod() const
DeclContext * getParent()
getParent - Returns the containing DeclContext.
unsigned getNumBases() const
Retrieves the number of base classes of this class.
Wraps an identifier and optional source location for the identifier.
const Type * getAsType() const
Retrieve the type stored in this nested name specifier.
The result type of a method or function.
A type, stored as a Type*.
void translateTemplateArguments(const ASTTemplateArgsPtr &In, TemplateArgumentListInfo &Out)
Translates template arguments as provided by the parser into template arguments used by semantic anal...
NestedNameSpecifier * getScopeRep() const
Retrieve the representation of the nested-name-specifier.
NamespaceDecl * getAsNamespace() const
Retrieve the namespace stored in this nested name specifier.
TypeLoc getTypeLocInContext(ASTContext &Context, QualType T)
Copies the type-location information to the given AST context and returns a TypeLoc referring into th...
SourceLocation getLastQualifierNameLoc() const
Retrieve the location of the name in the last qualifier in this nested name specifier.
void setLAngleLoc(SourceLocation Loc)
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
const Type * getTypePtr() const
Expr * getRepAsExpr() const
void ExitDeclaratorContext(Scope *S)
TagDecl - Represents the declaration of a struct/union/class/enum.
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context...
Represents a static or instance method of a struct/union/class.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
bool isInvalid() const
An error occurred during parsing of the scope specifier.
void setElaboratedKeywordLoc(SourceLocation Loc)
NamespaceAliasDecl * getAsNamespaceAlias() const
Retrieve the namespace alias stored in this nested name specifier.
SourceLocation getBegin() const
bool isFileContext() const
bool RequireCompleteDeclContext(CXXScopeSpec &SS, DeclContext *DC)
Require that the context specified by SS be complete.
void setTemplateKeywordLoc(SourceLocation Loc)
void diagnoseTypo(const TypoCorrection &Correction, const PartialDiagnostic &TypoDiag, bool ErrorRecovery=true)
Base class for declarations which introduce a typedef-name.
bool ActOnCXXNestedNameSpecifier(Scope *S, IdentifierInfo &Identifier, SourceLocation IdentifierLoc, SourceLocation CCLoc, ParsedType ObjectType, bool EnteringContext, CXXScopeSpec &SS, bool ErrorRecoveryLookup=false, bool *IsCorrectedToColon=nullptr)
The parser has parsed a nested-name-specifier 'identifier::'.
bool IsInvalidUnlessNestedName(Scope *S, CXXScopeSpec &SS, IdentifierInfo &Identifier, SourceLocation IdentifierLoc, SourceLocation ColonLoc, ParsedType ObjectType, bool EnteringContext)
The base class of all kinds of template declarations (e.g., class, function, etc.).
void setContextRange(SourceRange SR)
Sets a 'context' source range.
void EnterDeclaratorContext(Scope *S, DeclContext *DC)
Sema::LookupNameKind getLookupKind() const
Gets the kind of lookup to perform.
static const TST TST_decltype
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
bool BuildCXXNestedNameSpecifier(Scope *S, IdentifierInfo &Identifier, SourceLocation IdentifierLoc, SourceLocation CCLoc, QualType ObjectType, bool EnteringContext, CXXScopeSpec &SS, NamedDecl *ScopeLookupResult, bool ErrorRecoveryLookup, bool *IsCorrectedToColon=nullptr)
Build a new nested-name-specifier for "identifier::", as described by ActOnCXXNestedNameSpecifier.
IdentifierInfo * getAsIdentifier() const
Retrieve the identifier stored in this nested name specifier.
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template specialization this is.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
bool isCurrentInstantiation(const DeclContext *CurContext) const
Determine whether this dependent class is a current instantiation, when viewed from within the given ...
bool hasAnyDependentBases() const
Determine whether this class has any dependent base classes which are not the current instantiation...
A type that was preceded by the 'template' keyword, stored as a Type*.
bool ActOnSuperScopeSpecifier(SourceLocation SuperLoc, SourceLocation ColonColonLoc, CXXScopeSpec &SS)
The parser has parsed a '__super' nested-name-specifier.
bool isLambda() const
Determine whether this class describes a lambda function object.
bool empty() const
Return true if no decls were found.
NamedDecl * getCorrectionDecl() const
Gets the pointer to the declaration of the typo correction.
void RestoreNestedNameSpecifierAnnotation(void *Annotation, SourceRange AnnotationRange, CXXScopeSpec &SS)
Given an annotation pointer for a nested-name-specifier, restore the nested-name-specifier structure...
QualType BuildDecltypeType(Expr *E, SourceLocation Loc, bool AsUnevaluated=true)
DeclContext * getRedeclContext()
Wrapper for source info for record types.
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream...
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
bool ActOnCXXEnterDeclaratorScope(Scope *S, CXXScopeSpec &SS)
void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL, SourceLocation ColonColonLoc)
Extend the current nested-name-specifier by another nested-name-specifier component of the form 'type...
Captures information about "declaration specifiers".
bool isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS, SourceLocation IdLoc, IdentifierInfo &II, ParsedType ObjectType)
Represents a C++ struct/union/class.
BoundNodesTreeBuilder *const Builder
void * Allocate(size_t Size, unsigned Align=8) const
Provides information a specialization of a member of a class template, which may be a member function...
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Declaration of a class template.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string...
void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc)
Turn this (empty) nested-name-specifier into the global nested-name-specifier '::'.
void setRAngleLoc(SourceLocation Loc)
TagDecl * getDecl() const
static CXXRecordDecl * getCurrentInstantiationOf(QualType T, DeclContext *CurContext)
Find the current instantiation that associated with the given type.
Represents a type template specialization; the template must be a class template, a type alias templa...
void suppressDiagnostics()
Wrapper for template type parameters.
A trivial tuple used to represent a source range.
SourceLocation getLocation() const
TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, std::unique_ptr< CorrectionCandidateCallback > CCC, CorrectTypoKind Mode, DeclContext *MemberContext=nullptr, bool EnteringContext=false, const ObjCObjectPointerType *OPT=nullptr, bool RecordFailure=true)
Try to "correct" a typo in the source code by finding visible declarations whose names are similar to...
Represents a C++ namespace alias.
void setTemplateNameLoc(SourceLocation Loc)
No keyword precedes the qualified type name.
bool isNull() const
isNull - Return true if this QualType doesn't point to a type yet.
The global specifier '::'. There is no stored value.
SourceLocation ColonLoc
Location of ':'.
void clear()
Clears out any current state.