On Mon, Oct 10, 2011 at 6:02 PM, Kaelyn Uhrain <[email protected]> wrote: > Author: rikka > Date: Mon Oct 10 20:02:41 2011 > New Revision: 141621 > > URL: http://llvm.org/viewvc/llvm-project?rev=141621&view=rev > Log: > Add typo correction for type names. > > The main motivation was to do typo correction in C++ "new" statements, > though picking it up in other places where type names are expected was > pretty much a freebie. > > Added: > cfe/trunk/test/SemaCXX/typo-correction.cpp > Modified: > cfe/trunk/include/clang/Parse/Parser.h > cfe/trunk/include/clang/Sema/Sema.h > cfe/trunk/lib/Parse/ParseDecl.cpp > cfe/trunk/lib/Parse/Parser.cpp > cfe/trunk/lib/Sema/SemaDecl.cpp > cfe/trunk/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp > > Modified: cfe/trunk/include/clang/Parse/Parser.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=141621&r1=141620&r2=141621&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Parse/Parser.h (original) > +++ cfe/trunk/include/clang/Parse/Parser.h Mon Oct 10 20:02:41 2011 > @@ -436,7 +436,10 @@ > Tok.setAnnotationValue(ER.get()); > } > > - bool TryAnnotateTypeOrScopeToken(bool EnteringContext = false); > + // If NeedType is true, then TryAnnotateTypeOrScopeToken will try harder to > + // find a type name by attempting typo correction. > + bool TryAnnotateTypeOrScopeToken(bool EnteringContext = false, > + bool NeedType = false); > bool TryAnnotateCXXScopeToken(bool EnteringContext = false); > > /// TryAltiVecToken - Check for context-sensitive AltiVec identifier tokens, > > Modified: cfe/trunk/include/clang/Sema/Sema.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=141621&r1=141620&r2=141621&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Sema/Sema.h (original) > +++ cfe/trunk/include/clang/Sema/Sema.h Mon Oct 10 20:02:41 2011 > @@ -873,7 +873,8 @@ > bool isClassName = false, > bool HasTrailingDot = false, > ParsedType ObjectType = ParsedType(), > - bool WantNontrivialTypeSourceInfo = false); > + bool WantNontrivialTypeSourceInfo = false, > + IdentifierInfo **CorrectedII = 0); > TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S); > bool isMicrosoftMissingTypename(const CXXScopeSpec *SS); > bool DiagnoseUnknownTypeName(const IdentifierInfo &II, > > Modified: cfe/trunk/lib/Parse/ParseDecl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=141621&r1=141620&r2=141621&view=diff > ============================================================================== > --- cfe/trunk/lib/Parse/ParseDecl.cpp (original) > +++ cfe/trunk/lib/Parse/ParseDecl.cpp Mon Oct 10 20:02:41 2011 > @@ -2303,7 +2303,8 @@ > case tok::kw_typename: // typename foo::bar > // Annotate typenames and C++ scope specifiers. If we get one, just > // recurse to handle whatever we get. > - if (TryAnnotateTypeOrScopeToken()) > + if (TryAnnotateTypeOrScopeToken(/*EnteringContext=*/false, > + /*NeedType=*/true)) > return true; > if (Tok.is(tok::identifier)) > return false; > @@ -2316,7 +2317,8 @@ > > // Annotate typenames and C++ scope specifiers. If we get one, just > // recurse to handle whatever we get. > - if (TryAnnotateTypeOrScopeToken()) > + if (TryAnnotateTypeOrScopeToken(/*EnteringContext=*/false, > + /*NeedType=*/true)) > return true; > return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID, > TemplateInfo, SuppressDeclarations); > > Modified: cfe/trunk/lib/Parse/Parser.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=141621&r1=141620&r2=141621&view=diff > ============================================================================== > --- cfe/trunk/lib/Parse/Parser.cpp (original) > +++ cfe/trunk/lib/Parse/Parser.cpp Mon Oct 10 20:02:41 2011 > @@ -1204,7 +1204,7 @@ > /// > /// Note that this routine emits an error if you call it with ::new or > ::delete > /// as the current tokens, so only call it in contexts where these are > invalid. > -bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) { > +bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext, bool > NeedType) { > assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon) > || Tok.is(tok::kw_typename) || Tok.is(tok::annot_cxxscope)) && > "Cannot be a type or scope token!"); > @@ -1278,13 +1278,18 @@ > return true; > > if (Tok.is(tok::identifier)) { > + IdentifierInfo *CorrectedII = 0; > // Determine whether the identifier is a type name. > if (ParsedType Ty = Actions.getTypeName(*Tok.getIdentifierInfo(), > Tok.getLocation(), getCurScope(), > &SS, false, > NextToken().is(tok::period), > ParsedType(), > - > /*NonTrivialTypeSourceInfo*/true)) { > + /*NonTrivialTypeSourceInfo*/true, > + NeedType ? &CorrectedII : NULL)) > { > + // A FixIt was applied as a result of typo correction > + if (CorrectedII) > + Tok.setIdentifierInfo(CorrectedII); > // This is a typename. Replace the current token in-place with an > // annotation type token. > Tok.setKind(tok::annot_typename); > > Modified: cfe/trunk/lib/Sema/SemaDecl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=141621&r1=141620&r2=141621&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Oct 10 20:02:41 2011 > @@ -71,7 +71,8 @@ > Scope *S, CXXScopeSpec *SS, > bool isClassName, bool HasTrailingDot, > ParsedType ObjectTypePtr, > - bool WantNontrivialTypeSourceInfo) { > + bool WantNontrivialTypeSourceInfo, > + IdentifierInfo **CorrectedII) { > // Determine where we will perform name lookup. > DeclContext *LookupCtx = 0; > if (ObjectTypePtr) { > @@ -146,6 +147,51 @@ > switch (Result.getResultKind()) { > case LookupResult::NotFound: > case LookupResult::NotFoundInCurrentInstantiation: > + if (CorrectedII) { > + TypoCorrection Correction = CorrectTypo(Result.getLookupNameInfo(), > + Kind, S, SS, 0, false, > + Sema::CTC_Type); > + IdentifierInfo *NewII = Correction.getCorrectionAsIdentifierInfo(); > + TemplateTy Template; > + bool MemberOfUnknownSpecialization; > + UnqualifiedId TemplateName; > + TemplateName.setIdentifier(NewII, NameLoc); > + NestedNameSpecifier *NNS = Correction.getCorrectionSpecifier(); > + CXXScopeSpec NewSS, *NewSSPtr = SS; > + if (SS && NNS) { > + NewSS.MakeTrivial(Context, NNS, SourceRange(NameLoc)); > + NewSSPtr = &NewSS; > + } > + if (Correction && (NNS || NewII != &II) && > + // Ignore a correction to a template type as the to-be-corrected > + // identifier is not a template (typo correction for template names > + // is handled elsewhere). > + !(getLangOptions().CPlusPlus && NewSSPtr && > + isTemplateName(S, *NewSSPtr, false, TemplateName, ParsedType(), > + false, Template, MemberOfUnknownSpecialization))) > { > + ParsedType Ty = getTypeName(*NewII, NameLoc, S, NewSSPtr, > + isClassName, HasTrailingDot, > ObjectTypePtr, > + WantNontrivialTypeSourceInfo); > + if (Ty) { > + std::string CorrectedStr(Correction.getAsString(getLangOptions())); > + std::string CorrectedQuotedStr( > + Correction.getQuoted(getLangOptions())); > + Diag(NameLoc, diag::err_unknown_typename_suggest) > + << Result.getLookupName() << CorrectedQuotedStr > + << FixItHint::CreateReplacement(SourceRange(NameLoc), > + CorrectedStr); > + if (NamedDecl *FirstDecl = Correction.getCorrectionDecl()) > + Diag(FirstDecl->getLocation(), diag::note_previous_decl) > + << CorrectedQuotedStr; > + > + if (SS && NNS) > + SS->MakeTrivial(Context, NNS, SourceRange(NameLoc)); > + *CorrectedII = NewII; > + return Ty; > + } > + } > + } > + // If typo correction failed or was not performed, fall through > case LookupResult::FoundOverloaded: > case LookupResult::FoundUnresolvedValue: > Result.suppressDiagnostics(); > > Modified: > cfe/trunk/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp?rev=141621&r1=141620&r2=141621&view=diff > ============================================================================== > --- cfe/trunk/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp > (original) > +++ cfe/trunk/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp > Mon Oct 10 20:02:41 2011 > @@ -1,8 +1,10 @@ > // RUN: %clang_cc1 -fsyntax-only -verify -Wno-c++0x-extensions %s > > -namespace fizbin { class Foobar; } // expected-note{{'fizbin::Foobar' > declared here}} > +namespace fizbin { class Foobar {}; } // expected-note 2 {{'fizbin::Foobar' > declared here}} \ > + // expected-note {{'Foobar' declared > here}} > Foobar *my_bar // expected-error{{unknown type name 'Foobar'; did you mean > 'fizbin::Foobar'?}} > - = new Foobar; // expected-error{{expected a type}} > + = new Foobar; // expected-error{{unknown type name 'Foobar'; did you > mean 'fizbin::Foobar'?}} > +fizbin::Foobar *my_foo = new fizbin::FooBar; // expected-error{{unknown type > name 'FooBar'; did you mean 'Foobar'?}} > > namespace barstool { int toFoobar() { return 1; } } // expected-note 3 > {{'barstool::toFoobar' declared here}} > int Double(int x) { return x + x; } > @@ -62,11 +64,13 @@ > > // Test case from http://llvm.org/bugs/show_bug.cgi?id=10318 > namespace llvm { > - template <typename T> class GraphWriter {}; // > expected-note{{'llvm::GraphWriter' declared here}} > + template <typename T> class GraphWriter {}; // expected-note > {{'llvm::GraphWriter' declared here}} \ > + // expected-note > {{'GraphWriter' declared here}} > } > > struct S {}; > void bar() { > GraphWriter<S> x; //expected-error{{no template named 'GraphWriter'; did you > mean 'llvm::GraphWriter'?}} > - > + (void)new llvm::GraphWriter; // expected-error {{expected a type}} > + (void)new llvm::Graphwriter<S>; // expected-error {{no template named > 'Graphwriter' in namespace 'llvm'; did you mean 'GraphWriter'?}} > } > > Added: cfe/trunk/test/SemaCXX/typo-correction.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/typo-correction.cpp?rev=141621&view=auto > ============================================================================== > --- cfe/trunk/test/SemaCXX/typo-correction.cpp (added) > +++ cfe/trunk/test/SemaCXX/typo-correction.cpp Mon Oct 10 20:02:41 2011 > @@ -0,0 +1,25 @@ > +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-c++0x-extensions %s > + > +struct errc { > + int v_; > + operator int() const {return v_;} > +}; > + > +class error_condition > +{ > + int _val_; > +public: > + error_condition() : _val_(0) {} > + > + error_condition(int _val) > + : _val_(_val) {} > + > + template <class E> > + error_condition(E _e) > + {*this = make_error_condition(_e);} > + > +}; > + > +inline error_condition make_error_condition(errc _e) { > + return error_condition(static_cast<int>(_e)); > +}
This test could use a comment explaining what it is actually testing. -Eli _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
