[cfe-commits] r141621 - in /cfe/trunk: include/clang/Parse/Parser.h include/clang/Sema/Sema.h lib/Parse/ParseDecl.cpp lib/Parse/Parser.cpp lib/Sema/SemaDecl.cpp test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp test/SemaCXX/typo-corre
Eli Friedman
eli.friedman at gmail.com
Mon Oct 10 18:22:02 PDT 2011
On Mon, Oct 10, 2011 at 6:02 PM, Kaelyn Uhrain <rikka at google.com> 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
More information about the cfe-commits
mailing list