Skip to content

Commit

Permalink
Merged master:3035e676a388 into amd-gfx:242c915a4920
Browse files Browse the repository at this point in the history
Local branch amd-gfx 242c915 Reintroduce "[AMDGPU][CostModel] Refine cost model for half- and quarter-rate instructions."
Remote branch master 3035e67 [mlir][spirv] Add VectorInsertDynamicOp and vector.insertelement lowering
  • Loading branch information
Sw authored and Sw committed Nov 10, 2020
2 parents 242c915 + 3035e67 commit 7ee1df4
Show file tree
Hide file tree
Showing 26 changed files with 358 additions and 55 deletions.
87 changes: 84 additions & 3 deletions clang-tools-extra/clangd/refactor/Rename.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,86 @@ std::vector<SourceLocation> findOccurrencesWithinFile(ParsedAST &AST,
return Results;
}

// Lookup the declarations (if any) with the given Name in the context of
// RenameDecl.
NamedDecl *lookupSiblingWithName(const ASTContext &Ctx,
const NamedDecl &RenamedDecl,
llvm::StringRef Name) {
const auto &II = Ctx.Idents.get(Name);
DeclarationName LookupName(&II);
DeclContextLookupResult LookupResult;
const auto *DC = RenamedDecl.getDeclContext();
while (DC && DC->isTransparentContext())
DC = DC->getParent();
switch (DC->getDeclKind()) {
// The enclosing DeclContext may not be the enclosing scope, it might have
// false positives and negatives, so we only choose "confident" DeclContexts
// that don't have any subscopes that are neither DeclContexts nor
// transparent.
//
// Notably, FunctionDecl is excluded -- because local variables are not scoped
// to the function, but rather to the CompoundStmt that is its body. Lookup
// will not find function-local variables.
case Decl::TranslationUnit:
case Decl::Namespace:
case Decl::Record:
case Decl::Enum:
case Decl::CXXRecord:
LookupResult = DC->lookup(LookupName);
break;
default:
break;
}
// Lookup may contain the RenameDecl itself, exclude it.
auto It = llvm::find_if(LookupResult, [&RenamedDecl](const NamedDecl *D) {
return D->getCanonicalDecl() != RenamedDecl.getCanonicalDecl();
});
if (It != LookupResult.end())
return *It;
return nullptr;
}

struct InvalidName {
enum Kind {
Keywords,
Conflict,
};
Kind K;
std::string Details;
};

llvm::Error makeError(InvalidName Reason) {
auto Message = [](InvalidName Reason) {
switch (Reason.K) {
case InvalidName::Keywords:
return llvm::formatv("the chosen name \"{0}\" is a keyword",
Reason.Details);
case InvalidName::Conflict:
return llvm::formatv("conflict with the symbol in {0}", Reason.Details);
}
llvm_unreachable("unhandled InvalidName kind");
};
return error("invalid name: {0}", Message(Reason));
}

// Check if we can rename the given RenameDecl into NewName.
// Return details if the rename would produce a conflict.
llvm::Optional<InvalidName> checkName(const NamedDecl &RenameDecl,
llvm::StringRef NewName) {
auto &ASTCtx = RenameDecl.getASTContext();
if (isKeyword(NewName, ASTCtx.getLangOpts()))
return InvalidName{InvalidName::Keywords, NewName.str()};
// Name conflict detection.
// Function conflicts are subtle (overloading), so ignore them.
if (RenameDecl.getKind() != Decl::Function) {
if (auto *Conflict = lookupSiblingWithName(ASTCtx, RenameDecl, NewName))
return InvalidName{
InvalidName::Conflict,
Conflict->getLocation().printToString(ASTCtx.getSourceManager())};
}
return llvm::None;
}

// AST-based rename, it renames all occurrences in the main file.
llvm::Expected<tooling::Replacements>
renameWithinFile(ParsedAST &AST, const NamedDecl &RenameDecl,
Expand Down Expand Up @@ -476,11 +556,12 @@ llvm::Expected<RenameResult> rename(const RenameInputs &RInputs) {
return makeError(ReasonToReject::NoSymbolFound);
if (DeclsUnderCursor.size() > 1)
return makeError(ReasonToReject::AmbiguousSymbol);
if (isKeyword(RInputs.NewName, AST.getLangOpts()))
return makeError(ReasonToReject::RenameToKeywords);

const auto &RenameDecl =
llvm::cast<NamedDecl>(*(*DeclsUnderCursor.begin())->getCanonicalDecl());
auto Invalid = checkName(RenameDecl, RInputs.NewName);
if (Invalid)
return makeError(*Invalid);

auto Reject = renameable(RenameDecl, RInputs.MainFilePath, RInputs.Index,
Opts.AllowCrossFile);
if (Reject)
Expand Down
46 changes: 46 additions & 0 deletions clang-tools-extra/clangd/unittests/RenameTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,52 @@ TEST(RenameTest, Renameable) {
class Foo {};
)cpp",
"no symbol", !HeaderFile, nullptr},

{R"cpp(
namespace {
int Conflict;
int Va^r;
}
)cpp",
"conflict", !HeaderFile, nullptr, "Conflict"},

{R"cpp(
int Conflict;
int Va^r;
)cpp",
"conflict", !HeaderFile, nullptr, "Conflict"},

{R"cpp(
class Foo {
int Conflict;
int Va^r;
};
)cpp",
"conflict", !HeaderFile, nullptr, "Conflict"},

{R"cpp(
enum E {
Conflict,
Fo^o,
};
)cpp",
"conflict", !HeaderFile, nullptr, "Conflict"},

{R"cpp(
int Conflict;
enum E { // transparent context.
F^oo,
};
)cpp",
"conflict", !HeaderFile, nullptr, "Conflict"},

{R"cpp(// FIXME: detecting local variables is not supported yet.
void func() {
int Conflict;
int [[V^ar]];
}
)cpp",
nullptr, !HeaderFile, nullptr, "Conflict"},
};

for (const auto& Case : Cases) {
Expand Down
3 changes: 1 addition & 2 deletions clang/lib/AST/ItaniumMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5085,8 +5085,7 @@ void CXXNameMangler::mangleValueInTemplateArg(QualType T, const APValue &V) {
}

case APValue::Union: {
const CXXRecordDecl *RD = T->getAsCXXRecordDecl();
assert(RD && "unexpected type for union value");
assert(T->getAsCXXRecordDecl() && "unexpected type for union value");
const FieldDecl *FD = V.getUnionField();

if (!FD) {
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Format/FormatToken.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ namespace format {
TYPE(JsTypeColon) \
TYPE(JsTypeOperator) \
TYPE(JsTypeOptionalQuestion) \
TYPE(JsAndAndEqual) \
TYPE(JsPipePipeEqual) \
TYPE(JsNullishCoalescingEqual) \
TYPE(LambdaArrow) \
TYPE(LambdaLBrace) \
TYPE(LambdaLSquare) \
Expand Down
11 changes: 11 additions & 0 deletions clang/lib/Format/FormatTokenLexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ void FormatTokenLexer::tryMergePreviousTokens() {
tok::period};
static const tok::TokenKind JSNullishOperator[] = {tok::question,
tok::question};
static const tok::TokenKind JSNullishEqual[] = {tok::question,
tok::question, tok::equal};
static const tok::TokenKind JSPipePipeEqual[] = {tok::pipepipe, tok::equal};
static const tok::TokenKind JSAndAndEqual[] = {tok::ampamp, tok::equal};

// FIXME: Investigate what token type gives the correct operator priority.
if (tryMergeTokens(JSIdentity, TT_BinaryOperator))
Expand Down Expand Up @@ -148,6 +152,13 @@ void FormatTokenLexer::tryMergePreviousTokens() {
Tokens.back()->Tok.setKind(tok::period);
return;
}
if (tryMergeTokens(JSAndAndEqual, TT_JsAndAndEqual) ||
tryMergeTokens(JSPipePipeEqual, TT_JsPipePipeEqual) ||
tryMergeTokens(JSNullishEqual, TT_JsNullishCoalescingEqual)) {
// Treat like the "=" assignment operator.
Tokens.back()->Tok.setKind(tok::equal);
return;
}
if (tryMergeJSPrivateIdentifier())
return;
}
Expand Down
9 changes: 9 additions & 0 deletions clang/unittests/Format/FormatTestJS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2424,6 +2424,15 @@ TEST_F(FormatTestJS, NullishCoalescingOperator) {
getGoogleJSStyleWithColumns(40));
}

TEST_F(FormatTestJS, AssignmentOperators) {
verifyFormat("a &&= b;\n");
verifyFormat("a ||= b;\n");
// NB: need to split ? ?= to avoid it being interpreted by C++ as a trigraph
// for #.
verifyFormat("a ?"
"?= b;\n");
}

TEST_F(FormatTestJS, Conditional) {
verifyFormat("y = x ? 1 : 2;");
verifyFormat("x ? 1 : 2;");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ TEST_CASE(not_regular_file) {
} TestCases[] = {
{env.create_dir("dir"), std::errc::is_a_directory},
{env.create_fifo("fifo"), std::errc::not_supported},
{env.create_symlink("dir", "sym"), std::errc::is_a_directory}};
{env.create_directory_symlink("dir", "sym"), std::errc::is_a_directory}};

for (auto const& TC : TestCases) {
const path& p = TC.p;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ TEST_CASE(test_PR35078_with_symlink)
env.create_file("dir1/file1"),
env.create_dir("sym_dir"),
env.create_dir("sym_dir/nested_sym_dir"),
env.create_symlink("sym_dir/nested_sym_dir", "dir1/dir2"),
env.create_directory_symlink("sym_dir/nested_sym_dir", "dir1/dir2"),
env.create_dir("sym_dir/dir1"),
env.create_dir("sym_dir/dir1/dir2"),

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ TEST_CASE(test_copy_symlinks_to_symlink_dir)
const path file2 = env.create_file("file2", 101);
const path file2_sym = env.create_symlink(file2, "file2_sym");
const path dir = env.create_dir("dir");
const path dir_sym = env.create_symlink(dir, "dir_sym");
const path dir_sym = env.create_directory_symlink(dir, "dir_sym");
{
std::error_code ec = GetTestEC();
fs::copy(file1, dir_sym, copy_options::copy_symlinks, ec);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ TEST_CASE(copy_symlink_basic)
{
scoped_test_env env;
const path dir = env.create_dir("dir");
const path dir_sym = env.create_symlink(dir, "dir_sym");
const path dir_sym = env.create_directory_symlink(dir, "dir_sym");
const path file = env.create_file("file", 42);
const path file_sym = env.create_symlink(file, "file_sym");
{ // test for directory symlinks
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ TEST_CASE(create_directory_symlinks) {
scoped_test_env env;
const path root = env.create_dir("dir");
const path sym_dest_dead = env.make_env_path("dead");
const path dead_sym = env.create_symlink(sym_dest_dead, "dir/sym_dir");
const path dead_sym = env.create_directory_symlink(sym_dest_dead, "dir/sym_dir");
const path target = env.make_env_path("dir/sym_dir/foo");
{
std::error_code ec = GetTestEC();
Expand All @@ -84,7 +84,7 @@ TEST_CASE(create_directory_symlinks) {
TEST_CASE(create_directory_through_symlinks) {
scoped_test_env env;
const path root = env.create_dir("dir");
const path sym_dir = env.create_symlink(root, "sym_dir");
const path sym_dir = env.create_directory_symlink(root, "sym_dir");
const path target = env.make_env_path("sym_dir/foo");
const path resolved_target = env.make_env_path("dir/foo");
TEST_REQUIRE(is_directory(sym_dir));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ TEST_CASE(create_directory_symlink_basic)
{
scoped_test_env env;
const path dir = env.create_dir("dir");
const path dir_sym = env.create_symlink(dir, "dir_sym");
const path dir_sym = env.create_directory_symlink(dir, "dir_sym");

const path dest = env.make_env_path("dest1");
std::error_code ec;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ TEST_CASE(create_symlink_basic)
const path file = env.create_file("file", 42);
const path file_sym = env.create_symlink(file, "file_sym");
const path dir = env.create_dir("dir");
const path dir_sym = env.create_symlink(dir, "dir_sym");
const path dir_sym = env.create_directory_symlink(dir, "dir_sym");
{
const path dest = env.make_env_path("dest1");
std::error_code ec;
Expand All @@ -64,7 +64,7 @@ TEST_CASE(create_symlink_basic)
{
const path dest = env.make_env_path("dest2");
std::error_code ec;
fs::create_symlink(dir_sym, dest, ec);
fs::create_directory_symlink(dir_sym, dest, ec);
TEST_REQUIRE(!ec);
TEST_CHECK(is_symlink(dest));
TEST_CHECK(equivalent(dest, dir));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ TEST_CASE(basic_symlink_test)
} testCases[] = {
{env.create_symlink(dne, "dne_link"), dne},
{env.create_symlink(file, "file_link"), file},
{env.create_symlink(dir, "dir_link"), dir},
{env.create_directory_symlink(dir, "dir_link"), dir},
{nested_link, link}
};
for (auto& TC : testCases) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ TEST_CASE(symlink_to_dir)
scoped_test_env env;
const path dir = env.create_dir("dir");
const path file = env.create_file(dir / "file", 42);
const path link = env.create_symlink(dir, "sym");
const path link = env.create_directory_symlink(dir, "sym");

{
std::error_code ec = std::make_error_code(std::errc::address_in_use);
Expand All @@ -136,7 +136,7 @@ TEST_CASE(nested_dir)
env.create_file(dir / "file1", 42),
env.create_symlink(out_of_dir_file, dir / "sym1"),
env.create_file(dir1 / "file2", 42),
env.create_symlink(dir, dir1 / "sym2")
env.create_directory_symlink(dir, dir1 / "sym2")
};
const std::size_t expected_count = sizeof(all_files) / sizeof(all_files[0]);

Expand Down
34 changes: 22 additions & 12 deletions libcxx/test/support/filesystem_test_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,8 @@ namespace utils {
using ::ftruncate;
inline int symlink(const char* oldname, const char* newname, bool is_dir) { (void)is_dir; return ::symlink(oldname, newname); }
using ::link;
inline int setenv(const char *var, const char *val, int overwrite) {
return ::setenv(var, val, overwrite);
}
inline int unsetenv(const char *var) {
return ::unsetenv(var);
}
using ::setenv;
using ::unsetenv;
inline bool space(std::string path, std::uintmax_t &capacity,
std::uintmax_t &free, std::uintmax_t &avail) {
struct statvfs expect;
Expand Down Expand Up @@ -226,10 +222,10 @@ struct scoped_test_env
return filename;
}

std::string create_symlink(fs::path source_path,
fs::path to_path,
bool sanitize_source = true,
bool is_dir = false) {
std::string create_file_dir_symlink(fs::path source_path,
fs::path to_path,
bool sanitize_source = true,
bool is_dir = false) {
std::string source = source_path.string();
std::string to = to_path.string();
if (sanitize_source)
Expand All @@ -240,6 +236,20 @@ struct scoped_test_env
return to;
}

std::string create_symlink(fs::path source_path,
fs::path to_path,
bool sanitize_source = true) {
return create_file_dir_symlink(source_path, to_path, sanitize_source,
false);
}

std::string create_directory_symlink(fs::path source_path,
fs::path to_path,
bool sanitize_source = true) {
return create_file_dir_symlink(source_path, to_path, sanitize_source,
true);
}

std::string create_hardlink(fs::path source_path, fs::path to_path) {
std::string source = source_path.string();
std::string to = to_path.string();
Expand Down Expand Up @@ -325,12 +335,12 @@ class static_test_env {
env_.create_dir("dir1/dir2/dir3");
env_.create_file("dir1/dir2/dir3/file5");
env_.create_file("dir1/dir2/file4");
env_.create_symlink("dir3", "dir1/dir2/symlink_to_dir3", false, true);
env_.create_directory_symlink("dir3", "dir1/dir2/symlink_to_dir3", false);
env_.create_file("dir1/file1");
env_.create_file("dir1/file2", 42);
env_.create_file("empty_file");
env_.create_file("non_empty_file", 42);
env_.create_symlink("dir1", "symlink_to_dir", false, true);
env_.create_directory_symlink("dir1", "symlink_to_dir", false);
env_.create_symlink("empty_file", "symlink_to_empty_file", false);
}

Expand Down
Loading

0 comments on commit 7ee1df4

Please sign in to comment.