]> granicus.if.org Git - clang/commitdiff
When entering the scope of a declarator, make sure that the scope is
authorDouglas Gregor <dgregor@apple.com>
Thu, 24 Sep 2009 23:39:01 +0000 (23:39 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 24 Sep 2009 23:39:01 +0000 (23:39 +0000)
complete (or, possibly causing template instantiation).

Test this via some explicit specializations of member functions.

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

include/clang/Parse/Action.h
include/clang/Parse/Parser.h
lib/Sema/Sema.h
lib/Sema/SemaCXXScopeSpec.cpp
test/SemaTemplate/explicit-specialization-member.cpp [new file with mode: 0644]

index df85dfe8eb96739048ea713f916c8736fc9e7c56..8fdf779acde1391f791856ba4dcb9f32131055d8 100644 (file)
@@ -300,7 +300,9 @@ public:
   /// looked up in the declarator-id's scope, until the declarator is parsed and
   /// ActOnCXXExitDeclaratorScope is called.
   /// The 'SS' should be a non-empty valid CXXScopeSpec.
-  virtual void ActOnCXXEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
+  /// \returns true if an error occurred, false otherwise.
+  virtual bool ActOnCXXEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
+    return false;
   }
 
   /// ActOnCXXExitDeclaratorScope - Called when a declarator that previously
index b9b17d24d16c12acaf39f76e55474707c9db20b0..e11ca0ce6b17a5e08609189ea61081b498991d16 100644 (file)
@@ -1123,7 +1123,9 @@ private:
     void EnterDeclaratorScope() {
       assert(!EnteredScope && "Already entered the scope!");
       assert(SS.isSet() && "C++ scope was not set!");
-      P.Actions.ActOnCXXEnterDeclaratorScope(P.CurScope, SS);
+      if (P.Actions.ActOnCXXEnterDeclaratorScope(P.CurScope, SS))
+        SS.setScopeRep(0);
+      
       if (!SS.isInvalid())
         EnteredScope = true;
     }
index 18b56c5bfb2b62cab7d0b13c946287c748659149..0bb72568b19e601a4e51f7387e7f305aafc00b03 100644 (file)
@@ -2151,7 +2151,7 @@ public:
   /// looked up in the declarator-id's scope, until the declarator is parsed and
   /// ActOnCXXExitDeclaratorScope is called.
   /// The 'SS' should be a non-empty valid CXXScopeSpec.
-  virtual void ActOnCXXEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS);
+  virtual bool ActOnCXXEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS);
 
   /// ActOnCXXExitDeclaratorScope - Called when a declarator that previously
   /// invoked ActOnCXXEnterDeclaratorScope(), is finished. 'SS' is the same
index 60661f147e1c3cbcad17df2eda99f8a174b81cc5..8f536da777200f4d128dd2c48594cc272c7bbc26 100644 (file)
@@ -519,10 +519,18 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
 /// looked up in the declarator-id's scope, until the declarator is parsed and
 /// ActOnCXXExitDeclaratorScope is called.
 /// The 'SS' should be a non-empty valid CXXScopeSpec.
-void Sema::ActOnCXXEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
+bool Sema::ActOnCXXEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
   assert(SS.isSet() && "Parser passed invalid CXXScopeSpec.");
-  if (DeclContext *DC = computeDeclContext(SS, true))
+  if (DeclContext *DC = computeDeclContext(SS, true)) {
+    // Before we enter a declarator's context, we need to make sure that
+    // it is a complete declaration context.
+    if (!DC->isDependentContext() && RequireCompleteDeclContext(SS))
+      return true;
+      
     EnterDeclaratorContext(S, DC);
+  }
+  
+  return false;
 }
 
 /// ActOnCXXExitDeclaratorScope - Called when a declarator that previously
diff --git a/test/SemaTemplate/explicit-specialization-member.cpp b/test/SemaTemplate/explicit-specialization-member.cpp
new file mode 100644 (file)
index 0000000..197dae5
--- /dev/null
@@ -0,0 +1,11 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+template<typename T>
+struct X0 {
+  typedef T* type;
+  
+  void f0(T);
+  void f1(type);
+};
+
+template<> void X0<char>::f0(char);
+template<> void X0<char>::f1(type);