[clang] 6775fc6 - [clang-repl] Implement partial translation units and error recovery.

2021-07-11 Thread Vassil Vassilev via cfe-commits

Author: Vassil Vassilev
Date: 2021-07-11T10:23:41Z
New Revision: 6775fc6ffa3ca1c36b20c25fa4e7f48f81213cf2

URL: 
https://github.com/llvm/llvm-project/commit/6775fc6ffa3ca1c36b20c25fa4e7f48f81213cf2
DIFF: 
https://github.com/llvm/llvm-project/commit/6775fc6ffa3ca1c36b20c25fa4e7f48f81213cf2.diff

LOG: [clang-repl] Implement partial translation units and error recovery.

https://reviews.llvm.org/D96033 contained a discussion regarding efficient
modeling of error recovery. @rjmccall has outlined the key ideas:

Conceptually, we can split the translation unit into a sequence of partial
translation units (PTUs). Every declaration will be associated with a unique PTU
that owns it.

The first key insight here is that the owning PTU isn't always the "active"
(most recent) PTU, and it isn't always the PTU that the declaration
"comes from". A new declaration (that isn't a redeclaration or specialization of
anything) does belong to the active PTU. A template specialization, however,
belongs to the most recent PTU of all the declarations in its signature - mostly
that means that it can be pulled into a more recent PTU by its template
arguments.

The second key insight is that processing a PTU might extend an earlier PTU.
Rolling back the later PTU shouldn't throw that extension away. For example, if
the second PTU defines a template, and the third PTU requires that template to
be instantiated at float, that template specialization is still part of the
second PTU. Similarly, if the fifth PTU uses an inline function belonging to the
fourth, that definition still belongs to the fourth. When we go to emit code in
a new PTU, we map each declaration we have to emit back to its owning PTU and
emit it in a new module for just the extensions to that PTU. We keep track of
all the modules we've emitted for a PTU so that we can unload them all if we
decide to roll it back.

Most declarations/definitions will only refer to entities from the same or
earlier PTUs. However, it is possible (primarily by defining a
previously-declared entity, but also through templates or ADL) for an entity
that belongs to one PTU to refer to something from a later PTU. We will have to
keep track of this and prevent unwinding to later PTU when we recognize it.
Fortunately, this should be very rare; and crucially, we don't have to do the
bookkeeping for this if we've only got one PTU, e.g. in normal compilation.
Otherwise, PTUs after the first just need to record enough metadata to be able
to revert any changes they've made to declarations belonging to earlier PTUs,
e.g. to redeclaration chains or template specialization lists.

It should even eventually be possible for PTUs to provide their own slab
allocators which can be thrown away as part of rolling back the PTU. We can
maintain a notion of the active allocator and allocate things like Stmt/Expr
nodes in it, temporarily changing it to the appropriate PTU whenever we go to do
something like instantiate a function template. More care will be required when
allocating declarations and types, though.

We would want the PTU to be efficiently recoverable from a Decl; I'm not sure
how best to do that. An easy option that would cover most declarations would be
to make multiple TranslationUnitDecls and parent the declarations appropriately,
but I don't think that's good enough for things like member function templates,
since an instantiation of that would still be parented by its original class.
Maybe we can work this into the DC chain somehow, like how lexical DCs are.

We add a different kind of translation unit `TU_Incremental` which is a
complete translation unit that we might nonetheless incrementally extend later.
Because it is complete (and we might want to generate code for it), we do
perform template instantiation, but because it might be extended later, we don't
warn if it declares or uses undefined internal-linkage symbols.

This patch teaches clang-repl how to recover from errors by disconnecting the
most recent PTU and update the primary PTU lookup tables. For instance:

```./clang-repl
clang-repl> int i = 12; error;
In file included from <<< inputs >>>:1:
input_line_0:1:13: error: C++ requires a type specifier for all declarations
int i = 12; error;
^
error: Parsing failed.
clang-repl> int i = 13; extern "C" int printf(const char*,...);
clang-repl> auto r1 = printf("i=%d\n", i);
i=13
clang-repl> quit
```

Differential revision: https://reviews.llvm.org/D104918

Added: 
clang/include/clang/Interpreter/PartialTranslationUnit.h

Modified: 
clang/include/clang/AST/ASTContext.h
clang/include/clang/AST/Decl.h
clang/include/clang/AST/Redeclarable.h
clang/include/clang/Basic/LangOptions.h
clang/include/clang/Interpreter/Interpreter.h
clang/include/clang/Lex/Preprocessor.h
clang/include/clang/Sema/Sema.h
clang/lib/AST/ASTContext.cpp
clang/lib/AST/Decl.cpp
clang/lib/AST/DeclBase.cpp
clang/lib/Frontend/ASTUnit.cpp
clang/lib/Frontend/CompilerI

[PATCH] D104918: [clang-repl] Implement partial translation units and error recovery.

2021-07-11 Thread Vassil Vassilev via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG6775fc6ffa3c: [clang-repl] Implement partial translation 
units and error recovery. (authored by v.g.vassilev).
Herald added a project: clang.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D104918

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/Redeclarable.h
  clang/include/clang/Basic/LangOptions.h
  clang/include/clang/Interpreter/Interpreter.h
  clang/include/clang/Interpreter/PartialTranslationUnit.h
  clang/include/clang/Interpreter/Transaction.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/Decl.cpp
  clang/lib/AST/DeclBase.cpp
  clang/lib/Frontend/ASTUnit.cpp
  clang/lib/Frontend/CompilerInstance.cpp
  clang/lib/Interpreter/IncrementalParser.cpp
  clang/lib/Interpreter/IncrementalParser.h
  clang/lib/Interpreter/Interpreter.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/tools/clang-import-test/clang-import-test.cpp
  clang/unittests/AST/ASTVectorTest.cpp
  clang/unittests/Interpreter/IncrementalProcessingTest.cpp
  clang/unittests/Interpreter/InterpreterTest.cpp
  clang/unittests/Lex/PPCallbacksTest.cpp

Index: clang/unittests/Lex/PPCallbacksTest.cpp
===
--- clang/unittests/Lex/PPCallbacksTest.cpp
+++ clang/unittests/Lex/PPCallbacksTest.cpp
@@ -323,7 +323,7 @@
 // according to LangOptions, so we init Parser to register opencl
 // pragma handlers
 ASTContext Context(OpenCLLangOpts, SourceMgr, PP.getIdentifierTable(),
-   PP.getSelectorTable(), PP.getBuiltinInfo());
+   PP.getSelectorTable(), PP.getBuiltinInfo(), PP.TUKind);
 Context.InitBuiltinTypes(*Target);
 
 ASTConsumer Consumer;
Index: clang/unittests/Interpreter/InterpreterTest.cpp
===
--- clang/unittests/Interpreter/InterpreterTest.cpp
+++ clang/unittests/Interpreter/InterpreterTest.cpp
@@ -37,34 +37,41 @@
   return cantFail(clang::Interpreter::create(std::move(CI)));
 }
 
+static size_t DeclsSize(TranslationUnitDecl *PTUDecl) {
+  return std::distance(PTUDecl->decls().begin(), PTUDecl->decls().end());
+}
+
 TEST(InterpreterTest, Sanity) {
   std::unique_ptr Interp = createInterpreter();
-  Transaction &R1(cantFail(Interp->Parse("void g(); void g() {}")));
-  EXPECT_EQ(2U, R1.Decls.size());
 
-  Transaction &R2(cantFail(Interp->Parse("int i;")));
-  EXPECT_EQ(1U, R2.Decls.size());
+  using PTU = PartialTranslationUnit;
+
+  PTU &R1(cantFail(Interp->Parse("void g(); void g() {}")));
+  EXPECT_EQ(2U, DeclsSize(R1.TUPart));
+
+  PTU &R2(cantFail(Interp->Parse("int i;")));
+  EXPECT_EQ(1U, DeclsSize(R2.TUPart));
 }
 
-static std::string DeclToString(DeclGroupRef DGR) {
-  return llvm::cast(DGR.getSingleDecl())->getQualifiedNameAsString();
+static std::string DeclToString(Decl *D) {
+  return llvm::cast(D)->getQualifiedNameAsString();
 }
 
 TEST(InterpreterTest, IncrementalInputTopLevelDecls) {
   std::unique_ptr Interp = createInterpreter();
-  auto R1OrErr = Interp->Parse("int var1 = 42; int f() { return var1; }");
+  auto R1 = Interp->Parse("int var1 = 42; int f() { return var1; }");
   // gtest doesn't expand into explicit bool conversions.
-  EXPECT_TRUE(!!R1OrErr);
-  auto R1 = R1OrErr->Decls;
-  EXPECT_EQ(2U, R1.size());
-  EXPECT_EQ("var1", DeclToString(R1[0]));
-  EXPECT_EQ("f", DeclToString(R1[1]));
-
-  auto R2OrErr = Interp->Parse("int var2 = f();");
-  EXPECT_TRUE(!!R2OrErr);
-  auto R2 = R2OrErr->Decls;
-  EXPECT_EQ(1U, R2.size());
-  EXPECT_EQ("var2", DeclToString(R2[0]));
+  EXPECT_TRUE(!!R1);
+  auto R1DeclRange = R1->TUPart->decls();
+  EXPECT_EQ(2U, DeclsSize(R1->TUPart));
+  EXPECT_EQ("var1", DeclToString(*R1DeclRange.begin()));
+  EXPECT_EQ("f", DeclToString(*(++R1DeclRange.begin(;
+
+  auto R2 = Interp->Parse("int var2 = f();");
+  EXPECT_TRUE(!!R2);
+  auto R2DeclRange = R2->TUPart->decls();
+  EXPECT_EQ(1U, DeclsSize(R2->TUPart));
+  EXPECT_EQ("var2", DeclToString(*R2DeclRange.begin()));
 }
 
 TEST(InterpreterTest, Errors) {
@@ -83,9 +90,8 @@
   HasSubstr("error: unknown type name 'intentional_error'"));
   EXPECT_EQ("Parsing failed.", llvm::toString(std::move(Err)));
 
-#ifdef GTEST_HAS_DEATH_TEST
-  EXPECT_DEATH((void)Interp->Parse("int var1 = 42;"), "");
-#endif
+  auto RecoverErr = Interp->Parse("int var1 = 42;");
+  EXPECT_TRUE(!!RecoverErr);
 }
 
 // Here we test whether the user can mix declarations and statements. The
@@ -101,21 +107,21 @@
   DiagnosticsOS, new DiagnosticOptions());
 
   auto Interp = createInterpreter(ExtraArgs, DiagPrinter.get());
-  auto R1OrErr = Interp->Parse(
+  auto R1 = Interp->Parse(
   "in

[PATCH] D99484: Use `GNUInstallDirs` to support custom installation dirs.

2021-07-11 Thread John Ericson via Phabricator via cfe-commits
Ericson2314 updated this revision to Diff 357643.
Ericson2314 added a comment.
Herald added a subscriber: whisperity.

rebased, fixed some new DESTINATION


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D99484

Files:
  clang-tools-extra/clang-doc/tool/CMakeLists.txt
  clang-tools-extra/clang-include-fixer/find-all-symbols/tool/CMakeLists.txt
  clang-tools-extra/clang-include-fixer/tool/CMakeLists.txt
  clang-tools-extra/clang-tidy/CMakeLists.txt
  clang-tools-extra/clang-tidy/tool/CMakeLists.txt
  clang-tools-extra/modularize/CMakeLists.txt
  clang/CMakeLists.txt
  clang/cmake/modules/AddClang.cmake
  clang/tools/c-index-test/CMakeLists.txt
  clang/tools/clang-format/CMakeLists.txt
  clang/tools/clang-rename/CMakeLists.txt
  clang/tools/libclang/CMakeLists.txt
  clang/tools/scan-build-py/CMakeLists.txt
  clang/tools/scan-build/CMakeLists.txt
  clang/tools/scan-view/CMakeLists.txt
  clang/utils/hmaptool/CMakeLists.txt
  compiler-rt/cmake/base-config-ix.cmake
  flang/CMakeLists.txt
  flang/cmake/modules/AddFlang.cmake
  flang/tools/f18/CMakeLists.txt
  flang/tools/flang-driver/CMakeLists.txt
  libc/CMakeLists.txt
  libcxx/CMakeLists.txt
  libcxx/cmake/Modules/HandleLibCXXABI.cmake
  libcxx/include/CMakeLists.txt
  libcxx/src/CMakeLists.txt
  libcxxabi/CMakeLists.txt
  libunwind/CMakeLists.txt
  libunwind/src/CMakeLists.txt
  lld/CMakeLists.txt
  lld/cmake/modules/AddLLD.cmake
  lld/tools/lld/CMakeLists.txt
  lldb/CMakeLists.txt
  lldb/cmake/modules/AddLLDB.cmake
  lldb/cmake/modules/LLDBConfig.cmake
  mlir/CMakeLists.txt
  mlir/cmake/modules/AddMLIR.cmake
  openmp/CMakeLists.txt
  openmp/runtime/src/CMakeLists.txt
  openmp/tools/multiplex/CMakeLists.txt
  polly/CMakeLists.txt
  polly/cmake/CMakeLists.txt
  polly/lib/External/CMakeLists.txt
  pstl/CMakeLists.txt

Index: pstl/CMakeLists.txt
===
--- pstl/CMakeLists.txt
+++ pstl/CMakeLists.txt
@@ -7,6 +7,8 @@
 #===--===##
 cmake_minimum_required(VERSION 3.13.4)
 
+include(GNUInstallDirs)
+
 set(PARALLELSTL_VERSION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/include/pstl/internal/pstl_config.h")
 file(STRINGS "${PARALLELSTL_VERSION_FILE}" PARALLELSTL_VERSION_SOURCE REGEX "#define _PSTL_VERSION .*$")
 string(REGEX REPLACE "#define _PSTL_VERSION (.*)$" "\\1" PARALLELSTL_VERSION_SOURCE "${PARALLELSTL_VERSION_SOURCE}")
@@ -86,10 +88,10 @@
   "${CMAKE_CURRENT_BINARY_DIR}/ParallelSTLConfigVersion.cmake"
 DESTINATION lib/cmake/ParallelSTL)
 install(DIRECTORY include/
-DESTINATION include
+DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
 PATTERN "*.in" EXCLUDE)
 install(FILES "${PSTL_CONFIG_SITE_PATH}"
-DESTINATION include)
+DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
 
 add_custom_target(install-pstl
   COMMAND "${CMAKE_COMMAND}" -P "${PROJECT_BINARY_DIR}/cmake_install.cmake" -DCOMPONENT=ParallelSTL)
Index: polly/lib/External/CMakeLists.txt
===
--- polly/lib/External/CMakeLists.txt
+++ polly/lib/External/CMakeLists.txt
@@ -290,7 +290,7 @@
 install(DIRECTORY
   ${ISL_SOURCE_DIR}/include/
   ${ISL_BINARY_DIR}/include/
-  DESTINATION include/polly
+  DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/polly"
   FILES_MATCHING
   PATTERN "*.h"
   PATTERN "CMakeFiles" EXCLUDE
Index: polly/cmake/CMakeLists.txt
===
--- polly/cmake/CMakeLists.txt
+++ polly/cmake/CMakeLists.txt
@@ -83,14 +83,15 @@
 set(POLLY_CONFIG_LLVM_CMAKE_DIR "${LLVM_BINARY_DIR}/${LLVM_INSTALL_PACKAGE_DIR}")
 set(POLLY_CONFIG_CMAKE_DIR "${POLLY_INSTALL_PREFIX}/${POLLY_INSTALL_PACKAGE_DIR}")
 set(POLLY_CONFIG_LIBRARY_DIRS "${POLLY_INSTALL_PREFIX}/lib${LLVM_LIBDIR_SUFFIX}")
+get_filename_component(base_includedir "${CMAKE_INSTALL_INCLUDEDIR}" ABSOLUTE BASE_DIR "${POLLY_INSTALL_PREFIX}")
 if (POLLY_BUNDLED_ISL)
   set(POLLY_CONFIG_INCLUDE_DIRS
-"${POLLY_INSTALL_PREFIX}/include"
-"${POLLY_INSTALL_PREFIX}/include/polly"
+"${base_includedir}"
+"${base_includedir}/polly"
 )
 else()
   set(POLLY_CONFIG_INCLUDE_DIRS
-"${POLLY_INSTALL_PREFIX}/include"
+"${base_includedir}"
 ${ISL_INCLUDE_DIRS}
 )
 endif()
@@ -100,12 +101,12 @@
 foreach(tgt IN LISTS POLLY_CONFIG_EXPORTED_TARGETS)
   get_target_property(tgt_type ${tgt} TYPE)
   if (tgt_type STREQUAL "EXECUTABLE")
-set(tgt_prefix "bin/")
+set(tgt_prefix "${CMAKE_INSTALL_FULL_BINDIR}/")
   else()
-set(tgt_prefix "lib/")
+set(tgt_prefix "${CMAKE_INSTALL_FULL_LIBDIR}/")
   endif()
 
-  set(tgt_path "${CMAKE_INSTALL_PREFIX}/${tgt_prefix}$")
+  set(tgt_path "${tgt_prefix}$")
   file(RELATIVE_PATH tgt_path ${POLLY_CONFIG_CMAKE_DIR} ${tgt_path})
 
   if (NOT tgt_type STREQUAL "INTERFACE_LIBRARY")
Index: polly/

[clang] 5922f23 - Revert "[clang-repl] Implement partial translation units and error recovery."

2021-07-11 Thread Vassil Vassilev via cfe-commits

Author: Vassil Vassilev
Date: 2021-07-11T14:40:10Z
New Revision: 5922f234c8c95f61534160a31db15dfc10da9b60

URL: 
https://github.com/llvm/llvm-project/commit/5922f234c8c95f61534160a31db15dfc10da9b60
DIFF: 
https://github.com/llvm/llvm-project/commit/5922f234c8c95f61534160a31db15dfc10da9b60.diff

LOG: Revert "[clang-repl] Implement partial translation units and error 
recovery."

This reverts commit 6775fc6ffa3ca1c36b20c25fa4e7f48f81213cf2.

It also reverts "[lldb] Fix compilation by adjusting to the new ASTContext 
signature."

This reverts commit 03a3f86071c10a1f6cbbf7375aa6fe9d94168972.

We see some failures on the lldb infrastructure, these changes might play a role
in it. Let's revert it now and see if the bots will become green.

Ref: https://reviews.llvm.org/D104918

Added: 
clang/include/clang/Interpreter/Transaction.h

Modified: 
clang/include/clang/AST/ASTContext.h
clang/include/clang/AST/Decl.h
clang/include/clang/AST/Redeclarable.h
clang/include/clang/Basic/LangOptions.h
clang/include/clang/Interpreter/Interpreter.h
clang/include/clang/Lex/Preprocessor.h
clang/include/clang/Sema/Sema.h
clang/lib/AST/ASTContext.cpp
clang/lib/AST/Decl.cpp
clang/lib/AST/DeclBase.cpp
clang/lib/Frontend/ASTUnit.cpp
clang/lib/Frontend/CompilerInstance.cpp
clang/lib/Interpreter/IncrementalParser.cpp
clang/lib/Interpreter/IncrementalParser.h
clang/lib/Interpreter/Interpreter.cpp
clang/lib/Sema/Sema.cpp
clang/lib/Serialization/ASTReader.cpp
clang/tools/clang-import-test/clang-import-test.cpp
clang/unittests/AST/ASTVectorTest.cpp
clang/unittests/Interpreter/IncrementalProcessingTest.cpp
clang/unittests/Interpreter/InterpreterTest.cpp
clang/unittests/Lex/PPCallbacksTest.cpp
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp

Removed: 
clang/include/clang/Interpreter/PartialTranslationUnit.h



diff  --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index 34299581d89d4..5032f3194a9b7 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -459,7 +459,6 @@ class ASTContext : public RefCountedBase {
   friend class ASTWriter;
   template  friend class serialization::AbstractTypeReader;
   friend class CXXRecordDecl;
-  friend class IncrementalParser;
 
   /// A mapping to contain the template or declaration that
   /// a variable declaration describes or was instantiated from,
@@ -568,7 +567,7 @@ class ASTContext : public RefCountedBase {
   ImportDecl *FirstLocalImport = nullptr;
   ImportDecl *LastLocalImport = nullptr;
 
-  TranslationUnitDecl *TUDecl = nullptr;
+  TranslationUnitDecl *TUDecl;
   mutable ExternCContextDecl *ExternCContext = nullptr;
   mutable BuiltinTemplateDecl *MakeIntegerSeqDecl = nullptr;
   mutable BuiltinTemplateDecl *TypePackElementDecl = nullptr;
@@ -625,7 +624,6 @@ class ASTContext : public RefCountedBase {
   IdentifierTable &Idents;
   SelectorTable &Selectors;
   Builtin::Context &BuiltinInfo;
-  const TranslationUnitKind TUKind;
   mutable DeclarationNameTable DeclarationNames;
   IntrusiveRefCntPtr ExternalSource;
   ASTMutationListener *Listener = nullptr;
@@ -1024,18 +1022,7 @@ class ASTContext : public RefCountedBase {
   /// Get the initializations to perform when importing a module, if any.
   ArrayRef getModuleInitializers(Module *M);
 
-  TranslationUnitDecl *getTranslationUnitDecl() const {
-return TUDecl->getMostRecentDecl();
-  }
-  void addTranslationUnitDecl() {
-assert(!TUDecl || TUKind == TU_Incremental);
-TranslationUnitDecl *NewTUDecl = TranslationUnitDecl::Create(*this);
-if (TraversalScope.empty() || TraversalScope.back() == TUDecl)
-  TraversalScope = {NewTUDecl};
-if (TUDecl)
-  NewTUDecl->setPreviousDecl(TUDecl);
-TUDecl = NewTUDecl;
-  }
+  TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
 
   ExternCContextDecl *getExternCContextDecl() const;
   BuiltinTemplateDecl *getMakeIntegerSeqDecl() const;
@@ -1112,8 +1099,7 @@ class ASTContext : public RefCountedBase {
   llvm::DenseSet CUDADeviceVarODRUsedByHost;
 
   ASTContext(LangOptions &LOpts, SourceManager &SM, IdentifierTable &idents,
- SelectorTable &sels, Builtin::Context &builtins,
- TranslationUnitKind TUKind);
+ SelectorTable &sels, Builtin::Context &builtins);
   ASTContext(const ASTContext &) = delete;
   ASTContext &operator=(const ASTContext &) = delete;
   ~ASTContext();

diff  --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 510bf89789851..d22594ae8442a 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -79,23 +79,7 @@ class UnresolvedSetImpl;
 class VarTemplateDecl;
 
 /// The top declaration context.
-class TranslationUnitDecl : public Decl,
-public DeclContext,
-   

[PATCH] D98113: [Driver] Also search FilePaths for compiler-rt before falling back

2021-07-11 Thread Jessica Clarke via Phabricator via cfe-commits
jrtc27 added a comment.

Ping?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98113

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


[PATCH] D98113: [Driver] Also search FilePaths for compiler-rt before falling back

2021-07-11 Thread Luís Marques via Phabricator via cfe-commits
luismarques accepted this revision.
luismarques added a comment.
This revision is now accepted and ready to land.

LGTM.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D98113

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


[PATCH] D95588: [RISCV] Implement the MC layer support of P extension

2021-07-11 Thread Luís Marques via Phabricator via cfe-commits
luismarques added a comment.

This patch is nearly there! Just address the remaining review comments and it 
LGTM.

BTW, please mark all addressed inline comments as done. I think a few were 
missed, and it's helpful for a large patch like this.




Comment at: llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp:953-956
+static MCRegister convertGPRToGPRPair(MCRegister Reg) {
+  assert(isGPRPair(Reg) && "Invalid register");
+  return (Reg - RISCV::X0) / 2 + RISCV::X0_ZERO;
+}

Nitpicking: perhaps this could use better terminology. You're asserting that 
`Reg` is a GPRPair, and then you convert `Reg` to a GPRPair, but the return 
value would fail an assert of `isGPRPair`...



Comment at: llvm/lib/Target/RISCV/RISCVRegisterInfo.td:69
 
+def sub_lo : SubRegIndex<32>;
+def sub_hi : SubRegIndex<32, 32>;

jrtc27 wrote:
> This assumes RV32, and is not clear it applies to register pairs
What's the best way to address this?



Comment at: llvm/test/MC/RISCV/rv32zpsfoperand-invalid.s:6-9
+# Paired register operand
+
+# CHECK-ERROR: error: invalid operand for instruction
+smal a0, a1, a2

It would be nice to have a more specific error message, indicating the need for 
an even register operand. But not a deal-breaker, IMO.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D95588

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


[PATCH] D105754: [PowerPC] Fix L[D|W]ARX Implementation

2021-07-11 Thread Nemanja Ivanovic via Phabricator via cfe-commits
nemanjai requested changes to this revision.
nemanjai added a comment.
This revision now requires changes to proceed.

I believe that your failing test case is because you are attempting to emit 
code for these builtins in the target independent code and the values just 
happen to match up.




Comment at: clang/lib/CodeGen/CGBuiltin.cpp:997
 
+static llvm::Value *emitLoadReserveIntrinsic(CodeGenFunction &CGF,
+ unsigned BuiltinID,

lkail wrote:
> Maybe rename to `emitPPCLoadReserveIntrinsic` should be more appropriate, 
> since other targets also have similar load-reserve/load-linked/load-acquire 
> notions and what this function does is ad hoc to PPC.
+1



Comment at: clang/lib/CodeGen/CGBuiltin.cpp:1000
+ const CallExpr *E) {
+  Value *addr = CGF.EmitScalarExpr(E->getArg(0));
+

Nit: please follow naming conventions. Variables are to be capitalized.



Comment at: clang/lib/CodeGen/CGBuiltin.cpp:1015
+break;
+  }
+

lkail wrote:
> Adding `default: llvm_unreachable` would be nice.
+1



Comment at: clang/lib/CodeGen/CGBuiltin.cpp:5144
   }
+  case clang::PPC::BI__builtin_ppc_ldarx:
+  case clang::PPC::BI__builtin_ppc_lwarx:

Why?
Everything else is `Builtin::BI__` but these are 
`clang::PPC::BI__` for some reason.

That doesn't really make sense to me.
Also, what on earth is this doing here? This is a PPC builtin. Those should be 
handled in `EmitPPCBuiltinExpr()` and not here.



Comment at: 
llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-LoadReserve-StoreCond-64bit-only.ll:18
 entry:
-  %0 = bitcast i64* %a to i8*
-  %1 = tail call i64 @llvm.ppc.ldarx(i8* %0)
-  ret i64 %1
+  %0 = call i64 asm sideeffect "ldarx $0, $1", "=r,*Z,~{memory}"(i64* %a)
+  ret i64 %0

This is not the asm that the front end generates. Why would you generate one 
thing in the front end and then test a different thing in the back end?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D105754

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


[PATCH] D104420: thread_local support for AIX

2021-07-11 Thread Hubert Tong via Phabricator via cfe-commits
hubert.reinterpretcast added inline comments.



Comment at: clang/test/CodeGenCXX/cxx11-thread-local-reference.cpp:13
 // LINUX: @_ZTH1r ={{.*}} alias void (), void ()* @__tls_init
+// AIXX: @_ZTH1r ={{.*}} alias void (), void ()* @__tls_init
 // DARWIN: @_ZTH1r = internal alias void (), void ()* @__tls_init

Fix typo. Also, if the Linux and the AIX pattern is the same, adding a 
`NONDARWIN` prefix could help.



Comment at: clang/test/CodeGenCXX/cxx11-thread-local-reference.cpp:28-29
 
 // LINUX: define weak_odr hidden i32* @_ZTW1r() [[ATTR0:#[0-9]+]] comdat {
+// AIX: define weak_odr hidden i32* @_ZTW1r() [[ATTR0:#[0-9]+]] {
 // DARWIN: define cxx_fast_tlscc i32* @_ZTW1r() [[ATTR1:#[0-9]+]] {

Can use `{{.*}}` in place of `comdat ` to common up the Linux and the AIX 
pattern.



Comment at: clang/test/CodeGenCXX/cxx11-thread-local.cpp:12
 // RUN: %clang_cc1 -std=c++11 -fno-use-cxa-atexit -emit-llvm %s -o - -triple 
x86_64-apple-darwin12 | FileCheck --check-prefix=CHECK --check-prefix=DARWIN %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple 
powerpc64-unknown-aix-xcoff | FileCheck --check-prefix=CHECK --check-prefix=AIX 
%s
 

Minor nit: I think this should be moved to after line 5.



Comment at: clang/test/CodeGenCXX/cxx11-thread-local.cpp:18
 // LINUX-DAG: @a ={{.*}} thread_local global i32 0
+// AIX-DAG: @a ={{.*}} thread_local global i32 0
 // DARWIN-DAG: @a = internal thread_local global i32 0

Same comment as for the earlier file re: adding a prefix to handle the common 
Linux and AIX lines.



Comment at: clang/test/CodeGenCXX/cxx11-thread-local.cpp:229
 // LINUX: define linkonce_odr hidden i32* @_ZTWN1VIcE1mE() {{#[0-9]+}} comdat {
+// AIX: define linkonce_odr hidden i32* @_ZTWN1VIcE1mE() {{#[0-9]+}} {
 // LINUX: br i1 icmp ne (void ()* @_ZTHN1VIcE1mE,

Same comment as earlier about `comdat`.


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

https://reviews.llvm.org/D104420

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


[PATCH] D105083: [clangd] Ensure Ref::Container refers to an indexed symbol

2021-07-11 Thread Nathan Ridge via Phabricator via cfe-commits
nridge updated this revision to Diff 357823.
nridge added a comment.

Address review comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D105083

Files:
  clang-tools-extra/clangd/index/SymbolCollector.cpp
  clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp
  clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp

Index: clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
===
--- clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
+++ clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
@@ -811,8 +811,7 @@
   };
   EXPECT_EQ(Container("ref1a"),
 findSymbol(Symbols, "f2").ID); // function body (call)
-  // FIXME: This is wrongly contained by fptr and not f2.
-  EXPECT_NE(Container("ref1b"),
+  EXPECT_EQ(Container("ref1b"),
 findSymbol(Symbols, "f2").ID); // function body (address-of)
   EXPECT_EQ(Container("ref2"),
 findSymbol(Symbols, "v1").ID); // variable initializer
Index: clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp
===
--- clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp
+++ clang-tools-extra/clangd/unittests/CallHierarchyTests.cpp
@@ -26,6 +26,22 @@
 
 namespace clang {
 namespace clangd {
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &Stream,
+  const CallHierarchyItem &Item) {
+  return Stream << Item.name << "@" << Item.selectionRange;
+}
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &Stream,
+  const CallHierarchyIncomingCall &Call) {
+  Stream << "{ from: " << Call.from << ", ranges: [";
+  for (const auto &R : Call.fromRanges) {
+Stream << R;
+Stream << ", ";
+  }
+  return Stream << "] }";
+}
+
 namespace {
 
 using ::testing::AllOf;
@@ -252,6 +268,40 @@
   CheckCallHierarchy(*AST, CalleeC.point(), testPath("callee.cc"));
 }
 
+TEST(CallHierarchy, CallInLocalVarDecl) {
+  // Tests that local variable declarations are not treated as callers
+  // (they're not indexed, so they can't be represented as call hierarchy
+  // items); instead, the caller should be the containing function.
+  // However, namespace-scope variable declarations should be treated as
+  // callers because those are indexed and there is no enclosing entity
+  // that would be a useful caller.
+  Annotations Source(R"cpp(
+int call^ee();
+void caller1() {
+  $call1[[callee]]();
+}
+void caller2() {
+  int localVar = $call2[[callee]]();
+}
+int caller3 = $call3[[callee]]();
+  )cpp");
+  TestTU TU = TestTU::withCode(Source.code());
+  auto AST = TU.build();
+  auto Index = TU.index();
+
+  std::vector Items =
+  prepareCallHierarchy(AST, Source.point(), testPath(TU.Filename));
+  ASSERT_THAT(Items, ElementsAre(WithName("callee")));
+
+  auto Incoming = incomingCalls(Items[0], Index.get());
+  ASSERT_THAT(
+  Incoming,
+  ElementsAre(
+  AllOf(From(WithName("caller1")), FromRanges(Source.range("call1"))),
+  AllOf(From(WithName("caller2")), FromRanges(Source.range("call2"))),
+  AllOf(From(WithName("caller3")), FromRanges(Source.range("call3");
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang
Index: clang-tools-extra/clangd/index/SymbolCollector.cpp
===
--- clang-tools-extra/clangd/index/SymbolCollector.cpp
+++ clang-tools-extra/clangd/index/SymbolCollector.cpp
@@ -152,6 +152,31 @@
   return None;
 }
 
+// Given a ref contained in enclosing decl `Enclosing`, return
+// the decl that should be used as that ref's Ref::Container. This is
+// usually `Enclosing` itself, but in cases where `Enclosing` is not
+// indexed, we walk further up because Ref::Container should always be
+// an indexed symbol.
+// Note: we don't use DeclContext as the container as in some cases
+// it's useful to use a Decl which is not a DeclContext. For example,
+// for a ref occurring in the initializer of a namespace-scope variable,
+// it's useful to use that variable as the container, as otherwise the
+// next enclosing DeclContext would be a NamespaceDecl or TranslationUnitDecl,
+// which are both not indexed and less granular than we'd like for use cases
+// like call hierarchy.
+const Decl *getRefContainer(const Decl *Enclosing,
+const SymbolCollector::Options &Opts) {
+  while (Enclosing) {
+const NamedDecl *ND = dyn_cast_or_null(Enclosing);
+if (ND && SymbolCollector::shouldCollectSymbol(*ND, ND->getASTContext(),
+   Opts, true)) {
+  return ND;
+}
+Enclosing = dyn_cast_or_null(Enclosing->getDeclContext());
+  }
+  return nullptr;
+}
+
 } // namespace
 
 // Encapsulates decisions about how to record header paths in the index

[PATCH] D105083: [clangd] Ensure Ref::Container refers to an indexed symbol

2021-07-11 Thread Nathan Ridge via Phabricator via cfe-commits
nridge marked an inline comment as done.
nridge added inline comments.



Comment at: clang-tools-extra/clangd/index/SymbolCollector.cpp:159
+// indexed, we walk further up because Ref::Container should always be
+// an indexed symbol.
+const Decl *getRefContainer(const Decl *Enclosing,

kadircet wrote:
> can you also add some info about why we are not using `DeclContext`s ? 
> something like:
> ```
> Decls can nest under non-DeclContext nodes, in cases like initializer, where 
> they might be attributed to VarDecl.
> Preserving that level of granularity is especially useful for initializers at 
> top-level, as otherwise the only context we
> can attach these refs is TranslationUnitDecl, which we don't preserve in the 
> index.
> FIXME: Maybe we should have some symbols for representing file-scopes, that 
> way we can show these refs as
> being contained in the file-scope.
> ```
> 
> (Last fixme bit is optional, please add that if you also think the 
> functionality would be more useful that way)
I've added a comment to explain why we're not using`DeclContext` here.

I'm not sure if your other comment is still relevant, if we agree that the 
current behaviour is the desirable one.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D105083

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


[PATCH] D98710: [clang-tidy] Add --skip-headers, part 1 (use setTraversalScope)

2021-07-11 Thread Chih-Hung Hsieh via Phabricator via cfe-commits
chh updated this revision to Diff 357824.
chh marked 7 inline comments as done.
chh added a comment.

sync up latest clang/llvm source; more format/style changes


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

https://reviews.llvm.org/D98710

Files:
  clang-tools-extra/clang-tidy/ClangTidy.cpp
  clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
  clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
  clang-tools-extra/clang-tidy/ClangTidyOptions.h
  clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
  clang-tools-extra/test/clang-tidy/checkers/Inputs/skip-headers/my_header1.h
  clang-tools-extra/test/clang-tidy/checkers/Inputs/skip-headers/my_header2.h
  
clang-tools-extra/test/clang-tidy/checkers/bugprone-forward-declaration-namespace.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone-reserved-identifier.cpp
  clang-tools-extra/test/clang-tidy/checkers/bugprone-suspicious-include.cpp
  
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-interfaces-global-init.cpp
  clang-tools-extra/test/clang-tidy/checkers/google-namespaces.cpp
  clang-tools-extra/test/clang-tidy/checkers/google-objc-function-naming.m
  clang-tools-extra/test/clang-tidy/checkers/llvm-include-order.cpp
  
clang-tools-extra/test/clang-tidy/checkers/llvm-prefer-register-over-unsigned.cpp
  
clang-tools-extra/test/clang-tidy/checkers/llvmlibc-implementation-in-namespace.cpp
  
clang-tools-extra/test/clang-tidy/checkers/llvmlibc-restrict-system-libc-headers.cpp
  clang-tools-extra/test/clang-tidy/checkers/misc-no-recursion.cpp
  
clang-tools-extra/test/clang-tidy/checkers/modernize-deprecated-headers-cxx03.cpp
  
clang-tools-extra/test/clang-tidy/checkers/modernize-deprecated-headers-cxx11.cpp
  clang-tools-extra/test/clang-tidy/checkers/modernize-pass-by-value-header.cpp
  
clang-tools-extra/test/clang-tidy/checkers/portability-restrict-system-includes-allow.cpp
  
clang-tools-extra/test/clang-tidy/checkers/portability-restrict-system-includes-disallow.cpp
  
clang-tools-extra/test/clang-tidy/checkers/readability-simplify-bool-expr-chained-conditional-assignment.cpp
  
clang-tools-extra/test/clang-tidy/checkers/readability-simplify-bool-expr-chained-conditional-return.cpp
  
clang-tools-extra/test/clang-tidy/checkers/readability-simplify-bool-expr-members.cpp
  clang-tools-extra/test/clang-tidy/checkers/readability-simplify-bool-expr.cpp
  clang-tools-extra/test/clang-tidy/checkers/skip-headers.cpp
  clang/include/clang/Frontend/MultiplexConsumer.h

Index: clang/include/clang/Frontend/MultiplexConsumer.h
===
--- clang/include/clang/Frontend/MultiplexConsumer.h
+++ clang/include/clang/Frontend/MultiplexConsumer.h
@@ -77,8 +77,9 @@
   void InitializeSema(Sema &S) override;
   void ForgetSema() override;
 
-private:
+protected:
   std::vector> Consumers; // Owns these.
+private:
   std::unique_ptr MutationListener;
   std::unique_ptr DeserializationListener;
 };
Index: clang-tools-extra/test/clang-tidy/checkers/skip-headers.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/skip-headers.cpp
@@ -0,0 +1,54 @@
+// Test --skip-headers, --show-all-warnings, and --header-filter.
+// TODO: when skip-headers implementation is complete, add back
+//  -implicit-check-not="{{warning|error}}:"
+// and use no_hint instead of hint
+//
+// Default shows no warning in .h files, and give HINT to use --header-filter
+// RUN: clang-tidy %s -checks='*' -- \
+// RUN: 2>&1 | FileCheck %s -check-prefixes WARN,MAIN,HINT
+// later:-implicit-check-not="{{warning|error}}:"
+//
+// --skip-headers skips included files; finds only warnings in the main file.
+// RUN: clang-tidy %s -checks='*' --skip-headers -- \
+// RUN: 2>&1 | FileCheck %s -check-prefixes WARN,MAIN,HINT
+// later:no_hint -implicit-check-not="{{warning|error}}:"
+//
+// --show-all-warnings reports all warnings, even without --header-filters
+// RUN: clang-tidy %s -checks='*' --show-all-warnings -- \
+// RUN: 2>&1 | FileCheck %s -check-prefixes WARN,WARN_BOTH,MAIN,NO_HINT
+//
+// --header-filter='.*' is like --show-all-warnings
+// RUN: clang-tidy %s -checks='*' --header-filter='.*' -- \
+// RUN: 2>&1 | FileCheck %s -check-prefixes WARN,WARN_BOTH,MAIN,NO_HINT
+//
+// --header-filter='header1.h' shows only warnings in header1.h
+// RUN: clang-tidy %s -checks='*' --header-filter='header1.h' -- \
+// RUN: 2>&1 | FileCheck %s -check-prefixes WARN,WARN1,MAIN,HINT
+// later:-implicit-check-not="{{warning|error}}:"
+//
+// The main purpose of --show-all-warnings is to debug --skip-headers.
+// When used together, no warnings should be reported from header files.
+// RUN: clang-tidy %s -checks='*' --skip-headers --show-all-warnings -- \
+// RUN: 2>&1 | FileCheck %s -check-prefixes WARN,MAIN,NO_HINT
+// later:  -implicit-check-not="{{warning|error}}:"
+//
+// use --skip-headers and --header-filter='header2.h'
+// 

[PATCH] D98710: [clang-tidy] Add --skip-headers, part 1 (use setTraversalScope)

2021-07-11 Thread Chih-Hung Hsieh via Phabricator via cfe-commits
chh added inline comments.



Comment at: clang-tools-extra/clang-tidy/ClangTidy.cpp:310
+struct DeclFilter {
+  DeclFilter(ClangTidyContext &Ctx, SourceManager &SM)
+  : Context(Ctx), Sources(SM) {

sammccall wrote:
> Ctx is ultimately unused, just take the regex instead?
Context is used in skipFileID.




Comment at: clang-tools-extra/clang-tidy/ClangTidy.cpp:514
+  for (auto &Consumer : Consumers) {
+if (hasFilter() && Consumer.get() == FinderASTConsumerPtr) {
+  // Modify AST before calling the Finder's ASTConsumer.

sammccall wrote:
> This adds significant conceptual complexity and possible runtime costs to 
> guard against the possibility that the static analyzer would not be 
> compatible with simply setting the traversal scope.
> 
> Please do not do this. It may appear that you're cheaply eliminating a class 
> of bugs, but complexity is not cheap, and in the long run can also introduce 
> bugs. Instead investigate whether this is a real problem and why.
> 
> If it's not then `Context.setTraversalScope()` + 
> `MultiplexingASTConsumer::HandleTranslationUnit` is enough here, and 
> `FinderASTConsumerPtr` can go away.
For this first step implementation of skip-headers, could we limit the risk and 
impact to only AST MatchFinder based checks? If it works fine, we can add more 
performance improvements, handle PPCallback-based checks, and static analyzer 
checks. We can turn skip-headers to default or revert any follow up step.

At this time, we only know that PPCallback-based checks can save some more time 
with skip-headers, but do not know if any static analyzer check can benefit 
from skip-headers easily. In other words, we are sure to deliver big saving of 
runtime for clang-tidy users that do not enable static analyzer checks, but not 
sure about static analyzer check users.

The overhead and complexity of set/getTraversalScope and checking filters will 
be on the users of skip-header, but not on the static analyzer checkers.

If we apply the same change to AST for all consumers, the saving of code 
complexity is smaller than the risk of impact to static analyzer checks, and 
the saving of runtime is also much smaller than the already saved time in 
MatchFinder.




Comment at: clang-tools-extra/clang-tidy/ClangTidy.cpp:473
+MatchFinder::matchAST(Context);
+Context.setTraversalScope(SavedScope);
+  } else {

sammccall wrote:
> chh wrote:
> > sammccall wrote:
> > > Is restoring the traversal scope strictly needed by the static analyzer? 
> > > I would expect not, but I might be wrong.
> > I think it is safer to assume low or acceptable overhead in 
> > get/setTraversalScope and keep the impact only to the MatchFinder consumer, 
> > rather than depending on static analyzer working now or in the future with 
> > the changed AST.
> > 
> > I think it is safer to assume low or acceptable overhead in 
> > get/setTraversalScope
> We have reasons to believe this is not cheap. The first usage of getParent() 
> after changing traversal scope incurs a full AST traversal.
> 
> > rather than depending on static analyzer working now or in the future with 
> > the changed AST.
> 
> There are a fairly small number of reasons that setTraversalScope could break 
> static analyzer at this point, and I think they're all going to cause the 
> static analyzer to be slow when used with PCHes. However the static 
> analyzer's implementation and comments say that it goes to effort to be fast 
> with PCHes. So I do believe this is a more stable assumption, and in the long 
> run we may be able to simplify its implementation.
Okay, won't assume low overhead in set/getTraversalScope.
So far their impact is limited to skip-headers, which in this step is limited 
to only MatchFinder. Please see also my reply in the other comment.




Comment at: clang-tools-extra/clang-tidy/ClangTidyOptions.cpp:99
 IO.mapOptional("InheritParentConfig", Options.InheritParentConfig);
 IO.mapOptional("UseColor", Options.UseColor);
   }

sammccall wrote:
> Maybe an explicit comment that ShowAllHeaders, SkipHeaders are 
> runtime/optimization options that are configured at the command-line only, 
> and therefore not mapped here
Why SystemHeaders is not mapped?
I agree that ShowAllWarnings is not important here,
but SkipHeaders seems as important to be included here as HeaderFilterRegex and 
SystemHeaders.




Comment at: clang-tools-extra/clang-tidy/ClangTidyOptions.h:84
+  /// and system files when --system-headers is used.
+  llvm::Optional SkipHeaders;
+

sammccall wrote:
> This is easy to confuse with e.g. HeaderFilterRegex and SystemHeaders, which 
> control policy rather than just implementation strategy.
> I'd suggest calling this something like `PruneTraversal` which hints at the 
> implementation strategy it controls but most importantly that it's *not* 

[PATCH] D105457: [clang] Refactor AST printing tests to share more infrastructure

2021-07-11 Thread Nathan Ridge via Phabricator via cfe-commits
nridge updated this revision to Diff 357826.
nridge marked 3 inline comments as done.
nridge added a comment.

Address review comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D105457

Files:
  clang/unittests/AST/ASTPrint.h
  clang/unittests/AST/DeclPrinterTest.cpp
  clang/unittests/AST/NamedDeclPrinterTest.cpp
  clang/unittests/AST/StmtPrinterTest.cpp

Index: clang/unittests/AST/StmtPrinterTest.cpp
===
--- clang/unittests/AST/StmtPrinterTest.cpp
+++ clang/unittests/AST/StmtPrinterTest.cpp
@@ -38,11 +38,29 @@
   has(compoundStmt(has(stmt().bind("id");
 }
 
+static void PrintStmt(raw_ostream &Out, const ASTContext *Context,
+  const Stmt *S, PrintingPolicyAdjuster PolicyAdjuster) {
+  assert(S != nullptr && "Expected non-null Stmt");
+  PrintingPolicy Policy = Context->getPrintingPolicy();
+  if (PolicyAdjuster)
+PolicyAdjuster(Policy);
+  S->printPretty(Out, /*Helper*/ nullptr, Policy);
+}
+
+template 
+::testing::AssertionResult
+PrintedStmtMatches(StringRef Code, const std::vector &Args,
+   const Matcher &NodeMatch, StringRef ExpectedPrinted,
+   PrintingPolicyAdjuster PolicyAdjuster = nullptr) {
+  return PrintedNodeMatches(Code, Args, NodeMatch, ExpectedPrinted, "",
+  PrintStmt, PolicyAdjuster);
+}
+
 template 
 ::testing::AssertionResult
 PrintedStmtCXXMatches(StdVer Standard, StringRef Code, const T &NodeMatch,
   StringRef ExpectedPrinted,
-  PolicyAdjusterType PolicyAdjuster = None) {
+  PrintingPolicyAdjuster PolicyAdjuster = nullptr) {
   const char *StdOpt;
   switch (Standard) {
   case StdVer::CXX98: StdOpt = "-std=c++98"; break;
@@ -64,7 +82,7 @@
 ::testing::AssertionResult
 PrintedStmtMSMatches(StringRef Code, const T &NodeMatch,
  StringRef ExpectedPrinted,
- PolicyAdjusterType PolicyAdjuster = None) {
+ PrintingPolicyAdjuster PolicyAdjuster = nullptr) {
   std::vector Args = {
 "-std=c++98",
 "-target", "i686-pc-win32",
@@ -79,7 +97,7 @@
 ::testing::AssertionResult
 PrintedStmtObjCMatches(StringRef Code, const T &NodeMatch,
StringRef ExpectedPrinted,
-   PolicyAdjusterType PolicyAdjuster = None) {
+   PrintingPolicyAdjuster PolicyAdjuster = nullptr) {
   std::vector Args = {
 "-ObjC",
 "-fobjc-runtime=macosx-10.12.0",
@@ -202,10 +220,10 @@
 };
 )";
   // No implicit 'this'.
-  ASSERT_TRUE(PrintedStmtCXXMatches(StdVer::CXX11,
-  CPPSource, memberExpr(anything()).bind("id"), "field",
-  PolicyAdjusterType(
-  [](PrintingPolicy &PP) { PP.SuppressImplicitBase = true; })));
+  ASSERT_TRUE(PrintedStmtCXXMatches(
+  StdVer::CXX11, CPPSource, memberExpr(anything()).bind("id"), "field",
+
+  [](PrintingPolicy &PP) { PP.SuppressImplicitBase = true; }));
   // Print implicit 'this'.
   ASSERT_TRUE(PrintedStmtCXXMatches(StdVer::CXX11,
   CPPSource, memberExpr(anything()).bind("id"), "this->field"));
@@ -222,11 +240,10 @@
 @end
   )";
   // No implicit 'self'.
-  ASSERT_TRUE(PrintedStmtObjCMatches(ObjCSource, returnStmt().bind("id"),
- "return ivar;\n",
- PolicyAdjusterType([](PrintingPolicy &PP) {
-   PP.SuppressImplicitBase = true;
- })));
+  ASSERT_TRUE(PrintedStmtObjCMatches(
+  ObjCSource, returnStmt().bind("id"), "return ivar;\n",
+
+  [](PrintingPolicy &PP) { PP.SuppressImplicitBase = true; }));
   // Print implicit 'self'.
   ASSERT_TRUE(PrintedStmtObjCMatches(ObjCSource, returnStmt().bind("id"),
  "return self->ivar;\n"));
@@ -243,5 +260,6 @@
   // body not printed when TerseOutput is on.
   ASSERT_TRUE(PrintedStmtCXXMatches(
   StdVer::CXX11, CPPSource, lambdaExpr(anything()).bind("id"), "[] {}",
-  PolicyAdjusterType([](PrintingPolicy &PP) { PP.TerseOutput = true; })));
+
+  [](PrintingPolicy &PP) { PP.TerseOutput = true; }));
 }
Index: clang/unittests/AST/NamedDeclPrinterTest.cpp
===
--- clang/unittests/AST/NamedDeclPrinterTest.cpp
+++ clang/unittests/AST/NamedDeclPrinterTest.cpp
@@ -15,6 +15,7 @@
 //
 //===--===//
 
+#include "ASTPrint.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/PrettyPrinter.h"
@@ -66,31 +67,11 @@
 const DeclarationMatcher &NodeMatch, StringRef ExpectedPrinted,
 StringRef FileName,
 std::function Print) {
-  PrintMatch Printer(std::move(Print));
-  MatchFinder Finder;
-  Finder.addMatcher(NodeMatch

[PATCH] D105457: [clang] Refactor AST printing tests to share more infrastructure

2021-07-11 Thread Nathan Ridge via Phabricator via cfe-commits
nridge added inline comments.



Comment at: clang/unittests/AST/DeclPrinterTest.cpp:59
+  return PrintedNodeMatches(Code, Args, NodeMatch, ExpectedPrinted,
+  FileName, PrinterType{PrintDecl},
+  PolicyModifier, AllowError);

dblaikie wrote:
> Is the `PrinterType{}` needed here, or could `PrintDecl` be passed 
> directly/without explicitly constructing the wrapper? (functions should be 
> implicitly convertible to the lambda type, I think?) 
> 
> Similarly for all the `PrintingPolicyAdjuster(...)` - might be able to skip 
> that wrapping expression & rely on an implicit conversion.
Good call on both counts. (The `PrintingPolicyAdjuster(...)` stuff was left 
over from when the typedef was for an `Optional` which you 
correctly observed was redundant.)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D105457

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


[PATCH] D104619: [clang] Respect PrintingPolicy::FullyQualifiedName when printing a template-id

2021-07-11 Thread Nathan Ridge via Phabricator via cfe-commits
nridge updated this revision to Diff 357827.
nridge added a comment.

Rebase on top of refactor patch changes


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D104619

Files:
  clang/lib/AST/TypePrinter.cpp
  clang/unittests/AST/CMakeLists.txt
  clang/unittests/AST/TypePrinterTest.cpp


Index: clang/unittests/AST/TypePrinterTest.cpp
===
--- /dev/null
+++ clang/unittests/AST/TypePrinterTest.cpp
@@ -0,0 +1,65 @@
+//===- unittests/AST/TypePrinterTest.cpp --- Type printer tests 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file contains tests for QualType::print() and related methods.
+//
+//===--===//
+
+#include "ASTPrint.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/SmallString.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+using namespace ast_matchers;
+using namespace tooling;
+
+namespace {
+
+static void PrintType(raw_ostream &Out, const ASTContext *Context,
+  const QualType *T,
+  PrintingPolicyAdjuster PolicyAdjuster) {
+  assert(T && !T->isNull() && "Expected non-null Type");
+  PrintingPolicy Policy = Context->getPrintingPolicy();
+  if (PolicyAdjuster)
+PolicyAdjuster(Policy);
+  T->print(Out, Policy);
+}
+
+::testing::AssertionResult
+PrintedTypeMatches(StringRef Code, const std::vector &Args,
+   const DeclarationMatcher &NodeMatch,
+   StringRef ExpectedPrinted,
+   PrintingPolicyAdjuster PolicyAdjuster) {
+  return PrintedNodeMatches(Code, Args, NodeMatch, ExpectedPrinted,
+  "", PrintType, PolicyAdjuster);
+}
+
+} // unnamed namespace
+
+TEST(TypePrinter, TemplateId) {
+  std::string Code = R"cpp(
+namespace N {
+  template  struct Type {};
+  
+  template 
+  void Foo(const Type &Param);
+}
+  )cpp";
+  auto Matcher = parmVarDecl(hasType(qualType().bind("id")));
+
+  ASSERT_TRUE(PrintedTypeMatches(
+  Code, {}, Matcher, "const Type &",
+  [](PrintingPolicy &Policy) { Policy.FullyQualifiedName = false; }));
+
+  ASSERT_TRUE(PrintedTypeMatches(
+  Code, {}, Matcher, "const N::Type &",
+  [](PrintingPolicy &Policy) { Policy.FullyQualifiedName = true; }));
+}
\ No newline at end of file
Index: clang/unittests/AST/CMakeLists.txt
===
--- clang/unittests/AST/CMakeLists.txt
+++ clang/unittests/AST/CMakeLists.txt
@@ -29,6 +29,7 @@
   SourceLocationTest.cpp
   StmtPrinterTest.cpp
   StructuralEquivalenceTest.cpp
+  TypePrinterTest.cpp
   )
 
 clang_target_link_libraries(ASTTests
Index: clang/lib/AST/TypePrinter.cpp
===
--- clang/lib/AST/TypePrinter.cpp
+++ clang/lib/AST/TypePrinter.cpp
@@ -1456,7 +1456,7 @@
 void TypePrinter::printTemplateSpecializationBefore(
 const TemplateSpecializationType 
*T,
 raw_ostream &OS) {
-  printTemplateId(T, OS, false);
+  printTemplateId(T, OS, Policy.FullyQualifiedName);
 }
 
 void TypePrinter::printTemplateSpecializationAfter(


Index: clang/unittests/AST/TypePrinterTest.cpp
===
--- /dev/null
+++ clang/unittests/AST/TypePrinterTest.cpp
@@ -0,0 +1,65 @@
+//===- unittests/AST/TypePrinterTest.cpp --- Type printer tests ---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file contains tests for QualType::print() and related methods.
+//
+//===--===//
+
+#include "ASTPrint.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/SmallString.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+using namespace ast_matchers;
+using namespace tooling;
+
+namespace {
+
+static void PrintType(raw_ostream &Out, const ASTContext *Context,
+  const QualType *T,
+  PrintingPolicyAdjuster PolicyAdjuster) {
+  assert(T && !T->isNull() && "Expected non-null Type");
+  PrintingPolicy Policy = Context

[PATCH] D77491: [Sema] Introduce BuiltinAttr, per-declaration builtin-ness

2021-07-11 Thread Johannes Doerfert via Phabricator via cfe-commits
jdoerfert reopened this revision.
jdoerfert added a comment.
Herald added a subscriber: dexonsmith.

> A pthread_create() related test is XFAIL-ed, as it relied on it being 
> recognized as a builtin based on its name.
> The builtin declaration syntax is too restrictive and doesn't allow custom 
> structs, function pointers, etc.
> It seems to be the only case and fixing this would require reworking the 
> current builtin syntax, so this seems acceptable.

First:
Do I assume right this this feature was simply disabled without any plan to:

- inform the authors (me)
- update the documentation
- re-enable support eventually or provide alternatives

XFAILing a test and calling it a day seems inadequate IMHO.

Second:
Would an approach like this still work: https://reviews.llvm.org/D58531 ?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D77491

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


[PATCH] D105168: [RISCV] Unify the arch string parsing logic to RISCVISAInfo.

2021-07-11 Thread luxufan via Phabricator via cfe-commits
StephenFan added inline comments.



Comment at: llvm/lib/Support/RISCVISAInfo.cpp:115
+  return make_filter_range(SupportedExtensionInfos,
+   [&](const RISCVSupportedExtensionInfo &ExtInfo) {
+ return ExtInfo.Name == ExtName;

This lambda function will keep alive out of current scope.
Maybe the `[&]` should change to `[ExtName]`




Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D105168

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


[clang] d3e14fa - [analyzer][NFC] Display the correct function name even in crash dumps

2021-07-11 Thread Balazs Benics via cfe-commits

Author: Balazs Benics
Date: 2021-07-12T09:06:46+02:00
New Revision: d3e14fafc69a07e3dab9ddb91f1d810bb5f8d7a0

URL: 
https://github.com/llvm/llvm-project/commit/d3e14fafc69a07e3dab9ddb91f1d810bb5f8d7a0
DIFF: 
https://github.com/llvm/llvm-project/commit/d3e14fafc69a07e3dab9ddb91f1d810bb5f8d7a0.diff

LOG: [analyzer][NFC] Display the correct function name even in crash dumps

The `-analyzer-display-progress` displayed the function name of the
currently analyzed function. It differs in C and C++. In C++, it
prints the argument types as well in a comma-separated list.
While in C, only the function name is displayed, without the brackets.
E.g.:

  C++: foo(), foo(int, float)
  C:   foo

In crash traces, the analyzer dumps the location contexts, but the
string is not enough for `-analyze-function` in C++ mode.
This patch addresses the issue by dumping the proper function names
even in stack traces.

Reviewed By: NoQ

Differential Revision: https://reviews.llvm.org/D105708

Added: 


Modified: 
clang/include/clang/Analysis/AnalysisDeclContext.h
clang/lib/Analysis/AnalysisDeclContext.cpp
clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
clang/test/Analysis/crash-trace.c

Removed: 




diff  --git a/clang/include/clang/Analysis/AnalysisDeclContext.h 
b/clang/include/clang/Analysis/AnalysisDeclContext.h
index d12582f4f329..102970a1d55e 100644
--- a/clang/include/clang/Analysis/AnalysisDeclContext.h
+++ b/clang/include/clang/Analysis/AnalysisDeclContext.h
@@ -200,6 +200,8 @@ class AnalysisDeclContext {
   /// \returns Whether the root namespace of \p D is the \c std C++ namespace.
   static bool isInStdNamespace(const Decl *D);
 
+  static std::string getFunctionName(const Decl *D);
+
 private:
   std::unique_ptr &getAnalysisImpl(const void *tag);
 

diff  --git a/clang/lib/Analysis/AnalysisDeclContext.cpp 
b/clang/lib/Analysis/AnalysisDeclContext.cpp
index 783de6442645..d8466ac34a3d 100644
--- a/clang/lib/Analysis/AnalysisDeclContext.cpp
+++ b/clang/lib/Analysis/AnalysisDeclContext.cpp
@@ -337,6 +337,59 @@ bool AnalysisDeclContext::isInStdNamespace(const Decl *D) {
   return ND->isStdNamespace();
 }
 
+std::string AnalysisDeclContext::getFunctionName(const Decl *D) {
+  std::string Str;
+  llvm::raw_string_ostream OS(Str);
+  const ASTContext &Ctx = D->getASTContext();
+
+  if (const FunctionDecl *FD = dyn_cast(D)) {
+OS << FD->getQualifiedNameAsString();
+
+// In C++, there are overloads.
+
+if (Ctx.getLangOpts().CPlusPlus) {
+  OS << '(';
+  for (const auto &P : FD->parameters()) {
+if (P != *FD->param_begin())
+  OS << ", ";
+OS << P->getType().getAsString();
+  }
+  OS << ')';
+}
+
+  } else if (isa(D)) {
+PresumedLoc Loc = Ctx.getSourceManager().getPresumedLoc(D->getLocation());
+
+if (Loc.isValid()) {
+  OS << "block (line: " << Loc.getLine() << ", col: " << Loc.getColumn()
+ << ')';
+}
+
+  } else if (const ObjCMethodDecl *OMD = dyn_cast(D)) {
+
+// FIXME: copy-pasted from CGDebugInfo.cpp.
+OS << (OMD->isInstanceMethod() ? '-' : '+') << '[';
+const DeclContext *DC = OMD->getDeclContext();
+if (const auto *OID = dyn_cast(DC)) {
+  OS << OID->getName();
+} else if (const auto *OID = dyn_cast(DC)) {
+  OS << OID->getName();
+} else if (const auto *OC = dyn_cast(DC)) {
+  if (OC->IsClassExtension()) {
+OS << OC->getClassInterface()->getName();
+  } else {
+OS << OC->getIdentifier()->getNameStart() << '('
+   << OC->getIdentifier()->getNameStart() << ')';
+  }
+} else if (const auto *OCD = dyn_cast(DC)) {
+  OS << OCD->getClassInterface()->getName() << '(' << OCD->getName() << 
')';
+}
+OS << ' ' << OMD->getSelector().getAsString() << ']';
+  }
+
+  return OS.str();
+}
+
 LocationContextManager &AnalysisDeclContext::getLocationContextManager() {
   assert(
   ADCMgr &&
@@ -456,7 +509,7 @@ void LocationContext::dumpStack(raw_ostream &Out) const {
   Out << "\t#" << Frame << ' ';
   ++Frame;
   if (const auto *D = dyn_cast(LCtx->getDecl()))
-Out << "Calling " << D->getQualifiedNameAsString();
+Out << "Calling " << AnalysisDeclContext::getFunctionName(D);
   else
 Out << "Calling anonymous code";
   if (const Stmt *S = cast(LCtx)->getCallSite()) {

diff  --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp 
b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index 33914e98b90f..03b5c04f553f 100644
--- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -209,8 +209,8 @@ class AnalysisConsumer : public AnalysisASTConsumer,
   } else
 assert(Mode == (AM_Syntax | AM_Path) && "Unexpected mode!");
 
-  llvm::errs() << ": " << Loc.getFilename() << ' ' << getFunctionName(D)
-   << '\n';
+  llv

[PATCH] D105708: [analyzer][NFC] Display the correct function name even in crash dumps

2021-07-11 Thread Balázs Benics via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGd3e14fafc69a: [analyzer][NFC] Display the correct function 
name even in crash dumps (authored by steakhal).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D105708

Files:
  clang/include/clang/Analysis/AnalysisDeclContext.h
  clang/lib/Analysis/AnalysisDeclContext.cpp
  clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
  clang/test/Analysis/crash-trace.c

Index: clang/test/Analysis/crash-trace.c
===
--- clang/test/Analysis/crash-trace.c
+++ clang/test/Analysis/crash-trace.c
@@ -1,4 +1,7 @@
-// RUN: not --crash %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection %s 2>&1 | FileCheck %s
+// RUN: not --crash %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection \
+// RUN:   -x c   %s 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-C-ONLY
+// RUN: not --crash %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection \
+// RUN:   -x c++ %s 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-CXX-ONLY
 // REQUIRES: crash-recovery
 
 // Stack traces require back traces.
@@ -6,17 +9,22 @@
 
 void clang_analyzer_crash(void);
 
-void inlined() {
+void inlined(int x, float y) {
   clang_analyzer_crash();
 }
 
 void test() {
-  inlined();
+  inlined(0, 0);
 }
 
-// CHECK: 0.	Program arguments: {{.*}}clang
-// CHECK-NEXT: 1.	 parser at end of file
-// CHECK-NEXT: 2. While analyzing stack: 
-// CHECK-NEXT:  #0 Calling inlined at line 14
-// CHECK-NEXT:  #1 Calling test
-// CHECK-NEXT: 3.	{{.*}}crash-trace.c:{{[0-9]+}}:3: Error evaluating statement
+// CHECK:0. Program arguments: {{.*}}clang
+// CHECK-NEXT:   1.  parser at end of file
+// CHECK-NEXT:   2. While analyzing stack:
+//
+// CHECK-C-ONLY-NEXT:   #0 Calling inlined at line 17
+// CHECK-C-ONLY-NEXT:   #1 Calling test
+//
+// CHECK-CXX-ONLY-NEXT: #0 Calling inlined(int, float) at line 17
+// CHECK-CXX-ONLY-NEXT: #1 Calling test()
+//
+// CHECK-NEXT:   3. {{.*}}crash-trace.c:{{[0-9]+}}:3: Error evaluating statement
Index: clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
===
--- clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -209,8 +209,8 @@
   } else
 assert(Mode == (AM_Syntax | AM_Path) && "Unexpected mode!");
 
-  llvm::errs() << ": " << Loc.getFilename() << ' ' << getFunctionName(D)
-   << '\n';
+  llvm::errs() << ": " << Loc.getFilename() << ' '
+   << AnalysisDeclContext::getFunctionName(D) << '\n';
 }
   }
 
@@ -568,63 +568,10 @@
   Mgr.reset();
 }
 
-std::string AnalysisConsumer::getFunctionName(const Decl *D) {
-  std::string Str;
-  llvm::raw_string_ostream OS(Str);
-
-  if (const FunctionDecl *FD = dyn_cast(D)) {
-OS << FD->getQualifiedNameAsString();
-
-// In C++, there are overloads.
-if (Ctx->getLangOpts().CPlusPlus) {
-  OS << '(';
-  for (const auto &P : FD->parameters()) {
-if (P != *FD->param_begin())
-  OS << ", ";
-OS << P->getType().getAsString();
-  }
-  OS << ')';
-}
-
-  } else if (isa(D)) {
-PresumedLoc Loc = Ctx->getSourceManager().getPresumedLoc(D->getLocation());
-
-if (Loc.isValid()) {
-  OS << "block (line: " << Loc.getLine() << ", col: " << Loc.getColumn()
- << ')';
-}
-
-  } else if (const ObjCMethodDecl *OMD = dyn_cast(D)) {
-
-// FIXME: copy-pasted from CGDebugInfo.cpp.
-OS << (OMD->isInstanceMethod() ? '-' : '+') << '[';
-const DeclContext *DC = OMD->getDeclContext();
-if (const auto *OID = dyn_cast(DC)) {
-  OS << OID->getName();
-} else if (const auto *OID = dyn_cast(DC)) {
-  OS << OID->getName();
-} else if (const auto *OC = dyn_cast(DC)) {
-  if (OC->IsClassExtension()) {
-OS << OC->getClassInterface()->getName();
-  } else {
-OS << OC->getIdentifier()->getNameStart() << '('
-   << OC->getIdentifier()->getNameStart() << ')';
-  }
-} else if (const auto *OCD = dyn_cast(DC)) {
-  OS << OCD->getClassInterface()->getName() << '('
- << OCD->getName() << ')';
-}
-OS << ' ' << OMD->getSelector().getAsString() << ']';
-
-  }
-
-  return OS.str();
-}
-
 AnalysisConsumer::AnalysisMode
 AnalysisConsumer::getModeForDecl(Decl *D, AnalysisMode Mode) {
   if (!Opts->AnalyzeSpecificFunction.empty() &&
-  getFunctionName(D) != Opts->AnalyzeSpecificFunction)
+  AnalysisDeclContext::getFunctionName(D) != Opts->AnalyzeSpecificFunction)
 return AM_None;
 
   // Unless -analyze-all is specified, treat decls differently depending on
Index: clang/lib/Analysis/AnalysisDeclContext.cpp
===
--- clang/lib/Analysis/