diff options
Diffstat (limited to 'lib/Sema/Sema.cpp')
-rw-r--r-- | lib/Sema/Sema.cpp | 64 |
1 files changed, 60 insertions, 4 deletions
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index fb7d1991fb..3b4afef70b 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -26,7 +26,18 @@ #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/TargetInfo.h" using namespace clang; - + +FunctionScopeInfo::~FunctionScopeInfo() { } + +void FunctionScopeInfo::Clear(unsigned NumErrors) { + NeedsScopeChecking = false; + LabelMap.clear(); + SwitchStack.clear(); + NumErrorsAtStartOfFunction = NumErrors; +} + +BlockScopeInfo::~BlockScopeInfo() { } + static inline RecordDecl *CreateStructDecl(ASTContext &C, const char *Name) { if (C.getLangOptions().CPlusPlus) return CXXRecordDecl::Create(C, TagDecl::TK_struct, @@ -116,7 +127,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), - CurBlock(0), PackContext(0), ParsingDeclDepth(0), + PackContext(0), TopFunctionScope(0), ParsingDeclDepth(0), IdResolver(pp.getLangOptions()), StdNamespace(0), StdBadAlloc(0), GlobalNewDeleteDeclared(false), CompleteTranslationUnit(CompleteTranslationUnit), @@ -127,8 +138,6 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, if (getLangOptions().CPlusPlus) FieldCollector.reset(new CXXFieldCollector()); - NumErrorsAtStartOfFunction = 0; - // Tell diagnostics how to render things from the AST library. PP.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument, &Context); @@ -140,6 +149,8 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, Sema::~Sema() { if (PackContext) FreePackedContext(); delete TheTargetAttributesSema; + while (!FunctionScopes.empty()) + PopFunctionOrBlockScope(); } /// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast. @@ -344,6 +355,51 @@ Sema::Diag(SourceLocation Loc, const PartialDiagnostic& PD) { return Builder; } + +/// \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); + return; + } + + FunctionScopes.push_back( + new FunctionScopeInfo(getDiagnostics().getNumErrors())); +} + +void Sema::PushBlockScope(Scope *BlockScope, BlockDecl *Block) { + FunctionScopes.push_back(new BlockScopeInfo(getDiagnostics().getNumErrors(), + BlockScope, Block)); +} + +void Sema::PopFunctionOrBlockScope() { + if (FunctionScopes.back() != &TopFunctionScope) + delete FunctionScopes.back(); + else + TopFunctionScope.Clear(getDiagnostics().getNumErrors()); + + FunctionScopes.pop_back(); +} + +/// \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(); +} + +BlockScopeInfo *Sema::getCurBlock() { + if (FunctionScopes.empty()) + return 0; + + return dyn_cast<BlockScopeInfo>(FunctionScopes.back()); +} + void Sema::ActOnComment(SourceRange Comment) { Context.Comments.push_back(Comment); } |