djtodoro updated this revision to Diff 186611.
djtodoro added a comment.

- Rename: `VariableNotChanged `===> `ArgumentNotModified`
- Refactor a test case


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D58035/new/

https://reviews.llvm.org/D58035

Files:
  include/clang/AST/Decl.h
  lib/CodeGen/CGDebugInfo.cpp
  lib/Sema/SemaExpr.cpp
  test/CodeGen/debug-info-varchange.c

Index: test/CodeGen/debug-info-varchange.c
===================================================================
--- /dev/null
+++ test/CodeGen/debug-info-varchange.c
@@ -0,0 +1,35 @@
+// RUN: %clang -femit-param-entry-values -emit-llvm -S -g %s -o - | FileCheck %s
+
+// CHECK: !DILocalVariable(name: "a", arg: 1, scope: {{.*}}, file: {{.*}}, line: {{.*}}, type: {{.*}}, flags: DIFlagArgumentNotModified)
+// CHECK: !DILocalVariable(name: "b", arg: 2, scope: {{.*}}, file: {{.*}}, line: {{.*}}, type: {{.*}})
+// CHECK: !DILocalVariable(name: "test_s", arg: 3, scope: {{.*}}, file: {{.*}}, line: {{.*}}, type: {{.*}}, flags: DIFlagArgumentNotModified)
+// CHECK: !DILocalVariable(name: "test_s2", arg: 4, scope: {{.*}}, file: {{.*}}, line: {{.*}}, type: {{.*}})
+// CHECK: !DILocalVariable(name: "x", scope: {{.*}}, file: {{.*}}, line: {{.*}}, type: {{.*}})
+// CHECK: !DILocalVariable(name: "y", scope: {{.*}}, file: {{.*}}, line: {{.*}}, type: {{.*}})
+
+typedef struct s {
+  int m;
+  int n;
+}S;
+
+void foo (int a, int b,
+          S test_s, S test_s2)
+{
+  b++;
+  b = a + 1;
+  if (b>4)
+    test_s2.m = 434;
+}
+
+int main()
+{
+  S test_s = {4, 5};
+
+  int x = 5;
+  int y = 6;
+
+  foo(x , y, test_s, test_s);
+
+  return 0;
+}
+
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -16,6 +16,7 @@
 #include "clang/AST/ASTLambda.h"
 #include "clang/AST/ASTMutationListener.h"
 #include "clang/AST/CXXInheritance.h"
+#include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/EvaluatedExprVisitor.h"
@@ -11276,6 +11277,19 @@
     DiagnoseConstAssignment(S, E, Loc);
 }
 
+/// Argument's value might be modified, so update the info.
+static void EmitArgumentsValueModification(Expr *E) {
+  if (const DeclRefExpr *LHSDeclRef =
+          dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()))
+    if (const ValueDecl *Decl = LHSDeclRef->getDecl())
+      if (const VarDecl *VD = dyn_cast<VarDecl>(Decl)) {
+        if (!isa<ParmVarDecl>(VD))
+          return;
+        if (!VD->getIsArgumentModified())
+          VD->setIsArgumentModified();
+      }
+}
+
 /// CheckForModifiableLvalue - Verify that E is a modifiable lvalue.  If not,
 /// emit an error and return true.  If so, return false.
 static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) {
@@ -11283,6 +11297,12 @@
 
   S.CheckShadowingDeclModification(E, Loc);
 
+  if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
+    if (Expr *BaseExpr = ME->getBase())
+      EmitArgumentsValueModification(BaseExpr);
+  } else
+    EmitArgumentsValueModification(E);
+
   SourceLocation OrigLoc = Loc;
   Expr::isModifiableLvalueResult IsLV = E->isModifiableLvalue(S.Context,
                                                               &Loc);
Index: lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- lib/CodeGen/CGDebugInfo.cpp
+++ lib/CodeGen/CGDebugInfo.cpp
@@ -3778,6 +3778,11 @@
   if (VD->isImplicit())
     Flags |= llvm::DINode::FlagArtificial;
 
+  auto &CGOpts = CGM.getCodeGenOpts();
+  if (CGOpts.EnableParamEntryValues && !VD->getIsArgumentModified())
+    Flags |= llvm::DINode::FlagArgumentNotModified;
+
+
   auto Align = getDeclAlignIfRequired(VD, CGM.getContext());
 
   unsigned AddressSpace = CGM.getContext().getTargetAddressSpace(VD->getType());
Index: include/clang/AST/Decl.h
===================================================================
--- include/clang/AST/Decl.h
+++ include/clang/AST/Decl.h
@@ -840,6 +840,8 @@
   /// It is illegal to call this function with SC == None.
   static const char *getStorageClassSpecifierString(StorageClass SC);
 
+  mutable bool IsArgumentModified = false;
+
 protected:
   // A pointer union of Stmt * and EvaluatedStmt *. When an EvaluatedStmt, we
   // have allocated the auxiliary struct of information there.
@@ -1477,6 +1479,13 @@
   /// Do we need to emit an exit-time destructor for this variable?
   bool isNoDestroy(const ASTContext &) const;
 
+  bool getIsArgumentModified() const {
+    return IsArgumentModified;
+  }
+  void setIsArgumentModified() const {
+    IsArgumentModified = true;
+  }
+
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classofKind(Kind K) { return K >= firstVar && K <= lastVar; }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to