From: Chris Lattner Date: Thu, 4 Dec 2008 23:50:19 +0000 (+0000) Subject: change getCurFunctionDecl to skip through Block contexts to find X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=371f258e61e1365b951b17931a3c5ac1530fd1a0;p=clang change getCurFunctionDecl to skip through Block contexts to find the containing block. Introduce a new getCurFunctionOrMethodDecl method to check to see if we're in a function or objc method. Minor cleanups to other related places. This fixes rdar://6405429. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60564 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 35891b8b15..976d98be3a 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -57,8 +57,8 @@ protected: friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C); }; -/// NamedDecl - This represents a decl with a name. Many -/// decls have names, but not ObjCMethodDecl, @class, etc. +/// NamedDecl - This represents a decl with a name. Many decls have names such +/// as ObjCMethodDecl, but not @class, etc. class NamedDecl : public Decl { /// Name - The name of this declaration, which is typically a normal /// identifier but may also be a special kind of name (C++ diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 1a9e5fb30e..13226c0b0e 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -201,9 +201,29 @@ const LangOptions &Sema::getLangOptions() const { return PP.getLangOptions(); } +/// getCurFunctionDecl - If inside of a function body, this returns a pointer +/// to the function decl for the function being parsed. If we're currently +/// in a 'block', this returns the containing context. +FunctionDecl *Sema::getCurFunctionDecl() { + DeclContext *DC = CurContext; + while (isa(DC)) + DC = DC->getParent(); + return dyn_cast(DC); +} + ObjCMethodDecl *Sema::getCurMethodDecl() { DeclContext *DC = CurContext; while (isa(DC)) DC = DC->getParent(); return dyn_cast(DC); } + +NamedDecl *Sema::getCurFunctionOrMethodDecl() { + DeclContext *DC = CurContext; + while (isa(DC)) + DC = DC->getParent(); + if (isa(DC) || isa(DC)) + return cast(DC); + return 0; +} + diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index f82651bd28..ef15064638 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -329,16 +329,21 @@ public: void PushDeclContext(DeclContext *DC); void PopDeclContext(); - /// CurFunctionDecl - If inside of a function body, this returns a pointer to - /// the function decl for the function being parsed. - FunctionDecl *getCurFunctionDecl() { - return dyn_cast(CurContext); - } - - /// CurMethodDecl - If inside of a method body, this returns a pointer to - /// the method decl for the method being parsed. + /// getCurFunctionDecl - If inside of a function body, this returns a pointer + /// to the function decl for the function being parsed. If we're currently + /// in a 'block', this returns the containing context. + FunctionDecl *getCurFunctionDecl(); + + /// getCurMethodDecl - If inside of a method body, this returns a pointer to + /// the method decl for the method being parsed. If we're currently + /// in a 'block', this returns the containing context. ObjCMethodDecl *getCurMethodDecl(); + /// getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method + /// or C function we're in, otherwise return null. If we're currently + /// in a 'block', this returns the containing context. + NamedDecl *getCurFunctionOrMethodDecl(); + /// Add this decl to the scope shadowed decl chains. void PushOnScopeChains(NamedDecl *D, Scope *S); diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index bbc50d6bac..0c7da0edb0 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -184,8 +184,8 @@ bool Sema::SemaBuiltinVAStart(CallExpr *TheCall) { // FIXME: This isn't correct for methods (results in bogus warning). // Get the last formal in the current function. const ParmVarDecl *LastArg; - if (getCurFunctionDecl()) - LastArg = *(getCurFunctionDecl()->param_end()-1); + if (FunctionDecl *FD = getCurFunctionDecl()) + LastArg = *(FD->param_end()-1); else LastArg = *(getCurMethodDecl()->param_end()-1); SecondArgIsLastNamedArgument = PV == LastArg; diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 5aaa0dbc2f..ec86b9f2a6 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -505,14 +505,14 @@ Sema::ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, } // Verify that this is in a function context. - if (getCurFunctionDecl() == 0 && getCurMethodDecl() == 0) + if (getCurFunctionOrMethodDecl() == 0) return Diag(Loc, diag::err_predef_outside_function); // Pre-defined identifiers are of type char[x], where x is the length of the // string. unsigned Length; - if (getCurFunctionDecl()) - Length = getCurFunctionDecl()->getIdentifier()->getLength(); + if (FunctionDecl *FD = getCurFunctionDecl()) + Length = FD->getIdentifier()->getLength(); else Length = getCurMethodDecl()->getSynthesizedMethodSize(); @@ -1438,7 +1438,7 @@ ActOnCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty, DeclarationName())) return true; - bool isFileScope = !getCurFunctionDecl() && !getCurMethodDecl(); + bool isFileScope = getCurFunctionOrMethodDecl() == 0; if (isFileScope) { // 6.5.2.5p3 if (CheckForConstantInitializer(literalExpr, literalType)) return true; diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index a469713121..0159f5f0a5 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -750,9 +750,12 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprTy *rex) { Expr *RetValExp = static_cast(rex); if (CurBlock) return ActOnBlockReturnStmt(ReturnLoc, RetValExp); - QualType FnRetType = - getCurFunctionDecl() ? getCurFunctionDecl()->getResultType() : - getCurMethodDecl()->getResultType(); + + QualType FnRetType; + if (FunctionDecl *FD = getCurFunctionDecl()) + FnRetType = FD->getResultType(); + else + FnRetType = getCurMethodDecl()->getResultType(); if (FnRetType->isVoidType()) { if (RetValExp) {// C99 6.8.6.4p1 (ext_ since GCC warns) diff --git a/test/Sema/block-misc.c b/test/Sema/block-misc.c index 5509867c30..8349985ceb 100644 --- a/test/Sema/block-misc.c +++ b/test/Sema/block-misc.c @@ -70,3 +70,10 @@ void test5() { bar(^{ test5g = 1; }); } +// rdar://6405429 - __func__ in a block refers to the containing function name. +const char*test6() { + return ^{ + return __func__; + } (); +} +