]> granicus.if.org Git - clang/commitdiff
Enable correcting a member declaration where the type is class template,
authorKaelyn Uhrain <rikka@google.com>
Thu, 13 Feb 2014 20:14:07 +0000 (20:14 +0000)
committerKaelyn Uhrain <rikka@google.com>
Thu, 13 Feb 2014 20:14:07 +0000 (20:14 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@201360 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/Sema.h
lib/Parse/ParseDecl.cpp
lib/Sema/SemaDecl.cpp
test/SemaCXX/typo-correction-pt2.cpp

index df3cc596f4f62def9b41ab8ccf45a24d2484e7d4..d32507a06db49237d4977e4b9364af4ff481c9f0 100644 (file)
@@ -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().
index 0950ab09b76f60b27d00528ec448f126f51bcf8b..20ac4df54468b4134627852c3448c6b779f16858 100644 (file)
@@ -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
index 17e0f38e07de3af55f01dd357a7191b62bc9708c..72210757f34b890df800023648760b1c1593d550 100644 (file)
@@ -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)) {
index 1738bb41b912e496988ce329fbe3521013969adb..e08bef0741e3c0e80ffd22bbc00d808f88ff8454 100644 (file)
@@ -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}}
+};
+}