r341760 - [Tooling] Improve handling of CL-style options
Author: hamzasood Date: Sun Sep 9 05:06:35 2018 New Revision: 341760 URL: http://llvm.org/viewvc/llvm-project?rev=341760&view=rev Log: [Tooling] Improve handling of CL-style options This patch fixes the handling of clang-cl options in InterpolatingCompilationDatabase. They were previously ignored completely, which led to a lot of bugs: Additional options were being added with the wrong syntax. E.g. a file was specified as C++ by adding -x c++, which causes an error in CL mode. The args were parsed and then rendered, which means that the aliasing information was lost. E.g. /W4 was rendered to -Wall, which in CL mode means -Weverything. CL options were ignored when checking things like -std=, so a lot of logic was being bypassed. Differential Revision: https://reviews.llvm.org/D51321 Modified: cfe/trunk/lib/Tooling/InterpolatingCompilationDatabase.cpp cfe/trunk/unittests/Tooling/CompilationDatabaseTest.cpp Modified: cfe/trunk/lib/Tooling/InterpolatingCompilationDatabase.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/InterpolatingCompilationDatabase.cpp?rev=341760&r1=341759&r2=341760&view=diff == --- cfe/trunk/lib/Tooling/InterpolatingCompilationDatabase.cpp (original) +++ cfe/trunk/lib/Tooling/InterpolatingCompilationDatabase.cpp Sun Sep 9 05:06:35 2018 @@ -48,6 +48,7 @@ #include "clang/Frontend/LangStandard.h" #include "clang/Tooling/CompilationDatabase.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Option/ArgList.h" @@ -127,47 +128,68 @@ struct TransferableCommand { Optional Type; // Standard specified by -std. LangStandard::Kind Std = LangStandard::lang_unspecified; + // Whether the command line is for the cl-compatible driver. + bool ClangCLMode; TransferableCommand(CompileCommand C) - : Cmd(std::move(C)), Type(guessType(Cmd.Filename)) { -std::vector NewArgs = {Cmd.CommandLine.front()}; + : Cmd(std::move(C)), Type(guessType(Cmd.Filename)), +ClangCLMode(checkIsCLMode(Cmd.CommandLine)) { +std::vector OldArgs = std::move(Cmd.CommandLine); +Cmd.CommandLine.clear(); + +// Wrap the old arguments in an InputArgList. +llvm::opt::InputArgList ArgList; +{ + SmallVector TmpArgv; + for (const std::string &S : OldArgs) +TmpArgv.push_back(S.c_str()); + ArgList = {TmpArgv.begin(), TmpArgv.end()}; +} + // Parse the old args in order to strip out and record unwanted flags. +// We parse each argument individually so that we can retain the exact +// spelling of each argument; re-rendering is lossy for aliased flags. +// E.g. in CL mode, /W4 maps to -Wall. auto OptTable = clang::driver::createDriverOptTable(); -std::vector Argv; -for (unsigned I = 1; I < Cmd.CommandLine.size(); ++I) - Argv.push_back(Cmd.CommandLine[I].c_str()); -unsigned MissingI, MissingC; -auto ArgList = OptTable->ParseArgs(Argv, MissingI, MissingC); -for (const auto *Arg : ArgList) { - const auto &option = Arg->getOption(); +Cmd.CommandLine.emplace_back(OldArgs.front()); +for (unsigned Pos = 1; Pos < OldArgs.size();) { + using namespace driver::options; + + const unsigned OldPos = Pos; + std::unique_ptr Arg(OptTable->ParseOneArg( + ArgList, Pos, + /* Include */ClangCLMode ? CoreOption | CLOption : 0, + /* Exclude */ClangCLMode ? 0 : CLOption)); + + if (!Arg) +continue; + + const llvm::opt::Option &Opt = Arg->getOption(); + // Strip input and output files. - if (option.matches(clang::driver::options::OPT_INPUT) || - option.matches(clang::driver::options::OPT_o)) { + if (Opt.matches(OPT_INPUT) || Opt.matches(OPT_o) || + (ClangCLMode && (Opt.matches(OPT__SLASH_Fa) || + Opt.matches(OPT__SLASH_Fe) || + Opt.matches(OPT__SLASH_Fi) || + Opt.matches(OPT__SLASH_Fo continue; - } + // Strip -x, but record the overridden language. - if (option.matches(clang::driver::options::OPT_x)) { -for (const char *Value : Arg->getValues()) - Type = types::lookupTypeForTypeSpecifier(Value); + if (const auto GivenType = tryParseTypeArg(*Arg)) { +Type = *GivenType; continue; } - // Strip --std, but record the value. - if (option.matches(clang::driver::options::OPT_std_EQ)) { -for (const char *Value : Arg->getValues()) { - Std = llvm::StringSwitch(Value) -#define LANGSTANDARD(id, name, lang, desc, features) \ - .Case(name, LangStandard::lang_##id) -#define LANGSTANDARD_ALIAS(id, alias) .Case(alias, LangStandard::lang_##id) -#include "clang/Frontend/LangStandards.def" -.Default(Std); -} + +
[PATCH] D51321: [Tooling] Improve handling of CL-style options
This revision was automatically updated to reflect the committed changes. Closed by commit rL341760: [Tooling] Improve handling of CL-style options (authored by hamzasood, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D51321?vs=163098&id=164585#toc Repository: rL LLVM https://reviews.llvm.org/D51321 Files: cfe/trunk/lib/Tooling/InterpolatingCompilationDatabase.cpp cfe/trunk/unittests/Tooling/CompilationDatabaseTest.cpp Index: cfe/trunk/unittests/Tooling/CompilationDatabaseTest.cpp === --- cfe/trunk/unittests/Tooling/CompilationDatabaseTest.cpp +++ cfe/trunk/unittests/Tooling/CompilationDatabaseTest.cpp @@ -648,14 +648,17 @@ protected: // Adds an entry to the underlying compilation database. // A flag is injected: -D , so the command used can be identified. - void add(llvm::StringRef File, llvm::StringRef Flags = "") { -llvm::SmallVector Argv = {"clang", File, "-D", File}; + void add(StringRef File, StringRef Clang, StringRef Flags) { +SmallVector Argv = {Clang, File, "-D", File}; llvm::SplitString(Flags, Argv); -llvm::SmallString<32> Dir; + +SmallString<32> Dir; llvm::sys::path::system_temp_directory(false, Dir); + Entries[path(File)].push_back( {Dir, path(File), {Argv.begin(), Argv.end()}, "foo.o"}); } + void add(StringRef File, StringRef Flags = "") { add(File, "clang", Flags); } // Turn a unix path fragment (foo/bar.h) into a native path (C:\tmp\foo\bar.h) std::string path(llvm::SmallString<32> File) { @@ -739,6 +742,30 @@ EXPECT_EQ(getCommand("foo/bar/baz/shout.C"), "clang -D FOO/BAR/BAZ/SHOUT.cc"); } +TEST_F(InterpolateTest, Aliasing) { + add("foo.cpp", "-faligned-new"); + + // The interpolated command should keep the given flag as written, even though + // the flag is internally represented as an alias. + EXPECT_EQ(getCommand("foo.hpp"), "clang -D foo.cpp -faligned-new"); +} + +TEST_F(InterpolateTest, ClangCL) { + add("foo.cpp", "clang-cl", "/W4"); + + // Language flags should be added with CL syntax. + EXPECT_EQ(getCommand("foo.h"), "clang-cl -D foo.cpp /W4 /TP"); +} + +TEST_F(InterpolateTest, DriverModes) { + add("foo.cpp", "clang-cl", "--driver-mode=gcc"); + add("bar.cpp", "clang", "--driver-mode=cl"); + + // --driver-mode overrides should be respected. + EXPECT_EQ(getCommand("foo.h"), "clang-cl -D foo.cpp --driver-mode=gcc -x c++-header"); + EXPECT_EQ(getCommand("bar.h"), "clang -D bar.cpp --driver-mode=cl /TP"); +} + TEST(CompileCommandTest, EqualityOperator) { CompileCommand CCRef("/foo/bar", "hello.c", {"a", "b"}, "hello.o"); CompileCommand CCTest = CCRef; Index: cfe/trunk/lib/Tooling/InterpolatingCompilationDatabase.cpp === --- cfe/trunk/lib/Tooling/InterpolatingCompilationDatabase.cpp +++ cfe/trunk/lib/Tooling/InterpolatingCompilationDatabase.cpp @@ -48,6 +48,7 @@ #include "clang/Frontend/LangStandard.h" #include "clang/Tooling/CompilationDatabase.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Option/ArgList.h" @@ -127,47 +128,68 @@ Optional Type; // Standard specified by -std. LangStandard::Kind Std = LangStandard::lang_unspecified; + // Whether the command line is for the cl-compatible driver. + bool ClangCLMode; TransferableCommand(CompileCommand C) - : Cmd(std::move(C)), Type(guessType(Cmd.Filename)) { -std::vector NewArgs = {Cmd.CommandLine.front()}; + : Cmd(std::move(C)), Type(guessType(Cmd.Filename)), +ClangCLMode(checkIsCLMode(Cmd.CommandLine)) { +std::vector OldArgs = std::move(Cmd.CommandLine); +Cmd.CommandLine.clear(); + +// Wrap the old arguments in an InputArgList. +llvm::opt::InputArgList ArgList; +{ + SmallVector TmpArgv; + for (const std::string &S : OldArgs) +TmpArgv.push_back(S.c_str()); + ArgList = {TmpArgv.begin(), TmpArgv.end()}; +} + // Parse the old args in order to strip out and record unwanted flags. +// We parse each argument individually so that we can retain the exact +// spelling of each argument; re-rendering is lossy for aliased flags. +// E.g. in CL mode, /W4 maps to -Wall. auto OptTable = clang::driver::createDriverOptTable(); -std::vector Argv; -for (unsigned I = 1; I < Cmd.CommandLine.size(); ++I) - Argv.push_back(Cmd.CommandLine[I].c_str()); -unsigned MissingI, MissingC; -auto ArgList = OptTable->ParseArgs(Argv, MissingI, MissingC); -for (const auto *Arg : ArgList) { - const auto &option = Arg->getOption(); +Cmd.CommandLine.emplace_back(OldArgs.front()); +for (unsigned Pos = 1; Pos < OldArgs.size();) { + using namespace driver::options; + + const unsigned OldPos = Pos; + std::unique_ptr Arg(OptTable->ParseOn
[PATCH] D51321: [Tooling] Improve handling of CL-style options
hamzasood added a comment. Thanks for the help with this. I reverted most of my changes (including the parameterised tests) before committing; I think I implemented all of your suggestions. Repository: rL LLVM https://reviews.llvm.org/D51321 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r341761 - Fix build bots after a mistake in r341760
Author: hamzasood Date: Sun Sep 9 06:12:53 2018 New Revision: 341761 URL: http://llvm.org/viewvc/llvm-project?rev=341761&view=rev Log: Fix build bots after a mistake in r341760 Modified: cfe/trunk/lib/Tooling/InterpolatingCompilationDatabase.cpp Modified: cfe/trunk/lib/Tooling/InterpolatingCompilationDatabase.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/InterpolatingCompilationDatabase.cpp?rev=341761&r1=341760&r2=341761&view=diff == --- cfe/trunk/lib/Tooling/InterpolatingCompilationDatabase.cpp (original) +++ cfe/trunk/lib/Tooling/InterpolatingCompilationDatabase.cpp Sun Sep 9 06:12:53 2018 @@ -188,7 +188,7 @@ struct TransferableCommand { } Cmd.CommandLine.insert(Cmd.CommandLine.end(), - &OldArgs[OldPos], &OldArgs[Pos]); + OldArgs.data() + OldPos, OldArgs.data() + Pos); } if (Std != LangStandard::lang_unspecified) // -std take precedence over -x ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47912: [CMake] Consider LLVM_APPEND_VC_REV when generating SVNVersion.inc
hintonda added a comment. Sorry for the late comment... Are you amending an llvm commit or a clang commit? The reason I ask is that if I amend an llvm commit, I have to update around 78 targets (llvm + clang + libcxx + libcxxabi + libunwind), but if I amend a clang commit, I only have to update 18 targets. Since tools/clang/lib/Basic/SVNVersion.inc only includes revision number and repository for clang and llvm, the contents don't change on 'git commit --amend' of the clang repo. Conversely, include/llvm/Support/VCSRevision.h includes the git hash, so it changes each time 'git commit --amend' is run on the llvm repo. If the clang version is the one causing your problem, perhaps you could add a check to see if the file actually changed before overwriting it. See llvm/include/llvm/Support/CMakeLists.txt for an example of how to do this, i.e., the "undef" case. Repository: rC Clang https://reviews.llvm.org/D47912 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r341763 - [Sema] Make typo correction slightly more efficient
Author: maskray Date: Sun Sep 9 10:20:03 2018 New Revision: 341763 URL: http://llvm.org/viewvc/llvm-project?rev=341763&view=rev Log: [Sema] Make typo correction slightly more efficient edit_distance returns UpperBound+1 if the distance will exceed UpperBound. We can subtract 1 from UpperBound and change >= to > in the if condition. The threshold does not change but edit_distance will have more opportunity to bail out earlier. Modified: cfe/trunk/lib/Sema/SemaLookup.cpp Modified: cfe/trunk/lib/Sema/SemaLookup.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=341763&r1=341762&r2=341763&view=diff == --- cfe/trunk/lib/Sema/SemaLookup.cpp (original) +++ cfe/trunk/lib/Sema/SemaLookup.cpp Sun Sep 9 10:20:03 2018 @@ -3998,9 +3998,9 @@ void TypoCorrectionConsumer::addName(Str // Compute an upper bound on the allowable edit distance, so that the // edit-distance algorithm can short-circuit. - unsigned UpperBound = (TypoStr.size() + 2) / 3 + 1; + unsigned UpperBound = (TypoStr.size() + 2) / 3; unsigned ED = TypoStr.edit_distance(Name, true, UpperBound); - if (ED >= UpperBound) return; + if (ED > UpperBound) return; TypoCorrection TC(&SemaRef.Context.Idents.get(Name), ND, NNS, ED); if (isKeyword) TC.makeKeyword(); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D50619: [clang-tidy] Handle unresolved expressions in ExprMutationAnalyzer
shuaiwang added a comment. Ping :) Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D50619 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D51597: [ASTImporter] Fix import of VarDecl init
a_sidorin added a comment. Hi Gabor, The change looks mostly fine but the difference with ASTReader approach disturbs me a bit. Comment at: lib/AST/ASTImporter.cpp:1441 + To->setInit(ToInit); + if (From->isInitKnownICE()) { +EvaluatedStmt *Eval = To->ensureEvaluatedStmt(); I see that this is only a code move but I realized that ASTReader and ASTImporter handle this case differently. ASTReader code says: ``` if (Val > 1) { // IsInitKnownICE = 1, IsInitNotICE = 2, IsInitICE = 3 EvaluatedStmt *Eval = VD->ensureEvaluatedStmt(); Eval->CheckedICE = true; Eval->IsICE = Val == 3; } ``` but ASTimporter sets these bits only if `isInitKnownICE()` is `true`. This looks strange. Comment at: lib/AST/ASTImporter.cpp:3190 +// The VarDecl in the "From" context has a definition, but in the +// "To" context we already has a definition. +VarDecl *FoundDef = FoundVar->getDefinition(); have (same below) Comment at: unittests/AST/ASTImporterTest.cpp:3312 + ASSERT_NE(FromDWithInit, FromDWithDef); + ASSERT_EQ(FromDWithDef->getPreviousDecl() ,FromDWithInit); + Formatting of comma is broken. Same below. Repository: rC Clang https://reviews.llvm.org/D51597 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D51299: [python bindings] Expose template argument API for Type
kjteske added a comment. Thanks for the review @jbcoe , could you commit this for me? Repository: rC Clang https://reviews.llvm.org/D51299 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D51628: [clangd] Implement a Proof-of-Concept tool for symbol index exploration
kbobyrev added inline comments. Comment at: clang-tools-extra/clangd/dexplorer/Dexplorer.cpp:39 + +// FIXME(kbobyrev): Make this an actual REPL: probably use LLVM Command Line +// library for parsing flags and arguments. ilya-biryukov wrote: > Maybe we could expose `CommandLineParser` from > `llvm/lib/Support/CommandLine.cpp` as a public API and use it here? > Not sure if there are any obstacles to doing so or how much work is it, > though. > E.g. `cl::opt` seem to rely on being registered in the global parser and I'm > not sure if there's an easy way out of it. Yes, that might be tricky. I have thought about a few options, e.g. consuming the first token from the input string as the command and dispatching arguments parsed via `CommandLineParser` manually (discarding those which are not accepted by provided command, etc). There are still few complications: help wouldn't be separate and easily accessible (unless hardcoded, which is suboptimal). Another approach I could think of would be simplifying the interface of each command so that it would be easily parsed: * `> fuzzy-find request.json`: this would require `FuzzyFindRequest` JSON (de)serialization implementation, but that would be useful for the benchmark tool, too * `> lookup-id symbolid` * `> load symbol.yaml`/`swap symbol.yaml` * `> density-hist` * `> tokens-distribution` * `> dense-tokens` * `> sparse-tokens` And also a generic `> help` for the short reference of each command. Out of all these commands, only Fuzzy Find request would benefit a lot from a proper parsing of arguments, having JSON file representation might not be ideal, but it looks OK for the first iteration for me. Fuzzy Find request would presumably be one of the most used commands, though, but then again, we could iterate if that is not really convinient. Comment at: clang-tools-extra/clangd/dexplorer/Dexplorer.cpp:147 + + // FIXME(kbobyrev): Wrap time measurements into something like + // measureTime(Function, Arguments...). ilya-biryukov wrote: > +1 to this FIXME. > > Something like: > ``` > template > auto reportTime(StringRef Name, Func F) -> decltype(F()) { > auto Result = F(); > llvm::outs() << Name << " took " << ... > return Result; > } > ``` > > The code calling this API would be quite readable: > ``` > auto Index = reportTime("Build stage", []() { > return buildStaticIndex(...); > }); > ``` Ah, this looks really clean! I had few ideas of how to do that, but I couldn't converge to a reasonable solution which wouldn't look like abusing C++ to me :) Thanks! https://reviews.llvm.org/D51628 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D51297: [docs] Create a guide for Vim users on how to setup Clangd
kbobyrev added a comment. In https://reviews.llvm.org/D51297#1225546, @ilya-biryukov wrote: > I would stamp this from my side, but concerns whether we should recommend > YCM's LSP-based completer instead are probably still there. > @sammccall, WDYT? Yes, I can see your point, but I think this is better than nothing (which we currently have). Also, having the guide in LanguageClient-neovim Wiki might be easier for the users since they can change something (e.g. when the plugin is updated and the docs become outdated) and have an easier time finding out about the option. Would love to hear some feedback from @ioeric and @sammccall. https://reviews.llvm.org/D51297 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D51299: [python bindings] Expose template argument API for Type
jbcoe added a comment. I can commit this. Thanks for the great work! Repository: rC Clang https://reviews.llvm.org/D51299 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r341766 - [OpenMP] Add support for nested 'declare target' directives
Author: kli Date: Sun Sep 9 19:07:09 2018 New Revision: 341766 URL: http://llvm.org/viewvc/llvm-project?rev=341766&view=rev Log: [OpenMP] Add support for nested 'declare target' directives Add the capability to nest multiple declare target directives - including header files within a declare target region. Differential Revision: https://reviews.llvm.org/D51378 Patch by Patrick Lyster Added: cfe/trunk/test/OpenMP/Inputs/ cfe/trunk/test/OpenMP/Inputs/declare_target_include.h Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Parse/ParseOpenMP.cpp cfe/trunk/lib/Sema/SemaOpenMP.cpp cfe/trunk/test/OpenMP/declare_target_ast_print.cpp cfe/trunk/test/OpenMP/declare_target_messages.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=341766&r1=341765&r2=341766&view=diff == --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun Sep 9 19:07:09 2018 @@ -8783,8 +8783,6 @@ def warn_omp_linear_step_zero : Warning< def warn_omp_alignment_not_power_of_two : Warning< "aligned clause will be ignored because the requested alignment is not a power of 2">, InGroup; -def err_omp_enclosed_declare_target : Error< - "declare target region may not be enclosed within another declare target region">; def err_omp_invalid_target_decl : Error< "%0 used in declare target directive is not a variable or a function name">; def err_omp_declare_target_multiple : Error< Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=341766&r1=341765&r2=341766&view=diff == --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Sun Sep 9 19:07:09 2018 @@ -8601,8 +8601,8 @@ public: // private: void *VarDataSharingAttributesStack; - /// Set to true inside '#pragma omp declare target' region. - bool IsInOpenMPDeclareTargetContext = false; + /// Number of nested '#pragma omp declare target' directives. + unsigned DeclareTargetNestingLevel = 0; /// Initialization of data-sharing attributes stack. void InitDataSharingAttributesStack(); void DestroyDataSharingAttributesStack(); @@ -8736,7 +8736,7 @@ public: SourceLocation IdLoc = SourceLocation()); /// Return true inside OpenMP declare target region. bool isInOpenMPDeclareTargetContext() const { -return IsInOpenMPDeclareTargetContext; +return DeclareTargetNestingLevel > 0; } /// Return true inside OpenMP target region. bool isInOpenMPTargetExecutionDirective() const; Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=341766&r1=341765&r2=341766&view=diff == --- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original) +++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Sun Sep 9 19:07:09 2018 @@ -775,8 +775,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpen llvm::SmallVector Decls; DKind = parseOpenMPDirectiveKind(*this); -while (DKind != OMPD_end_declare_target && DKind != OMPD_declare_target && - Tok.isNot(tok::eof) && Tok.isNot(tok::r_brace)) { +while (DKind != OMPD_end_declare_target && Tok.isNot(tok::eof) && + Tok.isNot(tok::r_brace)) { DeclGroupPtrTy Ptr; // Here we expect to see some function declaration. if (AS == AS_none) { Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=341766&r1=341765&r2=341766&view=diff == --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original) +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Sun Sep 9 19:07:09 2018 @@ -12960,19 +12960,14 @@ bool Sema::ActOnStartOpenMPDeclareTarget Diag(Loc, diag::err_omp_region_not_file_context); return false; } - if (IsInOpenMPDeclareTargetContext) { -Diag(Loc, diag::err_omp_enclosed_declare_target); -return false; - } - - IsInOpenMPDeclareTargetContext = true; + ++DeclareTargetNestingLevel; return true; } void Sema::ActOnFinishOpenMPDeclareTargetDirective() { - assert(IsInOpenMPDeclareTargetContext && + assert(DeclareTargetNestingLevel > 0 && "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); - IsInOpenMPDeclareTargetContext = false; + --DeclareTargetNestingLevel; } void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, Added: cfe/trunk/test/OpenMP/Inputs/declare_target_include.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/O
[PATCH] D51378: [OPENMP] Add support for nested 'declare target' directives
This revision was automatically updated to reflect the committed changes. Closed by commit rC341766: [OpenMP] Add support for nested 'declare target' directives (authored by kli, committed by ). Changed prior to commit: https://reviews.llvm.org/D51378?vs=164037&id=164596#toc Repository: rC Clang https://reviews.llvm.org/D51378 Files: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/Sema.h lib/Parse/ParseOpenMP.cpp lib/Sema/SemaOpenMP.cpp test/OpenMP/Inputs/declare_target_include.h test/OpenMP/declare_target_ast_print.cpp test/OpenMP/declare_target_messages.cpp Index: include/clang/Sema/Sema.h === --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -8601,8 +8601,8 @@ // private: void *VarDataSharingAttributesStack; - /// Set to true inside '#pragma omp declare target' region. - bool IsInOpenMPDeclareTargetContext = false; + /// Number of nested '#pragma omp declare target' directives. + unsigned DeclareTargetNestingLevel = 0; /// Initialization of data-sharing attributes stack. void InitDataSharingAttributesStack(); void DestroyDataSharingAttributesStack(); @@ -8736,7 +8736,7 @@ SourceLocation IdLoc = SourceLocation()); /// Return true inside OpenMP declare target region. bool isInOpenMPDeclareTargetContext() const { -return IsInOpenMPDeclareTargetContext; +return DeclareTargetNestingLevel > 0; } /// Return true inside OpenMP target region. bool isInOpenMPTargetExecutionDirective() const; Index: include/clang/Basic/DiagnosticSemaKinds.td === --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -8783,8 +8783,6 @@ def warn_omp_alignment_not_power_of_two : Warning< "aligned clause will be ignored because the requested alignment is not a power of 2">, InGroup; -def err_omp_enclosed_declare_target : Error< - "declare target region may not be enclosed within another declare target region">; def err_omp_invalid_target_decl : Error< "%0 used in declare target directive is not a variable or a function name">; def err_omp_declare_target_multiple : Error< Index: test/OpenMP/Inputs/declare_target_include.h === --- test/OpenMP/Inputs/declare_target_include.h +++ test/OpenMP/Inputs/declare_target_include.h @@ -0,0 +1,3 @@ +#pragma omp declare target + void zyx(); +#pragma omp end declare target Index: test/OpenMP/declare_target_messages.cpp === --- test/OpenMP/declare_target_messages.cpp +++ test/OpenMP/declare_target_messages.cpp @@ -59,8 +59,19 @@ } } +#pragma omp declare target + void abc(); +#pragma omp end declare target +void cba(); +#pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}} -#pragma omp declare target // expected-note {{to match this '#pragma omp declare target'}} +#pragma omp declare target + #pragma omp declare target +void def(); + #pragma omp end declare target + void fed(); + +#pragma omp declare target #pragma omp threadprivate(a) // expected-note {{defined as threadprivate or thread local}} extern int b; int g; @@ -100,9 +111,12 @@ f(); c(); } -#pragma omp declare target // expected-error {{expected '#pragma omp end declare target'}} +#pragma omp declare target void foo1() {} #pragma omp end declare target + +#pragma omp end declare target +#pragma omp end declare target #pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}} int C::method() { Index: test/OpenMP/declare_target_ast_print.cpp === --- test/OpenMP/declare_target_ast_print.cpp +++ test/OpenMP/declare_target_ast_print.cpp @@ -1,10 +1,10 @@ -// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s - -// RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s -// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -I %S/Inputs -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -I %S/Inputs -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -I %S/Inputs -verify %s -ast-print | FileCheck %s + +// RUN: %clang_cc1 -verify -fopenmp-simd -I %S/Inputs -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -I %S/Inputs -emit-pch -o %t %s +// RUN: %clang_cc1 -fopen
r341775 - Part of PR33222: defer enforcing return type mismatch for dependent
Author: rsmith Date: Sun Sep 9 22:32:13 2018 New Revision: 341775 URL: http://llvm.org/viewvc/llvm-project?rev=341775&view=rev Log: Part of PR33222: defer enforcing return type mismatch for dependent friend function declarations of class templates. Modified: cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/test/SemaCXX/friend.cpp Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=341775&r1=341774&r2=341775&view=diff == --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Sun Sep 9 22:32:13 2018 @@ -1956,6 +1956,8 @@ public: FunctionDecl *NewFD, LookupResult &Previous, bool IsMemberSpecialization); bool shouldLinkDependentDeclWithPrevious(Decl *D, Decl *OldDecl); + bool canFullyTypeCheckRedeclaration(ValueDecl *NewD, ValueDecl *OldD, + QualType NewT, QualType OldT); void CheckMain(FunctionDecl *FD, const DeclSpec &D); void CheckMSVCRTEntryPoint(FunctionDecl *FD); Attr *getImplicitCodeSegOrSectionAttrForFunction(const FunctionDecl *FD, bool IsDefinition); Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=341775&r1=341774&r2=341775&view=diff == --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Sun Sep 9 22:32:13 2018 @@ -3254,8 +3254,8 @@ bool Sema::MergeFunctionDecl(FunctionDec ? New->getTypeSourceInfo()->getType()->castAs() : NewType)->getReturnType(); if (!Context.hasSameType(OldDeclaredReturnType, NewDeclaredReturnType) && -!((NewQType->isDependentType() || OldQType->isDependentType()) && - New->isLocalExternDecl())) { +canFullyTypeCheckRedeclaration(New, Old, NewDeclaredReturnType, + OldDeclaredReturnType)) { QualType ResQT; if (NewDeclaredReturnType->isObjCObjectPointerType() && OldDeclaredReturnType->isObjCObjectPointerType()) @@ -3423,13 +3423,11 @@ bool Sema::MergeFunctionDecl(FunctionDec if (OldQTypeForComparison == NewQType) return MergeCompatibleFunctionDecls(New, Old, S, MergeTypeWithOld); -if ((NewQType->isDependentType() || OldQType->isDependentType()) && -New->isLocalExternDecl()) { - // It's OK if we couldn't merge types for a local function declaraton - // if either the old or new type is dependent. We'll merge the types - // when we instantiate the function. +// If the types are imprecise (due to dependent constructs in friends or +// local extern declarations), it's OK if they differ. We'll check again +// during instantiation. +if (!canFullyTypeCheckRedeclaration(New, Old, NewQType, OldQType)) return false; -} // Fall through for conflicting redeclarations and redefinitions. } @@ -9300,6 +9298,39 @@ Attr *Sema::getImplicitCodeSegOrSectionA } return nullptr; } + +/// Determines if we can perform a correct type check for \p D as a +/// redeclaration of \p PrevDecl. If not, we can generally still perform a +/// best-effort check. +/// +/// \param NewD The new declaration. +/// \param OldD The old declaration. +/// \param NewT The portion of the type of the new declaration to check. +/// \param OldT The portion of the type of the old declaration to check. +bool Sema::canFullyTypeCheckRedeclaration(ValueDecl *NewD, ValueDecl *OldD, + QualType NewT, QualType OldT) { + if (!NewD->getLexicalDeclContext()->isDependentContext()) +return true; + + // For dependently-typed local extern declarations and friends, we can't + // perform a correct type check in general until instantiation: + // + // int f(); + // template void g() { T f(); } + // + // (valid if g() is only instantiated with T = int). + if (NewT->isDependentType() && + (NewD->isLocalExternDecl() || NewD->getFriendObjectKind())) +return false; + + // Similarly, if the previous declaration was a dependent local extern + // declaration, we don't really know its type yet. + if (OldT->isDependentType() && OldD->isLocalExternDecl()) +return false; + + return true; +} + /// Checks if the new declaration declared in dependent context must be /// put in the same redeclaration chain as the specified declaration. /// @@ -9310,20 +9341,30 @@ Attr *Sema::getImplicitCodeSegOrSectionA /// belongs to. /// bool Sema::shouldLinkDependentDeclWithPrevious(Decl *D, Decl *PrevDecl) { - // Any declarations should be put into redeclaration chains except for - // friend declaration in a dependent context that names a function in - // namespace sc
r341778 - PR33222: Require the declared return type not the actual return type to
Author: rsmith Date: Sun Sep 9 23:35:32 2018 New Revision: 341778 URL: http://llvm.org/viewvc/llvm-project?rev=341778&view=rev Log: PR33222: Require the declared return type not the actual return type to match when checking for redeclaration of a function template. This properly handles differences in deduced return types, particularly when performing redeclaration checks for a friend function template. Modified: cfe/trunk/include/clang/AST/Decl.h cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/lib/Sema/SemaOverload.cpp cfe/trunk/lib/Sema/SemaTemplate.cpp cfe/trunk/test/SemaCXX/cxx1y-deduced-return-type.cpp Modified: cfe/trunk/include/clang/AST/Decl.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=341778&r1=341777&r2=341778&view=diff == --- cfe/trunk/include/clang/AST/Decl.h (original) +++ cfe/trunk/include/clang/AST/Decl.h Sun Sep 9 23:35:32 2018 @@ -2269,8 +2269,7 @@ public: unsigned getMinRequiredArguments() const; QualType getReturnType() const { -assert(getType()->getAs() && "Expected a FunctionType!"); -return getType()->getAs()->getReturnType(); +return getType()->castAs()->getReturnType(); } /// Attempt to compute an informative source range covering the @@ -2278,14 +2277,22 @@ public: /// limited representation in the AST. SourceRange getReturnTypeSourceRange() const; + /// Get the declared return type, which may differ from the actual return + /// type if the return type is deduced. + QualType getDeclaredReturnType() const { +auto *TSI = getTypeSourceInfo(); +QualType T = TSI ? TSI->getType() : getType(); +return T->castAs()->getReturnType(); + } + /// Attempt to compute an informative source range covering the /// function exception specification, if any. SourceRange getExceptionSpecSourceRange() const; /// Determine the type of an expression that calls this function. QualType getCallResultType() const { -assert(getType()->getAs() && "Expected a FunctionType!"); -return getType()->getAs()->getCallResultType(getASTContext()); +return getType()->castAs()->getCallResultType( +getASTContext()); } /// Returns the WarnUnusedResultAttr that is either declared on this Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=341778&r1=341777&r2=341778&view=diff == --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Sun Sep 9 23:35:32 2018 @@ -3245,20 +3245,15 @@ bool Sema::MergeFunctionDecl(FunctionDec // Redeclarations or specializations of a function or function template // with a declared return type that uses a placeholder type shall also // use that placeholder, not a deduced type. -QualType OldDeclaredReturnType = -(Old->getTypeSourceInfo() - ? Old->getTypeSourceInfo()->getType()->castAs() - : OldType)->getReturnType(); -QualType NewDeclaredReturnType = -(New->getTypeSourceInfo() - ? New->getTypeSourceInfo()->getType()->castAs() - : NewType)->getReturnType(); +QualType OldDeclaredReturnType = Old->getDeclaredReturnType(); +QualType NewDeclaredReturnType = New->getDeclaredReturnType(); if (!Context.hasSameType(OldDeclaredReturnType, NewDeclaredReturnType) && canFullyTypeCheckRedeclaration(New, Old, NewDeclaredReturnType, OldDeclaredReturnType)) { QualType ResQT; if (NewDeclaredReturnType->isObjCObjectPointerType() && OldDeclaredReturnType->isObjCObjectPointerType()) +// FIXME: This does the wrong thing for a deduced return type. ResQT = Context.mergeObjCGCQualifiers(NewQType, OldQType); if (ResQT.isNull()) { if (New->isCXXClassMember() && New->isOutOfLine()) Modified: cfe/trunk/lib/Sema/SemaOverload.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=341778&r1=341777&r2=341778&view=diff == --- cfe/trunk/lib/Sema/SemaOverload.cpp (original) +++ cfe/trunk/lib/Sema/SemaOverload.cpp Sun Sep 9 23:35:32 2018 @@ -1105,7 +1105,8 @@ bool Sema::IsOverload(FunctionDecl *New, (!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(), OldTemplate->getTemplateParameters(), false, TPL_TemplateMatch) || - OldType->getReturnType() != NewType->getReturnType())) + !Context.hasSameType(Old->getDeclaredReturnType(), +New->getDeclaredReturnType( return true; // If the function is a class member, its signature includes the Modified: cfe/trunk/lib/Sema/SemaTemp