[PATCH] D130303: Fix include order in CXType.cpp

2023-03-10 Thread Collin Baker via Phabricator via cfe-commits
collinbaker added a comment.

Collin Baker
collinba...@chromium.org

This should also be in the author field of the commits

Thanks!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D130303

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D130303: Fix include order in CXType.cpp

2023-03-09 Thread Collin Baker via Phabricator via cfe-commits
collinbaker added a comment.

All done. Again, I don't have commit access so someone else will need to land 
this.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D130303

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D130303: Fix include order in CXType.cpp

2023-03-09 Thread Collin Baker via Phabricator via cfe-commits
collinbaker updated this revision to Diff 503954.
collinbaker added a comment.

Rebase w/ conflict in libclang.map


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D130303

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang-c/Index.h
  clang/tools/libclang/CXType.cpp
  clang/tools/libclang/libclang.map


Index: clang/tools/libclang/libclang.map
===
--- clang/tools/libclang/libclang.map
+++ clang/tools/libclang/libclang.map
@@ -422,6 +422,7 @@
   global:
 clang_CXXMethod_isExplicit;
 clang_createIndexWithOptions;
+clang_isBitFieldDecl;
 };
 
 # Example of how to add a new symbol version entry.  If you do add a new symbol
Index: clang/tools/libclang/CXType.cpp
===
--- clang/tools/libclang/CXType.cpp
+++ clang/tools/libclang/CXType.cpp
@@ -10,11 +10,11 @@
 //
 //======//
 
+#include "CXType.h"
 #include "CIndexer.h"
 #include "CXCursor.h"
 #include "CXString.h"
 #include "CXTranslationUnit.h"
-#include "CXType.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
@@ -371,14 +371,27 @@
   return ULLONG_MAX;
 }
 
+unsigned clang_isBitFieldDecl(CXCursor C) {
+  using namespace cxcursor;
+
+  if (clang_isDeclaration(C.kind)) {
+const Decl *D = getCursorDecl(C);
+
+if (const auto *FD = dyn_cast_or_null(D))
+  return FD->isBitField();
+  }
+
+  return 0;
+}
+
 int clang_getFieldDeclBitWidth(CXCursor C) {
   using namespace cxcursor;
 
   if (clang_isDeclaration(C.kind)) {
 const Decl *D = getCursorDecl(C);
 
-if (const FieldDecl *FD = dyn_cast_or_null(D)) {
-  if (FD->isBitField())
+if (const auto *FD = dyn_cast_or_null(D)) {
+  if (FD->isBitField() && !FD->getBitWidth()->isValueDependent())
 return FD->getBitWidthValue(getCursorContext(C));
 }
   }
Index: clang/include/clang-c/Index.h
===
--- clang/include/clang-c/Index.h
+++ clang/include/clang-c/Index.h
@@ -3016,10 +3016,18 @@
 CINDEX_LINKAGE unsigned long long
 clang_getEnumConstantDeclUnsignedValue(CXCursor C);
 
+/**
+ * Returns non-zero if a field declaration has a bit width expression.
+ *
+ * If the cursor does not reference a bit field declaration 0 is returned.
+ */
+CINDEX_LINKAGE unsigned clang_isBitFieldDecl(CXCursor C);
+
 /**
  * Retrieve the bit width of a bit field declaration as an integer.
  *
- * If a cursor that is not a bit field declaration is passed in, -1 is 
returned.
+ * If the cursor does not reference a bit field, or if the bit field's width
+ * expression cannot be evaluated, -1 is returned.
  */
 CINDEX_LINKAGE int clang_getFieldDeclBitWidth(CXCursor C);
 
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -295,6 +295,11 @@
 - Introduced the new function ``clang_CXXMethod_isExplicit``,
   which identifies whether a constructor or conversion function cursor
   was marked with the explicit identifier.
+- Added check in ``clang_getFieldDeclBitWidth`` for whether a bit field
+  has an evaluable bit width. Fixes undefined behavior when called on a
+  bit field whose width depends on a template paramter.
+- Added function ``clang_isBitFieldDecl`` to check if a struct/class field is a
+  bit field.
 
 - Introduced the new ``CXIndex`` constructor function
   ``clang_createIndexWithOptions``, which allows overriding precompiled 
preamble


Index: clang/tools/libclang/libclang.map
===
--- clang/tools/libclang/libclang.map
+++ clang/tools/libclang/libclang.map
@@ -422,6 +422,7 @@
   global:
 clang_CXXMethod_isExplicit;
 clang_createIndexWithOptions;
+clang_isBitFieldDecl;
 };
 
 # Example of how to add a new symbol version entry.  If you do add a new symbol
Index: clang/tools/libclang/CXType.cpp
===
--- clang/tools/libclang/CXType.cpp
+++ clang/tools/libclang/CXType.cpp
@@ -10,11 +10,11 @@
 //
 //======//
 
+#include "CXType.h"
 #include "CIndexer.h"
 #include "CXCursor.h"
 #include "CXString.h"
 #include "CXTranslationUnit.h"
-#include "CXType.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
@@ -371,14 +371,27 @@
   return ULLONG_MAX;
 }
 
+unsigned clang_isBitFieldDecl(CXCursor C) {
+  using namespace cxcursor;
+
+  if (clang_isDeclaration(C.kind)) {
+const Decl *D = getCursorDecl(C);
+
+if (const auto *FD = dyn_cast_or_null(D))
+  return FD->isBitField();
+  }
+
+  return 0;
+}
+
 int 

[PATCH] D130303: Fix include order in CXType.cpp

2023-03-09 Thread Collin Baker via Phabricator via cfe-commits
collinbaker marked 5 inline comments as done.
collinbaker added a comment.

I am very bad at using differential


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D130303

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D130303: Fix include order in CXType.cpp

2023-03-09 Thread Collin Baker via Phabricator via cfe-commits
collinbaker updated this revision to Diff 503953.
collinbaker retitled this revision from "Handle template parameter-dependent 
bit field widths in libclang" to "Fix include order in CXType.cpp".
collinbaker edited the summary of this revision.
collinbaker added a comment.

Re-add "Fixes" commit message footer


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D130303

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang-c/Index.h
  clang/tools/libclang/CXType.cpp
  clang/tools/libclang/libclang.map


Index: clang/tools/libclang/libclang.map
===
--- clang/tools/libclang/libclang.map
+++ clang/tools/libclang/libclang.map
@@ -421,6 +421,7 @@
 LLVM_17 {
   global:
 clang_CXXMethod_isExplicit;
+clang_isBitFieldDecl;
 };
 
 # Example of how to add a new symbol version entry.  If you do add a new symbol
Index: clang/tools/libclang/CXType.cpp
===
--- clang/tools/libclang/CXType.cpp
+++ clang/tools/libclang/CXType.cpp
@@ -10,11 +10,11 @@
 //
 //======//
 
+#include "CXType.h"
 #include "CIndexer.h"
 #include "CXCursor.h"
 #include "CXString.h"
 #include "CXTranslationUnit.h"
-#include "CXType.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
@@ -371,14 +371,27 @@
   return ULLONG_MAX;
 }
 
+unsigned clang_isBitFieldDecl(CXCursor C) {
+  using namespace cxcursor;
+
+  if (clang_isDeclaration(C.kind)) {
+const Decl *D = getCursorDecl(C);
+
+if (const auto *FD = dyn_cast_or_null(D))
+  return FD->isBitField();
+  }
+
+  return 0;
+}
+
 int clang_getFieldDeclBitWidth(CXCursor C) {
   using namespace cxcursor;
 
   if (clang_isDeclaration(C.kind)) {
 const Decl *D = getCursorDecl(C);
 
-if (const FieldDecl *FD = dyn_cast_or_null(D)) {
-  if (FD->isBitField())
+if (const auto *FD = dyn_cast_or_null(D)) {
+  if (FD->isBitField() && !FD->getBitWidth()->isValueDependent())
 return FD->getBitWidthValue(getCursorContext(C));
 }
   }
Index: clang/include/clang-c/Index.h
===
--- clang/include/clang-c/Index.h
+++ clang/include/clang-c/Index.h
@@ -2887,10 +2887,18 @@
 CINDEX_LINKAGE unsigned long long
 clang_getEnumConstantDeclUnsignedValue(CXCursor C);
 
+/**
+ * Returns non-zero if a field declaration has a bit width expression.
+ *
+ * If the cursor does not reference a bit field declaration 0 is returned.
+ */
+CINDEX_LINKAGE unsigned clang_isBitFieldDecl(CXCursor C);
+
 /**
  * Retrieve the bit width of a bit field declaration as an integer.
  *
- * If a cursor that is not a bit field declaration is passed in, -1 is 
returned.
+ * If the cursor does not reference a bit field, or if the bit field's width
+ * expression cannot be evaluated, -1 is returned.
  */
 CINDEX_LINKAGE int clang_getFieldDeclBitWidth(CXCursor C);
 
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -290,6 +290,11 @@
 - Introduced the new function ``clang_CXXMethod_isExplicit``,
   which identifies whether a constructor or conversion function cursor
   was marked with the explicit identifier.
+- Added check in ``clang_getFieldDeclBitWidth`` for whether a bit field
+  has an evaluable bit width. Fixes undefined behavior when called on a
+  bit field whose width depends on a template paramter.
+- Added function ``clang_isBitFieldDecl`` to check if a struct/class field is a
+  bit field.
 
 Static Analyzer
 ---


Index: clang/tools/libclang/libclang.map
===
--- clang/tools/libclang/libclang.map
+++ clang/tools/libclang/libclang.map
@@ -421,6 +421,7 @@
 LLVM_17 {
   global:
 clang_CXXMethod_isExplicit;
+clang_isBitFieldDecl;
 };
 
 # Example of how to add a new symbol version entry.  If you do add a new symbol
Index: clang/tools/libclang/CXType.cpp
===
--- clang/tools/libclang/CXType.cpp
+++ clang/tools/libclang/CXType.cpp
@@ -10,11 +10,11 @@
 //
 //======//
 
+#include "CXType.h"
 #include "CIndexer.h"
 #include "CXCursor.h"
 #include "CXString.h"
 #include "CXTranslationUnit.h"
-#include "CXType.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
@@ -371,14 +371,27 @@
   return ULLONG_MAX;
 }
 
+unsigned clang_isBitFieldDecl(CXCursor C) {
+  using namespace cxcursor;
+
+  if (clang_isDeclaration(C.kind)) {
+const Decl *D = getCursorDecl(C);
+
+if (const auto *FD = dyn_cast_or_null(D))
+  return FD->isBitField();
+  }
+
+  

[PATCH] D130303: Handle template parameter-dependent bit field widths in libclang

2023-03-09 Thread Collin Baker via Phabricator via cfe-commits
collinbaker updated this revision to Diff 503952.
collinbaker added a comment.

Missed commit


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D130303

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang-c/Index.h
  clang/tools/libclang/CXType.cpp
  clang/tools/libclang/libclang.map


Index: clang/tools/libclang/libclang.map
===
--- clang/tools/libclang/libclang.map
+++ clang/tools/libclang/libclang.map
@@ -421,6 +421,7 @@
 LLVM_17 {
   global:
 clang_CXXMethod_isExplicit;
+clang_isBitFieldDecl;
 };
 
 # Example of how to add a new symbol version entry.  If you do add a new symbol
Index: clang/tools/libclang/CXType.cpp
===
--- clang/tools/libclang/CXType.cpp
+++ clang/tools/libclang/CXType.cpp
@@ -10,11 +10,11 @@
 //
 //======//
 
+#include "CXType.h"
 #include "CIndexer.h"
 #include "CXCursor.h"
 #include "CXString.h"
 #include "CXTranslationUnit.h"
-#include "CXType.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
@@ -371,14 +371,27 @@
   return ULLONG_MAX;
 }
 
+unsigned clang_isBitFieldDecl(CXCursor C) {
+  using namespace cxcursor;
+
+  if (clang_isDeclaration(C.kind)) {
+const Decl *D = getCursorDecl(C);
+
+if (const auto *FD = dyn_cast_or_null(D))
+  return FD->isBitField();
+  }
+
+  return 0;
+}
+
 int clang_getFieldDeclBitWidth(CXCursor C) {
   using namespace cxcursor;
 
   if (clang_isDeclaration(C.kind)) {
 const Decl *D = getCursorDecl(C);
 
-if (const FieldDecl *FD = dyn_cast_or_null(D)) {
-  if (FD->isBitField())
+if (const auto *FD = dyn_cast_or_null(D)) {
+  if (FD->isBitField() && !FD->getBitWidth()->isValueDependent())
 return FD->getBitWidthValue(getCursorContext(C));
 }
   }
Index: clang/include/clang-c/Index.h
===
--- clang/include/clang-c/Index.h
+++ clang/include/clang-c/Index.h
@@ -2887,10 +2887,18 @@
 CINDEX_LINKAGE unsigned long long
 clang_getEnumConstantDeclUnsignedValue(CXCursor C);
 
+/**
+ * Returns non-zero if a field declaration has a bit width expression.
+ *
+ * If the cursor does not reference a bit field declaration 0 is returned.
+ */
+CINDEX_LINKAGE unsigned clang_isBitFieldDecl(CXCursor C);
+
 /**
  * Retrieve the bit width of a bit field declaration as an integer.
  *
- * If a cursor that is not a bit field declaration is passed in, -1 is 
returned.
+ * If the cursor does not reference a bit field, or if the bit field's width
+ * expression cannot be evaluated, -1 is returned.
  */
 CINDEX_LINKAGE int clang_getFieldDeclBitWidth(CXCursor C);
 
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -290,6 +290,11 @@
 - Introduced the new function ``clang_CXXMethod_isExplicit``,
   which identifies whether a constructor or conversion function cursor
   was marked with the explicit identifier.
+- Added check in ``clang_getFieldDeclBitWidth`` for whether a bit field
+  has an evaluable bit width. Fixes undefined behavior when called on a
+  bit field whose width depends on a template paramter.
+- Added function ``clang_isBitFieldDecl`` to check if a struct/class field is a
+  bit field.
 
 Static Analyzer
 ---


Index: clang/tools/libclang/libclang.map
===
--- clang/tools/libclang/libclang.map
+++ clang/tools/libclang/libclang.map
@@ -421,6 +421,7 @@
 LLVM_17 {
   global:
 clang_CXXMethod_isExplicit;
+clang_isBitFieldDecl;
 };
 
 # Example of how to add a new symbol version entry.  If you do add a new symbol
Index: clang/tools/libclang/CXType.cpp
===
--- clang/tools/libclang/CXType.cpp
+++ clang/tools/libclang/CXType.cpp
@@ -10,11 +10,11 @@
 //
 //======//
 
+#include "CXType.h"
 #include "CIndexer.h"
 #include "CXCursor.h"
 #include "CXString.h"
 #include "CXTranslationUnit.h"
-#include "CXType.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
@@ -371,14 +371,27 @@
   return ULLONG_MAX;
 }
 
+unsigned clang_isBitFieldDecl(CXCursor C) {
+  using namespace cxcursor;
+
+  if (clang_isDeclaration(C.kind)) {
+const Decl *D = getCursorDecl(C);
+
+if (const auto *FD = dyn_cast_or_null(D))
+  return FD->isBitField();
+  }
+
+  return 0;
+}
+
 int clang_getFieldDeclBitWidth(CXCursor C) {
   using namespace cxcursor;
 
   if (clang_isDeclaration(C.kind)) {
 const Decl *D = getCursorDecl(C);
 
-if (const FieldDecl *FD = 

[PATCH] D130303: Handle template parameter-dependent bit field widths in libclang

2023-03-09 Thread Collin Baker via Phabricator via cfe-commits
collinbaker updated this revision to Diff 503950.
collinbaker marked 3 inline comments as done.
collinbaker edited the summary of this revision.
collinbaker added a comment.

Cleanups and split header order change to separate commit


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D130303

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang-c/Index.h
  clang/tools/libclang/CXType.cpp
  clang/tools/libclang/libclang.map


Index: clang/tools/libclang/libclang.map
===
--- clang/tools/libclang/libclang.map
+++ clang/tools/libclang/libclang.map
@@ -421,6 +421,7 @@
 LLVM_17 {
   global:
 clang_CXXMethod_isExplicit;
+clang_isBitFieldDecl;
 };
 
 # Example of how to add a new symbol version entry.  If you do add a new symbol
Index: clang/tools/libclang/CXType.cpp
===
--- clang/tools/libclang/CXType.cpp
+++ clang/tools/libclang/CXType.cpp
@@ -371,14 +371,27 @@
   return ULLONG_MAX;
 }
 
+unsigned clang_isBitFieldDecl(CXCursor C) {
+  using namespace cxcursor;
+
+  if (clang_isDeclaration(C.kind)) {
+const Decl *D = getCursorDecl(C);
+
+if (const auto *FD = dyn_cast_or_null(D))
+  return FD->isBitField();
+  }
+
+  return 0;
+}
+
 int clang_getFieldDeclBitWidth(CXCursor C) {
   using namespace cxcursor;
 
   if (clang_isDeclaration(C.kind)) {
 const Decl *D = getCursorDecl(C);
 
-if (const FieldDecl *FD = dyn_cast_or_null(D)) {
-  if (FD->isBitField())
+if (const auto *FD = dyn_cast_or_null(D)) {
+  if (FD->isBitField() && !FD->getBitWidth()->isValueDependent())
 return FD->getBitWidthValue(getCursorContext(C));
 }
   }
Index: clang/include/clang-c/Index.h
===
--- clang/include/clang-c/Index.h
+++ clang/include/clang-c/Index.h
@@ -2887,10 +2887,18 @@
 CINDEX_LINKAGE unsigned long long
 clang_getEnumConstantDeclUnsignedValue(CXCursor C);
 
+/**
+ * Returns non-zero if a field declaration has a bit width expression.
+ *
+ * If the cursor does not reference a bit field declaration 0 is returned.
+ */
+CINDEX_LINKAGE unsigned clang_isBitFieldDecl(CXCursor C);
+
 /**
  * Retrieve the bit width of a bit field declaration as an integer.
  *
- * If a cursor that is not a bit field declaration is passed in, -1 is 
returned.
+ * If the cursor does not reference a bit field, or if the bit field's width
+ * expression cannot be evaluated, -1 is returned.
  */
 CINDEX_LINKAGE int clang_getFieldDeclBitWidth(CXCursor C);
 
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -290,6 +290,11 @@
 - Introduced the new function ``clang_CXXMethod_isExplicit``,
   which identifies whether a constructor or conversion function cursor
   was marked with the explicit identifier.
+- Added check in ``clang_getFieldDeclBitWidth`` for whether a bit field
+  has an evaluable bit width. Fixes undefined behavior when called on a
+  bit field whose width depends on a template paramter.
+- Added function ``clang_isBitFieldDecl`` to check if a struct/class field is a
+  bit field.
 
 Static Analyzer
 ---


Index: clang/tools/libclang/libclang.map
===
--- clang/tools/libclang/libclang.map
+++ clang/tools/libclang/libclang.map
@@ -421,6 +421,7 @@
 LLVM_17 {
   global:
 clang_CXXMethod_isExplicit;
+clang_isBitFieldDecl;
 };
 
 # Example of how to add a new symbol version entry.  If you do add a new symbol
Index: clang/tools/libclang/CXType.cpp
===
--- clang/tools/libclang/CXType.cpp
+++ clang/tools/libclang/CXType.cpp
@@ -371,14 +371,27 @@
   return ULLONG_MAX;
 }
 
+unsigned clang_isBitFieldDecl(CXCursor C) {
+  using namespace cxcursor;
+
+  if (clang_isDeclaration(C.kind)) {
+const Decl *D = getCursorDecl(C);
+
+if (const auto *FD = dyn_cast_or_null(D))
+  return FD->isBitField();
+  }
+
+  return 0;
+}
+
 int clang_getFieldDeclBitWidth(CXCursor C) {
   using namespace cxcursor;
 
   if (clang_isDeclaration(C.kind)) {
 const Decl *D = getCursorDecl(C);
 
-if (const FieldDecl *FD = dyn_cast_or_null(D)) {
-  if (FD->isBitField())
+if (const auto *FD = dyn_cast_or_null(D)) {
+  if (FD->isBitField() && !FD->getBitWidth()->isValueDependent())
 return FD->getBitWidthValue(getCursorContext(C));
 }
   }
Index: clang/include/clang-c/Index.h
===
--- clang/include/clang-c/Index.h
+++ clang/include/clang-c/Index.h
@@ -2887,10 +2887,18 @@
 CINDEX_LINKAGE unsigned long long
 clang_getEnumConstantDeclUnsignedValue(CXCursor C);
 
+/**
+ * Returns non-zero if a field 

[PATCH] D130303: Handle template parameter-dependent bit field widths in libclang

2023-03-08 Thread Collin Baker via Phabricator via cfe-commits
collinbaker marked 5 inline comments as done.
collinbaker added a comment.

Changed as requested. Again leaving it up to a committer to commit this




Comment at: clang/include/clang-c/Index.h:3552
+ * If the cursor does not reference a bit field declaration or if the bit
+ * field's width does not depend on template parameters, 0 is returned.
+ */

vedgy wrote:
> vedgy wrote:
> > collinbaker wrote:
> > > vedgy wrote:
> > > > I just thought how the new API could be used in KDevelop. Currently 
> > > > when `clang_getFieldDeclBitWidth()` is positive, e.g. 2, KDevelop shows 
> > > >  ` : 2` after the data member name in a tooltip. Ideally a 
> > > > template-param-dependent expression (actual code) would be displayed 
> > > > after the colon. If that's difficult to implement, `: 
> > > > [tparam-dependent]` or `: ?` could be displayed instead. But it would 
> > > > be more convenient and efficient to get this information by a single 
> > > > call to `clang_getFieldDeclBitWidth()` instead of calling 
> > > > `clang_isFieldDeclBitWidthDependent()` each time 
> > > > `clang_getFieldDeclBitWidth()` returns `-1`. So how about returning 
> > > > `-2` or `0` from `clang_getFieldDeclBitWidth()` instead of adding this 
> > > > new API?
> > > I understand the motivation but I don't think requiring an extra call is 
> > > asking too much of libclang clients, and it's one extra call that doesn't 
> > > do much work and will be called rarely so I don't see efficiency 
> > > concerns. Without strong reasons otherwise I think it's better to be 
> > > explicit here.
> > KDevelop calls `clang_getFieldDeclBitWidth()` for each encountered class 
> > member declaration. `clang_isFieldDeclBitWidthDependent()` would have to be 
> > called each time `clang_getFieldDeclBitWidth()` returns `-1`, which would 
> > be most of the time, because few class members are bit-fields. The work 
> > this new function does is the same as that of 
> > `clang_getFieldDeclBitWidth()`  (repeated).
> > 
> > If the concern about returning `-2` from `clang_getFieldDeclBitWidth()` is 
> > cryptic return codes, an `enum` with named constants can be introduced.
> > 
> > If the concern is breaking backward compatibility for users that relied on 
> > the returned value being positive or `-1`, then a replacement for 
> > `clang_getFieldDeclBitWidth()` with the most convenient API should be 
> > introduced and `clang_getFieldDeclBitWidth()` itself - deprecated.
> > 
> > KDevelop simply stores the value returned by `clang_getFieldDeclBitWidth()` 
> > in an `int16_t m_bitWidth` data member and uses it later. So if `-2` is 
> > returned, the only place in code to adjust would be the use of this data 
> > member. With the current `clang_isFieldDeclBitWidthDependent()` 
> > implementation, this function would have to be called, `-2` explicitly 
> > stored in `m_bitWidth` and the use of `m_bitWidth` would have to be 
> > adjusted just the same.
> > 
> > Have you considered potential usage of the added API in your project? Which 
> > alternative would be more convenient to use?
> One more API alternative is to replace `clang_isFieldDeclBitWidthDependent()` 
> with `clang_isBitFieldDecl()`. The usage would be more straightforward and 
> efficient: first call `clang_isBitFieldDecl()`; if it returns true (should be 
> rare enough), call `clang_getFieldDeclBitWidth()`; if that returns `-1`, then 
> the bit-field width must be unknown (dependent on template parameters). Such 
> usage would still be less convenient and efficient compared to 
> `clang_getFieldDeclBitWidth()` returning `-2` though.
Implemented as `clang_isBitFieldDecl` rather than magic return value



Comment at: clang/tools/libclang/CXType.cpp:13
 
+#include "CXType.h"
 #include "CIndexer.h"

vedgy wrote:
> I guess //clang-format// did this include reordering. But it certainly looks 
> out of place and the include order becomes wrong. So I think it should be 
> reverted.
I don't agree, it's pretty standard for a source file to have its associated 
header include at the top.



Comment at: clang/tools/libclang/CXType.cpp:404
+  if (FD->isBitField() && !FD->getBitWidth()->isValueDependent())
 return FD->getBitWidthValue(getCursorContext(C));
 }

vedgy wrote:
> I thought of the same fix while analyzing the assertion failure here: 
> https://bugs.kde.org/show_bug.cgi?id=438249#c19
> 
> An alternative implementation is to place this same check in 
> `clang::FieldDecl::getBitWidthValue()`. This looks like a general issue that 
> could affect non-libclang users of `clang::FieldDecl::getBitWidthValue()`. 
> But apparently no one else has stumbled upon it.
> 
> `clang::FieldDecl::getBitWidthValue()` returns `unsigned` and has no 
> error-reporting mechanism yet. It could return 
> `std::numeric_limits::max()` (or `0` if that's an invalid bit width 
> value) in case of the value dependence.
This would 

[PATCH] D130303: Handle template parameter-dependent bit field widths in libclang

2023-03-08 Thread Collin Baker via Phabricator via cfe-commits
collinbaker updated this revision to Diff 503570.
collinbaker edited the summary of this revision.
collinbaker added a comment.

Requested changes


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D130303

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang-c/Index.h
  clang/tools/libclang/CXType.cpp
  clang/tools/libclang/libclang.map


Index: clang/tools/libclang/libclang.map
===
--- clang/tools/libclang/libclang.map
+++ clang/tools/libclang/libclang.map
@@ -421,6 +421,7 @@
 LLVM_17 {
   global:
 clang_CXXMethod_isExplicit;
+clang_isBitFieldDecl;
 };
 
 # Example of how to add a new symbol version entry.  If you do add a new symbol
Index: clang/tools/libclang/CXType.cpp
===
--- clang/tools/libclang/CXType.cpp
+++ clang/tools/libclang/CXType.cpp
@@ -10,11 +10,11 @@
 //
 //======//
 
+#include "CXType.h"
 #include "CIndexer.h"
 #include "CXCursor.h"
 #include "CXString.h"
 #include "CXTranslationUnit.h"
-#include "CXType.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
@@ -371,7 +371,7 @@
   return ULLONG_MAX;
 }
 
-int clang_getFieldDeclBitWidth(CXCursor C) {
+unsigned clang_isBitFieldDecl(CXCursor C) {
   using namespace cxcursor;
 
   if (clang_isDeclaration(C.kind)) {
@@ -379,6 +379,21 @@
 
 if (const FieldDecl *FD = dyn_cast_or_null(D)) {
   if (FD->isBitField())
+return 1;
+}
+  }
+
+  return 0;
+}
+
+int clang_getFieldDeclBitWidth(CXCursor C) {
+  using namespace cxcursor;
+
+  if (clang_isDeclaration(C.kind)) {
+const Decl *D = getCursorDecl(C);
+
+if (const FieldDecl *FD = dyn_cast_or_null(D)) {
+  if (FD->isBitField() && !FD->getBitWidth()->isValueDependent())
 return FD->getBitWidthValue(getCursorContext(C));
 }
   }
Index: clang/include/clang-c/Index.h
===
--- clang/include/clang-c/Index.h
+++ clang/include/clang-c/Index.h
@@ -2887,10 +2887,18 @@
 CINDEX_LINKAGE unsigned long long
 clang_getEnumConstantDeclUnsignedValue(CXCursor C);
 
+/**
+ * Returns non-zero if a field declaration has a bit width expression.
+ *
+ * If the cursor does not reference a bit field declaration 0 is returned.
+ */
+CINDEX_LINKAGE unsigned clang_isBitFieldDecl(CXCursor C);
+
 /**
  * Retrieve the bit width of a bit field declaration as an integer.
  *
- * If a cursor that is not a bit field declaration is passed in, -1 is 
returned.
+ * If the cursor does not reference a bit field, or if the bit field's width
+ * expression cannot be evaluated, -1 is returned.
  */
 CINDEX_LINKAGE int clang_getFieldDeclBitWidth(CXCursor C);
 
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -290,6 +290,11 @@
 - Introduced the new function ``clang_CXXMethod_isExplicit``,
   which identifies whether a constructor or conversion function cursor
   was marked with the explicit identifier.
+- Added check in ``clang_getFieldDeclBitWidth`` for whether a bit field
+  has an evaluable bit width. Fixes undefined behavior when called on a
+  bit field whose width depends on a template paramter.
+- Added function ``clang_isBitFieldDecl`` to check if a struct/class field is a
+  bit field.
 
 Static Analyzer
 ---


Index: clang/tools/libclang/libclang.map
===
--- clang/tools/libclang/libclang.map
+++ clang/tools/libclang/libclang.map
@@ -421,6 +421,7 @@
 LLVM_17 {
   global:
 clang_CXXMethod_isExplicit;
+clang_isBitFieldDecl;
 };
 
 # Example of how to add a new symbol version entry.  If you do add a new symbol
Index: clang/tools/libclang/CXType.cpp
===
--- clang/tools/libclang/CXType.cpp
+++ clang/tools/libclang/CXType.cpp
@@ -10,11 +10,11 @@
 //
 //======//
 
+#include "CXType.h"
 #include "CIndexer.h"
 #include "CXCursor.h"
 #include "CXString.h"
 #include "CXTranslationUnit.h"
-#include "CXType.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
@@ -371,7 +371,7 @@
   return ULLONG_MAX;
 }
 
-int clang_getFieldDeclBitWidth(CXCursor C) {
+unsigned clang_isBitFieldDecl(CXCursor C) {
   using namespace cxcursor;
 
   if (clang_isDeclaration(C.kind)) {
@@ -379,6 +379,21 @@
 
 if (const FieldDecl *FD = dyn_cast_or_null(D)) {
   if (FD->isBitField())
+return 1;
+}
+  }
+
+  return 0;
+}
+
+int clang_getFieldDeclBitWidth(CXCursor C) {
+  using namespace cxcursor;
+
+  if (clang_isDeclaration(C.kind)) {

[PATCH] D130303: Handle template parameter-dependent bit field widths in libclang

2023-03-07 Thread Collin Baker via Phabricator via cfe-commits
collinbaker added a comment.

@dexonsmith can you weigh in?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D130303

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D130303: Handle template parameter-dependent bit field widths in libclang

2023-03-06 Thread Collin Baker via Phabricator via cfe-commits
collinbaker marked 3 inline comments as done.
collinbaker added a comment.

Thanks for the review. Someone else will need to commit since I don't have 
permission.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D130303

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D130303: Handle template parameter-dependent bit field widths in libclang

2023-03-06 Thread Collin Baker via Phabricator via cfe-commits
collinbaker updated this revision to Diff 502763.
collinbaker added a comment.

Add symbol to version map


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D130303

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang-c/Index.h
  clang/tools/libclang/CXType.cpp
  clang/tools/libclang/libclang.map

Index: clang/tools/libclang/libclang.map
===
--- clang/tools/libclang/libclang.map
+++ clang/tools/libclang/libclang.map
@@ -421,6 +421,7 @@
 LLVM_17 {
   global:
 clang_CXXMethod_isExplicit;
+clang_isFieldDeclBitWidthDependent;
 };
 
 # Example of how to add a new symbol version entry.  If you do add a new symbol
Index: clang/tools/libclang/CXType.cpp
===
--- clang/tools/libclang/CXType.cpp
+++ clang/tools/libclang/CXType.cpp
@@ -10,11 +10,11 @@
 //
 //======//
 
+#include "CXType.h"
 #include "CIndexer.h"
 #include "CXCursor.h"
 #include "CXString.h"
 #include "CXTranslationUnit.h"
-#include "CXType.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
@@ -371,6 +371,21 @@
   return ULLONG_MAX;
 }
 
+unsigned clang_isFieldDeclBitWidthDependent(CXCursor C) {
+  using namespace cxcursor;
+
+  if (clang_isDeclaration(C.kind)) {
+const Decl *D = getCursorDecl(C);
+
+if (const FieldDecl *FD = dyn_cast_or_null(D)) {
+  if (FD->isBitField() && FD->getBitWidth()->isValueDependent())
+return 1;
+}
+  }
+
+  return 0;
+}
+
 int clang_getFieldDeclBitWidth(CXCursor C) {
   using namespace cxcursor;
 
@@ -378,7 +393,7 @@
 const Decl *D = getCursorDecl(C);
 
 if (const FieldDecl *FD = dyn_cast_or_null(D)) {
-  if (FD->isBitField())
+  if (FD->isBitField() && !FD->getBitWidth()->isValueDependent())
 return FD->getBitWidthValue(getCursorContext(C));
 }
   }
Index: clang/include/clang-c/Index.h
===
--- clang/include/clang-c/Index.h
+++ clang/include/clang-c/Index.h
@@ -2887,10 +2887,19 @@
 CINDEX_LINKAGE unsigned long long
 clang_getEnumConstantDeclUnsignedValue(CXCursor C);
 
+/**
+ * Returns non-zero if a bit field's width depends on template parameters.
+ *
+ * If the cursor does not reference a bit field declaration or if the bit
+ * field's width does not depend on template parameters, 0 is returned.
+ */
+CINDEX_LINKAGE unsigned clang_isFieldDeclBitWidthDependent(CXCursor C);
+
 /**
  * Retrieve the bit width of a bit field declaration as an integer.
  *
- * If a cursor that is not a bit field declaration is passed in, -1 is returned.
+ * If a cursor that is not a bit field declaration is passed in, or if the bit
+ * field's width expression cannot be evaluated, -1 is returned.
  */
 CINDEX_LINKAGE int clang_getFieldDeclBitWidth(CXCursor C);
 
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -290,6 +290,11 @@
 - Introduced the new function ``clang_CXXMethod_isExplicit``,
   which identifies whether a constructor or conversion function cursor
   was marked with the explicit identifier.
+- Added check in ``clang_getFieldDeclBitWidth`` for whether a bit field
+  has an evaluable bit width. Fixes undefined behavior when called on a
+  bit field whose width depends on a template paramter.
+- Added function ``clang_isFieldDeclBitWidthDependent`` to check if a
+  bit field's width depends on a template parameter.
 
 Static Analyzer
 ---
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D130303: Handle template parameter-dependent bit field widths in libclang

2023-03-06 Thread Collin Baker via Phabricator via cfe-commits
collinbaker added inline comments.



Comment at: clang/include/clang-c/Index.h:3552
+ * If the cursor does not reference a bit field declaration or if the bit
+ * field's width does not depend on template parameters, 0 is returned.
+ */

vedgy wrote:
> I just thought how the new API could be used in KDevelop. Currently when 
> `clang_getFieldDeclBitWidth()` is positive, e.g. 2, KDevelop shows  ` : 2` 
> after the data member name in a tooltip. Ideally a template-param-dependent 
> expression (actual code) would be displayed after the colon. If that's 
> difficult to implement, `: [tparam-dependent]` or `: ?` could be displayed 
> instead. But it would be more convenient and efficient to get this 
> information by a single call to `clang_getFieldDeclBitWidth()` instead of 
> calling `clang_isFieldDeclBitWidthDependent()` each time 
> `clang_getFieldDeclBitWidth()` returns `-1`. So how about returning `-2` or 
> `0` from `clang_getFieldDeclBitWidth()` instead of adding this new API?
I understand the motivation but I don't think requiring an extra call is asking 
too much of libclang clients, and it's one extra call that doesn't do much work 
and will be called rarely so I don't see efficiency concerns. Without strong 
reasons otherwise I think it's better to be explicit here.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D130303

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D130303: Handle template parameter-dependent bit field widths in libclang

2023-03-06 Thread Collin Baker via Phabricator via cfe-commits
collinbaker updated this revision to Diff 502762.
collinbaker added a comment.

Add release notes and remove unneeded include


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D130303

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang-c/Index.h
  clang/tools/libclang/CXType.cpp


Index: clang/tools/libclang/CXType.cpp
===
--- clang/tools/libclang/CXType.cpp
+++ clang/tools/libclang/CXType.cpp
@@ -10,11 +10,11 @@
 //
 //======//
 
+#include "CXType.h"
 #include "CIndexer.h"
 #include "CXCursor.h"
 #include "CXString.h"
 #include "CXTranslationUnit.h"
-#include "CXType.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
@@ -371,6 +371,21 @@
   return ULLONG_MAX;
 }
 
+unsigned clang_isFieldDeclBitWidthDependent(CXCursor C) {
+  using namespace cxcursor;
+
+  if (clang_isDeclaration(C.kind)) {
+const Decl *D = getCursorDecl(C);
+
+if (const FieldDecl *FD = dyn_cast_or_null(D)) {
+  if (FD->isBitField() && FD->getBitWidth()->isValueDependent())
+return 1;
+}
+  }
+
+  return 0;
+}
+
 int clang_getFieldDeclBitWidth(CXCursor C) {
   using namespace cxcursor;
 
@@ -378,7 +393,7 @@
 const Decl *D = getCursorDecl(C);
 
 if (const FieldDecl *FD = dyn_cast_or_null(D)) {
-  if (FD->isBitField())
+  if (FD->isBitField() && !FD->getBitWidth()->isValueDependent())
 return FD->getBitWidthValue(getCursorContext(C));
 }
   }
Index: clang/include/clang-c/Index.h
===
--- clang/include/clang-c/Index.h
+++ clang/include/clang-c/Index.h
@@ -2887,10 +2887,19 @@
 CINDEX_LINKAGE unsigned long long
 clang_getEnumConstantDeclUnsignedValue(CXCursor C);
 
+/**
+ * Returns non-zero if a bit field's width depends on template parameters.
+ *
+ * If the cursor does not reference a bit field declaration or if the bit
+ * field's width does not depend on template parameters, 0 is returned.
+ */
+CINDEX_LINKAGE unsigned clang_isFieldDeclBitWidthDependent(CXCursor C);
+
 /**
  * Retrieve the bit width of a bit field declaration as an integer.
  *
- * If a cursor that is not a bit field declaration is passed in, -1 is 
returned.
+ * If a cursor that is not a bit field declaration is passed in, or if the bit
+ * field's width expression cannot be evaluated, -1 is returned.
  */
 CINDEX_LINKAGE int clang_getFieldDeclBitWidth(CXCursor C);
 
Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -290,6 +290,11 @@
 - Introduced the new function ``clang_CXXMethod_isExplicit``,
   which identifies whether a constructor or conversion function cursor
   was marked with the explicit identifier.
+- Added check in ``clang_getFieldDeclBitWidth`` for whether a bit field
+  has an evaluable bit width. Fixes undefined behavior when called on a
+  bit field whose width depends on a template paramter.
+- Added function ``clang_isFieldDeclBitWidthDependent`` to check if a
+  bit field's width depends on a template parameter.
 
 Static Analyzer
 ---


Index: clang/tools/libclang/CXType.cpp
===
--- clang/tools/libclang/CXType.cpp
+++ clang/tools/libclang/CXType.cpp
@@ -10,11 +10,11 @@
 //
 //======//
 
+#include "CXType.h"
 #include "CIndexer.h"
 #include "CXCursor.h"
 #include "CXString.h"
 #include "CXTranslationUnit.h"
-#include "CXType.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
@@ -371,6 +371,21 @@
   return ULLONG_MAX;
 }
 
+unsigned clang_isFieldDeclBitWidthDependent(CXCursor C) {
+  using namespace cxcursor;
+
+  if (clang_isDeclaration(C.kind)) {
+const Decl *D = getCursorDecl(C);
+
+if (const FieldDecl *FD = dyn_cast_or_null(D)) {
+  if (FD->isBitField() && FD->getBitWidth()->isValueDependent())
+return 1;
+}
+  }
+
+  return 0;
+}
+
 int clang_getFieldDeclBitWidth(CXCursor C) {
   using namespace cxcursor;
 
@@ -378,7 +393,7 @@
 const Decl *D = getCursorDecl(C);
 
 if (const FieldDecl *FD = dyn_cast_or_null(D)) {
-  if (FD->isBitField())
+  if (FD->isBitField() && !FD->getBitWidth()->isValueDependent())
 return FD->getBitWidthValue(getCursorContext(C));
 }
   }
Index: clang/include/clang-c/Index.h
===
--- clang/include/clang-c/Index.h
+++ clang/include/clang-c/Index.h
@@ -2887,10 +2887,19 @@
 CINDEX_LINKAGE unsigned long long
 clang_getEnumConstantDeclUnsignedValue(CXCursor C);
 
+/**
+ * Returns non-zero if a bit field's width depends on 

[PATCH] D130303: Handle template parameter-dependent bit field widths in libclang

2023-03-06 Thread Collin Baker via Phabricator via cfe-commits
collinbaker updated this revision to Diff 502758.
collinbaker added a comment.

Sync with upstream changes


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D130303

Files:
  clang/include/clang-c/Index.h
  clang/tools/libclang/CXType.cpp


Index: clang/tools/libclang/CXType.cpp
===
--- clang/tools/libclang/CXType.cpp
+++ clang/tools/libclang/CXType.cpp
@@ -10,11 +10,12 @@
 //
 //======//
 
+#include "CXType.h"
 #include "CIndexer.h"
 #include "CXCursor.h"
 #include "CXString.h"
 #include "CXTranslationUnit.h"
-#include "CXType.h"
+#include "clang-c/Index.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
@@ -371,6 +372,21 @@
   return ULLONG_MAX;
 }
 
+unsigned clang_isFieldDeclBitWidthDependent(CXCursor C) {
+  using namespace cxcursor;
+
+  if (clang_isDeclaration(C.kind)) {
+const Decl *D = getCursorDecl(C);
+
+if (const FieldDecl *FD = dyn_cast_or_null(D)) {
+  if (FD->isBitField() && FD->getBitWidth()->isValueDependent())
+return 1;
+}
+  }
+
+  return 0;
+}
+
 int clang_getFieldDeclBitWidth(CXCursor C) {
   using namespace cxcursor;
 
@@ -378,7 +394,7 @@
 const Decl *D = getCursorDecl(C);
 
 if (const FieldDecl *FD = dyn_cast_or_null(D)) {
-  if (FD->isBitField())
+  if (FD->isBitField() && !FD->getBitWidth()->isValueDependent())
 return FD->getBitWidthValue(getCursorContext(C));
 }
   }
Index: clang/include/clang-c/Index.h
===
--- clang/include/clang-c/Index.h
+++ clang/include/clang-c/Index.h
@@ -2887,10 +2887,19 @@
 CINDEX_LINKAGE unsigned long long
 clang_getEnumConstantDeclUnsignedValue(CXCursor C);
 
+/**
+ * Returns non-zero if a bit field's width depends on template parameters.
+ *
+ * If the cursor does not reference a bit field declaration or if the bit
+ * field's width does not depend on template parameters, 0 is returned.
+ */
+CINDEX_LINKAGE unsigned clang_isFieldDeclBitWidthDependent(CXCursor C);
+
 /**
  * Retrieve the bit width of a bit field declaration as an integer.
  *
- * If a cursor that is not a bit field declaration is passed in, -1 is 
returned.
+ * If a cursor that is not a bit field declaration is passed in, or if the bit
+ * field's width expression cannot be evaluated, -1 is returned.
  */
 CINDEX_LINKAGE int clang_getFieldDeclBitWidth(CXCursor C);
 


Index: clang/tools/libclang/CXType.cpp
===
--- clang/tools/libclang/CXType.cpp
+++ clang/tools/libclang/CXType.cpp
@@ -10,11 +10,12 @@
 //
 //======//
 
+#include "CXType.h"
 #include "CIndexer.h"
 #include "CXCursor.h"
 #include "CXString.h"
 #include "CXTranslationUnit.h"
-#include "CXType.h"
+#include "clang-c/Index.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
@@ -371,6 +372,21 @@
   return ULLONG_MAX;
 }
 
+unsigned clang_isFieldDeclBitWidthDependent(CXCursor C) {
+  using namespace cxcursor;
+
+  if (clang_isDeclaration(C.kind)) {
+const Decl *D = getCursorDecl(C);
+
+if (const FieldDecl *FD = dyn_cast_or_null(D)) {
+  if (FD->isBitField() && FD->getBitWidth()->isValueDependent())
+return 1;
+}
+  }
+
+  return 0;
+}
+
 int clang_getFieldDeclBitWidth(CXCursor C) {
   using namespace cxcursor;
 
@@ -378,7 +394,7 @@
 const Decl *D = getCursorDecl(C);
 
 if (const FieldDecl *FD = dyn_cast_or_null(D)) {
-  if (FD->isBitField())
+  if (FD->isBitField() && !FD->getBitWidth()->isValueDependent())
 return FD->getBitWidthValue(getCursorContext(C));
 }
   }
Index: clang/include/clang-c/Index.h
===
--- clang/include/clang-c/Index.h
+++ clang/include/clang-c/Index.h
@@ -2887,10 +2887,19 @@
 CINDEX_LINKAGE unsigned long long
 clang_getEnumConstantDeclUnsignedValue(CXCursor C);
 
+/**
+ * Returns non-zero if a bit field's width depends on template parameters.
+ *
+ * If the cursor does not reference a bit field declaration or if the bit
+ * field's width does not depend on template parameters, 0 is returned.
+ */
+CINDEX_LINKAGE unsigned clang_isFieldDeclBitWidthDependent(CXCursor C);
+
 /**
  * Retrieve the bit width of a bit field declaration as an integer.
  *
- * If a cursor that is not a bit field declaration is passed in, -1 is returned.
+ * If a cursor that is not a bit field declaration is passed in, or if the bit
+ * field's width expression cannot be evaluated, -1 is returned.
  */
 CINDEX_LINKAGE int clang_getFieldDeclBitWidth(CXCursor C);
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org

[PATCH] D130303: Handle template parameter-dependent bit field widths in libclang

2022-08-10 Thread Collin Baker via Phabricator via cfe-commits
collinbaker added a comment.

Pinging this


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D130303

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D130303: Handle template parameter-dependent bit field widths in libclang

2022-07-21 Thread Collin Baker via Phabricator via cfe-commits
collinbaker created this revision.
collinbaker added a reviewer: rnk.
Herald added a subscriber: arphaman.
Herald added a project: All.
collinbaker requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

In a class template, a bit field's width may depend on a template
parameter. In this case the width expression cannot be evaluated.

Previously clang_getFieldDeclBitWidth() would assert, or cause memory
unsafety and return an invalid result if assertions are disabled.

This adds a check for this case which returns an error code. An
additional function clang_isFieldDeclBitWidthDependent() as added for
users to check for this case.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D130303

Files:
  clang/include/clang-c/Index.h
  clang/tools/libclang/CXType.cpp


Index: clang/tools/libclang/CXType.cpp
===
--- clang/tools/libclang/CXType.cpp
+++ clang/tools/libclang/CXType.cpp
@@ -15,6 +15,7 @@
 #include "CXString.h"
 #include "CXTranslationUnit.h"
 #include "CXType.h"
+#include "clang-c/Index.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
@@ -377,6 +378,21 @@
   return ULLONG_MAX;
 }
 
+unsigned clang_isFieldDeclBitWidthDependent(CXCursor C) {
+  using namespace cxcursor;
+
+  if (clang_isDeclaration(C.kind)) {
+const Decl *D = getCursorDecl(C);
+
+if (const FieldDecl *FD = dyn_cast_or_null(D)) {
+  if (FD->isBitField() && FD->getBitWidth()->isValueDependent())
+return 1;
+}
+  }
+
+  return 0;
+}
+
 int clang_getFieldDeclBitWidth(CXCursor C) {
   using namespace cxcursor;
 
@@ -384,7 +400,7 @@
 const Decl *D = getCursorDecl(C);
 
 if (const FieldDecl *FD = dyn_cast_or_null(D)) {
-  if (FD->isBitField())
+  if (FD->isBitField() && !FD->getBitWidth()->isValueDependent())
 return FD->getBitWidthValue(getCursorContext(C));
 }
   }
Index: clang/include/clang-c/Index.h
===
--- clang/include/clang-c/Index.h
+++ clang/include/clang-c/Index.h
@@ -3545,10 +3545,19 @@
 CINDEX_LINKAGE unsigned long long
 clang_getEnumConstantDeclUnsignedValue(CXCursor C);
 
+/**
+ * Returns non-zero if a bit field's width depends on template parameters.
+ *
+ * If the cursor does not reference a bit field declaration or if the bit
+ * field's width does not depend on template parameters, 0 is returned.
+ */
+CINDEX_LINKAGE unsigned clang_isFieldDeclBitWidthDependent(CXCursor C);
+
 /**
  * Retrieve the bit width of a bit field declaration as an integer.
  *
- * If a cursor that is not a bit field declaration is passed in, -1 is 
returned.
+ * If a cursor that is not a bit field declaration is passed in, or if the bit
+ * field's width expression cannot be evaluated, -1 is returned.
  */
 CINDEX_LINKAGE int clang_getFieldDeclBitWidth(CXCursor C);
 


Index: clang/tools/libclang/CXType.cpp
===
--- clang/tools/libclang/CXType.cpp
+++ clang/tools/libclang/CXType.cpp
@@ -15,6 +15,7 @@
 #include "CXString.h"
 #include "CXTranslationUnit.h"
 #include "CXType.h"
+#include "clang-c/Index.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
@@ -377,6 +378,21 @@
   return ULLONG_MAX;
 }
 
+unsigned clang_isFieldDeclBitWidthDependent(CXCursor C) {
+  using namespace cxcursor;
+
+  if (clang_isDeclaration(C.kind)) {
+const Decl *D = getCursorDecl(C);
+
+if (const FieldDecl *FD = dyn_cast_or_null(D)) {
+  if (FD->isBitField() && FD->getBitWidth()->isValueDependent())
+return 1;
+}
+  }
+
+  return 0;
+}
+
 int clang_getFieldDeclBitWidth(CXCursor C) {
   using namespace cxcursor;
 
@@ -384,7 +400,7 @@
 const Decl *D = getCursorDecl(C);
 
 if (const FieldDecl *FD = dyn_cast_or_null(D)) {
-  if (FD->isBitField())
+  if (FD->isBitField() && !FD->getBitWidth()->isValueDependent())
 return FD->getBitWidthValue(getCursorContext(C));
 }
   }
Index: clang/include/clang-c/Index.h
===
--- clang/include/clang-c/Index.h
+++ clang/include/clang-c/Index.h
@@ -3545,10 +3545,19 @@
 CINDEX_LINKAGE unsigned long long
 clang_getEnumConstantDeclUnsignedValue(CXCursor C);
 
+/**
+ * Returns non-zero if a bit field's width depends on template parameters.
+ *
+ * If the cursor does not reference a bit field declaration or if the bit
+ * field's width does not depend on template parameters, 0 is returned.
+ */
+CINDEX_LINKAGE unsigned clang_isFieldDeclBitWidthDependent(CXCursor C);
+
 /**
  * Retrieve the bit width of a bit field declaration as an integer.
  *
- * If a cursor that is not a bit field declaration is passed in, -1 is returned.
+ * If a cursor that is not a bit field declaration is passed in, or if the bit
+ * field's width expression 

[PATCH] D115049: Fall back on Android triple w/o API level for runtimes search

2022-01-04 Thread Collin Baker via Phabricator via cfe-commits
collinbaker updated this revision to Diff 397394.
collinbaker added a comment.

Rebase


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115049

Files:
  clang/include/clang/Driver/ToolChain.h
  clang/lib/Driver/Driver.cpp
  clang/lib/Driver/ToolChain.cpp
  clang/lib/Driver/ToolChains/Fuchsia.cpp
  clang/lib/Driver/ToolChains/VEToolchain.cpp
  
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-linux-android/.keep
  
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-linux-android/libclang_rt.builtins.a
  
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-linux-android21/.keep
  
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-linux-android21/libclang_rt.builtins.a
  clang/test/Driver/linux-per-target-runtime-dir.c

Index: clang/test/Driver/linux-per-target-runtime-dir.c
===
--- clang/test/Driver/linux-per-target-runtime-dir.c
+++ clang/test/Driver/linux-per-target-runtime-dir.c
@@ -25,3 +25,21 @@
 // RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
 // RUN:   | FileCheck --check-prefix=CHECK-FILE-NAME-X8664 %s
 // CHECK-FILE-NAME-X8664: lib{{/|\\}}x86_64-unknown-linux-gnu{{/|\\}}libclang_rt.builtins.a
+
+// RUN: %clang -rtlib=compiler-rt -print-file-name=libclang_rt.builtins.a 2>&1 \
+// RUN: --target=aarch64-unknown-linux-android21 \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN:   | FileCheck --check-prefix=CHECK-FILE-NAME-ANDROID21 %s
+// CHECK-FILE-NAME-ANDROID21: lib{{/|\\}}aarch64-unknown-linux-android21{{/|\\}}libclang_rt.builtins.a
+
+// RUN: %clang -rtlib=compiler-rt -print-file-name=libclang_rt.builtins.a 2>&1 \
+// RUN: --target=aarch64-unknown-linux-android23 \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN:   | FileCheck --check-prefix=CHECK-FILE-NAME-ANDROID23 %s
+// CHECK-FILE-NAME-ANDROID23: lib{{/|\\}}aarch64-unknown-linux-android{{/|\\}}libclang_rt.builtins.a
+
+// RUN: %clang -rtlib=compiler-rt -print-file-name=libclang_rt.builtins.a 2>&1 \
+// RUN: --target=aarch64-unknown-linux-android \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN:   | FileCheck --check-prefix=CHECK-FILE-NAME-ANDROID %s
+// CHECK-FILE-NAME-ANDROID: lib{{/|\\}}aarch64-unknown-linux-android{{/|\\}}libclang_rt.builtins.a
Index: clang/lib/Driver/ToolChains/VEToolchain.cpp
===
--- clang/lib/Driver/ToolChains/VEToolchain.cpp
+++ clang/lib/Driver/ToolChains/VEToolchain.cpp
@@ -48,7 +48,8 @@
   //   ${BINPATH}/../lib/ve-unknown-linux-gnu, (== getStdlibPath)
   //   ${RESOURCEDIR}/lib/linux/ve, (== getArchSpecificLibPath)
   //   ${SYSROOT}/opt/nec/ve/lib,
-  getFilePaths().push_back(getStdlibPath());
+  for (auto  : getStdlibPaths())
+getFilePaths().push_back(std::move(Path));
   getFilePaths().push_back(getArchSpecificLibPath());
   getFilePaths().push_back(computeSysRoot() + "/opt/nec/ve/lib");
 }
Index: clang/lib/Driver/ToolChains/Fuchsia.cpp
===
--- clang/lib/Driver/ToolChains/Fuchsia.cpp
+++ clang/lib/Driver/ToolChains/Fuchsia.cpp
@@ -191,9 +191,11 @@
 
   auto FilePaths = [&](const Multilib ) -> std::vector {
 std::vector FP;
-SmallString<128> P(getStdlibPath());
-llvm::sys::path::append(P, M.gccSuffix());
-FP.push_back(std::string(P.str()));
+for (const std::string  : getStdlibPaths()) {
+  SmallString<128> P(Path);
+  llvm::sys::path::append(P, M.gccSuffix());
+  FP.push_back(std::string(P.str()));
+}
 return FP;
   };
 
Index: clang/lib/Driver/ToolChain.cpp
===
--- clang/lib/Driver/ToolChain.cpp
+++ clang/lib/Driver/ToolChain.cpp
@@ -75,17 +75,16 @@
  const ArgList )
 : D(D), Triple(T), Args(Args), CachedRTTIArg(GetRTTIArgument(Args)),
   CachedRTTIMode(CalculateRTTIMode(Args, Triple, CachedRTTIArg)) {
-  std::string RuntimePath = getRuntimePath();
-  if (getVFS().exists(RuntimePath))
-getLibraryPaths().push_back(RuntimePath);
-
-  std::string StdlibPath = getStdlibPath();
-  if (getVFS().exists(StdlibPath))
-getFilePaths().push_back(StdlibPath);
+  auto addIfExists = [this](path_list , const std::string ) {
+if (getVFS().exists(Path))
+  List.push_back(Path);
+  };
 
-  std::string CandidateLibPath = getArchSpecificLibPath();
-  if (getVFS().exists(CandidateLibPath))
-getFilePaths().push_back(CandidateLibPath);
+  for (const auto  : getRuntimePaths())
+addIfExists(getLibraryPaths(), Path);
+  for (const auto  : getStdlibPaths())
+addIfExists(getFilePaths(), Path);
+  addIfExists(getFilePaths(), 

[PATCH] D115049: Fall back on Android triple w/o API level for runtimes search

2021-12-13 Thread Collin Baker via Phabricator via cfe-commits
collinbaker marked 2 inline comments as done.
collinbaker added inline comments.



Comment at: clang/lib/Driver/ToolChain.cpp:500
+  if (getTriple().isAndroid() &&
+  getTriple().getEnvironmentName() != "android") {
+llvm::outs() << getTriple().getEnvironmentName() << "\n";

thakis wrote:
> Why do you need the environment check?
This skips adding an extra path if the triple doesn't have an Android API level.

E.g. for the target triple aarch64-unknown-linux-android23, the environment 
name will be "android23". The condition will be true since "android23" != 
"android", and the extra path will be appended. If it had just been "android" 
it'll skip this step.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115049

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D115049: Fall back on Android triple w/o API level for runtimes search

2021-12-13 Thread Collin Baker via Phabricator via cfe-commits
collinbaker updated this revision to Diff 393978.
collinbaker added a comment.

- Address comments
- Fix VEToolchain build error
- Rebase


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115049

Files:
  clang/include/clang/Driver/ToolChain.h
  clang/lib/Driver/Driver.cpp
  clang/lib/Driver/ToolChain.cpp
  clang/lib/Driver/ToolChains/Fuchsia.cpp
  clang/lib/Driver/ToolChains/VEToolchain.cpp
  
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-linux-android/.keep
  
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-linux-android/libclang_rt.builtins.a
  
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-linux-android21/.keep
  
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-linux-android21/libclang_rt.builtins.a
  clang/test/Driver/linux-per-target-runtime-dir.c

Index: clang/test/Driver/linux-per-target-runtime-dir.c
===
--- clang/test/Driver/linux-per-target-runtime-dir.c
+++ clang/test/Driver/linux-per-target-runtime-dir.c
@@ -25,3 +25,21 @@
 // RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
 // RUN:   | FileCheck --check-prefix=CHECK-FILE-NAME-X8664 %s
 // CHECK-FILE-NAME-X8664: lib{{/|\\}}x86_64-unknown-linux-gnu{{/|\\}}libclang_rt.builtins.a
+
+// RUN: %clang -rtlib=compiler-rt -print-file-name=libclang_rt.builtins.a 2>&1 \
+// RUN: --target=aarch64-unknown-linux-android21 \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN:   | FileCheck --check-prefix=CHECK-FILE-NAME-ANDROID21 %s
+// CHECK-FILE-NAME-ANDROID21: lib{{/|\\}}aarch64-unknown-linux-android21{{/|\\}}libclang_rt.builtins.a
+
+// RUN: %clang -rtlib=compiler-rt -print-file-name=libclang_rt.builtins.a 2>&1 \
+// RUN: --target=aarch64-unknown-linux-android23 \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN:   | FileCheck --check-prefix=CHECK-FILE-NAME-ANDROID23 %s
+// CHECK-FILE-NAME-ANDROID23: lib{{/|\\}}aarch64-unknown-linux-android{{/|\\}}libclang_rt.builtins.a
+
+// RUN: %clang -rtlib=compiler-rt -print-file-name=libclang_rt.builtins.a 2>&1 \
+// RUN: --target=aarch64-unknown-linux-android \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN:   | FileCheck --check-prefix=CHECK-FILE-NAME-ANDROID %s
+// CHECK-FILE-NAME-ANDROID: lib{{/|\\}}aarch64-unknown-linux-android{{/|\\}}libclang_rt.builtins.a
Index: clang/lib/Driver/ToolChains/VEToolchain.cpp
===
--- clang/lib/Driver/ToolChains/VEToolchain.cpp
+++ clang/lib/Driver/ToolChains/VEToolchain.cpp
@@ -48,7 +48,8 @@
   //   ${BINPATH}/../lib/ve-unknown-linux-gnu, (== getStdlibPath)
   //   ${RESOURCEDIR}/lib/linux/ve, (== getArchSpecificLibPath)
   //   ${SYSROOT}/opt/nec/ve/lib,
-  getFilePaths().push_back(getStdlibPath());
+  for (auto  : getStdlibPaths())
+getFilePaths().push_back(std::move(Path));
   getFilePaths().push_back(getArchSpecificLibPath());
   getFilePaths().push_back(computeSysRoot() + "/opt/nec/ve/lib");
 }
Index: clang/lib/Driver/ToolChains/Fuchsia.cpp
===
--- clang/lib/Driver/ToolChains/Fuchsia.cpp
+++ clang/lib/Driver/ToolChains/Fuchsia.cpp
@@ -191,9 +191,11 @@
 
   auto FilePaths = [&](const Multilib ) -> std::vector {
 std::vector FP;
-SmallString<128> P(getStdlibPath());
-llvm::sys::path::append(P, M.gccSuffix());
-FP.push_back(std::string(P.str()));
+for (const std::string  : getStdlibPaths()) {
+  SmallString<128> P(Path);
+  llvm::sys::path::append(P, M.gccSuffix());
+  FP.push_back(std::string(P.str()));
+}
 return FP;
   };
 
Index: clang/lib/Driver/ToolChain.cpp
===
--- clang/lib/Driver/ToolChain.cpp
+++ clang/lib/Driver/ToolChain.cpp
@@ -75,17 +75,16 @@
  const ArgList )
 : D(D), Triple(T), Args(Args), CachedRTTIArg(GetRTTIArgument(Args)),
   CachedRTTIMode(CalculateRTTIMode(Args, Triple, CachedRTTIArg)) {
-  std::string RuntimePath = getRuntimePath();
-  if (getVFS().exists(RuntimePath))
-getLibraryPaths().push_back(RuntimePath);
-
-  std::string StdlibPath = getStdlibPath();
-  if (getVFS().exists(StdlibPath))
-getFilePaths().push_back(StdlibPath);
+  auto addIfExists = [this](path_list , const std::string ) {
+if (getVFS().exists(Path))
+  List.push_back(Path);
+  };
 
-  std::string CandidateLibPath = getArchSpecificLibPath();
-  if (getVFS().exists(CandidateLibPath))
-getFilePaths().push_back(CandidateLibPath);
+  for (const auto  : getRuntimePaths())
+addIfExists(getLibraryPaths(), Path);
+  for (const auto  : getStdlibPaths())
+addIfExists(getFilePaths(), Path);
+  

[PATCH] D115049: Fall back on Android triple w/o API level for runtimes search

2021-12-03 Thread Collin Baker via Phabricator via cfe-commits
collinbaker updated this revision to Diff 391661.
collinbaker added a comment.

Fix variable name style


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115049

Files:
  clang/include/clang/Driver/ToolChain.h
  clang/lib/Driver/Driver.cpp
  clang/lib/Driver/ToolChain.cpp
  clang/lib/Driver/ToolChains/Fuchsia.cpp
  
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-linux-android/.keep
  
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-linux-android/libclang_rt.builtins.a
  
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-linux-android21/.keep
  
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-linux-android21/libclang_rt.builtins.a
  clang/test/Driver/linux-per-target-runtime-dir.c

Index: clang/test/Driver/linux-per-target-runtime-dir.c
===
--- clang/test/Driver/linux-per-target-runtime-dir.c
+++ clang/test/Driver/linux-per-target-runtime-dir.c
@@ -25,3 +25,21 @@
 // RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
 // RUN:   | FileCheck --check-prefix=CHECK-FILE-NAME-X8664 %s
 // CHECK-FILE-NAME-X8664: lib{{/|\\}}x86_64-unknown-linux-gnu{{/|\\}}libclang_rt.builtins.a
+
+// RUN: %clang -rtlib=compiler-rt -print-file-name=libclang_rt.builtins.a 2>&1 \
+// RUN: --target=aarch64-unknown-linux-android21 \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN:   | FileCheck --check-prefix=CHECK-FILE-NAME-ANDROID21 %s
+// CHECK-FILE-NAME-ANDROID21: lib{{/|\\}}aarch64-unknown-linux-android21{{/|\\}}libclang_rt.builtins.a
+
+// RUN: %clang -rtlib=compiler-rt -print-file-name=libclang_rt.builtins.a 2>&1 \
+// RUN: --target=aarch64-unknown-linux-android23 \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN:   | FileCheck --check-prefix=CHECK-FILE-NAME-ANDROID23 %s
+// CHECK-FILE-NAME-ANDROID23: lib{{/|\\}}aarch64-unknown-linux-android{{/|\\}}libclang_rt.builtins.a
+
+// RUN: %clang -rtlib=compiler-rt -print-file-name=libclang_rt.builtins.a 2>&1 \
+// RUN: --target=aarch64-unknown-linux-android \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN:   | FileCheck --check-prefix=CHECK-FILE-NAME-ANDROID %s
+// CHECK-FILE-NAME-ANDROID: lib{{/|\\}}aarch64-unknown-linux-android{{/|\\}}libclang_rt.builtins.a
Index: clang/lib/Driver/ToolChains/Fuchsia.cpp
===
--- clang/lib/Driver/ToolChains/Fuchsia.cpp
+++ clang/lib/Driver/ToolChains/Fuchsia.cpp
@@ -191,9 +191,11 @@
 
   auto FilePaths = [&](const Multilib ) -> std::vector {
 std::vector FP;
-SmallString<128> P(getStdlibPath());
-llvm::sys::path::append(P, M.gccSuffix());
-FP.push_back(std::string(P.str()));
+for (const std::string  : getStdlibPaths()) {
+  SmallString<128> P(Path);
+  llvm::sys::path::append(P, M.gccSuffix());
+  FP.push_back(std::string(P.str()));
+}
 return FP;
   };
 
Index: clang/lib/Driver/ToolChain.cpp
===
--- clang/lib/Driver/ToolChain.cpp
+++ clang/lib/Driver/ToolChain.cpp
@@ -75,17 +75,16 @@
  const ArgList )
 : D(D), Triple(T), Args(Args), CachedRTTIArg(GetRTTIArgument(Args)),
   CachedRTTIMode(CalculateRTTIMode(Args, Triple, CachedRTTIArg)) {
-  std::string RuntimePath = getRuntimePath();
-  if (getVFS().exists(RuntimePath))
-getLibraryPaths().push_back(RuntimePath);
-
-  std::string StdlibPath = getStdlibPath();
-  if (getVFS().exists(StdlibPath))
-getFilePaths().push_back(StdlibPath);
+  auto addIfExists = [this](path_list , const std::string ) {
+if (getVFS().exists(Path))
+  List.push_back(Path);
+  };
 
-  std::string CandidateLibPath = getArchSpecificLibPath();
-  if (getVFS().exists(CandidateLibPath))
-getFilePaths().push_back(CandidateLibPath);
+  for (const auto  : getRuntimePaths())
+addIfExists(getLibraryPaths(), Path);
+  for (const auto  : getStdlibPaths())
+addIfExists(getFilePaths(), Path);
+  addIfExists(getFilePaths(), getArchSpecificLibPath());
 }
 
 void ToolChain::setTripleEnvironment(llvm::Triple::EnvironmentType Env) {
@@ -485,16 +484,36 @@
   return Args.MakeArgString(getCompilerRT(Args, Component, Type));
 }
 
-std::string ToolChain::getRuntimePath() const {
-  SmallString<128> P(D.ResourceDir);
-  llvm::sys::path::append(P, "lib", getTripleString());
-  return std::string(P.str());
+ToolChain::path_list ToolChain::getRuntimePaths() const {
+  path_list Paths;
+  auto addPathForTriple = [this, ](const llvm::Triple ) {
+SmallString<128> P(D.ResourceDir);
+llvm::sys::path::append(P, "lib", Triple.str());
+Paths.push_back(std::string(P.str()));
+  };
+
+  addPathForTriple(getTriple());
+
+  // 

[PATCH] D115049: Fall back on Android triple w/o API level for runtimes search

2021-12-03 Thread Collin Baker via Phabricator via cfe-commits
collinbaker created this revision.
Herald added subscribers: abrachet, danielkiss, kristof.beyls.
collinbaker requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Clang searches for runtimes (e.g. libclang_rt*) first in a
subdirectory named for the target triple (corresponding to
LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON), then if it's not found uses
.../lib//libclang_rt* with a suffix corresponding to the arch and
environment name.

Android triples optionally include an API level indicating the minimum
Android version to be run on
(e.g. aarch64-unknown-linux-android21). When compiler-rt is built with
LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON this API level is part of the
output path.

Linking code built for a later API level against a runtime built for
an earlier one is safe. In projects with several API level targets
this is desireable to avoid re-building the same runtimes many
times. This is difficult with the current runtime search method: if
the API levels don't exactly match Clang gives up on the per-target
runtime directory path.

To enable this more simply, this change tries target triple without
the API level before falling back on the old layout.

Another option would be to try every API level in the triple,
e.g. check aarch-64-unknown-linux-android21, then ...20, then ...19,
etc.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D115049

Files:
  clang/include/clang/Driver/ToolChain.h
  clang/lib/Driver/Driver.cpp
  clang/lib/Driver/ToolChain.cpp
  clang/lib/Driver/ToolChains/Fuchsia.cpp
  
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-linux-android/.keep
  
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-linux-android/libclang_rt.builtins.a
  
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-linux-android21/.keep
  
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-linux-android21/libclang_rt.builtins.a
  clang/test/Driver/linux-per-target-runtime-dir.c

Index: clang/test/Driver/linux-per-target-runtime-dir.c
===
--- clang/test/Driver/linux-per-target-runtime-dir.c
+++ clang/test/Driver/linux-per-target-runtime-dir.c
@@ -25,3 +25,21 @@
 // RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
 // RUN:   | FileCheck --check-prefix=CHECK-FILE-NAME-X8664 %s
 // CHECK-FILE-NAME-X8664: lib{{/|\\}}x86_64-unknown-linux-gnu{{/|\\}}libclang_rt.builtins.a
+
+// RUN: %clang -rtlib=compiler-rt -print-file-name=libclang_rt.builtins.a 2>&1 \
+// RUN: --target=aarch64-unknown-linux-android21 \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN:   | FileCheck --check-prefix=CHECK-FILE-NAME-ANDROID21 %s
+// CHECK-FILE-NAME-ANDROID21: lib{{/|\\}}aarch64-unknown-linux-android21{{/|\\}}libclang_rt.builtins.a
+
+// RUN: %clang -rtlib=compiler-rt -print-file-name=libclang_rt.builtins.a 2>&1 \
+// RUN: --target=aarch64-unknown-linux-android23 \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN:   | FileCheck --check-prefix=CHECK-FILE-NAME-ANDROID23 %s
+// CHECK-FILE-NAME-ANDROID23: lib{{/|\\}}aarch64-unknown-linux-android{{/|\\}}libclang_rt.builtins.a
+
+// RUN: %clang -rtlib=compiler-rt -print-file-name=libclang_rt.builtins.a 2>&1 \
+// RUN: --target=aarch64-unknown-linux-android \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN:   | FileCheck --check-prefix=CHECK-FILE-NAME-ANDROID %s
+// CHECK-FILE-NAME-ANDROID: lib{{/|\\}}aarch64-unknown-linux-android{{/|\\}}libclang_rt.builtins.a
Index: clang/lib/Driver/ToolChains/Fuchsia.cpp
===
--- clang/lib/Driver/ToolChains/Fuchsia.cpp
+++ clang/lib/Driver/ToolChains/Fuchsia.cpp
@@ -191,9 +191,11 @@
 
   auto FilePaths = [&](const Multilib ) -> std::vector {
 std::vector FP;
-SmallString<128> P(getStdlibPath());
-llvm::sys::path::append(P, M.gccSuffix());
-FP.push_back(std::string(P.str()));
+for (const std::string  : getStdlibPaths()) {
+  SmallString<128> P(Path);
+  llvm::sys::path::append(P, M.gccSuffix());
+  FP.push_back(std::string(P.str()));
+}
 return FP;
   };
 
Index: clang/lib/Driver/ToolChain.cpp
===
--- clang/lib/Driver/ToolChain.cpp
+++ clang/lib/Driver/ToolChain.cpp
@@ -75,17 +75,16 @@
  const ArgList )
 : D(D), Triple(T), Args(Args), CachedRTTIArg(GetRTTIArgument(Args)),
   CachedRTTIMode(CalculateRTTIMode(Args, Triple, CachedRTTIArg)) {
-  std::string RuntimePath = getRuntimePath();
-  if (getVFS().exists(RuntimePath))
-getLibraryPaths().push_back(RuntimePath);
-
-  std::string StdlibPath = getStdlibPath();
-  if (getVFS().exists(StdlibPath))
-