]> granicus.if.org Git - clang/commitdiff
Handle predefined expression for a captured statement
authorWei Pan <wei.pan@intel.com>
Mon, 26 Aug 2013 14:27:34 +0000 (14:27 +0000)
committerWei Pan <wei.pan@intel.com>
Mon, 26 Aug 2013 14:27:34 +0000 (14:27 +0000)
- __func__ or __FUNCTION__ returns captured statement's parent
  function name, not the one compiler generated.

Differential Revision: http://llvm-reviews.chandlerc.com/D1491

Reviewed by bkramer

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@189219 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/Expr.cpp
lib/CodeGen/CGExpr.cpp
lib/Sema/SemaExpr.cpp
test/CodeGen/predefined-expr.c
test/SemaCXX/predefined-expr.cpp

index 0ba117e3e2a02e6d5f5ffd977f76d6e6bfe8de2f..ea91fbec4f85833c886bb9aa8bb8569e1e6d4b4c 100644 (file)
@@ -604,6 +604,16 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
     Out.flush();
     return Name.str().str();
   }
+  if (const CapturedDecl *CD = dyn_cast<CapturedDecl>(CurrentDecl)) {
+    for (const DeclContext *DC = CD->getParent(); DC; DC = DC->getParent())
+      // Skip to its enclosing function or method, but not its enclosing
+      // CapturedDecl.
+      if (DC->isFunctionOrMethod() && (DC->getDeclKind() != Decl::Captured)) {
+        const Decl *D = Decl::castFromDeclContext(DC);
+        return ComputeName(IT, D);
+      }
+    llvm_unreachable("CapturedDecl not inside a function or method");
+  }
   if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CurrentDecl)) {
     SmallString<256> Name;
     llvm::raw_svector_ostream Out(Name);
index f5ca2d09740db85f0c4f939aba1554b9445b2720..2579d5bd633bac83168b2bbf07b0fabc39d86b3e 100644 (file)
@@ -1972,6 +1972,10 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
       // Blocks use the mangled function name.
       // FIXME: ComputeName should handle blocks.
       FunctionName = FnName.str();
+    } else if (isa<CapturedDecl>(CurDecl)) {
+      // For a captured statement, the function name is its enclosing
+      // function name not the one compiler generated.
+      FunctionName = PredefinedExpr::ComputeName(IdentType, CurDecl);
     } else {
       FunctionName = PredefinedExpr::ComputeName(IdentType, CurDecl);
       assert(cast<ConstantArrayType>(E->getType())->getSize() - 1 ==
index 1c5e24e278f3bf7f4f902d2af598cf9048463487..e7061a682fd317c28a76bbf1fbe05cd9f0d3b620 100644 (file)
@@ -2765,6 +2765,8 @@ ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) {
     currentDecl = BSI->TheDecl;
   else if (const LambdaScopeInfo *LSI = getCurLambda())
     currentDecl = LSI->CallOperator;
+  else if (const CapturedRegionScopeInfo *CSI = getCurCapturedRegion())
+    currentDecl = CSI->TheCapturedDecl;
   else
     currentDecl = getCurFunctionOrMethodDecl();
 
index e2826b68d7df6432a4d82dc9428bb287fdd5df4b..3471dcdaa2a4aa3d396de0cba6d7717907ee995b 100644 (file)
@@ -6,6 +6,8 @@
 // CHECK: @__PRETTY_FUNCTION__.externFunction = private unnamed_addr constant [22 x i8] c"void externFunction()\00"
 // CHECK: @__func__.privateExternFunction = private unnamed_addr constant [22 x i8] c"privateExternFunction\00"
 // CHECK: @__PRETTY_FUNCTION__.privateExternFunction = private unnamed_addr constant [29 x i8] c"void privateExternFunction()\00"
+// CHECK: @__func__.__captured_stmt = private unnamed_addr constant [25 x i8] c"functionWithCapturedStmt\00"
+// CHECK: @__PRETTY_FUNCTION__.__captured_stmt = private unnamed_addr constant [32 x i8] c"void functionWithCapturedStmt()\00"
 // CHECK: @__func__.staticFunction = private unnamed_addr constant [15 x i8] c"staticFunction\00"
 // CHECK: @__PRETTY_FUNCTION__.staticFunction = private unnamed_addr constant [22 x i8] c"void staticFunction()\00"
 
@@ -29,6 +31,15 @@ __private_extern__ void privateExternFunction() {
   printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
 }
 
+void functionWithCapturedStmt() {
+  #pragma clang __debug captured
+  {
+    printf("__func__ %s\n", __func__);
+    printf("__FUNCTION__ %s\n", __FUNCTION__);
+    printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+  }
+}
+
 static void staticFunction() {
   printf("__func__ %s\n", __func__);
   printf("__FUNCTION__ %s\n", __FUNCTION__);
@@ -39,6 +50,7 @@ int main() {
   plainFunction();
   externFunction();
   privateExternFunction();
+  functionWithCapturedStmt();
   staticFunction();
 
   return 0;
index dc1c52fa4ba76d587835d4f22c9ef77c4e53aa27..e203dd4be8fd8288b352a77034e5f125730e3968 100644 (file)
@@ -37,4 +37,29 @@ int main() {
     static_assert(sizeof(__PRETTY_FUNCTION__) == 1, "__main_block_invoke");
   }
   ();
+
+  #pragma clang __debug captured
+  {
+    static_assert(sizeof(__func__) == 5, "main");
+    static_assert(sizeof(__FUNCTION__) == 5, "main");
+    static_assert(sizeof(__PRETTY_FUNCTION__) == 11, "int main()");
+
+    #pragma clang __debug captured
+    {
+      static_assert(sizeof(__func__) == 5, "main");
+      static_assert(sizeof(__FUNCTION__) == 5, "main");
+      static_assert(sizeof(__PRETTY_FUNCTION__) == 11, "int main()");
+    }
+  }
+
+  []() {
+    #pragma clang __debug captured
+    {
+      static_assert(sizeof(__func__) == 11, "operator()");
+      static_assert(sizeof(__FUNCTION__) == 11, "operator()");
+      static_assert(sizeof(__PRETTY_FUNCTION__) == 51,
+                    "auto main()::<anonymous class>::operator()() const");
+    }
+  }
+  ();
 }