[PATCH] D70553: [clang-apply-replacements] Add command line option to overwrite readonly files.

2019-11-23 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

Can you add a test case for this functionality?




Comment at: 
clang-tools-extra/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp:52
+static cl::opt ForceOverwriteReadOnly(
+"force", cl::desc("Overwrite read-only files when applying 
replacements\n"),
+cl::init(false), cl::cat(ReplacementCategory));

Missing full stop at the end of the string.

Also, it looks like this is doing something subtly different than what the help 
text says. It looks like this is overwriting the *permissions* of the file when 
applying replacements. Nothing seems to reset the permissions back to what they 
once were when the file is closed. Is that accurate?



Comment at: 
clang-tools-extra/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp:161
+  using namespace llvm::sys::fs;
+  if (auto ErrorOrPerms = getPermissions(FileName)) {
+perms P = ErrorOrPerms.get();

Rather than spell out the type in the declaration name but use `auto`, how 
about: `ErrorOr EP` or something?


Repository:
  rCTE Clang Tools Extra

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

https://reviews.llvm.org/D70553



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


[PATCH] D70368: [clang-tidy] Rewrite modernize-avoid-bind check

2019-11-23 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman marked an inline comment as done.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

LGTM once you handle the last remaining nits from @Eugene.Zelenko.




Comment at: clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp:116
+static const Expr *ignoreTemporariesAndImplicitCasts(const Expr *E) {
+  if (const auto *T = dyn_cast(E))
+return ignoreTemporariesAndImplicitCasts(T->GetTemporaryExpr());

zturner wrote:
> aaron.ballman wrote:
> > What about `CXXBindTemporaryExpr`?
> > 
> > Would `Expr::IgnoreImplicit()` do too much stripping because it removes 
> > `FullExpr` as well?
> I don't actually know.  This patch is literally my first exposure to clang's 
> frontend and AST manipulations, so I was kind of just trying different things 
> until something worked here.  I didn't even know about `IgnoreImplicit()` or 
> `FullExpr`.  I'll play around with them and report back.
Unless you find some reason why they're critical in the initial version of your 
patch, I'm fine handling this as a follow-up if needed.


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

https://reviews.llvm.org/D70368



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


[PATCH] D68912: Adds -Wrange-loop-analysis to -Wall

2019-11-23 Thread Dávid Bolvanský via Phabricator via cfe-commits
xbolva00 added a comment.

In D68912#1754660 , @xbolva00 wrote:

> I think you can commit it, you already fixed some warnings.


Oh, I hit this (-Werror bots) hard :D Some bots use -Werror. So when build is 
warning-free, then please commit this patch.


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

https://reviews.llvm.org/D68912



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


[PATCH] D61837: Make it possible control matcher traversal kind with ASTContext

2019-11-23 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

LGTM with a few minor nits.




Comment at: clang/include/clang/AST/ASTContext.h:3009
   class ParentMap;
-  std::unique_ptr Parents;
+  std::map> Parents;
 

Do we need to use `std::map` here, or could we use an `IndexedMap` or 
`DenseMap`?

(`std::map` tends to perform poorly under some circumstances and the keys in 
this case look like they should be small and dense, but if we can't use one of 
the more specialized containers for some reason, it's fine to stick with 
`std::map`.)



Comment at: clang/lib/AST/ASTContext.cpp:120
+ASTContext::traverseIgnored(const ast_type_traits::DynTypedNode ) const {
+  if (auto *E = N.get()) {
+return ast_type_traits::DynTypedNode::create(*traverseIgnored(E));

Because `N` is const, does its `get<>` method return a `const` pointer? If so, 
switch to `const auto *` for clarity.



Comment at: clang/lib/ASTMatchers/ASTMatchersInternal.cpp:222
   BoundNodesTreeBuilder *Builder) const {
-  if (RestrictKind.isBaseOf(DynNode.getNodeKind()) &&
-  Implementation->dynMatches(DynNode, Finder, Builder)) {
+  TraversalKindScope raii(Finder->getASTContext(),
+  Implementation->TraversalKind());

`raii` -> `RAII` per naming conventions.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D61837



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


[PATCH] D70625: [DebugInfo][BPF] Support to emit debugInfo for extern variables

2019-11-23 Thread Yonghong Song via Phabricator via cfe-commits
yonghong-song added a comment.

@dblaikie Thanks for the review. To address your comments below:

> the title talks about global variables
>  the description talks about extern types (guessing that's just a typo?)

The title is "Support to emit debugInfo for extern variables". In the 
description, I am using "extern" variables as well. But in the implementation, 
I am using "GlobalDecl" or "GlobalDeclOnly". I indeed need to make naming 
convention consistent.

>   the patch itself seems to have code that's visiting more functions? ( 
> processFuncPrototypes )

The proceessFuncPrototypes filtered any function without debug info and 
defined. So based on my testing, it only emits extern functions. But do let me 
know if I miss anything here.

>   & also I'd generally still prefer to see two patches for each piece of new 
> debug info - first adding the functionality to LLVM, then second using that 
> functionality in Clang (even though we're in the monorepo - these are still 
> divisible patches that makes code review, revert, root cause analysis, etc, 
> easier)

Agree. I will separate the patch into two separate patches as you suggested, 
add more tests for the clang patch and resubmit.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D70625



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


[PATCH] D70627: [AST] Split out Attrs.h for table generated *Attr classes

2019-11-23 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

Basically LGTM but I am hoping we can get a better name than `Attr.h` and 
`Attrs.h`.




Comment at: clang/include/clang/AST/Attrs.h:1
+//===--- Attr.h - Classes for representing attributes --*- C++ -*-===//
+//

This should read `Attrs.h` instead, but I find the naming distinction to be a 
bit too subtle. How about `AttrSubclasses.h` or `ConcreteAttrs.h` (other 
suggestions welcome too).



Comment at: clang/include/clang/AST/Attrs.h:13
+
+#ifndef LLVM_CLANG_AST_ATTRS_H
+#define LLVM_CLANG_AST_ATTRS_H

Once the file name is updated, be sure to update the include guards.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D70627



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


[PATCH] D70469: [attributes] [analyzer] Add handle related attributes

2019-11-23 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang/include/clang/Basic/Attr.td:3445
+  let Spellings = [Clang<"acquire_handle">];
+  let Subjects = SubjectList<[Function, ParmVar], ErrorDiag>;
+  let Documentation = [AcquireHandleDocs];

xazax.hun wrote:
> aaron.ballman wrote:
> > What about function-like interfaces such as lambdas, blocks, or other 
> > callable objects that are not a `FunctionDecl`?
> Good point!
This get you partway there -- `FunctionLike` allows functions and function 
pointers, but I don't think it allows lambdas or blocks. You should add some 
test cases for all of these (including function pointers) to verify you're able 
to mark the entities you want and get the behavior you're after.

For instance, on function pointers and lambdas, this may impact the function 
*type* which is a good design question to be thinking about. What should happen 
with code like:
```
[[clang::acquire_handle]] void int open(const char *);
int (*fp)(const char *) = open;
```
If the attribute is a type attribute as opposed to a declaration attribute, 
then you can think about diagnostics in these sort of cases. However, if it is 
a type attribute, there is more work involved in hooking it up to the type 
system.

FWIW, this attribute smells like it should be a type attribute rather than a 
declaration attribute because I can imagine wanting to use this with function 
pointers and not losing the analysis capabilities (esp for things like callback 
functions).



Comment at: clang/include/clang/Basic/Attr.td:3451
+  let Spellings = [Clang<"use_handle">];
+  let Subjects = SubjectList<[ParmVar]>;
+  let Documentation = [UseHandleDocs];

One test that you should add is whether this case is properly handled:
```
void (*fp)(int whatever [[clang::uses_handle]]);
[](int whatever [[clang::uses_handle]]){};
```
e.g., when it's on a parameter declaration of function pointer type or a 
lambda, does everything still behave as expected?



Comment at: clang/include/clang/Basic/AttrDocs.td:4473
+  let Content = [{
+Handles are a way to identify resources like files, sockets, processes. They
+are more opaque than pointers and widely used in system programming. They have

sockets, processes -> sockets, and processes



Comment at: clang/lib/Sema/SemaDeclAttr.cpp:6523
+  // Warn if the parameter is definitely not an output parameter.
+  if (auto *PVD = dyn_cast(D)) {
+if (PVD->getType()->isIntegerType()) {

`const auto *`



Comment at: clang/lib/Sema/SemaDeclAttr.cpp:6524
+  if (auto *PVD = dyn_cast(D)) {
+if (PVD->getType()->isIntegerType()) {
+  S.Diag(AL.getLoc(), diag::err_attribute_output_parameter)

I'm skeptical of this. I think a better check is if the type is a pointer or 
reference -- was there a reason you didn't go with that approach?


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

https://reviews.llvm.org/D70469



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


[PATCH] D70596: [analyzer][docs] NFC: Extend documentation for MallocOverflow checker

2019-11-23 Thread Borsik Gábor via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG79e2325f145d: [analyzer][docs] NFC: Extend documentation for 
MallocOverflow checker (authored by boga95).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D70596

Files:
  clang/docs/analyzer/checkers.rst


Index: clang/docs/analyzer/checkers.rst
===
--- clang/docs/analyzer/checkers.rst
+++ clang/docs/analyzer/checkers.rst
@@ -1974,6 +1974,12 @@
void *p = malloc(n * sizeof(int)); // warn
  }
 
+ void test2(int n) {
+   if (n > 100) // gives an upper-bound
+ return;
+   void *p = malloc(n * sizeof(int)); // no warning
+ }
+
 .. _alpha-security-MmapWriteExec:
 
 alpha.security.MmapWriteExec (C)


Index: clang/docs/analyzer/checkers.rst
===
--- clang/docs/analyzer/checkers.rst
+++ clang/docs/analyzer/checkers.rst
@@ -1974,6 +1974,12 @@
void *p = malloc(n * sizeof(int)); // warn
  }
 
+ void test2(int n) {
+   if (n > 100) // gives an upper-bound
+ return;
+   void *p = malloc(n * sizeof(int)); // no warning
+ }
+
 .. _alpha-security-MmapWriteExec:
 
 alpha.security.MmapWriteExec (C)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D59516: [analyzer] Add custom filter functions for GenericTaintChecker

2019-11-23 Thread Borsik Gábor via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
boga95 marked 2 inline comments as done.
Closed by commit rG89bc4c662c6c: [analyzer] Add custom filter functions for 
GenericTaintChecker (authored by boga95).

Changed prior to commit:
  https://reviews.llvm.org/D59516?vs=220385=230771#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D59516

Files:
  clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/Taint.cpp
  clang/lib/StaticAnalyzer/Checkers/Taint.h
  clang/test/Analysis/Inputs/taint-generic-config.yaml
  clang/test/Analysis/taint-generic.c

Index: clang/test/Analysis/taint-generic.c
===
--- clang/test/Analysis/taint-generic.c
+++ clang/test/Analysis/taint-generic.c
@@ -56,6 +56,8 @@
 extern FILE *stdin;
 #endif
 
+#define bool _Bool
+
 int fscanf(FILE *restrict stream, const char *restrict format, ...);
 int sprintf(char *str, const char *format, ...);
 void setproctitle(const char *fmt, ...);
@@ -346,6 +348,7 @@
 void myScanf(const char*, ...);
 int myPropagator(int, int*);
 int mySnprintf(char*, size_t, const char*, ...);
+bool isOutOfRange(const int*);
 void mySink(int, int, int);
 
 void testConfigurationSources1() {
@@ -372,6 +375,13 @@
   Buffer[y] = 1; // expected-warning {{Out of bound memory access }}
 }
 
+void testConfigurationFilter() {
+  int x = mySource1();
+  if (isOutOfRange()) // the filter function
+return;
+  Buffer[x] = 1; // no-warning
+}
+
 void testConfigurationSinks() {
   int x = mySource1();
   mySink(x, 1, 2);
Index: clang/test/Analysis/Inputs/taint-generic-config.yaml
===
--- clang/test/Analysis/Inputs/taint-generic-config.yaml
+++ clang/test/Analysis/Inputs/taint-generic-config.yaml
@@ -36,8 +36,8 @@
 # A list of filter functions
 Filters:
   # int x; // x is tainted
-  # myFilter(); // x is not tainted anymore
-  - Name: myFilter
+  # isOutOfRange(); // x is not tainted anymore
+  - Name: isOutOfRange
 Args: [0]
 
 # A list of sink functions
Index: clang/lib/StaticAnalyzer/Checkers/Taint.h
===
--- clang/lib/StaticAnalyzer/Checkers/Taint.h
+++ clang/lib/StaticAnalyzer/Checkers/Taint.h
@@ -27,34 +27,39 @@
 static constexpr TaintTagType TaintTagGeneric = 0;
 
 /// Create a new state in which the value of the statement is marked as tainted.
-LLVM_NODISCARD ProgramStateRef
-addTaint(ProgramStateRef State, const Stmt *S, const LocationContext *LCtx,
- TaintTagType Kind = TaintTagGeneric);
+LLVM_NODISCARD ProgramStateRef addTaint(ProgramStateRef State, const Stmt *S,
+const LocationContext *LCtx,
+TaintTagType Kind = TaintTagGeneric);
 
 /// Create a new state in which the value is marked as tainted.
-LLVM_NODISCARD ProgramStateRef
-addTaint(ProgramStateRef State, SVal V,
- TaintTagType Kind = TaintTagGeneric);
+LLVM_NODISCARD ProgramStateRef addTaint(ProgramStateRef State, SVal V,
+TaintTagType Kind = TaintTagGeneric);
 
 /// Create a new state in which the symbol is marked as tainted.
-LLVM_NODISCARD ProgramStateRef
-addTaint(ProgramStateRef State, SymbolRef Sym,
- TaintTagType Kind = TaintTagGeneric);
+LLVM_NODISCARD ProgramStateRef addTaint(ProgramStateRef State, SymbolRef Sym,
+TaintTagType Kind = TaintTagGeneric);
 
 /// Create a new state in which the pointer represented by the region
 /// is marked as tainted.
-LLVM_NODISCARD ProgramStateRef
-addTaint(ProgramStateRef State, const MemRegion *R,
- TaintTagType Kind = TaintTagGeneric);
+LLVM_NODISCARD ProgramStateRef addTaint(ProgramStateRef State,
+const MemRegion *R,
+TaintTagType Kind = TaintTagGeneric);
+
+LLVM_NODISCARD ProgramStateRef removeTaint(ProgramStateRef State, SVal V);
+
+LLVM_NODISCARD ProgramStateRef removeTaint(ProgramStateRef State,
+   const MemRegion *R);
+
+LLVM_NODISCARD ProgramStateRef removeTaint(ProgramStateRef State,
+   SymbolRef Sym);
 
 /// Create a new state in a which a sub-region of a given symbol is tainted.
 /// This might be necessary when referring to regions that can not have an
 /// individual symbol, e.g. if they are represented by the default binding of
 /// a LazyCompoundVal.
-LLVM_NODISCARD ProgramStateRef
-addPartialTaint(ProgramStateRef State,
-SymbolRef ParentSym, const SubRegion *SubRegion,
-TaintTagType Kind = TaintTagGeneric);
+LLVM_NODISCARD ProgramStateRef addPartialTaint(
+ProgramStateRef State, SymbolRef ParentSym, const SubRegion *SubRegion,

[clang] 89bc4c6 - [analyzer] Add custom filter functions for GenericTaintChecker

2019-11-23 Thread Borsik Gabor via cfe-commits

Author: Borsik Gabor
Date: 2019-11-23T20:12:15+01:00
New Revision: 89bc4c662c6c316f037347bf46efb9dc7584b15a

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

LOG: [analyzer] Add custom filter functions for GenericTaintChecker

This patch is the last of the series of patches which allow the user to
annotate their functions with taint propagation rules.

I implemented the use of the configured filtering functions. These
functions can remove taintedness from the symbols which are passed at
the specified arguments to the filters.

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

Added: 


Modified: 
clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
clang/lib/StaticAnalyzer/Checkers/Taint.cpp
clang/lib/StaticAnalyzer/Checkers/Taint.h
clang/test/Analysis/Inputs/taint-generic-config.yaml
clang/test/Analysis/taint-generic.c

Removed: 




diff  --git a/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
index d442b26b3959..2ceb6313920b 100644
--- a/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
@@ -98,13 +98,20 @@ class GenericTaintChecker
   }
 
   /// Catch taint related bugs. Check if tainted data is passed to a
-  /// system call etc.
-  bool checkPre(const CallExpr *CE, CheckerContext ) const;
+  /// system call etc. Returns true on matching.
+  bool checkPre(const CallExpr *CE, const FunctionDecl *FDecl, StringRef Name,
+CheckerContext ) const;
 
-  /// Add taint sources on a pre-visit.
-  void addSourcesPre(const CallExpr *CE, CheckerContext ) const;
+  /// Add taint sources on a pre-visit. Returns true on matching.
+  bool addSourcesPre(const CallExpr *CE, const FunctionDecl *FDecl,
+ StringRef Name, CheckerContext ) const;
 
-  /// Propagate taint generated at pre-visit.
+  /// Mark filter's arguments not tainted on a pre-visit. Returns true on
+  /// matching.
+  bool addFiltersPre(const CallExpr *CE, StringRef Name,
+ CheckerContext ) const;
+
+  /// Propagate taint generated at pre-visit. Returns true on matching.
   bool propagateFromPre(const CallExpr *CE, CheckerContext ) const;
 
   /// Check if the region the expression evaluates to is the standard input,
@@ -442,14 +449,26 @@ 
GenericTaintChecker::TaintPropagationRule::getTaintPropagationRule(
 
 void GenericTaintChecker::checkPreStmt(const CallExpr *CE,
CheckerContext ) const {
+  const FunctionDecl *FDecl = C.getCalleeDecl(CE);
+  // Check for non-global functions.
+  if (!FDecl || FDecl->getKind() != Decl::Function)
+return;
+
+  StringRef Name = C.getCalleeName(FDecl);
+  if (Name.empty())
+return;
+
   // Check for taintedness related errors first: system call, uncontrolled
   // format string, tainted buffer size.
-  if (checkPre(CE, C))
+  if (checkPre(CE, FDecl, Name, C))
 return;
 
   // Marks the function's arguments and/or return value tainted if it present 
in
   // the list.
-  addSourcesPre(CE, C);
+  if (addSourcesPre(CE, FDecl, Name, C))
+return;
+
+  addFiltersPre(CE, Name, C);
 }
 
 void GenericTaintChecker::checkPostStmt(const CallExpr *CE,
@@ -464,31 +483,46 @@ void GenericTaintChecker::printState(raw_ostream , 
ProgramStateRef State,
   printTaint(State, Out, NL, Sep);
 }
 
-void GenericTaintChecker::addSourcesPre(const CallExpr *CE,
+bool GenericTaintChecker::addSourcesPre(const CallExpr *CE,
+const FunctionDecl *FDecl,
+StringRef Name,
 CheckerContext ) const {
-  ProgramStateRef State = nullptr;
-  const FunctionDecl *FDecl = C.getCalleeDecl(CE);
-  if (!FDecl || FDecl->getKind() != Decl::Function)
-return;
-
-  StringRef Name = C.getCalleeName(FDecl);
-  if (Name.empty())
-return;
-
   // First, try generating a propagation rule for this function.
   TaintPropagationRule Rule = TaintPropagationRule::getTaintPropagationRule(
   this->CustomPropagations, FDecl, Name, C);
   if (!Rule.isNull()) {
-State = Rule.process(CE, C);
-if (!State)
-  return;
-C.addTransition(State);
-return;
+ProgramStateRef State = Rule.process(CE, C);
+if (State) {
+  C.addTransition(State);
+  return true;
+}
   }
+  return false;
+}
 
-  if (!State)
-return;
-  C.addTransition(State);
+bool GenericTaintChecker::addFiltersPre(const CallExpr *CE, StringRef Name,
+CheckerContext ) const {
+  auto It = CustomFilters.find(Name);
+  if (It == CustomFilters.end())
+return false;
+
+  ProgramStateRef State = C.getState();
+  

[PATCH] D69855: [clang-tidy] Fix llvm-namespace-comment for macro expansions

2019-11-23 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman closed this revision.
aaron.ballman added a comment.

In D69855#1754047 , @twardakm wrote:

> @aaron.ballman thanks for the review :) Can you please push the change on my 
> behalf? I don't have commit rights.


I've commit on your behalf in 4736d63f752f8d13f4c6a9afd558565c32119718 
, thank 
you for the patch!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D69855



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


[clang-tools-extra] 4736d63 - Fix llvm-namespace-comment for macro expansions

2019-11-23 Thread Aaron Ballman via cfe-commits

Author: Marcin Twardak
Date: 2019-11-23T13:08:14-05:00
New Revision: 4736d63f752f8d13f4c6a9afd558565c32119718

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

LOG: Fix llvm-namespace-comment for macro expansions

If a namespace is a macro name, it should be allowed to close the
namespace with the same name.

Added: 
clang-tools-extra/test/clang-tidy/checkers/llvm-namespace-comment.cpp

Modified: 
clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp
clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.h

clang-tools-extra/test/clang-tidy/checkers/google-readability-namespace-comments.cpp

Removed: 




diff  --git 
a/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp
index eb3d7c505b83..a2a56241e8ab 100644
--- a/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp
@@ -19,6 +19,44 @@ namespace clang {
 namespace tidy {
 namespace readability {
 
+namespace {
+class NamespaceCommentPPCallbacks : public PPCallbacks {
+public:
+  NamespaceCommentPPCallbacks(Preprocessor *PP, NamespaceCommentCheck *Check)
+  : PP(PP), Check(Check) {}
+
+  void MacroDefined(const Token , const MacroDirective *MD) {
+// Record all defined macros. We store the whole token to compare names
+// later.
+
+const MacroInfo * MI = MD->getMacroInfo();
+
+if (MI->isFunctionLike())
+  return;
+
+std::string ValueBuffer;
+llvm::raw_string_ostream Value(ValueBuffer);
+
+SmallString<128> SpellingBuffer;
+bool First = true;
+for (const auto  : MI->tokens()) {
+  if (!First && T.hasLeadingSpace())
+Value << ' ';
+
+  Value << PP->getSpelling(T, SpellingBuffer);
+  First = false;
+}
+
+Check->addMacro(MacroNameTok.getIdentifierInfo()->getName().str(),
+Value.str());
+  }
+
+private:
+  Preprocessor *PP;
+  NamespaceCommentCheck *Check;
+};
+} // namespace
+
 NamespaceCommentCheck::NamespaceCommentCheck(StringRef Name,
  ClangTidyContext *Context)
 : ClangTidyCheck(Name, Context),
@@ -40,24 +78,37 @@ void NamespaceCommentCheck::registerMatchers(MatchFinder 
*Finder) {
 Finder->addMatcher(namespaceDecl().bind("namespace"), this);
 }
 
+void NamespaceCommentCheck::registerPPCallbacks(
+const SourceManager , Preprocessor *PP, Preprocessor *ModuleExpanderPP) 
{
+  PP->addPPCallbacks(std::make_unique(PP, this));
+}
+
 static bool locationsInSameFile(const SourceManager ,
 SourceLocation Loc1, SourceLocation Loc2) {
   return Loc1.isFileID() && Loc2.isFileID() &&
  Sources.getFileID(Loc1) == Sources.getFileID(Loc2);
 }
 
-static std::string getNamespaceComment(const NamespaceDecl *ND,
-   bool InsertLineBreak) {
+std::string NamespaceCommentCheck::getNamespaceComment(const NamespaceDecl *ND,
+   bool InsertLineBreak) {
   std::string Fix = "// namespace";
-  if (!ND->isAnonymousNamespace())
-Fix.append(" ").append(ND->getNameAsString());
+  if (!ND->isAnonymousNamespace()) {
+bool IsNamespaceMacroExpansion;
+StringRef MacroDefinition;
+std::tie(IsNamespaceMacroExpansion, MacroDefinition) =
+isNamespaceMacroExpansion(ND->getName());
+
+Fix.append(" ").append(IsNamespaceMacroExpansion ? MacroDefinition
+ : ND->getName());
+  }
   if (InsertLineBreak)
 Fix.append("\n");
   return Fix;
 }
 
-static std::string getNamespaceComment(const std::string ,
-   bool InsertLineBreak) {
+std::string
+NamespaceCommentCheck::getNamespaceComment(const std::string ,
+   bool InsertLineBreak) {
   std::string Fix = "// namespace ";
   Fix.append(NameSpaceName);
   if (InsertLineBreak)
@@ -65,6 +116,32 @@ static std::string getNamespaceComment(const std::string 
,
   return Fix;
 }
 
+void NamespaceCommentCheck::addMacro(const std::string ,
+ const std::string ) noexcept {
+  Macros.emplace_back(Name, Value);
+}
+
+bool NamespaceCommentCheck::isNamespaceMacroDefinition(
+const StringRef NameSpaceName) {
+  return llvm::any_of(Macros, [](const auto ) {
+return NameSpaceName == Macro.first;
+  });
+}
+
+std::tuple NamespaceCommentCheck::isNamespaceMacroExpansion(
+const StringRef NameSpaceName) {
+  const auto  =
+  llvm::find_if(Macros, [](const auto ) {
+return NameSpaceName == Macro.second;
+  });
+
+  const bool IsNamespaceMacroExpansion = 

[PATCH] D69391: Add #pragma clang loop ivdep

2019-11-23 Thread Yashas Andaluri via Phabricator via cfe-commits
YashasAndaluri updated this revision to Diff 230767.
YashasAndaluri edited the summary of this revision.
YashasAndaluri added a comment.

Added IvdepEnable loop attribute and `llvm.loop.vectorize.ivdep.enable` 
metadata.


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

https://reviews.llvm.org/D69391

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/lib/CodeGen/CGLoopInfo.cpp
  clang/lib/CodeGen/CGLoopInfo.h
  clang/lib/Parse/ParsePragma.cpp
  clang/lib/Sema/SemaStmtAttr.cpp
  clang/test/AST/ast-print-pragmas.cpp
  clang/test/CodeGenCXX/pragma-loop-ivdep.cpp
  clang/test/Parser/pragma-loop.cpp
  clang/test/Parser/pragma-unroll-and-jam.cpp

Index: clang/test/Parser/pragma-unroll-and-jam.cpp
===
--- clang/test/Parser/pragma-unroll-and-jam.cpp
+++ clang/test/Parser/pragma-unroll-and-jam.cpp
@@ -67,7 +67,7 @@
   }
 
 // pragma clang unroll_and_jam is disabled for the moment
-/* expected-error {{invalid option 'unroll_and_jam'; expected vectorize, vectorize_width, interleave, interleave_count, unroll, unroll_count, pipeline, pipeline_initiation_interval, vectorize_predicate, or distribute}} */ #pragma clang loop unroll_and_jam(4)
+/* expected-error {{invalid option 'unroll_and_jam'; expected vectorize, vectorize_width, interleave, interleave_count, unroll, unroll_count, pipeline, pipeline_initiation_interval, vectorize_predicate, ivdep, or distribute}} */ #pragma clang loop unroll_and_jam(4)
   for (int i = 0; i < Length; i++) {
 for (int j = 0; j < Length; j++) {
   List[i * Length + j] = Value;
Index: clang/test/Parser/pragma-loop.cpp
===
--- clang/test/Parser/pragma-loop.cpp
+++ clang/test/Parser/pragma-loop.cpp
@@ -82,6 +82,7 @@
 #pragma clang loop vectorize(enable)
 #pragma clang loop interleave(enable)
 #pragma clang loop vectorize_predicate(enable)
+#pragma clang loop ivdep(enable)
 #pragma clang loop unroll(full)
   while (i + 1 < Length) {
 List[i] = i;
@@ -135,12 +136,14 @@
 /* expected-error {{expected '('}} */ #pragma clang loop vectorize_predicate
 /* expected-error {{expected '('}} */ #pragma clang loop unroll
 /* expected-error {{expected '('}} */ #pragma clang loop distribute
+/* expected-error {{expected '('}} */ #pragma clang loop ivdep
 
 /* expected-error {{expected ')'}} */ #pragma clang loop vectorize(enable
 /* expected-error {{expected ')'}} */ #pragma clang loop interleave(enable
 /* expected-error {{expected ')'}} */ #pragma clang loop vectorize_predicate(enable
 /* expected-error {{expected ')'}} */ #pragma clang loop unroll(full
 /* expected-error {{expected ')'}} */ #pragma clang loop distribute(enable
+/* expected-error {{expected ')'}} */ #pragma clang loop ivdep(enable
 
 /* expected-error {{expected ')'}} */ #pragma clang loop vectorize_width(4
 /* expected-error {{expected ')'}} */ #pragma clang loop interleave_count(4
@@ -151,7 +154,7 @@
 /* expected-error {{missing argument; expected 'enable', 'full' or 'disable'}} */ #pragma clang loop unroll()
 /* expected-error {{missing argument; expected 'enable' or 'disable'}} */ #pragma clang loop distribute()
 
-/* expected-error {{missing option; expected vectorize, vectorize_width, interleave, interleave_count, unroll, unroll_count, pipeline, pipeline_initiation_interval, vectorize_predicate, or distribute}} */ #pragma clang loop
+/* expected-error {{missing option; expected vectorize, vectorize_width, interleave, interleave_count, unroll, unroll_count, pipeline, pipeline_initiation_interval, vectorize_predicate, ivdep, or distribute}} */ #pragma clang loop
 /* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop badkeyword
 /* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop badkeyword(enable)
 /* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop vectorize(enable) badkeyword(4)
@@ -205,6 +208,7 @@
 /* expected-error {{invalid argument; expected 'enable', 'assume_safety' or 'disable'}} */ #pragma clang loop interleave(badidentifier)
 /* expected-error {{invalid argument; expected 'enable', 'full' or 'disable'}} */ #pragma clang loop unroll(badidentifier)
 /* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop distribute(badidentifier)
+/* expected-error {{invalid argument; expected 'enable'}} */ #pragma clang loop ivdep(badidentifier)
   while (i-7 < Length) {
 List[i] = i;
   }
Index: clang/test/CodeGenCXX/pragma-loop-ivdep.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/pragma-loop-ivdep.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+void test0(int *a, int *b, int LEN_1D) {
+  // CHECK-LABEL: @{{.*}}test0{{.*}}(
+  

[PATCH] D55326: [Driver] Fix incorrect GNU triplet for PowerPC on SUSE Linux

2019-11-23 Thread Aaron Puchert via Phabricator via cfe-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rG0010ea4224c7: [Driver] Fix incorrect GNU triplet for PowerPC 
on SUSE Linux (authored by aaronpuchert).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D55326

Files:
  clang/lib/Driver/ToolChains/Gnu.cpp
  clang/test/Driver/Inputs/opensuse_tumbleweed_ppc_tree/usr/lib/crt1.o
  clang/test/Driver/Inputs/opensuse_tumbleweed_ppc_tree/usr/lib/crti.o
  clang/test/Driver/Inputs/opensuse_tumbleweed_ppc_tree/usr/lib/crtn.o
  
clang/test/Driver/Inputs/opensuse_tumbleweed_ppc_tree/usr/lib/gcc/powerpc64-suse-linux/9/crtbegin.o
  
clang/test/Driver/Inputs/opensuse_tumbleweed_ppc_tree/usr/lib/gcc/powerpc64-suse-linux/9/crtend.o
  clang/test/Driver/linux-ld.c


Index: clang/test/Driver/linux-ld.c
===
--- clang/test/Driver/linux-ld.c
+++ clang/test/Driver/linux-ld.c
@@ -879,6 +879,21 @@
 // CHECK-OPENSUSE-TW-RISCV64: 
"{{.*}}/usr/lib64/gcc/riscv64-suse-linux/9{{/|}}crtend.o"
 // CHECK-OPENSUSE-TW-RISCV64: 
"{{.*}}/usr/lib64/gcc/riscv64-suse-linux/9/../../../../lib64{{/|}}crtn.o"
 //
+// Check openSUSE Tumbleweed on ppc
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: --target=powerpc-unknown-linux-gnu -rtlib=platform \
+// RUN: --gcc-toolchain="" \
+// RUN: --sysroot=%S/Inputs/opensuse_tumbleweed_ppc_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-OPENSUSE-TW-PPC %s
+// CHECK-OPENSUSE-TW-PPC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-OPENSUSE-TW-PPC: 
"{{.*}}/usr/lib/gcc/powerpc64-suse-linux/9/../../..{{/|}}crt1.o"
+// CHECK-OPENSUSE-TW-PPC: 
"{{.*}}/usr/lib/gcc/powerpc64-suse-linux/9/../../..{{/|}}crti.o"
+// CHECK-OPENSUSE-TW-PPC: 
"{{.*}}/usr/lib/gcc/powerpc64-suse-linux/9{{/|}}crtbegin.o"
+// CHECK-OPENSUSE-TW-PPC: "-L[[SYSROOT]]/usr/lib/gcc/powerpc64-suse-linux/9"
+// CHECK-OPENSUSE-TW-PPC: 
"-L[[SYSROOT]]/usr/lib/gcc/powerpc64-suse-linux/9/../../.."
+// CHECK-OPENSUSE-TW-PPC: 
"{{.*}}/usr/lib/gcc/powerpc64-suse-linux/9{{/|}}crtend.o"
+// CHECK-OPENSUSE-TW-PPC: 
"{{.*}}/usr/lib/gcc/powerpc64-suse-linux/9/../../..{{/|}}crtn.o"
+//
 // Check dynamic-linker for different archs
 // RUN: %clang %s -### -o %t.o 2>&1 \
 // RUN: --target=arm-linux-gnueabi \
Index: clang/lib/Driver/ToolChains/Gnu.cpp
===
--- clang/lib/Driver/ToolChains/Gnu.cpp
+++ clang/lib/Driver/ToolChains/Gnu.cpp
@@ -2057,7 +2057,9 @@
   static const char *const PPCLibDirs[] = {"/lib32", "/lib"};
   static const char *const PPCTriples[] = {
   "powerpc-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc-linux-gnuspe",
-  "powerpc-suse-linux", "powerpc-montavista-linuxspe"};
+  // On 32-bit PowerPC systems running SUSE Linux, gcc is configured as a
+  // 64-bit compiler which defaults to "-m32", hence 
"powerpc64-suse-linux".
+  "powerpc64-suse-linux", "powerpc-montavista-linuxspe"};
   static const char *const PPC64LibDirs[] = {"/lib64", "/lib"};
   static const char *const PPC64Triples[] = {
   "powerpc64-linux-gnu", "powerpc64-unknown-linux-gnu",


Index: clang/test/Driver/linux-ld.c
===
--- clang/test/Driver/linux-ld.c
+++ clang/test/Driver/linux-ld.c
@@ -879,6 +879,21 @@
 // CHECK-OPENSUSE-TW-RISCV64: "{{.*}}/usr/lib64/gcc/riscv64-suse-linux/9{{/|}}crtend.o"
 // CHECK-OPENSUSE-TW-RISCV64: "{{.*}}/usr/lib64/gcc/riscv64-suse-linux/9/../../../../lib64{{/|}}crtn.o"
 //
+// Check openSUSE Tumbleweed on ppc
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: --target=powerpc-unknown-linux-gnu -rtlib=platform \
+// RUN: --gcc-toolchain="" \
+// RUN: --sysroot=%S/Inputs/opensuse_tumbleweed_ppc_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-OPENSUSE-TW-PPC %s
+// CHECK-OPENSUSE-TW-PPC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-OPENSUSE-TW-PPC: "{{.*}}/usr/lib/gcc/powerpc64-suse-linux/9/../../..{{/|}}crt1.o"
+// CHECK-OPENSUSE-TW-PPC: "{{.*}}/usr/lib/gcc/powerpc64-suse-linux/9/../../..{{/|}}crti.o"
+// CHECK-OPENSUSE-TW-PPC: "{{.*}}/usr/lib/gcc/powerpc64-suse-linux/9{{/|}}crtbegin.o"
+// CHECK-OPENSUSE-TW-PPC: "-L[[SYSROOT]]/usr/lib/gcc/powerpc64-suse-linux/9"
+// CHECK-OPENSUSE-TW-PPC: "-L[[SYSROOT]]/usr/lib/gcc/powerpc64-suse-linux/9/../../.."
+// CHECK-OPENSUSE-TW-PPC: "{{.*}}/usr/lib/gcc/powerpc64-suse-linux/9{{/|}}crtend.o"
+// CHECK-OPENSUSE-TW-PPC: "{{.*}}/usr/lib/gcc/powerpc64-suse-linux/9/../../..{{/|}}crtn.o"
+//
 // Check dynamic-linker for different archs
 // RUN: %clang %s -### -o %t.o 2>&1 \
 // RUN: --target=arm-linux-gnueabi \
Index: clang/lib/Driver/ToolChains/Gnu.cpp

[clang] 0010ea4 - [Driver] Fix incorrect GNU triplet for PowerPC on SUSE Linux

2019-11-23 Thread Aaron Puchert via cfe-commits

Author: Aaron Puchert
Date: 2019-11-23T16:00:53+01:00
New Revision: 0010ea4224c7ff6b5aebeecacf10a7ced7d390b7

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

LOG: [Driver] Fix incorrect GNU triplet for PowerPC on SUSE Linux

Summary:
On SUSE distributions for 32-bit PowerPC, gcc is configured
as a 64-bit compiler using the GNU triplet "powerpc64-suse-linux",
but invoked with "-m32" by default. Thus, the correct GNU triplet
for 32-bit PowerPC SUSE distributions is "powerpc64-suse-linux"
and not "powerpc-suse-linux".

Reviewers: jrtc27, nemanjai, glaubitz

Reviewed By: nemanjai

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

Added: 
clang/test/Driver/Inputs/opensuse_tumbleweed_ppc_tree/usr/lib/crt1.o
clang/test/Driver/Inputs/opensuse_tumbleweed_ppc_tree/usr/lib/crti.o
clang/test/Driver/Inputs/opensuse_tumbleweed_ppc_tree/usr/lib/crtn.o

clang/test/Driver/Inputs/opensuse_tumbleweed_ppc_tree/usr/lib/gcc/powerpc64-suse-linux/9/crtbegin.o

clang/test/Driver/Inputs/opensuse_tumbleweed_ppc_tree/usr/lib/gcc/powerpc64-suse-linux/9/crtend.o

Modified: 
clang/lib/Driver/ToolChains/Gnu.cpp
clang/test/Driver/linux-ld.c

Removed: 




diff  --git a/clang/lib/Driver/ToolChains/Gnu.cpp 
b/clang/lib/Driver/ToolChains/Gnu.cpp
index eb84a99a16b7..4c6956d54b7a 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -2057,7 +2057,9 @@ void 
Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
   static const char *const PPCLibDirs[] = {"/lib32", "/lib"};
   static const char *const PPCTriples[] = {
   "powerpc-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc-linux-gnuspe",
-  "powerpc-suse-linux", "powerpc-montavista-linuxspe"};
+  // On 32-bit PowerPC systems running SUSE Linux, gcc is configured as a
+  // 64-bit compiler which defaults to "-m32", hence 
"powerpc64-suse-linux".
+  "powerpc64-suse-linux", "powerpc-montavista-linuxspe"};
   static const char *const PPC64LibDirs[] = {"/lib64", "/lib"};
   static const char *const PPC64Triples[] = {
   "powerpc64-linux-gnu", "powerpc64-unknown-linux-gnu",

diff  --git 
a/clang/test/Driver/Inputs/opensuse_tumbleweed_ppc_tree/usr/lib/crt1.o 
b/clang/test/Driver/Inputs/opensuse_tumbleweed_ppc_tree/usr/lib/crt1.o
new file mode 100644
index ..e69de29bb2d1

diff  --git 
a/clang/test/Driver/Inputs/opensuse_tumbleweed_ppc_tree/usr/lib/crti.o 
b/clang/test/Driver/Inputs/opensuse_tumbleweed_ppc_tree/usr/lib/crti.o
new file mode 100644
index ..e69de29bb2d1

diff  --git 
a/clang/test/Driver/Inputs/opensuse_tumbleweed_ppc_tree/usr/lib/crtn.o 
b/clang/test/Driver/Inputs/opensuse_tumbleweed_ppc_tree/usr/lib/crtn.o
new file mode 100644
index ..e69de29bb2d1

diff  --git 
a/clang/test/Driver/Inputs/opensuse_tumbleweed_ppc_tree/usr/lib/gcc/powerpc64-suse-linux/9/crtbegin.o
 
b/clang/test/Driver/Inputs/opensuse_tumbleweed_ppc_tree/usr/lib/gcc/powerpc64-suse-linux/9/crtbegin.o
new file mode 100644
index ..e69de29bb2d1

diff  --git 
a/clang/test/Driver/Inputs/opensuse_tumbleweed_ppc_tree/usr/lib/gcc/powerpc64-suse-linux/9/crtend.o
 
b/clang/test/Driver/Inputs/opensuse_tumbleweed_ppc_tree/usr/lib/gcc/powerpc64-suse-linux/9/crtend.o
new file mode 100644
index ..e69de29bb2d1

diff  --git a/clang/test/Driver/linux-ld.c b/clang/test/Driver/linux-ld.c
index 7aba660d51fb..51227550b528 100644
--- a/clang/test/Driver/linux-ld.c
+++ b/clang/test/Driver/linux-ld.c
@@ -879,6 +879,21 @@
 // CHECK-OPENSUSE-TW-RISCV64: 
"{{.*}}/usr/lib64/gcc/riscv64-suse-linux/9{{/|}}crtend.o"
 // CHECK-OPENSUSE-TW-RISCV64: 
"{{.*}}/usr/lib64/gcc/riscv64-suse-linux/9/../../../../lib64{{/|}}crtn.o"
 //
+// Check openSUSE Tumbleweed on ppc
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: --target=powerpc-unknown-linux-gnu -rtlib=platform \
+// RUN: --gcc-toolchain="" \
+// RUN: --sysroot=%S/Inputs/opensuse_tumbleweed_ppc_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-OPENSUSE-TW-PPC %s
+// CHECK-OPENSUSE-TW-PPC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-OPENSUSE-TW-PPC: 
"{{.*}}/usr/lib/gcc/powerpc64-suse-linux/9/../../..{{/|}}crt1.o"
+// CHECK-OPENSUSE-TW-PPC: 
"{{.*}}/usr/lib/gcc/powerpc64-suse-linux/9/../../..{{/|}}crti.o"
+// CHECK-OPENSUSE-TW-PPC: 
"{{.*}}/usr/lib/gcc/powerpc64-suse-linux/9{{/|}}crtbegin.o"
+// CHECK-OPENSUSE-TW-PPC: "-L[[SYSROOT]]/usr/lib/gcc/powerpc64-suse-linux/9"
+// CHECK-OPENSUSE-TW-PPC: 
"-L[[SYSROOT]]/usr/lib/gcc/powerpc64-suse-linux/9/../../.."
+// CHECK-OPENSUSE-TW-PPC: 
"{{.*}}/usr/lib/gcc/powerpc64-suse-linux/9{{/|}}crtend.o"
+// CHECK-OPENSUSE-TW-PPC: 
"{{.*}}/usr/lib/gcc/powerpc64-suse-linux/9/../../..{{/|}}crtn.o"
+//
 // 

[PATCH] D70500: [WebAssembly] Enable use of wasm-opt and LTO-enabled system libraries

2019-11-23 Thread Nico Weber via Phabricator via cfe-commits
thakis added a comment.

In D70500#1757738 , @thakis wrote:

> ps: The test fails for me, probably because I don't have wasm-opt on PATH? 
> How does this work on the regular bots? Do they all have emscripten installed?


Looks like it might fail with LLVM_APPEND_VC_REV=NO set.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D70500



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


[PATCH] D70500: [WebAssembly] Enable use of wasm-opt and LTO-enabled system libraries

2019-11-23 Thread Nico Weber via Phabricator via cfe-commits
thakis added inline comments.



Comment at: clang/lib/Driver/ToolChains/WebAssembly.cpp:137
+  getFilePaths().push_back(getDriver().SysRoot + "/lib/" + MultiarchTriple 
+
+   "/llvm-lto");
+}

sunfish wrote:
> sbc100 wrote:
> > Is there any kind of president here?   i.e. do any other platforms have 
> > support for this kind thing?  Seems like good idea I'd just like to be sure 
> > we follow existing practices.
> I looked around, but didn't see anything similar.
One immediate problem of this approach is that if HAVE_VCS_VERSION_INC is not 
set, then the test fails, but if it is set, `clang --version` reports a current 
git hash, which is either out of date or requires a pretty big rebuild on every 
single git commit (i.e. not just after `git pull` but also after local 
commits). Neither's great.

Do you expected that sysroots will ship 3-4 LTO folders, to support ~2 years of 
clang releases? Or do you expect that a sysroot will always support a single 
clang/llvm revision? If so, maybe the LLVM version is enough?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D70500



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


[clang] ed33cb5 - [RISCV] Add missing REQUIRES to clang tests

2019-11-23 Thread David Zarzycki via cfe-commits

Author: David Zarzycki
Date: 2019-11-23T14:47:09+02:00
New Revision: ed33cb5b147402c06a3e0a9082b0f991a9d91a1b

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

LOG: [RISCV] Add missing REQUIRES to clang tests

Fixes: e0f22fe04a5c9eb244ff0533549743b7deb03b99

Added: 


Modified: 
clang/test/Driver/riscv32-toolchain-extra.c
clang/test/Driver/riscv64-toolchain-extra.c

Removed: 




diff  --git a/clang/test/Driver/riscv32-toolchain-extra.c 
b/clang/test/Driver/riscv32-toolchain-extra.c
index d07d0f199ae2..a52972f6020a 100644
--- a/clang/test/Driver/riscv32-toolchain-extra.c
+++ b/clang/test/Driver/riscv32-toolchain-extra.c
@@ -3,7 +3,7 @@
 // The tests here are similar to those in riscv32-toolchain.c, however
 // these tests need to create symlinks to test directory trees in order to
 // set up the environment and therefore shell support is required.
-// REQUIRES: shell
+// REQUIRES: shell, riscv-registered-target
 // UNSUPPORTED: system-windows
 
 // If there is no GCC install detected then the driver searches for executables

diff  --git a/clang/test/Driver/riscv64-toolchain-extra.c 
b/clang/test/Driver/riscv64-toolchain-extra.c
index 243adecc5ecb..999b8c95fae4 100644
--- a/clang/test/Driver/riscv64-toolchain-extra.c
+++ b/clang/test/Driver/riscv64-toolchain-extra.c
@@ -3,7 +3,7 @@
 // The tests here are similar to those in riscv64-toolchain.c, however
 // these tests need to create symlinks to test directory trees in order to
 // set up the environment and therefore shell support is required.
-// REQUIRES: shell
+// REQUIRES: shell, riscv-registered-target
 // UNSUPPORTED: system-windows
 
 // If there is no GCC install detected then the driver searches for executables



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


[PATCH] D70500: [WebAssembly] Enable use of wasm-opt and LTO-enabled system libraries

2019-11-23 Thread Nico Weber via Phabricator via cfe-commits
thakis reopened this revision.
thakis added a comment.
This revision is now accepted and ready to land.

Please don't add code to the driver that runs programs off PATH. Nothing else 
does this. If you need to run an external program, look for it next to the 
compiler, like we do for gas with -fno-integrated-as, linker, etc. People can 
use the existing -B flag to make clang look elsewhere if they need that.

It's also somewhat uncommon to run non-LLVM binaries, but I can see the need 
for doing that at least during some transition period (like we did with the 
assembler).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D70500



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


[PATCH] D70500: [WebAssembly] Enable use of wasm-opt and LTO-enabled system libraries

2019-11-23 Thread Nico Weber via Phabricator via cfe-commits
thakis added a comment.

ps: The test fails for me, probably because I don't have wasm-opt on PATH? How 
does this work on the regular bots? Do they all have emscripten installed?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D70500



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


[PATCH] D70633: clang-format-vs : Fix Unicode Replacements

2019-11-23 Thread empty2fill via Phabricator via cfe-commits
empty2fill created this revision.
empty2fill added reviewers: clang-format, hans.
empty2fill added a project: clang-format.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Use UTF-8 for communication with clang-format and convert the replacements 
offset/length to characters position/count.

Internally VisualStudio.Text.Editor.IWpfTextView use sequence of Unicode 
characters encoded using UTF-16 and use characters position/count for 
manipulating text.

Resolved "Error while running clang-format: Specified argument was out of the 
range of valid values. Parameter name: replaceSpan".


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D70633

Files:
  clang/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs

Index: clang/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs
===
--- clang/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs
+++ clang/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs
@@ -24,6 +24,7 @@
 using System.Runtime.InteropServices;
 using System.Xml.Linq;
 using System.Linq;
+using System.Text;
 
 namespace LLVM.ClangFormat
 {
@@ -292,8 +293,7 @@
 string text = view.TextBuffer.CurrentSnapshot.GetText();
 int start = view.Selection.Start.Position.GetContainingLine().Start.Position;
 int end = view.Selection.End.Position.GetContainingLine().End.Position;
-int length = end - start;
-
+
 // clang-format doesn't support formatting a range that starts at the end
 // of the file.
 if (start >= text.Length && text.Length > 0)
@@ -301,7 +301,7 @@
 string path = Vsix.GetDocumentParent(view);
 string filePath = Vsix.GetDocumentPath(view);
 
-RunClangFormatAndApplyReplacements(text, start, length, path, filePath, options, view);
+RunClangFormatAndApplyReplacements(text, start, end, path, filePath, options, view);
 }
 
 /// 
@@ -336,11 +336,11 @@
 RunClangFormatAndApplyReplacements(text, 0, text.Length, path, filePath, options, view);
 }
 
-private void RunClangFormatAndApplyReplacements(string text, int offset, int length, string path, string filePath, OptionPageGrid options, IWpfTextView view)
+private void RunClangFormatAndApplyReplacements(string text, int start, int end, string path, string filePath, OptionPageGrid options, IWpfTextView view)
 {
 try
 {
-string replacements = RunClangFormat(text, offset, length, path, filePath, options);
+string replacements = RunClangFormat(text, start, end, path, filePath, options);
 ApplyClangFormatReplacements(replacements, view);
 }
 catch (Exception e)
@@ -363,9 +363,9 @@
 /// 
 /// Runs the given text through clang-format and returns the replacements as XML.
 /// 
-/// Formats the text range starting at offset of the given length.
+/// Formats the text in range start and end.
 /// 
-private static string RunClangFormat(string text, int offset, int length, string path, string filePath, OptionPageGrid options)
+private static string RunClangFormat(string text, int start, int end, string path, string filePath, OptionPageGrid options)
 {
 string vsixPath = Path.GetDirectoryName(
 typeof(ClangFormatPackage).Assembly.Location);
@@ -373,6 +373,9 @@
 System.Diagnostics.Process process = new System.Diagnostics.Process();
 process.StartInfo.UseShellExecute = false;
 process.StartInfo.FileName = vsixPath + "\\clang-format.exe";
+char[] chars = text.ToCharArray();
+int offset = Encoding.UTF8.GetByteCount(chars, 0, start);
+int length = Encoding.UTF8.GetByteCount(chars, 0, end) - offset;
 // Poor man's escaping - this will not work when quotes are already escaped
 // in the input (but we don't need more).
 string style = options.Style.Replace("\"", "\\\"");
@@ -413,10 +416,11 @@
 // 2. We write everything to the standard output - this cannot block, as clang-format
 //reads the full standard input before analyzing it without writing anything to the
 //standard output.
-process.StandardInput.Write(text);
+StreamWriter utf8Writer = new StreamWriter(process.StandardInput.BaseStream, new UTF8Encoding(false));
+utf8Writer.Write(text);
 // 3. We notify clang-format that the input is done - after this point clang-format
 //will start analyzing the input and eventually write the output.
-process.StandardInput.Close();
+utf8Writer.Close();
 // 4. We must read clang-format's output before waiting for it to exit; 

[PATCH] D70222: [clangd] Add support for .rsp files in compile_commands.json

2019-11-23 Thread liu hui via Phabricator via cfe-commits
lh123 updated this revision to Diff 230756.
lh123 added a comment.

Expand response files before `inferMissingCompileCommands` and 
`inferTargetAndDriverMode`


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

https://reviews.llvm.org/D70222

Files:
  clang/include/clang/Tooling/CompilationDatabase.h
  clang/lib/Tooling/CMakeLists.txt
  clang/lib/Tooling/CompilationDatabase.cpp
  clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
  clang/lib/Tooling/JSONCompilationDatabase.cpp
  clang/unittests/Tooling/CompilationDatabaseTest.cpp

Index: clang/unittests/Tooling/CompilationDatabaseTest.cpp
===
--- clang/unittests/Tooling/CompilationDatabaseTest.cpp
+++ clang/unittests/Tooling/CompilationDatabaseTest.cpp
@@ -17,6 +17,7 @@
 #include "llvm/Support/TargetSelect.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
+#include 
 
 namespace clang {
 namespace tooling {
@@ -859,5 +860,76 @@
 "clang++ --driver-mode=g++ bar.cpp -D bar.cpp");
 }
 
+class ExpandResponseFilesTest : public MemDBTest {
+protected:
+  void SetUp() override {
+InnerDir = path(StringRef("inner"));
+std::error_code EC = llvm::sys::fs::create_directory(InnerDir);
+EXPECT_TRUE(!EC);
+
+llvm::sys::path::append(RspFileName1, InnerDir, "rsp1.rsp");
+std::ofstream RspFile1(RspFileName1.c_str());
+RspFile1 << "-Dflag1";
+RspFile1.close();
+
+RspFileName2 = path(StringRef("rsp2.rsp"));
+std::ofstream RspFile2(RspFileName2.c_str());
+RspFile2 << "-Dflag2 @rsp3.rsp";
+RspFile2.close();
+
+RspFileName3 = path(StringRef("rsp3.rsp"));
+std::ofstream RspFile3(RspFileName3.c_str());
+RspFile3 << "-Dflag3";
+RspFile3.close();
+
+RspFileName4 = path(StringRef("rsp4.rsp"));
+std::ofstream  RspFile4(RspFileName4.c_str());
+RspFile4 << "-Dflag4 @rsp4.rsp";
+RspFile4.close();
+
+llvm::sys::path::append(RspFileName5, InnerDir, "rsp5.rsp");
+std::ofstream RspFile5(RspFileName5.c_str());
+RspFile5 << "-Dflag5 @inner/rsp1.rsp";
+RspFile5.close();
+  }
+
+  void TearDown() override {
+llvm::sys::fs::remove(RspFileName5);
+llvm::sys::fs::remove(RspFileName4);
+llvm::sys::fs::remove(RspFileName3);
+llvm::sys::fs::remove(RspFileName2);
+llvm::sys::fs::remove(RspFileName1);
+llvm::sys::fs::remove(InnerDir);
+  }
+
+  std::string getCommand(llvm::StringRef F) {
+auto Results = expandResponseFiles(std::make_unique(Entries))
+   ->getCompileCommands(path(F));
+if (Results.empty()) {
+  return "none";
+}
+return llvm::join(Results[0].CommandLine, " ");
+  }
+
+  SmallString<128> InnerDir;
+  SmallString<128> RspFileName1;
+  SmallString<128> RspFileName2;
+  SmallString<128> RspFileName3;
+  SmallString<128> RspFileName4;
+  SmallString<128> RspFileName5;
+};
+
+TEST_F(ExpandResponseFilesTest, ExpandResponseFiles) {
+  // clang-format off
+  add("foo.cpp", "clang",
+  ("@inner/rsp1.rsp @rsp2.rsp @rsp4.rsp "
+"@" + RspFileName1 + " @inner/rsp5.rsp @rsp6.rsp")
+  .str());
+  // clang-format on
+  EXPECT_EQ(getCommand("foo.cpp"), "clang foo.cpp -D foo.cpp -Dflag1 -Dflag2 "
+   "-Dflag3 -Dflag4 @rsp4.rsp -Dflag1 "
+   "-Dflag5 -Dflag1 @rsp6.rsp");
+}
+
 } // end namespace tooling
 } // end namespace clang
Index: clang/lib/Tooling/JSONCompilationDatabase.cpp
===
--- clang/lib/Tooling/JSONCompilationDatabase.cpp
+++ clang/lib/Tooling/JSONCompilationDatabase.cpp
@@ -167,8 +167,8 @@
 llvm::sys::path::append(JSONDatabasePath, "compile_commands.json");
 auto Base = JSONCompilationDatabase::loadFromFile(
 JSONDatabasePath, ErrorMessage, JSONCommandLineSyntax::AutoDetect);
-return Base ? inferTargetAndDriverMode(
-  inferMissingCompileCommands(std::move(Base)))
+return Base ? inferTargetAndDriverMode(inferMissingCompileCommands(
+  expandResponseFiles(std::move(Base
 : nullptr;
   }
 };
Index: clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
===
--- /dev/null
+++ clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
@@ -0,0 +1,192 @@
+//===- ExpandResponseFileCompilationDataBase.cpp --===//
+//
+// 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
+//
+//===--===//
+
+#include "clang/Tooling/CompilationDatabase.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/ErrorOr.h"
+#include 

[Diffusion] rG825235c140e7: Revert "[Sema] Use the canonical type in function isVector"

2019-11-23 Thread Sjoerd Meijer via Phabricator via cfe-commits
SjoerdMeijer added a comment.

I don't think I have full context of the problem but in this diff I see 
type `__fp16`, which is the storage-only type. But if we are talking about 
v8.2-A and FP16, then we are talking about the native type (e.g. 
source-language type `_Float16`), and for that you need to enable the `+fp16` 
architecture extension.  I would have to refresh my memory, but I thought 
`-fnative-half-type` was used to enable OpenCL fp16 types? Either way, it looks 
like there's interaction between `__fp16` and native FP16 types, but I don't 
think adding `-fnative-half-type` is the right approach. But as I said, I don't 
know exactly what the problem is, and would need to have a proper look when I'm 
back at my desk.


BRANCHES
  master

Users:
  ahatanak (Author)

https://reviews.llvm.org/rG825235c140e7



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


[PATCH] D69628: [Clang] Pragma vectorize_width() implies vectorize(enable), take 3

2019-11-23 Thread Sjoerd Meijer via Phabricator via cfe-commits
SjoerdMeijer marked an inline comment as done.
SjoerdMeijer added inline comments.



Comment at: clang/lib/CodeGen/CGLoopInfo.cpp:302-306
+// Imply vectorize.enable when it is not already disabled/enabled.
+Args.push_back(
+MDNode::get(Ctx, {MDString::get(Ctx, "llvm.loop.vectorize.enable"),
+  ConstantAsMetadata::get(ConstantInt::get(
+  llvm::Type::getInt1Ty(Ctx), 1))}));

Meinersbur wrote:
> SjoerdMeijer wrote:
> > Meinersbur wrote:
> > > [serious] Why not reusing the `Args.push_back` code from above? I think 
> > > it is important `vectorize_predicate` and `vectorize_width` (and ever 
> > > additional property we introduce in the future) the same way. IMHO 
> > > everything else becomes more and more confusing.
> > > I have the following in mind:
> > > 
> > > ```
> > > if (Attrs.VectorizeEnable != LoopAttributes::Unspecified ||
> > >   IsVectorPredicateEnabled || Attrs.VectorizeWidth > 1) {
> > > auto AttrVal = Attrs.VectorizeEnable != LoopAttributes::Disable;
> > > Args.push_back(..., ConstantInt::get(AttrVal));
> > > }
> > > ```
> > > 
> > No worries, and thanks for looking again! I was a bit reluctant to touch 
> > that piece of logic (and actually thought this if-elseif was not too bad 
> > and explicit in identifying the different cases), but yeah, what you 
> > suggest make sense, so will address this soon.
> Sounds like a typical case of "[[ 
> https://en.wikipedia.org/wiki/Technical_debt | technical debt ]]".
yep, but it's been addressed


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

https://reviews.llvm.org/D69628



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


[PATCH] D70222: [clangd] Add support for .rsp files in compile_commands.json

2019-11-23 Thread liu hui via Phabricator via cfe-commits
lh123 updated this revision to Diff 230752.
lh123 added a comment.
Herald added a subscriber: mgorny.

Address comment


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

https://reviews.llvm.org/D70222

Files:
  clang/include/clang/Tooling/CompilationDatabase.h
  clang/lib/Tooling/CMakeLists.txt
  clang/lib/Tooling/CompilationDatabase.cpp
  clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
  clang/lib/Tooling/JSONCompilationDatabase.cpp
  clang/unittests/Tooling/CompilationDatabaseTest.cpp

Index: clang/unittests/Tooling/CompilationDatabaseTest.cpp
===
--- clang/unittests/Tooling/CompilationDatabaseTest.cpp
+++ clang/unittests/Tooling/CompilationDatabaseTest.cpp
@@ -17,6 +17,7 @@
 #include "llvm/Support/TargetSelect.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
+#include 
 
 namespace clang {
 namespace tooling {
@@ -859,5 +860,76 @@
 "clang++ --driver-mode=g++ bar.cpp -D bar.cpp");
 }
 
+class ExpandResponseFilesTest : public MemDBTest {
+protected:
+  void SetUp() override {
+InnerDir = path(StringRef("inner"));
+std::error_code EC = llvm::sys::fs::create_directory(InnerDir);
+EXPECT_TRUE(!EC);
+
+llvm::sys::path::append(RspFileName1, InnerDir, "rsp1.rsp");
+std::ofstream RspFile1(RspFileName1.c_str());
+RspFile1 << "-Dflag1";
+RspFile1.close();
+
+RspFileName2 = path(StringRef("rsp2.rsp"));
+std::ofstream RspFile2(RspFileName2.c_str());
+RspFile2 << "-Dflag2 @rsp3.rsp";
+RspFile2.close();
+
+RspFileName3 = path(StringRef("rsp3.rsp"));
+std::ofstream RspFile3(RspFileName3.c_str());
+RspFile3 << "-Dflag3";
+RspFile3.close();
+
+RspFileName4 = path(StringRef("rsp4.rsp"));
+std::ofstream  RspFile4(RspFileName4.c_str());
+RspFile4 << "-Dflag4 @rsp4.rsp";
+RspFile4.close();
+
+llvm::sys::path::append(RspFileName5, InnerDir, "rsp5.rsp");
+std::ofstream RspFile5(RspFileName5.c_str());
+RspFile5 << "-Dflag5 @inner/rsp1.rsp";
+RspFile5.close();
+  }
+
+  void TearDown() override {
+llvm::sys::fs::remove(RspFileName5);
+llvm::sys::fs::remove(RspFileName4);
+llvm::sys::fs::remove(RspFileName3);
+llvm::sys::fs::remove(RspFileName2);
+llvm::sys::fs::remove(RspFileName1);
+llvm::sys::fs::remove(InnerDir);
+  }
+
+  std::string getCommand(llvm::StringRef F) {
+auto Results = expandResponseFiles(std::make_unique(Entries))
+   ->getCompileCommands(path(F));
+if (Results.empty()) {
+  return "none";
+}
+return llvm::join(Results[0].CommandLine, " ");
+  }
+
+  SmallString<128> InnerDir;
+  SmallString<128> RspFileName1;
+  SmallString<128> RspFileName2;
+  SmallString<128> RspFileName3;
+  SmallString<128> RspFileName4;
+  SmallString<128> RspFileName5;
+};
+
+TEST_F(ExpandResponseFilesTest, ExpandResponseFiles) {
+  // clang-format off
+  add("foo.cpp", "clang",
+  ("@inner/rsp1.rsp @rsp2.rsp @rsp4.rsp "
+"@" + RspFileName1 + " @inner/rsp5.rsp @rsp6.rsp")
+  .str());
+  // clang-format on
+  EXPECT_THAT(getCommand("foo.cpp"), "clang foo.cpp -D foo.cpp -Dflag1 -Dflag2 "
+ "-Dflag3 -Dflag4 @rsp4.rsp -Dflag1 "
+ "-Dflag5 -Dflag1 @rsp6.rsp");
+}
+
 } // end namespace tooling
 } // end namespace clang
Index: clang/lib/Tooling/JSONCompilationDatabase.cpp
===
--- clang/lib/Tooling/JSONCompilationDatabase.cpp
+++ clang/lib/Tooling/JSONCompilationDatabase.cpp
@@ -167,8 +167,8 @@
 llvm::sys::path::append(JSONDatabasePath, "compile_commands.json");
 auto Base = JSONCompilationDatabase::loadFromFile(
 JSONDatabasePath, ErrorMessage, JSONCommandLineSyntax::AutoDetect);
-return Base ? inferTargetAndDriverMode(
-  inferMissingCompileCommands(std::move(Base)))
+return Base ? expandResponseFiles(inferTargetAndDriverMode(
+  inferMissingCompileCommands(std::move(Base
 : nullptr;
   }
 };
Index: clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
===
--- /dev/null
+++ clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
@@ -0,0 +1,192 @@
+//===- ExpandResponseFileCompilationDataBase.cpp --===//
+//
+// 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
+//
+//===--===//
+
+#include "clang/Tooling/CompilationDatabase.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include