]> granicus.if.org Git - clang/commitdiff
Split FunctionScopeInfo and BlockScopeInfo into their own header.
authorJohn McCall <rjmccall@apple.com>
Wed, 25 Aug 2010 08:40:02 +0000 (08:40 +0000)
committerJohn McCall <rjmccall@apple.com>
Wed, 25 Aug 2010 08:40:02 +0000 (08:40 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112038 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/ScopeInfo.h [new file with mode: 0644]
include/clang/Sema/Sema.h
lib/Sema/Sema.cpp
lib/Sema/SemaChecking.cpp
lib/Sema/SemaCodeComplete.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclObjC.cpp
lib/Sema/SemaExpr.cpp
lib/Sema/SemaLookup.cpp
lib/Sema/SemaStmt.cpp
lib/Sema/TreeTransform.h

diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h
new file mode 100644 (file)
index 0000000..50cfa9b
--- /dev/null
@@ -0,0 +1,137 @@
+//===--- ScopeInfo.h - Information about a semantic context -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines FunctionScopeInfo and BlockScopeInfo.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_SCOPE_INFO_H
+#define LLVM_CLANG_SEMA_SCOPE_INFO_H
+
+#include "clang/AST/Type.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+
+class BlockDecl;
+class IdentifierInfo;
+class LabelStmt;
+class ReturnStmt;
+class Scope;
+class SwitchStmt;
+
+namespace sema {
+
+/// \brief Retains information about a function, method, or block that is
+/// currently being parsed.
+class FunctionScopeInfo {
+public:
+
+  /// \brief Whether this scope information structure defined information for
+  /// a block.
+  bool IsBlockInfo;
+
+  /// \brief Whether this function contains a VLA, @try, try, C++
+  /// initializer, or anything else that can't be jumped past.
+  bool HasBranchProtectedScope;
+
+  /// \brief Whether this function contains any switches or direct gotos.
+  bool HasBranchIntoScope;
+
+  /// \brief Whether this function contains any indirect gotos.
+  bool HasIndirectGoto;
+
+  /// \brief The number of errors that had occurred before starting this
+  /// function or block.
+  unsigned NumErrorsAtStartOfFunction;
+
+  /// LabelMap - This is a mapping from label identifiers to the LabelStmt for
+  /// it (which acts like the label decl in some ways).  Forward referenced
+  /// labels have a LabelStmt created for them with a null location & SubStmt.
+  llvm::DenseMap<IdentifierInfo*, LabelStmt*> LabelMap;
+
+  /// SwitchStack - This is the current set of active switch statements in the
+  /// block.
+  llvm::SmallVector<SwitchStmt*, 8> SwitchStack;
+
+  /// \brief The list of return statements that occur within the function or
+  /// block, if there is any chance of applying the named return value
+  /// optimization.
+  llvm::SmallVector<ReturnStmt *, 4> Returns;
+
+  void setHasBranchIntoScope() {
+    HasBranchIntoScope = true;
+  }
+
+  void setHasBranchProtectedScope() {
+    HasBranchProtectedScope = true;
+  }
+
+  void setHasIndirectGoto() {
+    HasIndirectGoto = true;
+  }
+
+  bool NeedsScopeChecking() const {
+    return HasIndirectGoto ||
+          (HasBranchProtectedScope && HasBranchIntoScope);
+  }
+  
+  FunctionScopeInfo(unsigned NumErrors)
+    : IsBlockInfo(false),
+      HasBranchProtectedScope(false),
+      HasBranchIntoScope(false),
+      HasIndirectGoto(false),
+      NumErrorsAtStartOfFunction(NumErrors) { }
+
+  virtual ~FunctionScopeInfo();
+
+  /// \brief Clear out the information in this function scope, making it
+  /// suitable for reuse.
+  void Clear(unsigned NumErrors);
+
+  static bool classof(const FunctionScopeInfo *FSI) { return true; }
+};
+
+/// \brief Retains information about a block that is currently being parsed.
+class BlockScopeInfo : public FunctionScopeInfo {
+public:
+  bool hasBlockDeclRefExprs;
+
+  BlockDecl *TheDecl;
+  
+  /// TheScope - This is the scope for the block itself, which contains
+  /// arguments etc.
+  Scope *TheScope;
+
+  /// ReturnType - The return type of the block, or null if the block
+  /// signature didn't provide an explicit return type.
+  QualType ReturnType;
+
+  /// BlockType - The function type of the block, if one was given.
+  /// Its return type may be BuiltinType::Dependent.
+  QualType FunctionType;
+
+  BlockScopeInfo(unsigned NumErrors, Scope *BlockScope, BlockDecl *Block)
+    : FunctionScopeInfo(NumErrors), hasBlockDeclRefExprs(false),
+      TheDecl(Block), TheScope(BlockScope)
+  {
+    IsBlockInfo = true;
+  }
+
+  virtual ~BlockScopeInfo();
+
+  static bool classof(const FunctionScopeInfo *FSI) { return FSI->IsBlockInfo; }
+  static bool classof(const BlockScopeInfo *BSI) { return true; }
+};
+
+}
+}
+
+#endif
index 2c06bcaf9820c593a019980f8b39796ba4d92a6f..01c5a41b428b57887357adab05b4c8b34003e004 100644 (file)
@@ -121,97 +121,11 @@ namespace clang {
 
 namespace sema {
   class AccessedEntity;
+  class BlockScopeInfo;
+  class FunctionScopeInfo;
   class TemplateDeductionInfo;
 }  
 
-/// \brief Retains information about a function, method, or block that is
-/// currently being parsed.
-struct FunctionScopeInfo {
-  /// \brief Whether this scope information structure defined information for
-  /// a block.
-  bool IsBlockInfo;
-
-  /// \brief Whether this function contains a VLA, @try, try, C++
-  /// initializer, or anything else that can't be jumped past.
-  bool HasBranchProtectedScope;
-
-  /// \brief Whether this function contains any switches or direct gotos.
-  bool HasBranchIntoScope;
-
-  /// \brief Whether this function contains any indirect gotos.
-  bool HasIndirectGoto;
-
-  /// \brief The number of errors that had occurred before starting this
-  /// function or block.
-  unsigned NumErrorsAtStartOfFunction;
-
-  /// LabelMap - This is a mapping from label identifiers to the LabelStmt for
-  /// it (which acts like the label decl in some ways).  Forward referenced
-  /// labels have a LabelStmt created for them with a null location & SubStmt.
-  llvm::DenseMap<IdentifierInfo*, LabelStmt*> LabelMap;
-
-  /// SwitchStack - This is the current set of active switch statements in the
-  /// block.
-  llvm::SmallVector<SwitchStmt*, 8> SwitchStack;
-
-  /// \brief The list of return statements that occur within the function or
-  /// block, if there is any chance of applying the named return value
-  /// optimization.
-  llvm::SmallVector<ReturnStmt *, 4> Returns;
-
-  bool NeedsScopeChecking() const {
-    return HasIndirectGoto ||
-          (HasBranchProtectedScope && HasBranchIntoScope);
-  }
-  
-  FunctionScopeInfo(unsigned NumErrors)
-    : IsBlockInfo(false),
-      HasBranchProtectedScope(false),
-      HasBranchIntoScope(false),
-      HasIndirectGoto(false),
-      NumErrorsAtStartOfFunction(NumErrors) { }
-
-  virtual ~FunctionScopeInfo();
-
-  /// \brief Clear out the information in this function scope, making it
-  /// suitable for reuse.
-  void Clear(unsigned NumErrors);
-
-  static bool classof(const FunctionScopeInfo *FSI) { return true; }
-};
-
-
-/// \brief Retains information about a block that is currently being parsed.
-struct BlockScopeInfo : FunctionScopeInfo {
-  bool hasBlockDeclRefExprs;
-
-  BlockDecl *TheDecl;
-  
-  /// TheScope - This is the scope for the block itself, which contains
-  /// arguments etc.
-  Scope *TheScope;
-
-  /// ReturnType - The return type of the block, or null if the block
-  /// signature didn't provide an explicit return type.
-  QualType ReturnType;
-
-  /// BlockType - The function type of the block, if one was given.
-  /// Its return type may be BuiltinType::Dependent.
-  QualType FunctionType;
-
-  BlockScopeInfo(unsigned NumErrors, Scope *BlockScope, BlockDecl *Block)
-    : FunctionScopeInfo(NumErrors), hasBlockDeclRefExprs(false),
-      TheDecl(Block), TheScope(BlockScope)
-  {
-    IsBlockInfo = true;
-  }
-
-  virtual ~BlockScopeInfo();
-
-  static bool classof(const FunctionScopeInfo *FSI) { return FSI->IsBlockInfo; }
-  static bool classof(const BlockScopeInfo *BSI) { return true; }
-};
-
 /// \brief Holds a QualType and a TypeSourceInfo* that came out of a declarator
 /// parsing.
 ///
@@ -303,16 +217,11 @@ public:
   /// VisContext - Manages the stack for #pragma GCC visibility.
   void *VisContext; // Really a "PragmaVisStack*"
 
-  /// \brief Stack containing information about each of the nested function,
-  /// block, and method scopes that are currently active.
-  llvm::SmallVector<FunctionScopeInfo *, 4> FunctionScopes;
-
-  /// \brief Cached function scope object used for the top function scope
-  /// and when there is no function scope (in error cases).
+  /// \brief Stack containing information about each of the nested
+  /// function, block, and method scopes that are currently active.
   ///
-  /// This should never be accessed directly; rather, its address will
-  /// be pushed into \c FunctionScopes when we want to re-use it.
-  FunctionScopeInfo TopFunctionScope;
+  /// This array is never empty, but the first element is meaningless.
+  llvm::SmallVector<sema::FunctionScopeInfo *, 4> FunctionScopes;
 
   /// ExprTemporaries - This is the stack of temporaries that are created by
   /// the current full expression.
@@ -727,52 +636,14 @@ public:
   void PushBlockScope(Scope *BlockScope, BlockDecl *Block);
   void PopFunctionOrBlockScope();
 
-  /// getLabelMap() - Return the current label map.  If we're in a block, we
-  /// return it.
-  llvm::DenseMap<IdentifierInfo*, LabelStmt*> &getLabelMap() {
-    if (FunctionScopes.empty())
-      return TopFunctionScope.LabelMap;
-
-    return FunctionScopes.back()->LabelMap;
-  }
-
-  /// getSwitchStack - This is returns the switch stack for the current block or
-  /// function.
-  llvm::SmallVector<SwitchStmt*,8> &getSwitchStack() {
-    if (FunctionScopes.empty())
-      return TopFunctionScope.SwitchStack;
-
-    return FunctionScopes.back()->SwitchStack;
+  sema::FunctionScopeInfo *getCurFunction() const {
+    return FunctionScopes.back();
   }
 
-  /// \brief Determine whether the current function or block needs scope
-  /// checking.
-  bool FunctionNeedsScopeChecking() {
-    if (!FunctionScopes.empty())
-      return FunctionScopes.back()->NeedsScopeChecking();
-    return false;
-  }
-
-  void setFunctionHasBranchIntoScope() {
-    if (!FunctionScopes.empty())
-      FunctionScopes.back()->HasBranchIntoScope = true;
-  }
-
-  void setFunctionHasBranchProtectedScope() {
-    if (!FunctionScopes.empty())
-      FunctionScopes.back()->HasBranchProtectedScope = true;
-  }
-
-  void setFunctionHasIndirectGoto() {
-    if (!FunctionScopes.empty())
-      FunctionScopes.back()->HasIndirectGoto = true;
-  }
-  
-
   bool hasAnyErrorsInThisFunction() const;
 
   /// \brief Retrieve the current block, if any.
-  BlockScopeInfo *getCurBlock();
+  sema::BlockScopeInfo *getCurBlock();
 
   /// WeakTopLevelDeclDecls - access to #pragma weak-generated Decls
   llvm::SmallVector<Decl*,2> &WeakTopLevelDecls() { return WeakTopLevelDecl; }
index 1de7b7fbead873c9eb4e8ddb86c997f99f048456..2320d7dc3234906bca2131b496b179f1402b5f84 100644 (file)
@@ -20,6 +20,7 @@
 #include "clang/Sema/CXXFieldCollector.h"
 #include "clang/Sema/ExternalSemaSource.h"
 #include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
 #include "clang/Sema/SemaConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTDiagnostic.h"
@@ -30,6 +31,7 @@
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/TargetInfo.h"
 using namespace clang;
+using namespace sema;
 
 FunctionScopeInfo::~FunctionScopeInfo() { }
 
@@ -129,7 +131,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
     LangOpts(pp.getLangOptions()), PP(pp), Context(ctxt), Consumer(consumer),
     Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()),
     ExternalSource(0), CodeCompleter(CodeCompleter), CurContext(0), 
-    PackContext(0), VisContext(0), TopFunctionScope(0), ParsingDeclDepth(0),
+    PackContext(0), VisContext(0), ParsingDeclDepth(0),
     IdResolver(pp.getLangOptions()), GlobalNewDeleteDeclared(false), 
     CompleteTranslationUnit(CompleteTranslationUnit),
     NumSFINAEErrors(0), SuppressAccessChecking(false),
@@ -146,6 +148,8 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
 
   ExprEvalContexts.push_back(
                   ExpressionEvaluationContextRecord(PotentiallyEvaluated, 0));  
+
+  FunctionScopes.push_back(new FunctionScopeInfo(Diags.getNumErrors()));
 }
 
 void Sema::Initialize() {
@@ -166,8 +170,12 @@ Sema::~Sema() {
   if (PackContext) FreePackedContext();
   if (VisContext) FreeVisContext();
   delete TheTargetAttributesSema;
-  while (!FunctionScopes.empty())
-    PopFunctionOrBlockScope();
+
+  // Kill all the active scopes.
+  for (unsigned I = 1, E = FunctionScopes.size(); I != E; ++I)
+    delete FunctionScopes[I];
+  if (FunctionScopes.size() == 1)
+    delete FunctionScopes[0];
   
   // Tell the SemaConsumer to forget about us; we're going out of scope.
   if (SemaConsumer *SC = dyn_cast<SemaConsumer>(&Consumer))
@@ -510,11 +518,11 @@ Scope *Sema::getScopeForContext(DeclContext *Ctx) {
 
 /// \brief Enter a new function scope
 void Sema::PushFunctionScope() {
-  if (FunctionScopes.empty()) {
-    // Use the "top" function scope rather than having to allocate memory for
-    // a new scope.
-    TopFunctionScope.Clear(getDiagnostics().getNumErrors());
-    FunctionScopes.push_back(&TopFunctionScope);
+  if (FunctionScopes.size() == 1) {
+    // Use the "top" function scope rather than having to allocate
+    // memory for a new scope.
+    FunctionScopes.back()->Clear(getDiagnostics().getNumErrors());
+    FunctionScopes.push_back(FunctionScopes.back());
     return;
   }
   
@@ -528,21 +536,17 @@ void Sema::PushBlockScope(Scope *BlockScope, BlockDecl *Block) {
 }
 
 void Sema::PopFunctionOrBlockScope() {
-  if (FunctionScopes.back() != &TopFunctionScope)
-    delete FunctionScopes.back();
-  else
-    TopFunctionScope.Clear(getDiagnostics().getNumErrors());
-  
-  FunctionScopes.pop_back();
+  FunctionScopeInfo *Scope = FunctionScopes.pop_back_val();
+  assert(!FunctionScopes.empty() && "mismatched push/pop!");
+  if (FunctionScopes.back() != Scope)
+    delete Scope;
 }
 
 /// \brief Determine whether any errors occurred within this function/method/
 /// block.
 bool Sema::hasAnyErrorsInThisFunction() const {
-  unsigned NumErrors = TopFunctionScope.NumErrorsAtStartOfFunction;
-  if (!FunctionScopes.empty())
-    NumErrors = FunctionScopes.back()->NumErrorsAtStartOfFunction;
-  return NumErrors != getDiagnostics().getNumErrors();
+  return getCurFunction()->NumErrorsAtStartOfFunction
+             != getDiagnostics().getNumErrors();
 }
 
 BlockScopeInfo *Sema::getCurBlock() {
index 7a64511f32290b4c683d41edd147213e2f080122..7ea96f4014e5b03c5acbc7ddff0d7381a17a9da9 100644 (file)
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Sema/Sema.h"
+#include "clang/Sema/ScopeInfo.h"
 #include "clang/Analysis/Analyses/FormatString.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CharUnits.h"
@@ -32,6 +33,7 @@
 #include "clang/Basic/TargetInfo.h"
 #include <limits>
 using namespace clang;
+using namespace sema;
 
 /// getLocationOfStringLiteralByte - Return a source location that points to the
 /// specified byte of the specified string literal.
index 4228bed9ee0f4b694b92aa641fe2864daf4b3ef6..ad4382e09b384a2498e9e2e1cae896894d931c48 100644 (file)
@@ -16,6 +16,7 @@
 #include "clang/Sema/CodeCompleteConsumer.h"
 #include "clang/Sema/ExternalSemaSource.h"
 #include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
@@ -29,6 +30,7 @@
 #include <vector>
 
 using namespace clang;
+using namespace sema;
 
 namespace {
   /// \brief A container of code-completion results.
@@ -1376,7 +1378,7 @@ static void AddOrdinaryNameResults(Action::ParserCompletionContext CCC,
     }
     
     // Switch-specific statements.
-    if (!SemaRef.getSwitchStack().empty()) {
+    if (!SemaRef.getCurFunction()->SwitchStack.empty()) {
       // case expression:
       Pattern = new CodeCompletionString;
       Pattern->AddTypedTextChunk("case");
@@ -2751,10 +2753,10 @@ void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
 }
 
 void Sema::CodeCompleteCase(Scope *S) {
-  if (getSwitchStack().empty() || !CodeCompleter)
+  if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
     return;
   
-  SwitchStmt *Switch = getSwitchStack().back();
+  SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
   if (!Switch->getCond()->getType()->isEnumeralType()) {
     CodeCompleteExpressionData Data(Switch->getCond()->getType());
     Data.IntegralConstantExpression = true;
index 219a46d7dadb10e1b59d01f324ae85f417f749c8..659c0d1a92b122d4b735487406ef7da48af7585f 100644 (file)
@@ -16,6 +16,7 @@
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/CXXFieldCollector.h"
 #include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
 #include "clang/AST/APValue.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
@@ -39,6 +40,7 @@
 #include <cstring>
 #include <functional>
 using namespace clang;
+using namespace sema;
 
 /// getDeclName - Return a pretty name for the specified decl if possible, or
 /// an empty string if not.  This is used for pretty crash reporting.
@@ -2546,7 +2548,7 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
   // that redeclarations will match.
   QualType T = NewTD->getUnderlyingType();
   if (T->isVariablyModifiedType()) {
-    setFunctionHasBranchProtectedScope();
+    getCurFunction()->setHasBranchProtectedScope();
 
     if (S->getFnParent() == 0) {
       bool SizeIsNegative;
@@ -2983,7 +2985,7 @@ void Sema::CheckVariableDeclaration(VarDecl *NewVD,
   bool isVM = T->isVariablyModifiedType();
   if (isVM || NewVD->hasAttr<CleanupAttr>() ||
       NewVD->hasAttr<BlocksAttr>())
-    setFunctionHasBranchProtectedScope();
+    getCurFunction()->setHasBranchProtectedScope();
 
   if ((isVM && NewVD->hasLinkage()) ||
       (T->isVariableArrayType() && NewVD->hasGlobalStorage())) {
@@ -4152,7 +4154,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
   }  
 
   if (getLangOptions().CPlusPlus && VDecl->hasLocalStorage())
-    setFunctionHasBranchProtectedScope();
+    getCurFunction()->setHasBranchProtectedScope();
 
   // Capture the variable that is being initialized and the style of
   // initialization.
@@ -4477,7 +4479,7 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl,
       // clarifies that this applies to a "variable with automatic
       // storage duration", not a "local variable".
       if (getLangOptions().CPlusPlus && Var->hasLocalStorage())
-        setFunctionHasBranchProtectedScope();
+        getCurFunction()->setHasBranchProtectedScope();
 
       InitializedEntity Entity = InitializedEntity::InitializeVariable(Var);
       InitializationKind Kind
@@ -4901,9 +4903,11 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) {
 /// FIXME: Employ a smarter algorithm that accounts for multiple return 
 /// statements and the lifetimes of the NRVO candidates. We should be able to
 /// find a maximal set of NRVO variables.
-static void ComputeNRVO(Stmt *Body, ReturnStmt **Returns, unsigned NumReturns) {
+static void ComputeNRVO(Stmt *Body, FunctionScopeInfo *Scope) {
+  ReturnStmt **Returns = Scope->Returns.data();
+
   const VarDecl *NRVOCandidate = 0;
-  for (unsigned I = 0; I != NumReturns; ++I) {
+  for (unsigned I = 0, E = Scope->Returns.size(); I != E; ++I) {
     if (!Returns[I]->getNRVOCandidate())
       return;
     
@@ -4948,8 +4952,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
       if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(FD))
         MarkVTableUsed(FD->getLocation(), Constructor->getParent());
       
-      ComputeNRVO(Body, FunctionScopes.back()->Returns.data(),
-                  FunctionScopes.back()->Returns.size());
+      ComputeNRVO(Body, getCurFunction());
     }
     
     assert(FD == getCurFunctionDecl() && "Function parsing confused");
@@ -4966,8 +4969,9 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
   // Verify and clean out per-function state.
 
   // Check goto/label use.
+  FunctionScopeInfo *CurFn = getCurFunction();
   for (llvm::DenseMap<IdentifierInfo*, LabelStmt*>::iterator
-       I = getLabelMap().begin(), E = getLabelMap().end(); I != E; ++I) {
+         I = CurFn->LabelMap.begin(), E = CurFn->LabelMap.end(); I != E; ++I) {
     LabelStmt *L = I->second;
 
     // Verify that we have no forward references left.  If so, there was a goto
@@ -5013,7 +5017,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
     
     // Verify that that gotos and switch cases don't jump into scopes illegally.
     // Verify that that gotos and switch cases don't jump into scopes illegally.
-    if (FunctionNeedsScopeChecking() &&
+    if (getCurFunction()->NeedsScopeChecking() &&
         !dcl->isInvalidDecl() &&
         !hasAnyErrorsInThisFunction())
       DiagnoseInvalidJumps(Body);
index b4acfbd04433c83938c524c386a21651398b8b90..13e42edaae6edc5cfe3085449140ad93a2e1ae0c 100644 (file)
@@ -15,6 +15,7 @@
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/ExternalSemaSource.h"
 #include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
@@ -1480,7 +1481,7 @@ Decl *Sema::ActOnMethodDeclaration(
   // Make sure we can establish a context for the method.
   if (!ClassDecl) {
     Diag(MethodLoc, diag::error_missing_method_context);
-    getLabelMap().clear();
+    getCurFunction()->LabelMap.clear();
     return 0;
   }
   QualType resultDeclType;
index ae8e657aee866111879cf3bc51447a4e6a1ab817..5986eca373724808f3489df9d076aee84115f997 100644 (file)
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/Designator.h"
 #include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
 #include "clang/Sema/ParsedTemplate.h"
 #include "clang/Sema/Template.h"
 using namespace clang;
+using namespace sema;
 
 
 /// \brief Determine whether the use of this declaration is valid, and
@@ -6790,7 +6792,7 @@ ExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc,
                                             SourceLocation LabLoc,
                                             IdentifierInfo *LabelII) {
   // Look up the record for this label identifier.
-  LabelStmt *&LabelDecl = getLabelMap()[LabelII];
+  LabelStmt *&LabelDecl = getCurFunction()->LabelMap[LabelII];
 
   // If we haven't seen this label yet, create a forward reference. It
   // will be validated and/or cleaned up in ActOnFinishFunctionBody.
@@ -7268,7 +7270,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
   BlockTy = Context.getBlockPointerType(BlockTy);
 
   // If needed, diagnose invalid gotos and switches in the block.
-  if (FunctionNeedsScopeChecking() && !hasAnyErrorsInThisFunction())
+  if (getCurFunction()->NeedsScopeChecking() && !hasAnyErrorsInThisFunction())
     DiagnoseInvalidJumps(cast<CompoundStmt>(Body));
 
   BSI->TheDecl->setBody(cast<CompoundStmt>(Body));
index 8c8c0073b3ab83e3e8855de8e5f19c5982688426..4cc78ef976ff5793f792dd8b0970ed0050cd214e 100644 (file)
@@ -15,6 +15,7 @@
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
 #include "clang/Sema/TemplateDeduction.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CXXInheritance.h"
@@ -2986,7 +2987,7 @@ DeclarationName Sema::CorrectTypo(LookupResult &Res, Scope *S, CXXScopeSpec *SS,
       if (S && S->getContinueParent())
         Consumer.addKeywordResult(Context, "continue");
       
-      if (!getSwitchStack().empty()) {
+      if (!getCurFunction()->SwitchStack.empty()) {
         Consumer.addKeywordResult(Context, "case");
         Consumer.addKeywordResult(Context, "default");
       }
index 7f88e2ff52fe2247050383b601822c2a8989541a..41aec13e8222d2b976cf90e69ea57fa757e6e739 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "clang/Sema/Sema.h"
 #include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
 #include "clang/Sema/Initialization.h"
 #include "clang/AST/APValue.h"
 #include "clang/AST/ASTContext.h"
@@ -27,6 +28,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallVector.h"
 using namespace clang;
+using namespace sema;
 
 StmtResult Sema::ActOnExprStmt(FullExprArg expr) {
   Expr *E = expr.get();
@@ -190,14 +192,14 @@ Sema::ActOnCaseStmt(SourceLocation CaseLoc, Expr *LHSVal,
     RHSVal = 0;  // Recover by just forgetting about it.
   }
 
-  if (getSwitchStack().empty()) {
+  if (getCurFunction()->SwitchStack.empty()) {
     Diag(CaseLoc, diag::err_case_not_in_switch);
     return StmtError();
   }
 
   CaseStmt *CS = new (Context) CaseStmt(LHSVal, RHSVal, CaseLoc, DotDotDotLoc,
                                         ColonLoc);
-  getSwitchStack().back()->addSwitchCase(CS);
+  getCurFunction()->SwitchStack.back()->addSwitchCase(CS);
   return Owned(CS);
 }
 
@@ -210,13 +212,13 @@ void Sema::ActOnCaseStmtBody(Stmt *caseStmt, Stmt *SubStmt) {
 StmtResult
 Sema::ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc,
                        Stmt *SubStmt, Scope *CurScope) {
-  if (getSwitchStack().empty()) {
+  if (getCurFunction()->SwitchStack.empty()) {
     Diag(DefaultLoc, diag::err_default_not_in_switch);
     return Owned(SubStmt);
   }
 
   DefaultStmt *DS = new (Context) DefaultStmt(DefaultLoc, ColonLoc, SubStmt);
-  getSwitchStack().back()->addSwitchCase(DS);
+  getCurFunction()->SwitchStack.back()->addSwitchCase(DS);
   return Owned(DS);
 }
 
@@ -224,7 +226,7 @@ StmtResult
 Sema::ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II,
                      SourceLocation ColonLoc, Stmt *SubStmt) {
   // Look up the record for this label identifier.
-  LabelStmt *&LabelDecl = getLabelMap()[II];
+  LabelStmt *&LabelDecl = getCurFunction()->LabelMap[II];
 
   // If not forward referenced or defined already, just create a new LabelStmt.
   if (LabelDecl == 0)
@@ -421,10 +423,10 @@ Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, Expr *Cond,
     Cond = CondResult.take();
   }
 
-  setFunctionHasBranchIntoScope();
+  getCurFunction()->setHasBranchIntoScope();
     
   SwitchStmt *SS = new (Context) SwitchStmt(Context, ConditionVar, Cond);
-  getSwitchStack().push_back(SS);
+  getCurFunction()->SwitchStack.push_back(SS);
   return Owned(SS);
 }
 
@@ -432,10 +434,11 @@ StmtResult
 Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
                             Stmt *BodyStmt) {
   SwitchStmt *SS = cast<SwitchStmt>(Switch);
-  assert(SS == getSwitchStack().back() && "switch stack missing push/pop!");
+  assert(SS == getCurFunction()->SwitchStack.back() &&
+         "switch stack missing push/pop!");
 
   SS->setBody(BodyStmt, SwitchLoc);
-  getSwitchStack().pop_back();
+  getCurFunction()->SwitchStack.pop_back();
 
   if (SS->getCond() == 0)
     return StmtError();
@@ -941,9 +944,9 @@ StmtResult
 Sema::ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
                     IdentifierInfo *LabelII) {
   // Look up the record for this label identifier.
-  LabelStmt *&LabelDecl = getLabelMap()[LabelII];
+  LabelStmt *&LabelDecl = getCurFunction()->LabelMap[LabelII];
 
-  setFunctionHasBranchIntoScope();
+  getCurFunction()->setHasBranchIntoScope();
 
   // If we haven't seen this label yet, create a forward reference.
   if (LabelDecl == 0)
@@ -965,7 +968,7 @@ Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc,
       return StmtError();
   }
 
-  setFunctionHasIndirectGoto();
+  getCurFunction()->setHasIndirectGoto();
 
   return Owned(new (Context) IndirectGotoStmt(GotoLoc, StarLoc, E));
 }
@@ -1482,7 +1485,7 @@ Sema::ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body) {
 StmtResult
 Sema::ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try, 
                          MultiStmtArg CatchStmts, Stmt *Finally) {
-  setFunctionHasBranchProtectedScope();
+  getCurFunction()->setHasBranchProtectedScope();
   unsigned NumCatchStmts = CatchStmts.size();
   return Owned(ObjCAtTryStmt::Create(Context, AtLoc, Try,
                                      CatchStmts.release(),
@@ -1526,7 +1529,7 @@ Sema::ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw,
 StmtResult
 Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *SyncExpr,
                                   Stmt *SyncBody) {
-  setFunctionHasBranchProtectedScope();
+  getCurFunction()->setHasBranchProtectedScope();
 
   // Make sure the expression type is an ObjC pointer or "void *".
   if (!SyncExpr->getType()->isDependentType() &&
@@ -1632,7 +1635,7 @@ Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock,
     }
   }
 
-  setFunctionHasBranchProtectedScope();
+  getCurFunction()->setHasBranchProtectedScope();
 
   // FIXME: We should detect handlers that cannot catch anything because an
   // earlier handler catches a superclass. Need to find a method that is not
index fe1f6b96e866e45491de9ad88c8498ae83052813..432caa73294448feb424cb37cdbcc9304d65f44e 100644 (file)
@@ -16,6 +16,7 @@
 #include "clang/Sema/Sema.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/SemaDiagnostic.h"
+#include "clang/Sema/ScopeInfo.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
@@ -32,6 +33,7 @@
 #include <algorithm>
 
 namespace clang {
+using namespace sema;
 
 /// \brief A semantic tree transformation that allows one to transform one
 /// abstract syntax tree into another.