Enable correcting a member declaration where the type is class template,
and the class name is shadowed by another member. Recovery still needs to be figured out, which is non-trivial since the parser has already gone down a much different path than if it had recognized the class template as type instead of seeing the member that shadowed the class template. llvm-svn: 201360
This commit is contained in:
parent
b1b5007c52
commit
67b44c9871
|
@ -1354,7 +1354,8 @@ public:
|
|||
SourceLocation IILoc,
|
||||
Scope *S,
|
||||
CXXScopeSpec *SS,
|
||||
ParsedType &SuggestedType);
|
||||
ParsedType &SuggestedType,
|
||||
bool AllowClassTemplates = false);
|
||||
|
||||
/// \brief Describes the result of the name lookup and resolution performed
|
||||
/// by \c ClassifyName().
|
||||
|
|
|
@ -2192,7 +2192,9 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
|
|||
// diagnostic and attempt to recover.
|
||||
ParsedType T;
|
||||
IdentifierInfo *II = Tok.getIdentifierInfo();
|
||||
if (Actions.DiagnoseUnknownTypeName(II, Loc, getCurScope(), SS, T)) {
|
||||
if (Actions.DiagnoseUnknownTypeName(II, Loc, getCurScope(), SS, T,
|
||||
getLangOpts().CPlusPlus &&
|
||||
NextToken().is(tok::less))) {
|
||||
// The action emitted a diagnostic, so we don't have to.
|
||||
if (T) {
|
||||
// The action has suggested that the type T could be used. Set that as
|
||||
|
|
|
@ -62,24 +62,29 @@ namespace {
|
|||
|
||||
class TypeNameValidatorCCC : public CorrectionCandidateCallback {
|
||||
public:
|
||||
TypeNameValidatorCCC(bool AllowInvalid, bool WantClass=false)
|
||||
: AllowInvalidDecl(AllowInvalid), WantClassName(WantClass) {
|
||||
TypeNameValidatorCCC(bool AllowInvalid, bool WantClass=false,
|
||||
bool AllowTemplates=false)
|
||||
: AllowInvalidDecl(AllowInvalid), WantClassName(WantClass),
|
||||
AllowClassTemplates(AllowTemplates) {
|
||||
WantExpressionKeywords = false;
|
||||
WantCXXNamedCasts = false;
|
||||
WantRemainingKeywords = false;
|
||||
}
|
||||
|
||||
virtual bool ValidateCandidate(const TypoCorrection &candidate) {
|
||||
if (NamedDecl *ND = candidate.getCorrectionDecl())
|
||||
return (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND)) &&
|
||||
(AllowInvalidDecl || !ND->isInvalidDecl());
|
||||
else
|
||||
return !WantClassName && candidate.isKeyword();
|
||||
if (NamedDecl *ND = candidate.getCorrectionDecl()) {
|
||||
bool IsType = isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
|
||||
bool AllowedTemplate = AllowClassTemplates && isa<ClassTemplateDecl>(ND);
|
||||
return (IsType || AllowedTemplate) &&
|
||||
(AllowInvalidDecl || !ND->isInvalidDecl());
|
||||
}
|
||||
return !WantClassName && candidate.isKeyword();
|
||||
}
|
||||
|
||||
private:
|
||||
bool AllowInvalidDecl;
|
||||
bool WantClassName;
|
||||
bool AllowClassTemplates;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -394,13 +399,14 @@ bool Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
|
|||
SourceLocation IILoc,
|
||||
Scope *S,
|
||||
CXXScopeSpec *SS,
|
||||
ParsedType &SuggestedType) {
|
||||
ParsedType &SuggestedType,
|
||||
bool AllowClassTemplates) {
|
||||
// We don't have anything to suggest (yet).
|
||||
SuggestedType = ParsedType();
|
||||
|
||||
// There may have been a typo in the name of the type. Look up typo
|
||||
// results, in case we have something that we can suggest.
|
||||
TypeNameValidatorCCC Validator(false);
|
||||
TypeNameValidatorCCC Validator(false, false, AllowClassTemplates);
|
||||
if (TypoCorrection Corrected = CorrectTypo(DeclarationNameInfo(II, IILoc),
|
||||
LookupOrdinaryName, S, SS,
|
||||
Validator)) {
|
||||
|
|
|
@ -223,3 +223,14 @@ SmallSetVector<foo*, 2> fooSet;
|
|||
}
|
||||
|
||||
PR18685::BitVector Map; // expected-error-re {{no type named 'BitVector' in namespace 'PR18685'{{$}}}}
|
||||
|
||||
namespace shadowed_template {
|
||||
template <typename T> class Fizbin {}; // expected-note {{'::shadowed_template::Fizbin' declared here}}
|
||||
class Baz {
|
||||
int Fizbin();
|
||||
// TODO: Teach the parser to recover from the typo correction instead of
|
||||
// continuing to treat the template name as an implicit-int declaration.
|
||||
Fizbin<int> qux; // expected-error {{unknown type name 'Fizbin'; did you mean '::shadowed_template::Fizbin'?}} \
|
||||
// expected-error {{expected member name or ';' after declaration specifiers}}
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue