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

- Add a field in `ParmVarDecl` instead of `VarDecl`
- Use a bit in `ParmVarDeclBitfields` to indicate parameter modification
- Add support for the bit in  `ASTReaderDecl.cpp` / `ASTWriterDecl.cpp`
- Add test case for templates


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
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriterDecl.cpp
  test/CodeGen/dbginfo-var-change-templates.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: test/CodeGen/dbginfo-var-change-templates.cpp
===================================================================
--- /dev/null
+++ test/CodeGen/dbginfo-var-change-templates.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang -femit-param-entry-values -emit-llvm -S -g %s -o - | FileCheck %s
+// CHECK: !DILocalVariable(name: "a", arg: 1, scope: {{.*}}, file: {{.*}}, line: {{.*}}, type: {{.*}})
+// CHECK: !DILocalVariable(name: "b", arg: 2, scope: {{.*}}, file: {{.*}}, line: {{.*}}, type: {{.*}}, flags: DIFlagArgumentNotModified)
+
+template <class T>
+__attribute__((noinline))
+T GetMin (T a, T b) {
+  T result;
+  ++a;
+  result = (a < b) ? a : b;
+  return result;
+}
+
+int baa () {
+  int i=5, j=6, k;
+  k=GetMin<int>(i,j);
+
+  if (i == k)
+    ++k;
+  else
+    --k;
+
+  return k;
+}
Index: lib/Serialization/ASTWriterDecl.cpp
===================================================================
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -1033,6 +1033,7 @@
   Record.push_back(D->hasUninstantiatedDefaultArg());
   if (D->hasUninstantiatedDefaultArg())
     Record.AddStmt(D->getUninstantiatedDefaultArg());
+  Record.push_back(D->isArgumentKnownToBeModified());
   Code = serialization::DECL_PARM_VAR;
 
   assert(!D->isARCPseudoStrong()); // can be true of ImplicitParamDecl
@@ -1046,6 +1047,7 @@
       !D->isImplicit() &&
       !D->isUsed(false) &&
       !D->isInvalidDecl() &&
+      !D->isArgumentKnownToBeModified() &&
       !D->isReferenced() &&
       D->getAccess() == AS_none &&
       !D->isModulePrivate() &&
@@ -2011,6 +2013,7 @@
   Abv->Add(BitCodeAbbrevOp(0));                       // KNRPromoted
   Abv->Add(BitCodeAbbrevOp(0));                       // HasInheritedDefaultArg
   Abv->Add(BitCodeAbbrevOp(0));                   // HasUninstantiatedDefaultArg
+  Abv->Add(BitCodeAbbrevOp(0));                       // IsArgumentKnownToBeModified
   // Type Source Info
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
Index: lib/Serialization/ASTReaderDecl.cpp
===================================================================
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -1441,7 +1441,7 @@
   PD->ParmVarDeclBits.HasInheritedDefaultArg = Record.readInt();
   if (Record.readInt()) // hasUninstantiatedDefaultArg.
     PD->setUninstantiatedDefaultArg(Record.readExpr());
-
+  PD->ParmVarDeclBits.IsArgumentKnownToBeModified = Record.readInt();
   // FIXME: If this is a redeclaration of a function from another module, handle
   // inheritance of default arguments.
 }
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,15 @@
     DiagnoseConstAssignment(S, E, Loc);
 }
 
+/// Argument's value might be modified, so update the info.
+static void EmitArgumentsValueModification(Expr *E) {
+  if (const auto *LHSDeclRef = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()))
+    if (const ValueDecl *Decl = LHSDeclRef->getDecl())
+      if (const auto *PD = dyn_cast<ParmVarDecl>(Decl))
+        if (!PD->isArgumentKnownToBeModified())
+          const_cast<ParmVarDecl*>(PD)->setIsArgumentKnownToBeModified();
+}
+
 /// 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 +11293,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,12 @@
   if (VD->isImplicit())
     Flags |= llvm::DINode::FlagArtificial;
 
+  if (const auto *PD = dyn_cast<ParmVarDecl>(VD)) {
+    auto &CGOpts = CGM.getCodeGenOpts();
+    if (CGOpts.EnableParamEntryValues && !PD->isArgumentKnownToBeModified())
+      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
@@ -905,6 +905,9 @@
     /// Whether this parameter is an ObjC method parameter or not.
     unsigned IsObjCMethodParam : 1;
 
+    /// Whether this parameter is known to be modified throughout a function.
+    unsigned IsArgumentKnownToBeModified  : 1;
+
     /// If IsObjCMethodParam, a Decl::ObjCDeclQualifier.
     /// Otherwise, the number of function parameter scopes enclosing
     /// the function parameter scope in which this parameter was
@@ -1560,6 +1563,7 @@
     assert(ParmVarDeclBits.DefaultArgKind == DAK_None);
     assert(ParmVarDeclBits.IsKNRPromoted == false);
     assert(ParmVarDeclBits.IsObjCMethodParam == false);
+    assert(ParmVarDeclBits.IsArgumentKnownToBeModified == false);
     setDefaultArg(DefArg);
   }
 
@@ -1593,6 +1597,13 @@
     return ParmVarDeclBits.IsObjCMethodParam;
   }
 
+  bool isArgumentKnownToBeModified() const {
+    return ParmVarDeclBits.IsArgumentKnownToBeModified;
+  }
+  void setIsArgumentKnownToBeModified() {
+    ParmVarDeclBits.IsArgumentKnownToBeModified = true;
+  }
+
   unsigned getFunctionScopeDepth() const {
     if (ParmVarDeclBits.IsObjCMethodParam) return 0;
     return ParmVarDeclBits.ScopeDepthOrObjCQuals;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to