]> granicus.if.org Git - clang/commitdiff
change getCurFunctionDecl to skip through Block contexts to find
authorChris Lattner <sabre@nondot.org>
Thu, 4 Dec 2008 23:50:19 +0000 (23:50 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 4 Dec 2008 23:50:19 +0000 (23:50 +0000)
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

include/clang/AST/Decl.h
lib/Sema/Sema.cpp
lib/Sema/Sema.h
lib/Sema/SemaChecking.cpp
lib/Sema/SemaExpr.cpp
lib/Sema/SemaStmt.cpp
test/Sema/block-misc.c

index 35891b8b153778a27780fcb563a830a298b87f0b..976d98be3a8e68db2cb9f6f36250caa0cc876ab5 100644 (file)
@@ -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++
index 1a9e5fb30eadde008d650a51e3c3c1950e107ddb..13226c0b0ea23e0899d0fbebb52d5aaad0473862 100644 (file)
@@ -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<BlockDecl>(DC))
+    DC = DC->getParent();
+  return dyn_cast<FunctionDecl>(DC);
+}
+
 ObjCMethodDecl *Sema::getCurMethodDecl() {
   DeclContext *DC = CurContext;
   while (isa<BlockDecl>(DC))
     DC = DC->getParent();
   return dyn_cast<ObjCMethodDecl>(DC);
 }
+
+NamedDecl *Sema::getCurFunctionOrMethodDecl() {
+  DeclContext *DC = CurContext;
+  while (isa<BlockDecl>(DC))
+    DC = DC->getParent();
+  if (isa<ObjCMethodDecl>(DC) || isa<FunctionDecl>(DC))
+    return cast<NamedDecl>(DC);
+  return 0;
+}
+
index f82651bd2816a6713cf00af835d9ac151549cec9..ef1506463814719be240e65a3a2dd4c11fbf3d44 100644 (file)
@@ -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<FunctionDecl>(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);
 
index bbc50d6bac49d1d4d239a85b1f9d3dad938afa8a..0c7da0edb05df3750042d2a3bbb114e0dc351495 100644 (file)
@@ -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;
index 5aaa0dbc2f4fcf8ff8b0fb6602ccd7cff105ca88..ec86b9f2a6bfcbc41eeed12036a260b9ad91f513 100644 (file)
@@ -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;
index a469713121daf5cc4f175c36e5e7c2737a439c8e..0159f5f0a5397f5e139e3f61b4b77f5e1f6649ac 100644 (file)
@@ -750,9 +750,12 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprTy *rex) {
   Expr *RetValExp = static_cast<Expr *>(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)
index 5509867c30afe17ee2fd029143bcff89b60ba112..8349985ceb5afb467ac6e7fcd6a02b639b6e8019 100644 (file)
@@ -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__;
+    } ();
+}
+