]> granicus.if.org Git - clang/commitdiff
Make IdentifierResolver::isDeclInScope regard declarations of a parent 'control'...
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Tue, 9 Sep 2008 21:57:58 +0000 (21:57 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Tue, 9 Sep 2008 21:57:58 +0000 (21:57 +0000)
The 'control' scope is the 'condition' scope of if/switch/while statements and the scope that contains the for-init-statement and 'condition' of a for statement.

e.g:
if (int x = 0 /*'control' scope*/) {
  // x will be regarded as part of this substatement scope.
} else {
  // and as part of this substatement scope too.
}

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

lib/Sema/IdentifierResolver.cpp
lib/Sema/IdentifierResolver.h

index 8c0c4d693268660c1f9b6f1527da3ae23de1b632..e97de7381785bc17ace3092df6ae8ac0fe79defa 100644 (file)
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "IdentifierResolver.h"
+#include "clang/Basic/LangOptions.h"
 #include <list>
 #include <vector>
 
@@ -144,9 +145,26 @@ IdentifierResolver::~IdentifierResolver() {
 /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
 /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
 /// true if 'D' belongs to the given declaration context.
-bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S) {
-  if (Ctx->isFunctionOrMethod())
-    return S->isDeclScope(D);
+bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx,
+                                       Scope *S) const {
+  if (Ctx->isFunctionOrMethod()) {
+    if (S->isDeclScope(D))
+      return true;
+    if (LangOpt.CPlusPlus) {
+      // C++ 3.3.2p4:
+      // Names declared in the for-init-statement, and in the condition of if,
+      // while, for, and switch statements are local to the if, while, for, or
+      // switch statement (including the controlled statement), and shall not be
+      // redeclared in a subsequent condition of that statement nor in the
+      // outermost block (or, for the if statement, any of the outermost blocks)
+      // of the controlled statement.
+      //
+      assert(S->getParent() && "No TUScope?");
+      if (S->getParent()->getFlags() & Scope::ControlScope)
+        return S->getParent()->isDeclScope(D);
+    }
+    return false;
+  }
 
   return LookupContext(D) == LookupContext(Ctx);
 }
index 82c4f06196aa534ad70da58b834ad3e65c58d0a8..c661145d89f6d76c7381799336ef1365ab063e5e 100644 (file)
@@ -207,7 +207,7 @@ public:
   /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
   /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
   /// true if 'D' belongs to the given declaration context.
-  static bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S = 0);
+  bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S = 0) const;
 
   /// AddDecl - Link the decl to its shadowed decl chain.
   void AddDecl(NamedDecl *D);