[cfe-commits] r103323 - in /cfe/trunk: include/clang/AST/RecursiveASTVisitor.h lib/Frontend/BoostConAction.cpp lib/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaTemplate/instantiate-non-dependent-types.cpp

Douglas Gregor dgregor at apple.com
Fri May 7 16:12:07 PDT 2010


Author: dgregor
Date: Fri May  7 18:12:07 2010
New Revision: 103323

URL: http://llvm.org/viewvc/llvm-project?rev=103323&view=rev
Log:
When we encounter a non-dependent type during template instantiation,
mark any declarations we see inside of that type as
"referenced". Fixes PR7079.


Added:
    cfe/trunk/test/SemaTemplate/instantiate-non-dependent-types.cpp
Modified:
    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
    cfe/trunk/lib/Frontend/BoostConAction.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp

Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=103323&r1=103322&r2=103323&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Fri May  7 18:12:07 2010
@@ -257,6 +257,8 @@
    case Type::Class: DISPATCH(Class##Type, Class##Type, T.getTypePtr());
 #include "clang/AST/TypeNodes.def"
     }
+    
+    return false;
   }
   
   template<typename Derived>
@@ -291,6 +293,8 @@
     case NestedNameSpecifier::TypeSpecWithTemplate:
       return Visit(QualType(NNS->getAsType(), 0));
     }
+    
+    return false;
   }
 
   template<typename Derived>
@@ -327,6 +331,8 @@
       return getDerived().VisitTemplateArguments(Arg.pack_begin(), 
                                                  Arg.pack_size());
     }
+    
+    return false;
   }
   
   template<typename Derived>
@@ -614,7 +620,8 @@
       return true;
     
     if (T->getTemplateId() &&
-        getDerived().VisitTemplateSpecializationType(T->getTemplateId()))
+        getDerived().VisitTemplateSpecializationType(
+                  const_cast<TemplateSpecializationType *>(T->getTemplateId())))
       return true;
     
     return getDerived().VisitType(T);

Modified: cfe/trunk/lib/Frontend/BoostConAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/BoostConAction.cpp?rev=103323&r1=103322&r2=103323&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/BoostConAction.cpp (original)
+++ cfe/trunk/lib/Frontend/BoostConAction.cpp Fri May  7 18:12:07 2010
@@ -10,6 +10,7 @@
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include <cstdio>
+#include <iostream>
 using namespace clang;
 
 namespace {
@@ -19,6 +20,11 @@
     /// HandleTranslationUnit - This method is called when the ASTs for entire
     /// translation unit have been parsed.
     virtual void HandleTranslationUnit(ASTContext &Ctx);
+                                
+    bool VisitCXXRecordDecl(CXXRecordDecl *D) {
+      std::cout << D->getNameAsString() << std::endl;
+      return false;
+    }                                
   };
 }
 

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=103323&r1=103322&r2=103323&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri May  7 18:12:07 2010
@@ -1784,6 +1784,7 @@
   virtual void PopExpressionEvaluationContext();
 
   void MarkDeclarationReferenced(SourceLocation Loc, Decl *D);
+  void MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T);
   bool DiagRuntimeBehavior(SourceLocation Loc, const PartialDiagnostic &PD);
 
   // Primary Expressions.

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=103323&r1=103322&r2=103323&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri May  7 18:12:07 2010
@@ -22,6 +22,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
+#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/SourceManager.h"
@@ -7572,6 +7573,48 @@
   }
 }
 
+namespace {
+  // Mark all of the declarations referenced 
+  // FIXME: Not fully implemented yet! We need to have a better understanding
+  // of when we're entering 
+  class MarkReferencedDecls : public RecursiveASTVisitor<MarkReferencedDecls> {
+    Sema &S;
+    SourceLocation Loc;
+    
+  public:
+    typedef RecursiveASTVisitor<MarkReferencedDecls> Inherited;
+    
+    MarkReferencedDecls(Sema &S, SourceLocation Loc) : S(S), Loc(Loc) { }
+    
+    bool VisitTemplateArgument(const TemplateArgument &Arg);
+    bool VisitRecordType(RecordType *T);
+  };
+}
+
+bool MarkReferencedDecls::VisitTemplateArgument(const TemplateArgument &Arg) {
+  if (Arg.getKind() == TemplateArgument::Declaration) {
+    S.MarkDeclarationReferenced(Loc, Arg.getAsDecl());
+  }
+  
+  return Inherited::VisitTemplateArgument(Arg);
+}
+
+bool MarkReferencedDecls::VisitRecordType(RecordType *T) {
+  if (ClassTemplateSpecializationDecl *Spec
+                  = dyn_cast<ClassTemplateSpecializationDecl>(T->getDecl())) {
+    const TemplateArgumentList &Args = Spec->getTemplateArgs();
+    return VisitTemplateArguments(Args.getFlatArgumentList(), 
+                                  Args.flat_size());
+  }
+
+  return false;
+}
+
+void Sema::MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T) {
+  MarkReferencedDecls Marker(*this, Loc);
+  Marker.Visit(Context.getCanonicalType(T));
+}
+
 /// \brief Emit a diagnostic that describes an effect on the run-time behavior
 /// of the program being compiled.
 ///

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=103323&r1=103322&r2=103323&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Fri May  7 18:12:07 2010
@@ -560,9 +560,7 @@
     ///
     /// For the purposes of template instantiation, a type has already been
     /// transformed if it is NULL or if it is not dependent.
-    bool AlreadyTransformed(QualType T) {
-      return T.isNull() || !T->isDependentType();
-    }
+    bool AlreadyTransformed(QualType T);
 
     /// \brief Returns the location of the entity being instantiated, if known.
     SourceLocation getBaseLocation() { return Loc; }
@@ -624,6 +622,17 @@
   };
 }
 
+bool TemplateInstantiator::AlreadyTransformed(QualType T) {
+  if (T.isNull())
+    return true;
+  
+  if (T->isDependentType())
+    return false;
+  
+  getSema().MarkDeclarationsReferencedInType(Loc, T);
+  return true;
+}
+
 Decl *TemplateInstantiator::TransformDecl(SourceLocation Loc, Decl *D) {
   if (!D)
     return 0;

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=103323&r1=103322&r2=103323&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Fri May  7 18:12:07 2010
@@ -191,6 +191,8 @@
       Invalid = true;
       DI = SemaRef.Context.getTrivialTypeSourceInfo(SemaRef.Context.IntTy);
     }
+  } else {
+    SemaRef.MarkDeclarationsReferencedInType(D->getLocation(), DI->getType());
   }
 
   // Create the new typedef
@@ -440,6 +442,8 @@
         << DI->getType();
       Invalid = true;
     }
+  } else {
+    SemaRef.MarkDeclarationsReferencedInType(D->getLocation(), DI->getType());
   }
 
   Expr *BitWidth = D->getBitWidth();

Added: cfe/trunk/test/SemaTemplate/instantiate-non-dependent-types.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-non-dependent-types.cpp?rev=103323&view=auto
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-non-dependent-types.cpp (added)
+++ cfe/trunk/test/SemaTemplate/instantiate-non-dependent-types.cpp Fri May  7 18:12:07 2010
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T>
+struct X1 {
+  static void member() { T* x = 1; } // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}}
+};
+
+template<void(*)()> struct instantiate { };
+
+template<typename T>
+struct X2 {
+  typedef instantiate<&X1<int>::member> i; // expected-note{{in instantiation of}}
+};
+
+X2<int> x; 





More information about the cfe-commits mailing list