[PATCH] D59233: libclang/CIndexer.cpp: Use loadquery() on AIX for path to library

2019-03-23 Thread Hubert Tong via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
hubert.reinterpretcast marked 3 inline comments as done.
Closed by commit rC356843: libclang/CIndexer.cpp: Use loadquery() on AIX for 
path to library (authored by hubert.reinterpretcast, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D59233?vs=190170&id=192005#toc

Repository:
  rC Clang

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

https://reviews.llvm.org/D59233

Files:
  tools/libclang/CIndexer.cpp


Index: tools/libclang/CIndexer.cpp
===
--- tools/libclang/CIndexer.cpp
+++ tools/libclang/CIndexer.cpp
@@ -32,12 +32,69 @@
 
 #ifdef _WIN32
 #include 
+#elif defined(_AIX)
+#include 
+#include 
 #else
 #include 
 #endif
 
 using namespace clang;
 
+#ifdef _AIX
+namespace clang {
+namespace {
+
+template 
+void getClangResourcesPathImplAIX(LibClangPathType &LibClangPath) {
+  int PrevErrno = errno;
+
+  size_t BufSize = 2048u;
+  std::unique_ptr Buf;
+  while (true) {
+Buf = llvm::make_unique(BufSize);
+errno = 0;
+int Ret = loadquery(L_GETXINFO, Buf.get(), (unsigned int)BufSize);
+if (Ret != -1)
+  break; // loadquery() was successful.
+if (errno != ENOMEM)
+  llvm_unreachable("Encountered an unexpected loadquery() failure");
+
+// errno == ENOMEM; try to allocate more memory.
+if ((BufSize & ~((-1u) >> 1u)) != 0u)
+  llvm::report_fatal_error("BufSize needed for loadquery() too large");
+
+Buf.release();
+BufSize <<= 1u;
+  }
+
+  // Extract the function entry point from the function descriptor.
+  uint64_t EntryAddr =
+  reinterpret_cast(clang_createTranslationUnit);
+
+  // Loop to locate the function entry point in the loadquery() results.
+  ld_xinfo *CurInfo = reinterpret_cast(Buf.get());
+  while (true) {
+uint64_t CurTextStart = (uint64_t)CurInfo->ldinfo_textorg;
+uint64_t CurTextEnd = CurTextStart + CurInfo->ldinfo_textsize;
+if (CurTextStart <= EntryAddr && EntryAddr < CurTextEnd)
+  break; // Successfully located.
+
+if (CurInfo->ldinfo_next == 0u)
+  llvm::report_fatal_error("Cannot locate entry point in "
+   "the loadquery() results");
+CurInfo = reinterpret_cast(reinterpret_cast(CurInfo) +
+   CurInfo->ldinfo_next);
+  }
+
+  LibClangPath += reinterpret_cast(CurInfo) + CurInfo->ldinfo_filename;
+  errno = PrevErrno;
+}
+
+} // end anonymous namespace
+} // end namespace clang
+#endif
+
 const std::string &CIndexer::getClangResourcesPath() {
   // Did we already compute the path?
   if (!ResourcesPath.empty())
@@ -64,6 +121,8 @@
 #endif
 
   LibClangPath += path;
+#elif defined(_AIX)
+  getClangResourcesPathImplAIX(LibClangPath);
 #else
   // This silly cast below avoids a C++ warning.
   Dl_info info;


Index: tools/libclang/CIndexer.cpp
===
--- tools/libclang/CIndexer.cpp
+++ tools/libclang/CIndexer.cpp
@@ -32,12 +32,69 @@
 
 #ifdef _WIN32
 #include 
+#elif defined(_AIX)
+#include 
+#include 
 #else
 #include 
 #endif
 
 using namespace clang;
 
+#ifdef _AIX
+namespace clang {
+namespace {
+
+template 
+void getClangResourcesPathImplAIX(LibClangPathType &LibClangPath) {
+  int PrevErrno = errno;
+
+  size_t BufSize = 2048u;
+  std::unique_ptr Buf;
+  while (true) {
+Buf = llvm::make_unique(BufSize);
+errno = 0;
+int Ret = loadquery(L_GETXINFO, Buf.get(), (unsigned int)BufSize);
+if (Ret != -1)
+  break; // loadquery() was successful.
+if (errno != ENOMEM)
+  llvm_unreachable("Encountered an unexpected loadquery() failure");
+
+// errno == ENOMEM; try to allocate more memory.
+if ((BufSize & ~((-1u) >> 1u)) != 0u)
+  llvm::report_fatal_error("BufSize needed for loadquery() too large");
+
+Buf.release();
+BufSize <<= 1u;
+  }
+
+  // Extract the function entry point from the function descriptor.
+  uint64_t EntryAddr =
+  reinterpret_cast(clang_createTranslationUnit);
+
+  // Loop to locate the function entry point in the loadquery() results.
+  ld_xinfo *CurInfo = reinterpret_cast(Buf.get());
+  while (true) {
+uint64_t CurTextStart = (uint64_t)CurInfo->ldinfo_textorg;
+uint64_t CurTextEnd = CurTextStart + CurInfo->ldinfo_textsize;
+if (CurTextStart <= EntryAddr && EntryAddr < CurTextEnd)
+  break; // Successfully located.
+
+if (CurInfo->ldinfo_next == 0u)
+  llvm::report_fatal_error("Cannot locate entry point in "
+   "the loadquery() results");
+CurInfo = reinterpret_cast(reinterpret_cast(CurInfo) +
+   CurInfo->ldinfo_next);
+  }
+
+  LibClangPath += reinterpret_cast(CurInfo) + CurInfo->ldinfo_filename;
+  errno = PrevErrno;
+}
+
+} // end anonymous namespace
+} // end namespace clang
+#endif
+
 const std::string &CIndexer::getClangResourcesPath() {
   // Di

[PATCH] D59233: libclang/CIndexer.cpp: Use loadquery() on AIX for path to library

2019-03-22 Thread Alex Bradbury via Phabricator via cfe-commits
asb added a comment.

In D59233#1439656 , 
@hubert.reinterpretcast wrote:

> Thanks @xingxue for the review. I will update for the error handling before 
> committing.


Use of report_fatal_error/llvm_unreachable isn't fully consistent within the 
LLVM codebase, but I think your choices here are sensible.


Repository:
  rC Clang

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

https://reviews.llvm.org/D59233



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


[PATCH] D59233: libclang/CIndexer.cpp: Use loadquery() on AIX for path to library

2019-03-22 Thread Hubert Tong via Phabricator via cfe-commits
hubert.reinterpretcast marked 6 inline comments as done.
hubert.reinterpretcast added a comment.
Herald added a subscriber: jsji.

Thanks @xingxue for the review. I will update for the error handling before 
committing.




Comment at: tools/libclang/CIndexer.cpp:61
+if (errno != ENOMEM)
+  llvm_unreachable("Encountered an unexpected loadquery() failure");
+

hubert.reinterpretcast wrote:
> Based on available documentation, this situation should not occur (and thus I 
> believe `llvm_unreachable` is appropriate).
I'll leave this one as `llvm_unreachable`, either the failure is resolved on a 
later call or the loop will terminate when the amount of memory to request 
(checked below) is too large.



Comment at: tools/libclang/CIndexer.cpp:65
+if ((BufSize & ~((-1u) >> 1u)) != 0u)
+  llvm_unreachable("BufSize needed for loadquery() too large");
+

hubert.reinterpretcast wrote:
> This situation is not impossible, but highly improbable. This is a 
> non-programmatic error, and the Programmer's Manual appears to recommend the 
> use of `report_fatal_error`. Some additional guidance would be appreciated.
I will change this to `report_fatal_error`.



Comment at: tools/libclang/CIndexer.cpp:84
+if (CurInfo->ldinfo_next == 0u)
+  llvm_unreachable("Cannot locate entry point in the loadquery() results");
+CurInfo = reinterpret_cast(reinterpret_cast(CurInfo) +

hubert.reinterpretcast wrote:
> This is also supposed to not happen.
I will change this to `report_fatal_error`. Infinite loops are unfriendly.


Repository:
  rC Clang

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

https://reviews.llvm.org/D59233



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


[PATCH] D59233: libclang/CIndexer.cpp: Use loadquery() on AIX for path to library

2019-03-15 Thread Hubert Tong via Phabricator via cfe-commits
hubert.reinterpretcast added subscribers: asb, majnemer, lhames.
hubert.reinterpretcast added a comment.

@asb @lhames @majnemer, based on D36826 , I 
believe that your guidance would be helpful here regarding the use of 
`llvm_unreachable`, `report_fatal_error`, and `assert`.


Repository:
  rC Clang

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

https://reviews.llvm.org/D59233



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


[PATCH] D59233: libclang/CIndexer.cpp: Use loadquery() on AIX for path to library

2019-03-15 Thread Xing Xue via Phabricator via cfe-commits
xingxue accepted this revision.
xingxue added a comment.
This revision is now accepted and ready to land.

LGTM.  Thanks!


Repository:
  rC Clang

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

https://reviews.llvm.org/D59233



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


[PATCH] D59233: libclang/CIndexer.cpp: Use loadquery() on AIX for path to library

2019-03-11 Thread Hubert Tong via Phabricator via cfe-commits
hubert.reinterpretcast added a comment.

I believe that the conditions being checked for with `llvm_unreachable` in this 
patch are of the debug-only variety; however, some input would be appreciated 
regarding the choice of using `llvm_unreachable` instead of 
`report_fatal_error` or `assert`.




Comment at: tools/libclang/CIndexer.cpp:61
+if (errno != ENOMEM)
+  llvm_unreachable("Encountered an unexpected loadquery() failure");
+

Based on available documentation, this situation should not occur (and thus I 
believe `llvm_unreachable` is appropriate).



Comment at: tools/libclang/CIndexer.cpp:65
+if ((BufSize & ~((-1u) >> 1u)) != 0u)
+  llvm_unreachable("BufSize needed for loadquery() too large");
+

This situation is not impossible, but highly improbable. This is a 
non-programmatic error, and the Programmer's Manual appears to recommend the 
use of `report_fatal_error`. Some additional guidance would be appreciated.



Comment at: tools/libclang/CIndexer.cpp:84
+if (CurInfo->ldinfo_next == 0u)
+  llvm_unreachable("Cannot locate entry point in the loadquery() results");
+CurInfo = reinterpret_cast(reinterpret_cast(CurInfo) +

This is also supposed to not happen.


Repository:
  rC Clang

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

https://reviews.llvm.org/D59233



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


[PATCH] D59233: libclang/CIndexer.cpp: Use loadquery() on AIX for path to library

2019-03-11 Thread Hubert Tong via Phabricator via cfe-commits
hubert.reinterpretcast created this revision.
hubert.reinterpretcast added reviewers: sfertile, xingxue, jasonliu.
Herald added a subscriber: arphaman.
Herald added a project: clang.

`dladdr` is not available on AIX. Similar functionality is presented through 
`loadquery`. This patch replaces a use of `dladdr` with a version based on 
`loadquery`.


Repository:
  rC Clang

https://reviews.llvm.org/D59233

Files:
  tools/libclang/CIndexer.cpp


Index: tools/libclang/CIndexer.cpp
===
--- tools/libclang/CIndexer.cpp
+++ tools/libclang/CIndexer.cpp
@@ -32,12 +32,68 @@
 
 #ifdef _WIN32
 #include 
+#elif defined(_AIX)
+#include 
+#include 
 #else
 #include 
 #endif
 
 using namespace clang;
 
+#ifdef _AIX
+namespace clang {
+namespace {
+
+template 
+void getClangResourcesPathImplAIX(LibClangPathType &LibClangPath) {
+  int PrevErrno = errno;
+
+  size_t BufSize = 2048u;
+  std::unique_ptr Buf;
+  while (true) {
+Buf = llvm::make_unique(BufSize);
+errno = 0;
+int Ret = loadquery(L_GETXINFO, Buf.get(), (unsigned int)BufSize);
+if (Ret != -1)
+  break; // loadquery() was successful.
+if (errno != ENOMEM)
+  llvm_unreachable("Encountered an unexpected loadquery() failure");
+
+// errno == ENOMEM; try to allocate more memory.
+if ((BufSize & ~((-1u) >> 1u)) != 0u)
+  llvm_unreachable("BufSize needed for loadquery() too large");
+
+Buf.release();
+BufSize <<= 1u;
+  }
+
+  // Extract the function entry point from the function descriptor.
+  uint64_t EntryAddr =
+  reinterpret_cast(clang_createTranslationUnit);
+
+  // Loop to locate the function entry point in the loadquery() results.
+  ld_xinfo *CurInfo = reinterpret_cast(Buf.get());
+  while (true) {
+uint64_t CurTextStart = (uint64_t)CurInfo->ldinfo_textorg;
+uint64_t CurTextEnd = CurTextStart + CurInfo->ldinfo_textsize;
+if (CurTextStart <= EntryAddr && EntryAddr < CurTextEnd)
+  break; // Successfully located.
+
+if (CurInfo->ldinfo_next == 0u)
+  llvm_unreachable("Cannot locate entry point in the loadquery() results");
+CurInfo = reinterpret_cast(reinterpret_cast(CurInfo) +
+   CurInfo->ldinfo_next);
+  }
+
+  LibClangPath += reinterpret_cast(CurInfo) + CurInfo->ldinfo_filename;
+  errno = PrevErrno;
+}
+
+} // end anonymous namespace
+} // end namespace clang
+#endif
+
 const std::string &CIndexer::getClangResourcesPath() {
   // Did we already compute the path?
   if (!ResourcesPath.empty())
@@ -64,6 +120,8 @@
 #endif
 
   LibClangPath += path;
+#elif defined(_AIX)
+  getClangResourcesPathImplAIX(LibClangPath);
 #else
   // This silly cast below avoids a C++ warning.
   Dl_info info;


Index: tools/libclang/CIndexer.cpp
===
--- tools/libclang/CIndexer.cpp
+++ tools/libclang/CIndexer.cpp
@@ -32,12 +32,68 @@
 
 #ifdef _WIN32
 #include 
+#elif defined(_AIX)
+#include 
+#include 
 #else
 #include 
 #endif
 
 using namespace clang;
 
+#ifdef _AIX
+namespace clang {
+namespace {
+
+template 
+void getClangResourcesPathImplAIX(LibClangPathType &LibClangPath) {
+  int PrevErrno = errno;
+
+  size_t BufSize = 2048u;
+  std::unique_ptr Buf;
+  while (true) {
+Buf = llvm::make_unique(BufSize);
+errno = 0;
+int Ret = loadquery(L_GETXINFO, Buf.get(), (unsigned int)BufSize);
+if (Ret != -1)
+  break; // loadquery() was successful.
+if (errno != ENOMEM)
+  llvm_unreachable("Encountered an unexpected loadquery() failure");
+
+// errno == ENOMEM; try to allocate more memory.
+if ((BufSize & ~((-1u) >> 1u)) != 0u)
+  llvm_unreachable("BufSize needed for loadquery() too large");
+
+Buf.release();
+BufSize <<= 1u;
+  }
+
+  // Extract the function entry point from the function descriptor.
+  uint64_t EntryAddr =
+  reinterpret_cast(clang_createTranslationUnit);
+
+  // Loop to locate the function entry point in the loadquery() results.
+  ld_xinfo *CurInfo = reinterpret_cast(Buf.get());
+  while (true) {
+uint64_t CurTextStart = (uint64_t)CurInfo->ldinfo_textorg;
+uint64_t CurTextEnd = CurTextStart + CurInfo->ldinfo_textsize;
+if (CurTextStart <= EntryAddr && EntryAddr < CurTextEnd)
+  break; // Successfully located.
+
+if (CurInfo->ldinfo_next == 0u)
+  llvm_unreachable("Cannot locate entry point in the loadquery() results");
+CurInfo = reinterpret_cast(reinterpret_cast(CurInfo) +
+   CurInfo->ldinfo_next);
+  }
+
+  LibClangPath += reinterpret_cast(CurInfo) + CurInfo->ldinfo_filename;
+  errno = PrevErrno;
+}
+
+} // end anonymous namespace
+} // end namespace clang
+#endif
+
 const std::string &CIndexer::getClangResourcesPath() {
   // Did we already compute the path?
   if (!ResourcesPath.empty())
@@ -64,6 +120,8 @@
 #endif
 
   LibClangPath += path;
+#elif defined(_AIX)
+  getClangResourcesPathImplAIX(LibClangP