diff options
author | John McCall <rjmccall@apple.com> | 2010-08-25 08:40:02 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-08-25 08:40:02 +0000 |
commit | aab3e41eb2391fd6aeb6ff65adc78cf3d015af9f (patch) | |
tree | 6eae086730849fcad1e21036c70a3275857e18cd /clang/lib | |
parent | cfe41db403840e4b929db3e92f938f3da01bd772 (diff) | |
download | bcm5719-llvm-aab3e41eb2391fd6aeb6ff65adc78cf3d015af9f.tar.gz bcm5719-llvm-aab3e41eb2391fd6aeb6ff65adc78cf3d015af9f.zip |
Split FunctionScopeInfo and BlockScopeInfo into their own header.
llvm-svn: 112038
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/Sema.cpp | 40 | ||||
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaCodeComplete.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 24 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 33 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 2 |
9 files changed, 71 insertions, 50 deletions
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 1de7b7fbead..2320d7dc323 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -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() { diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 7a64511f322..7ea96f4014e 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -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. diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 4228bed9ee0..ad4382e09b3 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -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; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 219a46d7dad..659c0d1a92b 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -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); diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index b4acfbd0443..13e42edaae6 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -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; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index ae8e657aee8..5986eca3737 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -32,9 +32,11 @@ #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)); diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 8c8c0073b3a..4cc78ef976f 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -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"); } diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 7f88e2ff52f..41aec13e822 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -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 diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index fe1f6b96e86..432caa73294 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -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. |