Compare commits
1 Commits
main
...
users/el-e
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2da6e6536d |
@ -138,12 +138,6 @@
|
|||||||
Dump function CFGs to graphviz format after each stage;enable '-print-loops'
|
Dump function CFGs to graphviz format after each stage;enable '-print-loops'
|
||||||
for color-coded blocks
|
for color-coded blocks
|
||||||
|
|
||||||
- `--dump-dot-func=<func1,func2,func3...>`
|
|
||||||
|
|
||||||
Dump function CFGs to graphviz format for specified functions only;
|
|
||||||
takes function name patterns (regex supported). Note: C++ function names
|
|
||||||
must be passed using their mangled names
|
|
||||||
|
|
||||||
- `--dump-linux-exceptions`
|
- `--dump-linux-exceptions`
|
||||||
|
|
||||||
Dump Linux kernel exception table
|
Dump Linux kernel exception table
|
||||||
|
@ -15,12 +15,6 @@
|
|||||||
|
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
|
|
||||||
namespace llvm {
|
|
||||||
namespace bolt {
|
|
||||||
class BinaryFunction;
|
|
||||||
}
|
|
||||||
} // namespace llvm
|
|
||||||
|
|
||||||
namespace opts {
|
namespace opts {
|
||||||
|
|
||||||
enum HeatmapModeKind {
|
enum HeatmapModeKind {
|
||||||
@ -106,9 +100,6 @@ extern llvm::cl::opt<unsigned> Verbosity;
|
|||||||
/// Return true if we should process all functions in the binary.
|
/// Return true if we should process all functions in the binary.
|
||||||
bool processAllFunctions();
|
bool processAllFunctions();
|
||||||
|
|
||||||
/// Return true if we should dump dot graphs for the given function.
|
|
||||||
bool shouldDumpDot(const llvm::bolt::BinaryFunction &Function);
|
|
||||||
|
|
||||||
enum GadgetScannerKind { GS_PACRET, GS_PAUTH, GS_ALL };
|
enum GadgetScannerKind { GS_PACRET, GS_PAUTH, GS_ALL };
|
||||||
|
|
||||||
extern llvm::cl::bits<GadgetScannerKind> GadgetScannersToRun;
|
extern llvm::cl::bits<GadgetScannerKind> GadgetScannersToRun;
|
||||||
|
@ -52,7 +52,6 @@ namespace opts {
|
|||||||
extern cl::opt<bool> PrintAll;
|
extern cl::opt<bool> PrintAll;
|
||||||
extern cl::opt<bool> PrintDynoStats;
|
extern cl::opt<bool> PrintDynoStats;
|
||||||
extern cl::opt<bool> DumpDotAll;
|
extern cl::opt<bool> DumpDotAll;
|
||||||
extern bool shouldDumpDot(const bolt::BinaryFunction &Function);
|
|
||||||
extern cl::opt<std::string> AsmDump;
|
extern cl::opt<std::string> AsmDump;
|
||||||
extern cl::opt<bolt::PLTCall::OptType> PLT;
|
extern cl::opt<bolt::PLTCall::OptType> PLT;
|
||||||
extern cl::opt<bolt::IdenticalCodeFolding::ICFLevel, false,
|
extern cl::opt<bolt::IdenticalCodeFolding::ICFLevel, false,
|
||||||
@ -341,7 +340,7 @@ Error BinaryFunctionPassManager::runPasses() {
|
|||||||
|
|
||||||
Function.print(BC.outs(), Message);
|
Function.print(BC.outs(), Message);
|
||||||
|
|
||||||
if (opts::shouldDumpDot(Function))
|
if (opts::DumpDotAll)
|
||||||
Function.dumpGraphForPass(PassIdName);
|
Function.dumpGraphForPass(PassIdName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,35 +115,6 @@ cl::opt<bool> DumpDotAll(
|
|||||||
"enable '-print-loops' for color-coded blocks"),
|
"enable '-print-loops' for color-coded blocks"),
|
||||||
cl::Hidden, cl::cat(BoltCategory));
|
cl::Hidden, cl::cat(BoltCategory));
|
||||||
|
|
||||||
cl::list<std::string> DumpDotFunc(
|
|
||||||
"dump-dot-func", cl::CommaSeparated,
|
|
||||||
cl::desc(
|
|
||||||
"dump function CFGs to graphviz format for specified functions only;"
|
|
||||||
"takes function name patterns (regex supported)"),
|
|
||||||
cl::value_desc("func1,func2,func3,..."), cl::Hidden, cl::cat(BoltCategory));
|
|
||||||
|
|
||||||
bool shouldDumpDot(const bolt::BinaryFunction &Function) {
|
|
||||||
// If dump-dot-all is enabled, dump all functions
|
|
||||||
if (DumpDotAll)
|
|
||||||
return !Function.isIgnored();
|
|
||||||
|
|
||||||
// If no specific functions specified in dump-dot-func, don't dump any
|
|
||||||
if (DumpDotFunc.empty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (Function.isIgnored())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check if function matches any of the specified patterns
|
|
||||||
for (const std::string &Name : DumpDotFunc) {
|
|
||||||
if (Function.hasNameRegex(Name)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cl::list<std::string>
|
static cl::list<std::string>
|
||||||
ForceFunctionNames("funcs",
|
ForceFunctionNames("funcs",
|
||||||
cl::CommaSeparated,
|
cl::CommaSeparated,
|
||||||
@ -3598,7 +3569,7 @@ void RewriteInstance::postProcessFunctions() {
|
|||||||
if (opts::PrintAll || opts::PrintCFG)
|
if (opts::PrintAll || opts::PrintCFG)
|
||||||
Function.print(BC->outs(), "after building cfg");
|
Function.print(BC->outs(), "after building cfg");
|
||||||
|
|
||||||
if (opts::shouldDumpDot(Function))
|
if (opts::DumpDotAll)
|
||||||
Function.dumpGraphForPass("00_build-cfg");
|
Function.dumpGraphForPass("00_build-cfg");
|
||||||
|
|
||||||
if (opts::PrintLoopInfo) {
|
if (opts::PrintLoopInfo) {
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
#include <iostream>
|
|
||||||
|
|
||||||
// Multiple functions to test selective dumping
|
|
||||||
int add(int a, int b) { return a + b; }
|
|
||||||
|
|
||||||
int multiply(int a, int b) { return a * b; }
|
|
||||||
|
|
||||||
int main_helper() {
|
|
||||||
std::cout << "Helper function" << std::endl;
|
|
||||||
return 42;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main_secondary() { return add(5, 3); }
|
|
||||||
|
|
||||||
void other_function() { std::cout << "Other function" << std::endl; }
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int result = add(10, 20);
|
|
||||||
result = multiply(result, 2);
|
|
||||||
main_helper();
|
|
||||||
main_secondary();
|
|
||||||
other_function();
|
|
||||||
return result;
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
# Test the --dump-dot-func option with multiple functions
|
|
||||||
# (includes tests for both mangled/unmangled names)
|
|
||||||
|
|
||||||
RUN: %clang++ %p/Inputs/multi-func.cpp -o %t.exe -Wl,-q
|
|
||||||
|
|
||||||
# Test 1: --dump-dot-func with specific function name (mangled)
|
|
||||||
RUN: llvm-bolt %t.exe -o %t.bolt1 --dump-dot-func=_Z3addii -v=1 2>&1 | FileCheck %s --check-prefix=ADD
|
|
||||||
|
|
||||||
# Test 2: --dump-dot-func with regex pattern (main.*)
|
|
||||||
RUN: llvm-bolt %t.exe -o %t.bolt2 --dump-dot-func="main.*" -v=1 2>&1 | FileCheck %s --check-prefix=MAIN-REGEX
|
|
||||||
|
|
||||||
# Test 3: --dump-dot-func with multiple specific functions (mangled names)
|
|
||||||
RUN: llvm-bolt %t.exe -o %t.bolt3 --dump-dot-func=_Z3addii,_Z8multiplyii -v=1 2>&1 | FileCheck %s --check-prefix=MULTI
|
|
||||||
|
|
||||||
# Test 4: No option specified should create no dot files
|
|
||||||
RUN: llvm-bolt %t.exe -o %t.bolt4 2>&1 | FileCheck %s --check-prefix=NONE
|
|
||||||
|
|
||||||
# Test 5: --dump-dot-func with non-existent function
|
|
||||||
RUN: llvm-bolt %t.exe -o %t.bolt5 --dump-dot-func=nonexistent -v=1 2>&1 | FileCheck %s --check-prefix=NONEXISTENT
|
|
||||||
|
|
||||||
# Test 6: Backward compatibility - --dump-dot-all should still work
|
|
||||||
RUN: llvm-bolt %t.exe -o %t.bolt6 --dump-dot-all -v=1 2>&1 | FileCheck %s --check-prefix=ALL
|
|
||||||
|
|
||||||
# Test 7: Test with unmangled function name (main function)
|
|
||||||
RUN: llvm-bolt %t.exe -o %t.bolt7 --dump-dot-func=main -v=1 2>&1 | FileCheck %s --check-prefix=MAIN-UNMANGLED
|
|
||||||
|
|
||||||
# Check that specific functions are dumped
|
|
||||||
ADD: BOLT-INFO: dumping CFG to _Z3addii-00_build-cfg.dot
|
|
||||||
ADD-NOT: BOLT-INFO: dumping CFG to main-00_build-cfg.dot
|
|
||||||
ADD-NOT: BOLT-INFO: dumping CFG to _Z8multiplyii-00_build-cfg.dot
|
|
||||||
ADD-NOT: BOLT-INFO: dumping CFG to _Z11main_helperv-00_build-cfg.dot
|
|
||||||
|
|
||||||
MAIN-REGEX-DAG: BOLT-INFO: dumping CFG to main-00_build-cfg.dot
|
|
||||||
MAIN-REGEX-NOT: BOLT-INFO: dumping CFG to _Z3addii-00_build-cfg.dot
|
|
||||||
MAIN-REGEX-NOT: BOLT-INFO: dumping CFG to _Z8multiplyii-00_build-cfg.dot
|
|
||||||
|
|
||||||
MULTI-DAG: BOLT-INFO: dumping CFG to _Z3addii-00_build-cfg.dot
|
|
||||||
MULTI-DAG: BOLT-INFO: dumping CFG to _Z8multiplyii-00_build-cfg.dot
|
|
||||||
MULTI-NOT: BOLT-INFO: dumping CFG to main-00_build-cfg.dot
|
|
||||||
MULTI-NOT: BOLT-INFO: dumping CFG to _Z11main_helperv-00_build-cfg.dot
|
|
||||||
|
|
||||||
# Should be no dumping messages when no option is specified
|
|
||||||
NONE-NOT: BOLT-INFO: dumping CFG
|
|
||||||
|
|
||||||
# Should be no dumping messages for non-existent function
|
|
||||||
NONEXISTENT-NOT: BOLT-INFO: dumping CFG
|
|
||||||
|
|
||||||
ALL: BOLT-INFO: dumping CFG to main-00_build-cfg.dot
|
|
||||||
|
|
||||||
MAIN-UNMANGLED: BOLT-INFO: dumping CFG to main-00_build-cfg.dot
|
|
||||||
MAIN-UNMANGLED-NOT: BOLT-INFO: dumping CFG to _Z3addii-00_build-cfg.dot
|
|
||||||
MAIN-UNMANGLED-NOT: BOLT-INFO: dumping CFG to _Z8multiplyii-00_build-cfg.dot
|
|
@ -15,12 +15,14 @@ using namespace clang::ast_matchers;
|
|||||||
|
|
||||||
namespace clang::tidy::bugprone {
|
namespace clang::tidy::bugprone {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
// Determine if the result of an expression is "stored" in some way.
|
// Determine if the result of an expression is "stored" in some way.
|
||||||
// It is true if the value is stored into a variable or used as initialization
|
// It is true if the value is stored into a variable or used as initialization
|
||||||
// or passed to a function or constructor.
|
// or passed to a function or constructor.
|
||||||
// For this use case compound assignments are not counted as a "store" (the 'E'
|
// For this use case compound assignments are not counted as a "store" (the 'E'
|
||||||
// expression should have pointer type).
|
// expression should have pointer type).
|
||||||
static bool isExprValueStored(const Expr *E, ASTContext &C) {
|
bool isExprValueStored(const Expr *E, ASTContext &C) {
|
||||||
E = E->IgnoreParenCasts();
|
E = E->IgnoreParenCasts();
|
||||||
// Get first non-paren, non-cast parent.
|
// Get first non-paren, non-cast parent.
|
||||||
ParentMapContext &PMap = C.getParentMapContext();
|
ParentMapContext &PMap = C.getParentMapContext();
|
||||||
@ -47,8 +49,6 @@ static bool isExprValueStored(const Expr *E, ASTContext &C) {
|
|||||||
return isa<CallExpr, CXXConstructExpr>(ParentE);
|
return isa<CallExpr, CXXConstructExpr>(ParentE);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
AST_MATCHER_P(CXXTryStmt, hasHandlerFor,
|
AST_MATCHER_P(CXXTryStmt, hasHandlerFor,
|
||||||
ast_matchers::internal::Matcher<QualType>, InnerMatcher) {
|
ast_matchers::internal::Matcher<QualType>, InnerMatcher) {
|
||||||
for (unsigned NH = Node.getNumHandlers(), I = 0; I < NH; ++I) {
|
for (unsigned NH = Node.getNumHandlers(), I = 0; I < NH; ++I) {
|
||||||
|
@ -14,8 +14,10 @@ using namespace clang::ast_matchers;
|
|||||||
|
|
||||||
namespace clang::tidy::bugprone {
|
namespace clang::tidy::bugprone {
|
||||||
|
|
||||||
static bool isConcatenatedLiteralsOnPurpose(ASTContext *Ctx,
|
namespace {
|
||||||
const StringLiteral *Lit) {
|
|
||||||
|
bool isConcatenatedLiteralsOnPurpose(ASTContext *Ctx,
|
||||||
|
const StringLiteral *Lit) {
|
||||||
// String literals surrounded by parentheses are assumed to be on purpose.
|
// String literals surrounded by parentheses are assumed to be on purpose.
|
||||||
// i.e.: const char* Array[] = { ("a" "b" "c"), "d", [...] };
|
// i.e.: const char* Array[] = { ("a" "b" "c"), "d", [...] };
|
||||||
|
|
||||||
@ -56,8 +58,6 @@ static bool isConcatenatedLiteralsOnPurpose(ASTContext *Ctx,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
AST_MATCHER_P(StringLiteral, isConcatenatedLiteral, unsigned,
|
AST_MATCHER_P(StringLiteral, isConcatenatedLiteral, unsigned,
|
||||||
MaxConcatenatedTokens) {
|
MaxConcatenatedTokens) {
|
||||||
return Node.getNumConcatenated() > 1 &&
|
return Node.getNumConcatenated() > 1 &&
|
||||||
|
@ -46,9 +46,7 @@ enum class ConversionKind {
|
|||||||
ToLongDouble
|
ToLongDouble
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
ConversionKind classifyConversionFunc(const FunctionDecl *FD) {
|
||||||
|
|
||||||
static ConversionKind classifyConversionFunc(const FunctionDecl *FD) {
|
|
||||||
return llvm::StringSwitch<ConversionKind>(FD->getName())
|
return llvm::StringSwitch<ConversionKind>(FD->getName())
|
||||||
.Cases("atoi", "atol", ConversionKind::ToInt)
|
.Cases("atoi", "atol", ConversionKind::ToInt)
|
||||||
.Case("atoll", ConversionKind::ToLongInt)
|
.Case("atoll", ConversionKind::ToLongInt)
|
||||||
@ -56,8 +54,8 @@ static ConversionKind classifyConversionFunc(const FunctionDecl *FD) {
|
|||||||
.Default(ConversionKind::None);
|
.Default(ConversionKind::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ConversionKind classifyFormatString(StringRef Fmt, const LangOptions &LO,
|
ConversionKind classifyFormatString(StringRef Fmt, const LangOptions &LO,
|
||||||
const TargetInfo &TI) {
|
const TargetInfo &TI) {
|
||||||
// Scan the format string for the first problematic format specifier, then
|
// Scan the format string for the first problematic format specifier, then
|
||||||
// report that as the conversion type. This will miss additional conversion
|
// report that as the conversion type. This will miss additional conversion
|
||||||
// specifiers, but that is acceptable behavior.
|
// specifiers, but that is acceptable behavior.
|
||||||
@ -130,7 +128,7 @@ static ConversionKind classifyFormatString(StringRef Fmt, const LangOptions &LO,
|
|||||||
return H.get();
|
return H.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
static StringRef classifyConversionType(ConversionKind K) {
|
StringRef classifyConversionType(ConversionKind K) {
|
||||||
switch (K) {
|
switch (K) {
|
||||||
case ConversionKind::None:
|
case ConversionKind::None:
|
||||||
llvm_unreachable("Unexpected conversion kind");
|
llvm_unreachable("Unexpected conversion kind");
|
||||||
@ -150,7 +148,7 @@ static StringRef classifyConversionType(ConversionKind K) {
|
|||||||
llvm_unreachable("Unknown conversion kind");
|
llvm_unreachable("Unknown conversion kind");
|
||||||
}
|
}
|
||||||
|
|
||||||
static StringRef classifyReplacement(ConversionKind K) {
|
StringRef classifyReplacement(ConversionKind K) {
|
||||||
switch (K) {
|
switch (K) {
|
||||||
case ConversionKind::None:
|
case ConversionKind::None:
|
||||||
llvm_unreachable("Unexpected conversion kind");
|
llvm_unreachable("Unexpected conversion kind");
|
||||||
@ -175,6 +173,7 @@ static StringRef classifyReplacement(ConversionKind K) {
|
|||||||
}
|
}
|
||||||
llvm_unreachable("Unknown conversion kind");
|
llvm_unreachable("Unknown conversion kind");
|
||||||
}
|
}
|
||||||
|
} // unnamed namespace
|
||||||
|
|
||||||
void StrToNumCheck::check(const MatchFinder::MatchResult &Result) {
|
void StrToNumCheck::check(const MatchFinder::MatchResult &Result) {
|
||||||
const auto *Call = Result.Nodes.getNodeAs<CallExpr>("expr");
|
const auto *Call = Result.Nodes.getNodeAs<CallExpr>("expr");
|
||||||
|
@ -59,9 +59,7 @@ AST_MATCHER(FunctionDecl, isPlacementOverload) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
OverloadedOperatorKind getCorrespondingOverload(const FunctionDecl *FD) {
|
||||||
|
|
||||||
static OverloadedOperatorKind getCorrespondingOverload(const FunctionDecl *FD) {
|
|
||||||
switch (FD->getOverloadedOperator()) {
|
switch (FD->getOverloadedOperator()) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -77,7 +75,7 @@ static OverloadedOperatorKind getCorrespondingOverload(const FunctionDecl *FD) {
|
|||||||
llvm_unreachable("Not an overloaded allocation operator");
|
llvm_unreachable("Not an overloaded allocation operator");
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *getOperatorName(OverloadedOperatorKind K) {
|
const char *getOperatorName(OverloadedOperatorKind K) {
|
||||||
switch (K) {
|
switch (K) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -93,14 +91,13 @@ static const char *getOperatorName(OverloadedOperatorKind K) {
|
|||||||
llvm_unreachable("Not an overloaded allocation operator");
|
llvm_unreachable("Not an overloaded allocation operator");
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool areCorrespondingOverloads(const FunctionDecl *LHS,
|
bool areCorrespondingOverloads(const FunctionDecl *LHS,
|
||||||
const FunctionDecl *RHS) {
|
const FunctionDecl *RHS) {
|
||||||
return RHS->getOverloadedOperator() == getCorrespondingOverload(LHS);
|
return RHS->getOverloadedOperator() == getCorrespondingOverload(LHS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
bool hasCorrespondingOverloadInBaseClass(const CXXMethodDecl *MD,
|
||||||
hasCorrespondingOverloadInBaseClass(const CXXMethodDecl *MD,
|
const CXXRecordDecl *RD = nullptr) {
|
||||||
const CXXRecordDecl *RD = nullptr) {
|
|
||||||
if (RD) {
|
if (RD) {
|
||||||
// Check the methods in the given class and accessible to derived classes.
|
// Check the methods in the given class and accessible to derived classes.
|
||||||
for (const auto *BMD : RD->methods())
|
for (const auto *BMD : RD->methods())
|
||||||
@ -127,6 +124,8 @@ hasCorrespondingOverloadInBaseClass(const CXXMethodDecl *MD,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
void NewDeleteOverloadsCheck::registerMatchers(MatchFinder *Finder) {
|
void NewDeleteOverloadsCheck::registerMatchers(MatchFinder *Finder) {
|
||||||
// Match all operator new and operator delete overloads (including the array
|
// Match all operator new and operator delete overloads (including the array
|
||||||
// forms). Do not match implicit operators, placement operators, or
|
// forms). Do not match implicit operators, placement operators, or
|
||||||
|
@ -395,12 +395,16 @@ void MacroToEnumCallbacks::Endif(SourceLocation Loc, SourceLocation IfLoc) {
|
|||||||
--CurrentFile->ConditionScopes;
|
--CurrentFile->ConditionScopes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
static bool textEquals(const char (&Needle)[N], const char *HayStack) {
|
bool textEquals(const char (&Needle)[N], const char *HayStack) {
|
||||||
return StringRef{HayStack, N - 1} == Needle;
|
return StringRef{HayStack, N - 1} == Needle;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t N> static size_t len(const char (&)[N]) { return N - 1; }
|
template <size_t N> size_t len(const char (&)[N]) { return N - 1; }
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
void MacroToEnumCallbacks::PragmaDirective(SourceLocation Loc,
|
void MacroToEnumCallbacks::PragmaDirective(SourceLocation Loc,
|
||||||
PragmaIntroducerKind Introducer) {
|
PragmaIntroducerKind Introducer) {
|
||||||
|
@ -16,13 +16,14 @@ using namespace clang::ast_matchers;
|
|||||||
|
|
||||||
namespace clang::tidy::modernize {
|
namespace clang::tidy::modernize {
|
||||||
|
|
||||||
static constexpr char ConstructorCall[] = "constructorCall";
|
namespace {
|
||||||
static constexpr char ResetCall[] = "resetCall";
|
|
||||||
static constexpr char NewExpression[] = "newExpression";
|
|
||||||
|
|
||||||
static std::string getNewExprName(const CXXNewExpr *NewExpr,
|
constexpr char ConstructorCall[] = "constructorCall";
|
||||||
const SourceManager &SM,
|
constexpr char ResetCall[] = "resetCall";
|
||||||
const LangOptions &Lang) {
|
constexpr char NewExpression[] = "newExpression";
|
||||||
|
|
||||||
|
std::string getNewExprName(const CXXNewExpr *NewExpr, const SourceManager &SM,
|
||||||
|
const LangOptions &Lang) {
|
||||||
StringRef WrittenName = Lexer::getSourceText(
|
StringRef WrittenName = Lexer::getSourceText(
|
||||||
CharSourceRange::getTokenRange(
|
CharSourceRange::getTokenRange(
|
||||||
NewExpr->getAllocatedTypeSourceInfo()->getTypeLoc().getSourceRange()),
|
NewExpr->getAllocatedTypeSourceInfo()->getTypeLoc().getSourceRange()),
|
||||||
@ -33,6 +34,8 @@ static std::string getNewExprName(const CXXNewExpr *NewExpr,
|
|||||||
return WrittenName.str();
|
return WrittenName.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
const char MakeSmartPtrCheck::PointerType[] = "pointerType";
|
const char MakeSmartPtrCheck::PointerType[] = "pointerType";
|
||||||
|
|
||||||
MakeSmartPtrCheck::MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context,
|
MakeSmartPtrCheck::MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context,
|
||||||
|
@ -19,7 +19,9 @@ using namespace clang::ast_matchers;
|
|||||||
|
|
||||||
namespace clang::tidy::modernize {
|
namespace clang::tidy::modernize {
|
||||||
|
|
||||||
static bool containsEscapes(StringRef HayStack, StringRef Escapes) {
|
namespace {
|
||||||
|
|
||||||
|
bool containsEscapes(StringRef HayStack, StringRef Escapes) {
|
||||||
size_t BackSlash = HayStack.find('\\');
|
size_t BackSlash = HayStack.find('\\');
|
||||||
if (BackSlash == StringRef::npos)
|
if (BackSlash == StringRef::npos)
|
||||||
return false;
|
return false;
|
||||||
@ -33,16 +35,16 @@ static bool containsEscapes(StringRef HayStack, StringRef Escapes) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isRawStringLiteral(StringRef Text) {
|
bool isRawStringLiteral(StringRef Text) {
|
||||||
// Already a raw string literal if R comes before ".
|
// Already a raw string literal if R comes before ".
|
||||||
const size_t QuotePos = Text.find('"');
|
const size_t QuotePos = Text.find('"');
|
||||||
assert(QuotePos != StringRef::npos);
|
assert(QuotePos != StringRef::npos);
|
||||||
return (QuotePos > 0) && (Text[QuotePos - 1] == 'R');
|
return (QuotePos > 0) && (Text[QuotePos - 1] == 'R');
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool containsEscapedCharacters(const MatchFinder::MatchResult &Result,
|
bool containsEscapedCharacters(const MatchFinder::MatchResult &Result,
|
||||||
const StringLiteral *Literal,
|
const StringLiteral *Literal,
|
||||||
const CharsBitSet &DisallowedChars) {
|
const CharsBitSet &DisallowedChars) {
|
||||||
// FIXME: Handle L"", u8"", u"" and U"" literals.
|
// FIXME: Handle L"", u8"", u"" and U"" literals.
|
||||||
if (!Literal->isOrdinary())
|
if (!Literal->isOrdinary())
|
||||||
return false;
|
return false;
|
||||||
@ -62,12 +64,14 @@ static bool containsEscapedCharacters(const MatchFinder::MatchResult &Result,
|
|||||||
return containsEscapes(Text, R"('\"?x01)");
|
return containsEscapes(Text, R"('\"?x01)");
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool containsDelimiter(StringRef Bytes, const std::string &Delimiter) {
|
bool containsDelimiter(StringRef Bytes, const std::string &Delimiter) {
|
||||||
return Bytes.find(Delimiter.empty()
|
return Bytes.find(Delimiter.empty()
|
||||||
? std::string(R"lit()")lit")
|
? std::string(R"lit()")lit")
|
||||||
: (")" + Delimiter + R"(")")) != StringRef::npos;
|
: (")" + Delimiter + R"(")")) != StringRef::npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
RawStringLiteralCheck::RawStringLiteralCheck(StringRef Name,
|
RawStringLiteralCheck::RawStringLiteralCheck(StringRef Name,
|
||||||
ClangTidyContext *Context)
|
ClangTidyContext *Context)
|
||||||
: ClangTidyCheck(Name, Context),
|
: ClangTidyCheck(Name, Context),
|
||||||
|
@ -29,13 +29,12 @@
|
|||||||
using namespace clang::ast_matchers;
|
using namespace clang::ast_matchers;
|
||||||
|
|
||||||
namespace clang::tidy::objc {
|
namespace clang::tidy::objc {
|
||||||
|
namespace {
|
||||||
|
|
||||||
static constexpr StringRef WeakText = "__weak";
|
static constexpr StringRef WeakText = "__weak";
|
||||||
static constexpr StringRef StrongText = "__strong";
|
static constexpr StringRef StrongText = "__strong";
|
||||||
static constexpr StringRef UnsafeUnretainedText = "__unsafe_unretained";
|
static constexpr StringRef UnsafeUnretainedText = "__unsafe_unretained";
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
/// Matches ObjCIvarRefExpr, DeclRefExpr, or MemberExpr that reference
|
/// Matches ObjCIvarRefExpr, DeclRefExpr, or MemberExpr that reference
|
||||||
/// Objective-C object (or block) variables or fields whose object lifetimes
|
/// Objective-C object (or block) variables or fields whose object lifetimes
|
||||||
/// are not __unsafe_unretained.
|
/// are not __unsafe_unretained.
|
||||||
@ -50,8 +49,6 @@ AST_POLYMORPHIC_MATCHER(isObjCManagedLifetime,
|
|||||||
QT.getQualifiers().getObjCLifetime() > Qualifiers::OCL_ExplicitNone;
|
QT.getQualifiers().getObjCLifetime() > Qualifiers::OCL_ExplicitNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
static std::optional<FixItHint>
|
static std::optional<FixItHint>
|
||||||
fixItHintReplacementForOwnershipString(StringRef Text, CharSourceRange Range,
|
fixItHintReplacementForOwnershipString(StringRef Text, CharSourceRange Range,
|
||||||
StringRef Ownership) {
|
StringRef Ownership) {
|
||||||
@ -96,6 +93,8 @@ fixItHintForVarDecl(const VarDecl *VD, const SourceManager &SM,
|
|||||||
return FixItHint::CreateInsertion(Range.getBegin(), "__unsafe_unretained ");
|
return FixItHint::CreateInsertion(Range.getBegin(), "__unsafe_unretained ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
void NSInvocationArgumentLifetimeCheck::registerMatchers(MatchFinder *Finder) {
|
void NSInvocationArgumentLifetimeCheck::registerMatchers(MatchFinder *Finder) {
|
||||||
Finder->addMatcher(
|
Finder->addMatcher(
|
||||||
traverse(
|
traverse(
|
||||||
|
@ -27,14 +27,11 @@ enum NamingStyle {
|
|||||||
CategoryProperty = 2,
|
CategoryProperty = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
/// For now we will only fix 'CamelCase' or 'abc_CamelCase' property to
|
/// For now we will only fix 'CamelCase' or 'abc_CamelCase' property to
|
||||||
/// 'camelCase' or 'abc_camelCase'. For other cases the users need to
|
/// 'camelCase' or 'abc_camelCase'. For other cases the users need to
|
||||||
/// come up with a proper name by their own.
|
/// come up with a proper name by their own.
|
||||||
/// FIXME: provide fix for snake_case to snakeCase
|
/// FIXME: provide fix for snake_case to snakeCase
|
||||||
static FixItHint generateFixItHint(const ObjCPropertyDecl *Decl,
|
FixItHint generateFixItHint(const ObjCPropertyDecl *Decl, NamingStyle Style) {
|
||||||
NamingStyle Style) {
|
|
||||||
auto Name = Decl->getName();
|
auto Name = Decl->getName();
|
||||||
auto NewName = Decl->getName().str();
|
auto NewName = Decl->getName().str();
|
||||||
size_t Index = 0;
|
size_t Index = 0;
|
||||||
@ -53,7 +50,7 @@ static FixItHint generateFixItHint(const ObjCPropertyDecl *Decl,
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string validPropertyNameRegex(bool UsedInMatcher) {
|
std::string validPropertyNameRegex(bool UsedInMatcher) {
|
||||||
// Allow any of these names:
|
// Allow any of these names:
|
||||||
// foo
|
// foo
|
||||||
// fooBar
|
// fooBar
|
||||||
@ -75,13 +72,13 @@ static std::string validPropertyNameRegex(bool UsedInMatcher) {
|
|||||||
return StartMatcher + "([a-z]|[A-Z][A-Z0-9])[a-z0-9A-Z]*$";
|
return StartMatcher + "([a-z]|[A-Z][A-Z0-9])[a-z0-9A-Z]*$";
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hasCategoryPropertyPrefix(llvm::StringRef PropertyName) {
|
bool hasCategoryPropertyPrefix(llvm::StringRef PropertyName) {
|
||||||
auto RegexExp =
|
auto RegexExp =
|
||||||
llvm::Regex("^[a-zA-Z][a-zA-Z0-9]*_[a-zA-Z0-9][a-zA-Z0-9_]+$");
|
llvm::Regex("^[a-zA-Z][a-zA-Z0-9]*_[a-zA-Z0-9][a-zA-Z0-9_]+$");
|
||||||
return RegexExp.match(PropertyName);
|
return RegexExp.match(PropertyName);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool prefixedPropertyNameValid(llvm::StringRef PropertyName) {
|
bool prefixedPropertyNameValid(llvm::StringRef PropertyName) {
|
||||||
size_t Start = PropertyName.find_first_of('_');
|
size_t Start = PropertyName.find_first_of('_');
|
||||||
assert(Start != llvm::StringRef::npos && Start + 1 < PropertyName.size());
|
assert(Start != llvm::StringRef::npos && Start + 1 < PropertyName.size());
|
||||||
auto Prefix = PropertyName.substr(0, Start);
|
auto Prefix = PropertyName.substr(0, Start);
|
||||||
@ -91,6 +88,7 @@ static bool prefixedPropertyNameValid(llvm::StringRef PropertyName) {
|
|||||||
auto RegexExp = llvm::Regex(llvm::StringRef(validPropertyNameRegex(false)));
|
auto RegexExp = llvm::Regex(llvm::StringRef(validPropertyNameRegex(false)));
|
||||||
return RegexExp.match(PropertyName.substr(Start + 1));
|
return RegexExp.match(PropertyName.substr(Start + 1));
|
||||||
}
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
void PropertyDeclarationCheck::registerMatchers(MatchFinder *Finder) {
|
void PropertyDeclarationCheck::registerMatchers(MatchFinder *Finder) {
|
||||||
Finder->addMatcher(objcPropertyDecl(
|
Finder->addMatcher(objcPropertyDecl(
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
namespace clang::tidy::performance {
|
namespace clang::tidy::performance {
|
||||||
|
namespace {
|
||||||
|
|
||||||
using namespace ::clang::ast_matchers;
|
using namespace ::clang::ast_matchers;
|
||||||
using llvm::StringRef;
|
using llvm::StringRef;
|
||||||
@ -29,8 +30,8 @@ static constexpr StringRef MethodDeclId = "methodDecl";
|
|||||||
static constexpr StringRef FunctionDeclId = "functionDecl";
|
static constexpr StringRef FunctionDeclId = "functionDecl";
|
||||||
static constexpr StringRef OldVarDeclId = "oldVarDecl";
|
static constexpr StringRef OldVarDeclId = "oldVarDecl";
|
||||||
|
|
||||||
static void recordFixes(const VarDecl &Var, ASTContext &Context,
|
void recordFixes(const VarDecl &Var, ASTContext &Context,
|
||||||
DiagnosticBuilder &Diagnostic) {
|
DiagnosticBuilder &Diagnostic) {
|
||||||
Diagnostic << utils::fixit::changeVarDeclToReference(Var, Context);
|
Diagnostic << utils::fixit::changeVarDeclToReference(Var, Context);
|
||||||
if (!Var.getType().isLocalConstQualified()) {
|
if (!Var.getType().isLocalConstQualified()) {
|
||||||
if (std::optional<FixItHint> Fix = utils::fixit::addQualifierToVarDecl(
|
if (std::optional<FixItHint> Fix = utils::fixit::addQualifierToVarDecl(
|
||||||
@ -39,8 +40,8 @@ static void recordFixes(const VarDecl &Var, ASTContext &Context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::optional<SourceLocation> firstLocAfterNewLine(SourceLocation Loc,
|
std::optional<SourceLocation> firstLocAfterNewLine(SourceLocation Loc,
|
||||||
SourceManager &SM) {
|
SourceManager &SM) {
|
||||||
bool Invalid = false;
|
bool Invalid = false;
|
||||||
const char *TextAfter = SM.getCharacterData(Loc, &Invalid);
|
const char *TextAfter = SM.getCharacterData(Loc, &Invalid);
|
||||||
if (Invalid) {
|
if (Invalid) {
|
||||||
@ -50,8 +51,8 @@ static std::optional<SourceLocation> firstLocAfterNewLine(SourceLocation Loc,
|
|||||||
return Loc.getLocWithOffset(TextAfter[Offset] == '\0' ? Offset : Offset + 1);
|
return Loc.getLocWithOffset(TextAfter[Offset] == '\0' ? Offset : Offset + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void recordRemoval(const DeclStmt &Stmt, ASTContext &Context,
|
void recordRemoval(const DeclStmt &Stmt, ASTContext &Context,
|
||||||
DiagnosticBuilder &Diagnostic) {
|
DiagnosticBuilder &Diagnostic) {
|
||||||
auto &SM = Context.getSourceManager();
|
auto &SM = Context.getSourceManager();
|
||||||
// Attempt to remove trailing comments as well.
|
// Attempt to remove trailing comments as well.
|
||||||
auto Tok = utils::lexer::findNextTokenSkippingComments(Stmt.getEndLoc(), SM,
|
auto Tok = utils::lexer::findNextTokenSkippingComments(Stmt.getEndLoc(), SM,
|
||||||
@ -73,8 +74,6 @@ static void recordRemoval(const DeclStmt &Stmt, ASTContext &Context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
AST_MATCHER_FUNCTION_P(StatementMatcher,
|
AST_MATCHER_FUNCTION_P(StatementMatcher,
|
||||||
isRefReturningMethodCallWithConstOverloads,
|
isRefReturningMethodCallWithConstOverloads,
|
||||||
std::vector<StringRef>, ExcludedContainerTypes) {
|
std::vector<StringRef>, ExcludedContainerTypes) {
|
||||||
@ -131,8 +130,6 @@ AST_MATCHER_FUNCTION_P(StatementMatcher, initializerReturnsReferenceToConst,
|
|||||||
hasUnaryOperand(OldVarDeclRef)))));
|
hasUnaryOperand(OldVarDeclRef)))));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
// This checks that the variable itself is only used as const, and also makes
|
// This checks that the variable itself is only used as const, and also makes
|
||||||
// sure that it does not reference another variable that could be modified in
|
// sure that it does not reference another variable that could be modified in
|
||||||
// the BlockStmt. It does this by checking the following:
|
// the BlockStmt. It does this by checking the following:
|
||||||
@ -183,13 +180,13 @@ static bool isInitializingVariableImmutable(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isVariableUnused(const VarDecl &Var, const Stmt &BlockStmt,
|
bool isVariableUnused(const VarDecl &Var, const Stmt &BlockStmt,
|
||||||
ASTContext &Context) {
|
ASTContext &Context) {
|
||||||
return allDeclRefExprs(Var, BlockStmt, Context).empty();
|
return allDeclRefExprs(Var, BlockStmt, Context).empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
static const SubstTemplateTypeParmType *
|
const SubstTemplateTypeParmType *getSubstitutedType(const QualType &Type,
|
||||||
getSubstitutedType(const QualType &Type, ASTContext &Context) {
|
ASTContext &Context) {
|
||||||
auto Matches = match(
|
auto Matches = match(
|
||||||
qualType(anyOf(substTemplateTypeParmType().bind("subst"),
|
qualType(anyOf(substTemplateTypeParmType().bind("subst"),
|
||||||
hasDescendant(substTemplateTypeParmType().bind("subst")))),
|
hasDescendant(substTemplateTypeParmType().bind("subst")))),
|
||||||
@ -197,9 +194,9 @@ getSubstitutedType(const QualType &Type, ASTContext &Context) {
|
|||||||
return selectFirst<SubstTemplateTypeParmType>("subst", Matches);
|
return selectFirst<SubstTemplateTypeParmType>("subst", Matches);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool differentReplacedTemplateParams(const QualType &VarType,
|
bool differentReplacedTemplateParams(const QualType &VarType,
|
||||||
const QualType &InitializerType,
|
const QualType &InitializerType,
|
||||||
ASTContext &Context) {
|
ASTContext &Context) {
|
||||||
if (const SubstTemplateTypeParmType *VarTmplType =
|
if (const SubstTemplateTypeParmType *VarTmplType =
|
||||||
getSubstitutedType(VarType, Context)) {
|
getSubstitutedType(VarType, Context)) {
|
||||||
if (const SubstTemplateTypeParmType *InitializerTmplType =
|
if (const SubstTemplateTypeParmType *InitializerTmplType =
|
||||||
@ -215,8 +212,8 @@ static bool differentReplacedTemplateParams(const QualType &VarType,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QualType constructorArgumentType(const VarDecl *OldVar,
|
QualType constructorArgumentType(const VarDecl *OldVar,
|
||||||
const BoundNodes &Nodes) {
|
const BoundNodes &Nodes) {
|
||||||
if (OldVar) {
|
if (OldVar) {
|
||||||
return OldVar->getType();
|
return OldVar->getType();
|
||||||
}
|
}
|
||||||
@ -227,6 +224,8 @@ static QualType constructorArgumentType(const VarDecl *OldVar,
|
|||||||
return MethodDecl->getReturnType();
|
return MethodDecl->getReturnType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
UnnecessaryCopyInitialization::UnnecessaryCopyInitialization(
|
UnnecessaryCopyInitialization::UnnecessaryCopyInitialization(
|
||||||
StringRef Name, ClangTidyContext *Context)
|
StringRef Name, ClangTidyContext *Context)
|
||||||
: ClangTidyCheck(Name, Context),
|
: ClangTidyCheck(Name, Context),
|
||||||
|
@ -21,14 +21,16 @@ using namespace clang::ast_matchers;
|
|||||||
|
|
||||||
namespace clang::tidy::performance {
|
namespace clang::tidy::performance {
|
||||||
|
|
||||||
static std::string paramNameOrIndex(StringRef Name, size_t Index) {
|
namespace {
|
||||||
|
|
||||||
|
std::string paramNameOrIndex(StringRef Name, size_t Index) {
|
||||||
return (Name.empty() ? llvm::Twine('#') + llvm::Twine(Index + 1)
|
return (Name.empty() ? llvm::Twine('#') + llvm::Twine(Index + 1)
|
||||||
: llvm::Twine('\'') + Name + llvm::Twine('\''))
|
: llvm::Twine('\'') + Name + llvm::Twine('\''))
|
||||||
.str();
|
.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hasLoopStmtAncestor(const DeclRefExpr &DeclRef, const Decl &Decl,
|
bool hasLoopStmtAncestor(const DeclRefExpr &DeclRef, const Decl &Decl,
|
||||||
ASTContext &Context) {
|
ASTContext &Context) {
|
||||||
auto Matches = match(
|
auto Matches = match(
|
||||||
traverse(TK_AsIs,
|
traverse(TK_AsIs,
|
||||||
decl(forEachDescendant(declRefExpr(
|
decl(forEachDescendant(declRefExpr(
|
||||||
@ -39,6 +41,8 @@ static bool hasLoopStmtAncestor(const DeclRefExpr &DeclRef, const Decl &Decl,
|
|||||||
return Matches.empty();
|
return Matches.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
UnnecessaryValueParamCheck::UnnecessaryValueParamCheck(
|
UnnecessaryValueParamCheck::UnnecessaryValueParamCheck(
|
||||||
StringRef Name, ClangTidyContext *Context)
|
StringRef Name, ClangTidyContext *Context)
|
||||||
: ClangTidyCheck(Name, Context),
|
: ClangTidyCheck(Name, Context),
|
||||||
|
@ -122,15 +122,15 @@ AST_MATCHER(EnumDecl, hasSequentialInitialValues) {
|
|||||||
return !AllEnumeratorsArePowersOfTwo;
|
return !AllEnumeratorsArePowersOfTwo;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
std::string getName(const EnumDecl *Decl) {
|
||||||
|
|
||||||
static std::string getName(const EnumDecl *Decl) {
|
|
||||||
if (!Decl->getDeclName())
|
if (!Decl->getDeclName())
|
||||||
return "<unnamed>";
|
return "<unnamed>";
|
||||||
|
|
||||||
return Decl->getQualifiedNameAsString();
|
return Decl->getQualifiedNameAsString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
EnumInitialValueCheck::EnumInitialValueCheck(StringRef Name,
|
EnumInitialValueCheck::EnumInitialValueCheck(StringRef Name,
|
||||||
ClangTidyContext *Context)
|
ClangTidyContext *Context)
|
||||||
: ClangTidyCheck(Name, Context),
|
: ClangTidyCheck(Name, Context),
|
||||||
|
@ -144,8 +144,6 @@ struct CognitiveComplexity final {
|
|||||||
void account(SourceLocation Loc, unsigned short Nesting, Criteria C);
|
void account(SourceLocation Loc, unsigned short Nesting, Criteria C);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
// All the possible messages that can be output. The choice of the message
|
// All the possible messages that can be output. The choice of the message
|
||||||
// to use is based of the combination of the CognitiveComplexity::Criteria.
|
// to use is based of the combination of the CognitiveComplexity::Criteria.
|
||||||
// It would be nice to have it in CognitiveComplexity struct, but then it is
|
// It would be nice to have it in CognitiveComplexity struct, but then it is
|
||||||
@ -165,27 +163,23 @@ static const std::array<const StringRef, 4> Msgs = {{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
// Criteria is a bitset, thus a few helpers are needed.
|
// Criteria is a bitset, thus a few helpers are needed.
|
||||||
static CognitiveComplexity::Criteria
|
CognitiveComplexity::Criteria operator|(CognitiveComplexity::Criteria LHS,
|
||||||
operator|(CognitiveComplexity::Criteria LHS,
|
CognitiveComplexity::Criteria RHS) {
|
||||||
CognitiveComplexity::Criteria RHS) {
|
|
||||||
return static_cast<CognitiveComplexity::Criteria>(llvm::to_underlying(LHS) |
|
return static_cast<CognitiveComplexity::Criteria>(llvm::to_underlying(LHS) |
|
||||||
llvm::to_underlying(RHS));
|
llvm::to_underlying(RHS));
|
||||||
}
|
}
|
||||||
static CognitiveComplexity::Criteria
|
CognitiveComplexity::Criteria operator&(CognitiveComplexity::Criteria LHS,
|
||||||
operator&(CognitiveComplexity::Criteria LHS,
|
CognitiveComplexity::Criteria RHS) {
|
||||||
CognitiveComplexity::Criteria RHS) {
|
|
||||||
return static_cast<CognitiveComplexity::Criteria>(llvm::to_underlying(LHS) &
|
return static_cast<CognitiveComplexity::Criteria>(llvm::to_underlying(LHS) &
|
||||||
llvm::to_underlying(RHS));
|
llvm::to_underlying(RHS));
|
||||||
}
|
}
|
||||||
static CognitiveComplexity::Criteria &
|
CognitiveComplexity::Criteria &operator|=(CognitiveComplexity::Criteria &LHS,
|
||||||
operator|=(CognitiveComplexity::Criteria &LHS,
|
CognitiveComplexity::Criteria RHS) {
|
||||||
CognitiveComplexity::Criteria RHS) {
|
|
||||||
LHS = operator|(LHS, RHS);
|
LHS = operator|(LHS, RHS);
|
||||||
return LHS;
|
return LHS;
|
||||||
}
|
}
|
||||||
static CognitiveComplexity::Criteria &
|
CognitiveComplexity::Criteria &operator&=(CognitiveComplexity::Criteria &LHS,
|
||||||
operator&=(CognitiveComplexity::Criteria &LHS,
|
CognitiveComplexity::Criteria RHS) {
|
||||||
CognitiveComplexity::Criteria RHS) {
|
|
||||||
LHS = operator&(LHS, RHS);
|
LHS = operator&(LHS, RHS);
|
||||||
return LHS;
|
return LHS;
|
||||||
}
|
}
|
||||||
@ -205,8 +199,6 @@ void CognitiveComplexity::account(SourceLocation Loc, unsigned short Nesting,
|
|||||||
Total += Increase;
|
Total += Increase;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
class FunctionASTVisitor final
|
class FunctionASTVisitor final
|
||||||
: public RecursiveASTVisitor<FunctionASTVisitor> {
|
: public RecursiveASTVisitor<FunctionASTVisitor> {
|
||||||
using Base = RecursiveASTVisitor<FunctionASTVisitor>;
|
using Base = RecursiveASTVisitor<FunctionASTVisitor>;
|
||||||
|
@ -41,11 +41,9 @@ AST_MATCHER(Stmt, isNULLMacroExpansion) {
|
|||||||
return isNULLMacroExpansion(&Node, Finder->getASTContext());
|
return isNULLMacroExpansion(&Node, Finder->getASTContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
StringRef getZeroLiteralToCompareWithForType(CastKind CastExprKind,
|
||||||
|
QualType Type,
|
||||||
static StringRef getZeroLiteralToCompareWithForType(CastKind CastExprKind,
|
ASTContext &Context) {
|
||||||
QualType Type,
|
|
||||||
ASTContext &Context) {
|
|
||||||
switch (CastExprKind) {
|
switch (CastExprKind) {
|
||||||
case CK_IntegralToBoolean:
|
case CK_IntegralToBoolean:
|
||||||
return Type->isUnsignedIntegerType() ? "0u" : "0";
|
return Type->isUnsignedIntegerType() ? "0u" : "0";
|
||||||
@ -64,15 +62,15 @@ static StringRef getZeroLiteralToCompareWithForType(CastKind CastExprKind,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isUnaryLogicalNotOperator(const Stmt *Statement) {
|
bool isUnaryLogicalNotOperator(const Stmt *Statement) {
|
||||||
const auto *UnaryOperatorExpr = dyn_cast<UnaryOperator>(Statement);
|
const auto *UnaryOperatorExpr = dyn_cast<UnaryOperator>(Statement);
|
||||||
return UnaryOperatorExpr && UnaryOperatorExpr->getOpcode() == UO_LNot;
|
return UnaryOperatorExpr && UnaryOperatorExpr->getOpcode() == UO_LNot;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fixGenericExprCastToBool(DiagnosticBuilder &Diag,
|
void fixGenericExprCastToBool(DiagnosticBuilder &Diag,
|
||||||
const ImplicitCastExpr *Cast,
|
const ImplicitCastExpr *Cast, const Stmt *Parent,
|
||||||
const Stmt *Parent, ASTContext &Context,
|
ASTContext &Context,
|
||||||
bool UseUpperCaseLiteralSuffix) {
|
bool UseUpperCaseLiteralSuffix) {
|
||||||
// In case of expressions like (! integer), we should remove the redundant not
|
// In case of expressions like (! integer), we should remove the redundant not
|
||||||
// operator and use inverted comparison (integer == 0).
|
// operator and use inverted comparison (integer == 0).
|
||||||
bool InvertComparison =
|
bool InvertComparison =
|
||||||
@ -135,8 +133,8 @@ static void fixGenericExprCastToBool(DiagnosticBuilder &Diag,
|
|||||||
Diag << FixItHint::CreateInsertion(EndLoc, EndLocInsertion);
|
Diag << FixItHint::CreateInsertion(EndLoc, EndLocInsertion);
|
||||||
}
|
}
|
||||||
|
|
||||||
static StringRef getEquivalentBoolLiteralForExpr(const Expr *Expression,
|
StringRef getEquivalentBoolLiteralForExpr(const Expr *Expression,
|
||||||
ASTContext &Context) {
|
ASTContext &Context) {
|
||||||
if (isNULLMacroExpansion(Expression, Context)) {
|
if (isNULLMacroExpansion(Expression, Context)) {
|
||||||
return "false";
|
return "false";
|
||||||
}
|
}
|
||||||
@ -163,7 +161,7 @@ static StringRef getEquivalentBoolLiteralForExpr(const Expr *Expression,
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool needsSpacePrefix(SourceLocation Loc, ASTContext &Context) {
|
bool needsSpacePrefix(SourceLocation Loc, ASTContext &Context) {
|
||||||
SourceRange PrefixRange(Loc.getLocWithOffset(-1), Loc);
|
SourceRange PrefixRange(Loc.getLocWithOffset(-1), Loc);
|
||||||
StringRef SpaceBeforeStmtStr = Lexer::getSourceText(
|
StringRef SpaceBeforeStmtStr = Lexer::getSourceText(
|
||||||
CharSourceRange::getCharRange(PrefixRange), Context.getSourceManager(),
|
CharSourceRange::getCharRange(PrefixRange), Context.getSourceManager(),
|
||||||
@ -175,10 +173,9 @@ static bool needsSpacePrefix(SourceLocation Loc, ASTContext &Context) {
|
|||||||
return !AllowedCharacters.contains(SpaceBeforeStmtStr.back());
|
return !AllowedCharacters.contains(SpaceBeforeStmtStr.back());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fixGenericExprCastFromBool(DiagnosticBuilder &Diag,
|
void fixGenericExprCastFromBool(DiagnosticBuilder &Diag,
|
||||||
const ImplicitCastExpr *Cast,
|
const ImplicitCastExpr *Cast,
|
||||||
ASTContext &Context,
|
ASTContext &Context, StringRef OtherType) {
|
||||||
StringRef OtherType) {
|
|
||||||
if (!Context.getLangOpts().CPlusPlus) {
|
if (!Context.getLangOpts().CPlusPlus) {
|
||||||
Diag << FixItHint::CreateInsertion(Cast->getBeginLoc(),
|
Diag << FixItHint::CreateInsertion(Cast->getBeginLoc(),
|
||||||
(Twine("(") + OtherType + ")").str());
|
(Twine("(") + OtherType + ")").str());
|
||||||
@ -203,9 +200,8 @@ static void fixGenericExprCastFromBool(DiagnosticBuilder &Diag,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static StringRef
|
StringRef getEquivalentForBoolLiteral(const CXXBoolLiteralExpr *BoolLiteral,
|
||||||
getEquivalentForBoolLiteral(const CXXBoolLiteralExpr *BoolLiteral,
|
QualType DestType, ASTContext &Context) {
|
||||||
QualType DestType, ASTContext &Context) {
|
|
||||||
// Prior to C++11, false literal could be implicitly converted to pointer.
|
// Prior to C++11, false literal could be implicitly converted to pointer.
|
||||||
if (!Context.getLangOpts().CPlusPlus11 &&
|
if (!Context.getLangOpts().CPlusPlus11 &&
|
||||||
(DestType->isPointerType() || DestType->isMemberPointerType()) &&
|
(DestType->isPointerType() || DestType->isMemberPointerType()) &&
|
||||||
@ -226,8 +222,8 @@ getEquivalentForBoolLiteral(const CXXBoolLiteralExpr *BoolLiteral,
|
|||||||
return BoolLiteral->getValue() ? "1" : "0";
|
return BoolLiteral->getValue() ? "1" : "0";
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isCastAllowedInCondition(const ImplicitCastExpr *Cast,
|
bool isCastAllowedInCondition(const ImplicitCastExpr *Cast,
|
||||||
ASTContext &Context) {
|
ASTContext &Context) {
|
||||||
std::queue<const Stmt *> Q;
|
std::queue<const Stmt *> Q;
|
||||||
Q.push(Cast);
|
Q.push(Cast);
|
||||||
|
|
||||||
@ -255,6 +251,8 @@ static bool isCastAllowedInCondition(const ImplicitCastExpr *Cast,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
ImplicitBoolConversionCheck::ImplicitBoolConversionCheck(
|
ImplicitBoolConversionCheck::ImplicitBoolConversionCheck(
|
||||||
StringRef Name, ClangTidyContext *Context)
|
StringRef Name, ClangTidyContext *Context)
|
||||||
: ClangTidyCheck(Name, Context),
|
: ClangTidyCheck(Name, Context),
|
||||||
|
@ -28,11 +28,8 @@ AST_MATCHER_P(QualType, hasUnqualifiedType,
|
|||||||
|
|
||||||
enum class Qualifier { Const, Volatile, Restrict };
|
enum class Qualifier { Const, Volatile, Restrict };
|
||||||
|
|
||||||
} // namespace
|
std::optional<Token> findQualToken(const VarDecl *Decl, Qualifier Qual,
|
||||||
|
const MatchFinder::MatchResult &Result) {
|
||||||
static std::optional<Token>
|
|
||||||
findQualToken(const VarDecl *Decl, Qualifier Qual,
|
|
||||||
const MatchFinder::MatchResult &Result) {
|
|
||||||
// Since either of the locs can be in a macro, use `makeFileCharRange` to be
|
// Since either of the locs can be in a macro, use `makeFileCharRange` to be
|
||||||
// sure that we have a consistent `CharSourceRange`, located entirely in the
|
// sure that we have a consistent `CharSourceRange`, located entirely in the
|
||||||
// source file.
|
// source file.
|
||||||
@ -61,7 +58,7 @@ findQualToken(const VarDecl *Decl, Qualifier Qual,
|
|||||||
*Result.SourceManager);
|
*Result.SourceManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::optional<SourceRange>
|
std::optional<SourceRange>
|
||||||
getTypeSpecifierLocation(const VarDecl *Var,
|
getTypeSpecifierLocation(const VarDecl *Var,
|
||||||
const MatchFinder::MatchResult &Result) {
|
const MatchFinder::MatchResult &Result) {
|
||||||
SourceRange TypeSpecifier(
|
SourceRange TypeSpecifier(
|
||||||
@ -76,8 +73,8 @@ getTypeSpecifierLocation(const VarDecl *Var,
|
|||||||
return TypeSpecifier;
|
return TypeSpecifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::optional<SourceRange>
|
std::optional<SourceRange> mergeReplacementRange(SourceRange &TypeSpecifier,
|
||||||
mergeReplacementRange(SourceRange &TypeSpecifier, const Token &ConstToken) {
|
const Token &ConstToken) {
|
||||||
if (TypeSpecifier.getBegin().getLocWithOffset(-1) == ConstToken.getEndLoc()) {
|
if (TypeSpecifier.getBegin().getLocWithOffset(-1) == ConstToken.getEndLoc()) {
|
||||||
TypeSpecifier.setBegin(ConstToken.getLocation());
|
TypeSpecifier.setBegin(ConstToken.getLocation());
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
@ -89,19 +86,21 @@ mergeReplacementRange(SourceRange &TypeSpecifier, const Token &ConstToken) {
|
|||||||
return SourceRange(ConstToken.getLocation(), ConstToken.getEndLoc());
|
return SourceRange(ConstToken.getLocation(), ConstToken.getEndLoc());
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isPointerConst(QualType QType) {
|
bool isPointerConst(QualType QType) {
|
||||||
QualType Pointee = QType->getPointeeType();
|
QualType Pointee = QType->getPointeeType();
|
||||||
assert(!Pointee.isNull() && "can't have a null Pointee");
|
assert(!Pointee.isNull() && "can't have a null Pointee");
|
||||||
return Pointee.isConstQualified();
|
return Pointee.isConstQualified();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isAutoPointerConst(QualType QType) {
|
bool isAutoPointerConst(QualType QType) {
|
||||||
QualType Pointee =
|
QualType Pointee =
|
||||||
cast<AutoType>(QType->getPointeeType().getTypePtr())->desugar();
|
cast<AutoType>(QType->getPointeeType().getTypePtr())->desugar();
|
||||||
assert(!Pointee.isNull() && "can't have a null Pointee");
|
assert(!Pointee.isNull() && "can't have a null Pointee");
|
||||||
return Pointee.isConstQualified();
|
return Pointee.isConstQualified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
QualifiedAutoCheck::QualifiedAutoCheck(StringRef Name,
|
QualifiedAutoCheck::QualifiedAutoCheck(StringRef Name,
|
||||||
ClangTidyContext *Context)
|
ClangTidyContext *Context)
|
||||||
: ClangTidyCheck(Name, Context),
|
: ClangTidyCheck(Name, Context),
|
||||||
|
@ -14,18 +14,19 @@ using namespace clang::ast_matchers;
|
|||||||
|
|
||||||
namespace clang::tidy::readability {
|
namespace clang::tidy::readability {
|
||||||
|
|
||||||
static const char *const RedundantReturnDiag =
|
namespace {
|
||||||
"redundant return statement at the end "
|
|
||||||
"of a function with a void return type";
|
|
||||||
static const char *const RedundantContinueDiag =
|
|
||||||
"redundant continue statement at the "
|
|
||||||
"end of loop statement";
|
|
||||||
|
|
||||||
static bool isLocationInMacroExpansion(const SourceManager &SM,
|
const char *const RedundantReturnDiag = "redundant return statement at the end "
|
||||||
SourceLocation Loc) {
|
"of a function with a void return type";
|
||||||
|
const char *const RedundantContinueDiag = "redundant continue statement at the "
|
||||||
|
"end of loop statement";
|
||||||
|
|
||||||
|
bool isLocationInMacroExpansion(const SourceManager &SM, SourceLocation Loc) {
|
||||||
return SM.isMacroBodyExpansion(Loc) || SM.isMacroArgExpansion(Loc);
|
return SM.isMacroBodyExpansion(Loc) || SM.isMacroArgExpansion(Loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
void RedundantControlFlowCheck::registerMatchers(MatchFinder *Finder) {
|
void RedundantControlFlowCheck::registerMatchers(MatchFinder *Finder) {
|
||||||
Finder->addMatcher(
|
Finder->addMatcher(
|
||||||
functionDecl(isDefinition(), returns(voidType()),
|
functionDecl(isDefinition(), returns(voidType()),
|
||||||
|
@ -13,14 +13,16 @@
|
|||||||
|
|
||||||
namespace clang::tidy::utils::type_traits {
|
namespace clang::tidy::utils::type_traits {
|
||||||
|
|
||||||
static bool classHasTrivialCopyAndDestroy(QualType Type) {
|
namespace {
|
||||||
|
|
||||||
|
bool classHasTrivialCopyAndDestroy(QualType Type) {
|
||||||
auto *Record = Type->getAsCXXRecordDecl();
|
auto *Record = Type->getAsCXXRecordDecl();
|
||||||
return Record && Record->hasDefinition() &&
|
return Record && Record->hasDefinition() &&
|
||||||
!Record->hasNonTrivialCopyConstructor() &&
|
!Record->hasNonTrivialCopyConstructor() &&
|
||||||
!Record->hasNonTrivialDestructor();
|
!Record->hasNonTrivialDestructor();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hasDeletedCopyConstructor(QualType Type) {
|
bool hasDeletedCopyConstructor(QualType Type) {
|
||||||
auto *Record = Type->getAsCXXRecordDecl();
|
auto *Record = Type->getAsCXXRecordDecl();
|
||||||
if (!Record || !Record->hasDefinition())
|
if (!Record || !Record->hasDefinition())
|
||||||
return false;
|
return false;
|
||||||
@ -31,6 +33,8 @@ static bool hasDeletedCopyConstructor(QualType Type) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
std::optional<bool> isExpensiveToCopy(QualType Type,
|
std::optional<bool> isExpensiveToCopy(QualType Type,
|
||||||
const ASTContext &Context) {
|
const ASTContext &Context) {
|
||||||
if (Type->isDependentType() || Type->isIncompleteType())
|
if (Type->isDependentType() || Type->isIncompleteType())
|
||||||
|
@ -309,13 +309,6 @@ NVPTX Support
|
|||||||
|
|
||||||
X86 Support
|
X86 Support
|
||||||
^^^^^^^^^^^
|
^^^^^^^^^^^
|
||||||
- More SSE, AVX and AVX512 intrinsics, including initializers and general
|
|
||||||
arithmetic can now be used in C++ constant expressions.
|
|
||||||
- Some SSE, AVX and AVX512 intrinsics have been converted to wrap
|
|
||||||
generic __builtin intrinsics.
|
|
||||||
- NOTE: Please avoid use of the __builtin_ia32_* intrinsics - these are not
|
|
||||||
guaranteed to exist in future releases, or match behaviour with previous
|
|
||||||
releases of clang or other compilers.
|
|
||||||
|
|
||||||
Arm and AArch64 Support
|
Arm and AArch64 Support
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -627,23 +627,11 @@ let Features = "avx2", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] i
|
|||||||
let Features = "avx2", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in {
|
let Features = "avx2", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in {
|
||||||
def pmuldq256 : X86Builtin<"_Vector<4, long long int>(_Vector<8, int>, _Vector<8, int>)">;
|
def pmuldq256 : X86Builtin<"_Vector<4, long long int>(_Vector<8, int>, _Vector<8, int>)">;
|
||||||
def pmuludq256 : X86Builtin<"_Vector<4, long long int>(_Vector<8, int>, _Vector<8, int>)">;
|
def pmuludq256 : X86Builtin<"_Vector<4, long long int>(_Vector<8, int>, _Vector<8, int>)">;
|
||||||
|
|
||||||
def pmulhuw256 : X86Builtin<"_Vector<16, unsigned short>(_Vector<16, unsigned short>, _Vector<16, unsigned short>)">;
|
|
||||||
def pmulhw256 : X86Builtin<"_Vector<16, short>(_Vector<16, short>, _Vector<16, short>)">;
|
|
||||||
|
|
||||||
def psllv8si : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>)">;
|
|
||||||
def psrav8si : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>)">;
|
|
||||||
def psrlv8si : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>)">;
|
|
||||||
def psllv4di : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, _Vector<4, long long int>)">;
|
|
||||||
def psrlv4di : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, _Vector<4, long long int>)">;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let Features = "avx2", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in {
|
let Features = "avx2", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in {
|
||||||
def psllv4si : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>)">;
|
def pmulhuw256 : X86Builtin<"_Vector<16, unsigned short>(_Vector<16, unsigned short>, _Vector<16, unsigned short>)">;
|
||||||
def psrav4si : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>)">;
|
def pmulhw256 : X86Builtin<"_Vector<16, short>(_Vector<16, short>, _Vector<16, short>)">;
|
||||||
def psrlv4si : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>)">;
|
|
||||||
def psllv2di : X86Builtin<"_Vector<2, long long int>(_Vector<2, long long int>, _Vector<2, long long int>)">;
|
|
||||||
def psrlv2di : X86Builtin<"_Vector<2, long long int>(_Vector<2, long long int>, _Vector<2, long long int>)">;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let Features = "avx2", Attributes = [NoThrow, RequiredVectorWidth<256>] in {
|
let Features = "avx2", Attributes = [NoThrow, RequiredVectorWidth<256>] in {
|
||||||
@ -666,6 +654,46 @@ let Features = "avx2", Attributes = [NoThrow, RequiredVectorWidth<128>] in {
|
|||||||
def maskstoreq : X86Builtin<"void(_Vector<2, long long int *>, _Vector<2, long long int>, _Vector<2, long long int>)">;
|
def maskstoreq : X86Builtin<"void(_Vector<2, long long int *>, _Vector<2, long long int>, _Vector<2, long long int>)">;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let Features = "avx2", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in {
|
||||||
|
def psllv8si : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>)">;
|
||||||
|
}
|
||||||
|
|
||||||
|
let Features = "avx2", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in {
|
||||||
|
def psllv4si : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>)">;
|
||||||
|
}
|
||||||
|
|
||||||
|
let Features = "avx2", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in {
|
||||||
|
def psllv4di : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, _Vector<4, long long int>)">;
|
||||||
|
}
|
||||||
|
|
||||||
|
let Features = "avx2", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in {
|
||||||
|
def psllv2di : X86Builtin<"_Vector<2, long long int>(_Vector<2, long long int>, _Vector<2, long long int>)">;
|
||||||
|
}
|
||||||
|
|
||||||
|
let Features = "avx2", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in {
|
||||||
|
def psrav8si : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>)">;
|
||||||
|
}
|
||||||
|
|
||||||
|
let Features = "avx2", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in {
|
||||||
|
def psrav4si : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>)">;
|
||||||
|
}
|
||||||
|
|
||||||
|
let Features = "avx2", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in {
|
||||||
|
def psrlv8si : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>)">;
|
||||||
|
}
|
||||||
|
|
||||||
|
let Features = "avx2", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in {
|
||||||
|
def psrlv4si : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>)">;
|
||||||
|
}
|
||||||
|
|
||||||
|
let Features = "avx2", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in {
|
||||||
|
def psrlv4di : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, _Vector<4, long long int>)">;
|
||||||
|
}
|
||||||
|
|
||||||
|
let Features = "avx2", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in {
|
||||||
|
def psrlv2di : X86Builtin<"_Vector<2, long long int>(_Vector<2, long long int>, _Vector<2, long long int>)">;
|
||||||
|
}
|
||||||
|
|
||||||
let Features = "avx2", Attributes = [NoThrow, RequiredVectorWidth<128>] in {
|
let Features = "avx2", Attributes = [NoThrow, RequiredVectorWidth<128>] in {
|
||||||
def gatherd_pd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, double const *, _Vector<4, int>, _Vector<2, double>, _Constant char)">;
|
def gatherd_pd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, double const *, _Vector<4, int>, _Vector<2, double>, _Constant char)">;
|
||||||
}
|
}
|
||||||
|
@ -1259,6 +1259,10 @@ public:
|
|||||||
ArrayRef<ConstraintInfo> OutputConstraints,
|
ArrayRef<ConstraintInfo> OutputConstraints,
|
||||||
unsigned &Index) const;
|
unsigned &Index) const;
|
||||||
|
|
||||||
|
std::string
|
||||||
|
simplifyConstraint(StringRef Constraint,
|
||||||
|
SmallVectorImpl<ConstraintInfo> *OutCons = nullptr) const;
|
||||||
|
|
||||||
// Constraint parm will be left pointing at the last character of
|
// Constraint parm will be left pointing at the last character of
|
||||||
// the constraint. In practice, it won't be changed unless the
|
// the constraint. In practice, it won't be changed unless the
|
||||||
// constraint is longer than one character.
|
// constraint is longer than one character.
|
||||||
|
@ -11669,24 +11669,13 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
|
|||||||
case clang::X86::BI__builtin_ia32_pmulhuw512:
|
case clang::X86::BI__builtin_ia32_pmulhuw512:
|
||||||
case clang::X86::BI__builtin_ia32_pmulhw128:
|
case clang::X86::BI__builtin_ia32_pmulhw128:
|
||||||
case clang::X86::BI__builtin_ia32_pmulhw256:
|
case clang::X86::BI__builtin_ia32_pmulhw256:
|
||||||
case clang::X86::BI__builtin_ia32_pmulhw512:
|
case clang::X86::BI__builtin_ia32_pmulhw512: {
|
||||||
case clang::X86::BI__builtin_ia32_psllv2di:
|
|
||||||
case clang::X86::BI__builtin_ia32_psllv4di:
|
|
||||||
case clang::X86::BI__builtin_ia32_psllv4si:
|
|
||||||
case clang::X86::BI__builtin_ia32_psllv8si:
|
|
||||||
case clang::X86::BI__builtin_ia32_psrav4si:
|
|
||||||
case clang::X86::BI__builtin_ia32_psrav8si:
|
|
||||||
case clang::X86::BI__builtin_ia32_psrlv2di:
|
|
||||||
case clang::X86::BI__builtin_ia32_psrlv4di:
|
|
||||||
case clang::X86::BI__builtin_ia32_psrlv4si:
|
|
||||||
case clang::X86::BI__builtin_ia32_psrlv8si:{
|
|
||||||
APValue SourceLHS, SourceRHS;
|
APValue SourceLHS, SourceRHS;
|
||||||
if (!EvaluateAsRValue(Info, E->getArg(0), SourceLHS) ||
|
if (!EvaluateAsRValue(Info, E->getArg(0), SourceLHS) ||
|
||||||
!EvaluateAsRValue(Info, E->getArg(1), SourceRHS))
|
!EvaluateAsRValue(Info, E->getArg(1), SourceRHS))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
QualType DestEltTy = E->getType()->castAs<VectorType>()->getElementType();
|
QualType DestEltTy = E->getType()->castAs<VectorType>()->getElementType();
|
||||||
bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
|
|
||||||
unsigned SourceLen = SourceLHS.getVectorLength();
|
unsigned SourceLen = SourceLHS.getVectorLength();
|
||||||
SmallVector<APValue, 4> ResultElements;
|
SmallVector<APValue, 4> ResultElements;
|
||||||
ResultElements.reserve(SourceLen);
|
ResultElements.reserve(SourceLen);
|
||||||
@ -11698,12 +11687,12 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
|
|||||||
case Builtin::BI__builtin_elementwise_add_sat:
|
case Builtin::BI__builtin_elementwise_add_sat:
|
||||||
ResultElements.push_back(APValue(
|
ResultElements.push_back(APValue(
|
||||||
APSInt(LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS),
|
APSInt(LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS),
|
||||||
DestUnsigned)));
|
DestEltTy->isUnsignedIntegerOrEnumerationType())));
|
||||||
break;
|
break;
|
||||||
case Builtin::BI__builtin_elementwise_sub_sat:
|
case Builtin::BI__builtin_elementwise_sub_sat:
|
||||||
ResultElements.push_back(APValue(
|
ResultElements.push_back(APValue(
|
||||||
APSInt(LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS),
|
APSInt(LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS),
|
||||||
DestUnsigned)));
|
DestEltTy->isUnsignedIntegerOrEnumerationType())));
|
||||||
break;
|
break;
|
||||||
case clang::X86::BI__builtin_ia32_pmulhuw128:
|
case clang::X86::BI__builtin_ia32_pmulhuw128:
|
||||||
case clang::X86::BI__builtin_ia32_pmulhuw256:
|
case clang::X86::BI__builtin_ia32_pmulhuw256:
|
||||||
@ -11717,40 +11706,6 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
|
|||||||
ResultElements.push_back(APValue(APSInt(llvm::APIntOps::mulhs(LHS, RHS),
|
ResultElements.push_back(APValue(APSInt(llvm::APIntOps::mulhs(LHS, RHS),
|
||||||
/*isUnsigned=*/false)));
|
/*isUnsigned=*/false)));
|
||||||
break;
|
break;
|
||||||
case clang::X86::BI__builtin_ia32_psllv2di:
|
|
||||||
case clang::X86::BI__builtin_ia32_psllv4di:
|
|
||||||
case clang::X86::BI__builtin_ia32_psllv4si:
|
|
||||||
case clang::X86::BI__builtin_ia32_psllv8si:
|
|
||||||
if (RHS.uge(RHS.getBitWidth())) {
|
|
||||||
ResultElements.push_back(
|
|
||||||
APValue(APSInt(APInt::getZero(RHS.getBitWidth()), DestUnsigned)));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ResultElements.push_back(
|
|
||||||
APValue(APSInt(LHS.shl(RHS.getZExtValue()), DestUnsigned)));
|
|
||||||
break;
|
|
||||||
case clang::X86::BI__builtin_ia32_psrav4si:
|
|
||||||
case clang::X86::BI__builtin_ia32_psrav8si:
|
|
||||||
if (RHS.uge(RHS.getBitWidth())) {
|
|
||||||
ResultElements.push_back(
|
|
||||||
APValue(APSInt(LHS.ashr(RHS.getBitWidth() - 1), DestUnsigned)));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ResultElements.push_back(
|
|
||||||
APValue(APSInt(LHS.ashr(RHS.getZExtValue()), DestUnsigned)));
|
|
||||||
break;
|
|
||||||
case clang::X86::BI__builtin_ia32_psrlv2di:
|
|
||||||
case clang::X86::BI__builtin_ia32_psrlv4di:
|
|
||||||
case clang::X86::BI__builtin_ia32_psrlv4si:
|
|
||||||
case clang::X86::BI__builtin_ia32_psrlv8si:
|
|
||||||
if (RHS.uge(RHS.getBitWidth())) {
|
|
||||||
ResultElements.push_back(
|
|
||||||
APValue(APSInt(APInt::getZero(RHS.getBitWidth()), DestUnsigned)));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ResultElements.push_back(
|
|
||||||
APValue(APSInt(LHS.lshr(RHS.getZExtValue()), DestUnsigned)));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "clang/Basic/LangOptions.h"
|
#include "clang/Basic/LangOptions.h"
|
||||||
#include "llvm/ADT/APFloat.h"
|
#include "llvm/ADT/APFloat.h"
|
||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
|
#include "llvm/ADT/StringExtras.h"
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include "llvm/TargetParser/TargetParser.h"
|
#include "llvm/TargetParser/TargetParser.h"
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
@ -1034,3 +1035,51 @@ void TargetInfo::copyAuxTarget(const TargetInfo *Aux) {
|
|||||||
auto *Src = static_cast<const TransferrableTargetInfo*>(Aux);
|
auto *Src = static_cast<const TransferrableTargetInfo*>(Aux);
|
||||||
*Target = *Src;
|
*Target = *Src;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
TargetInfo::simplifyConstraint(StringRef Constraint,
|
||||||
|
SmallVectorImpl<ConstraintInfo> *OutCons) const {
|
||||||
|
std::string Result;
|
||||||
|
|
||||||
|
for (const char *I = Constraint.begin(), *E = Constraint.end(); I < E; I++) {
|
||||||
|
switch (*I) {
|
||||||
|
default:
|
||||||
|
Result += convertConstraint(I);
|
||||||
|
break;
|
||||||
|
// Ignore these
|
||||||
|
case '*':
|
||||||
|
case '?':
|
||||||
|
case '!':
|
||||||
|
case '=': // Will see this and the following in mult-alt constraints.
|
||||||
|
case '+':
|
||||||
|
break;
|
||||||
|
case '#': // Ignore the rest of the constraint alternative.
|
||||||
|
while (I + 1 != E && I[1] != ',')
|
||||||
|
I++;
|
||||||
|
break;
|
||||||
|
case '&':
|
||||||
|
case '%':
|
||||||
|
Result += *I;
|
||||||
|
while (I + 1 != E && I[1] == *I)
|
||||||
|
I++;
|
||||||
|
break;
|
||||||
|
case ',':
|
||||||
|
Result += "|";
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
Result += "imr";
|
||||||
|
break;
|
||||||
|
case '[': {
|
||||||
|
assert(OutCons &&
|
||||||
|
"Must pass output names to constraints with a symbolic name");
|
||||||
|
unsigned Index;
|
||||||
|
bool ResolveResult = resolveSymbolicName(I, *OutCons, Index);
|
||||||
|
assert(ResolveResult && "Could not resolve symbolic name");
|
||||||
|
(void)ResolveResult;
|
||||||
|
Result += llvm::utostr(Index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
@ -174,9 +174,6 @@ protected:
|
|||||||
DefineStd(Builder, "unix", Opts);
|
DefineStd(Builder, "unix", Opts);
|
||||||
if (this->HasFloat128)
|
if (this->HasFloat128)
|
||||||
Builder.defineMacro("__FLOAT128__");
|
Builder.defineMacro("__FLOAT128__");
|
||||||
|
|
||||||
if (Opts.C11)
|
|
||||||
Builder.defineMacro("__STDC_NO_THREADS__");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -2454,56 +2454,6 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) {
|
|||||||
CaseRangeBlock = SavedCRBlock;
|
CaseRangeBlock = SavedCRBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string
|
|
||||||
SimplifyConstraint(const char *Constraint, const TargetInfo &Target,
|
|
||||||
SmallVectorImpl<TargetInfo::ConstraintInfo> *OutCons=nullptr) {
|
|
||||||
std::string Result;
|
|
||||||
|
|
||||||
while (*Constraint) {
|
|
||||||
switch (*Constraint) {
|
|
||||||
default:
|
|
||||||
Result += Target.convertConstraint(Constraint);
|
|
||||||
break;
|
|
||||||
// Ignore these
|
|
||||||
case '*':
|
|
||||||
case '?':
|
|
||||||
case '!':
|
|
||||||
case '=': // Will see this and the following in mult-alt constraints.
|
|
||||||
case '+':
|
|
||||||
break;
|
|
||||||
case '#': // Ignore the rest of the constraint alternative.
|
|
||||||
while (Constraint[1] && Constraint[1] != ',')
|
|
||||||
Constraint++;
|
|
||||||
break;
|
|
||||||
case '&':
|
|
||||||
case '%':
|
|
||||||
Result += *Constraint;
|
|
||||||
while (Constraint[1] && Constraint[1] == *Constraint)
|
|
||||||
Constraint++;
|
|
||||||
break;
|
|
||||||
case ',':
|
|
||||||
Result += "|";
|
|
||||||
break;
|
|
||||||
case 'g':
|
|
||||||
Result += "imr";
|
|
||||||
break;
|
|
||||||
case '[': {
|
|
||||||
assert(OutCons &&
|
|
||||||
"Must pass output names to constraints with a symbolic name");
|
|
||||||
unsigned Index;
|
|
||||||
bool result = Target.resolveSymbolicName(Constraint, *OutCons, Index);
|
|
||||||
assert(result && "Could not resolve symbolic name"); (void)result;
|
|
||||||
Result += llvm::utostr(Index);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Constraint++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// AddVariableConstraints - Look at AsmExpr and if it is a variable declared
|
/// AddVariableConstraints - Look at AsmExpr and if it is a variable declared
|
||||||
/// as using a particular register add that as a constraint that will be used
|
/// as using a particular register add that as a constraint that will be used
|
||||||
/// in this asm stmt.
|
/// in this asm stmt.
|
||||||
@ -2882,8 +2832,8 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
|
|||||||
|
|
||||||
// Simplify the output constraint.
|
// Simplify the output constraint.
|
||||||
std::string OutputConstraint(S.getOutputConstraint(i));
|
std::string OutputConstraint(S.getOutputConstraint(i));
|
||||||
OutputConstraint = SimplifyConstraint(OutputConstraint.c_str() + 1,
|
OutputConstraint = getTarget().simplifyConstraint(
|
||||||
getTarget(), &OutputConstraintInfos);
|
OutputConstraint.c_str() + 1, &OutputConstraintInfos);
|
||||||
|
|
||||||
const Expr *OutExpr = S.getOutputExpr(i);
|
const Expr *OutExpr = S.getOutputExpr(i);
|
||||||
OutExpr = OutExpr->IgnoreParenNoopCasts(getContext());
|
OutExpr = OutExpr->IgnoreParenNoopCasts(getContext());
|
||||||
@ -3045,8 +2995,8 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
|
|||||||
|
|
||||||
// Simplify the input constraint.
|
// Simplify the input constraint.
|
||||||
std::string InputConstraint(S.getInputConstraint(i));
|
std::string InputConstraint(S.getInputConstraint(i));
|
||||||
InputConstraint = SimplifyConstraint(InputConstraint.c_str(), getTarget(),
|
InputConstraint = getTarget().simplifyConstraint(InputConstraint.c_str(),
|
||||||
&OutputConstraintInfos);
|
&OutputConstraintInfos);
|
||||||
|
|
||||||
InputConstraint = AddVariableConstraints(
|
InputConstraint = AddVariableConstraints(
|
||||||
InputConstraint, *InputExpr->IgnoreParenNoopCasts(getContext()),
|
InputConstraint, *InputExpr->IgnoreParenNoopCasts(getContext()),
|
||||||
|
@ -3721,7 +3721,7 @@ _mm_maskstore_epi64(long long *__X, __m128i __M, __m128i __Y)
|
|||||||
/// A 256-bit vector of [8 x i32] containing the unsigned shift counts (in
|
/// A 256-bit vector of [8 x i32] containing the unsigned shift counts (in
|
||||||
/// bits).
|
/// bits).
|
||||||
/// \returns A 256-bit vector of [8 x i32] containing the result.
|
/// \returns A 256-bit vector of [8 x i32] containing the result.
|
||||||
static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
|
static __inline__ __m256i __DEFAULT_FN_ATTRS256
|
||||||
_mm256_sllv_epi32(__m256i __X, __m256i __Y)
|
_mm256_sllv_epi32(__m256i __X, __m256i __Y)
|
||||||
{
|
{
|
||||||
return (__m256i)__builtin_ia32_psllv8si((__v8si)__X, (__v8si)__Y);
|
return (__m256i)__builtin_ia32_psllv8si((__v8si)__X, (__v8si)__Y);
|
||||||
@ -3743,7 +3743,7 @@ _mm256_sllv_epi32(__m256i __X, __m256i __Y)
|
|||||||
/// A 128-bit vector of [4 x i32] containing the unsigned shift counts (in
|
/// A 128-bit vector of [4 x i32] containing the unsigned shift counts (in
|
||||||
/// bits).
|
/// bits).
|
||||||
/// \returns A 128-bit vector of [4 x i32] containing the result.
|
/// \returns A 128-bit vector of [4 x i32] containing the result.
|
||||||
static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
|
static __inline__ __m128i __DEFAULT_FN_ATTRS128
|
||||||
_mm_sllv_epi32(__m128i __X, __m128i __Y)
|
_mm_sllv_epi32(__m128i __X, __m128i __Y)
|
||||||
{
|
{
|
||||||
return (__m128i)__builtin_ia32_psllv4si((__v4si)__X, (__v4si)__Y);
|
return (__m128i)__builtin_ia32_psllv4si((__v4si)__X, (__v4si)__Y);
|
||||||
@ -3765,7 +3765,7 @@ _mm_sllv_epi32(__m128i __X, __m128i __Y)
|
|||||||
/// A 256-bit vector of [4 x i64] containing the unsigned shift counts (in
|
/// A 256-bit vector of [4 x i64] containing the unsigned shift counts (in
|
||||||
/// bits).
|
/// bits).
|
||||||
/// \returns A 256-bit vector of [4 x i64] containing the result.
|
/// \returns A 256-bit vector of [4 x i64] containing the result.
|
||||||
static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
|
static __inline__ __m256i __DEFAULT_FN_ATTRS256
|
||||||
_mm256_sllv_epi64(__m256i __X, __m256i __Y)
|
_mm256_sllv_epi64(__m256i __X, __m256i __Y)
|
||||||
{
|
{
|
||||||
return (__m256i)__builtin_ia32_psllv4di((__v4di)__X, (__v4di)__Y);
|
return (__m256i)__builtin_ia32_psllv4di((__v4di)__X, (__v4di)__Y);
|
||||||
@ -3787,7 +3787,7 @@ _mm256_sllv_epi64(__m256i __X, __m256i __Y)
|
|||||||
/// A 128-bit vector of [2 x i64] containing the unsigned shift counts (in
|
/// A 128-bit vector of [2 x i64] containing the unsigned shift counts (in
|
||||||
/// bits).
|
/// bits).
|
||||||
/// \returns A 128-bit vector of [2 x i64] containing the result.
|
/// \returns A 128-bit vector of [2 x i64] containing the result.
|
||||||
static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
|
static __inline__ __m128i __DEFAULT_FN_ATTRS128
|
||||||
_mm_sllv_epi64(__m128i __X, __m128i __Y)
|
_mm_sllv_epi64(__m128i __X, __m128i __Y)
|
||||||
{
|
{
|
||||||
return (__m128i)__builtin_ia32_psllv2di((__v2di)__X, (__v2di)__Y);
|
return (__m128i)__builtin_ia32_psllv2di((__v2di)__X, (__v2di)__Y);
|
||||||
@ -3810,7 +3810,7 @@ _mm_sllv_epi64(__m128i __X, __m128i __Y)
|
|||||||
/// A 256-bit vector of [8 x i32] containing the unsigned shift counts (in
|
/// A 256-bit vector of [8 x i32] containing the unsigned shift counts (in
|
||||||
/// bits).
|
/// bits).
|
||||||
/// \returns A 256-bit vector of [8 x i32] containing the result.
|
/// \returns A 256-bit vector of [8 x i32] containing the result.
|
||||||
static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
|
static __inline__ __m256i __DEFAULT_FN_ATTRS256
|
||||||
_mm256_srav_epi32(__m256i __X, __m256i __Y)
|
_mm256_srav_epi32(__m256i __X, __m256i __Y)
|
||||||
{
|
{
|
||||||
return (__m256i)__builtin_ia32_psrav8si((__v8si)__X, (__v8si)__Y);
|
return (__m256i)__builtin_ia32_psrav8si((__v8si)__X, (__v8si)__Y);
|
||||||
@ -3833,7 +3833,7 @@ _mm256_srav_epi32(__m256i __X, __m256i __Y)
|
|||||||
/// A 128-bit vector of [4 x i32] containing the unsigned shift counts (in
|
/// A 128-bit vector of [4 x i32] containing the unsigned shift counts (in
|
||||||
/// bits).
|
/// bits).
|
||||||
/// \returns A 128-bit vector of [4 x i32] containing the result.
|
/// \returns A 128-bit vector of [4 x i32] containing the result.
|
||||||
static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
|
static __inline__ __m128i __DEFAULT_FN_ATTRS128
|
||||||
_mm_srav_epi32(__m128i __X, __m128i __Y)
|
_mm_srav_epi32(__m128i __X, __m128i __Y)
|
||||||
{
|
{
|
||||||
return (__m128i)__builtin_ia32_psrav4si((__v4si)__X, (__v4si)__Y);
|
return (__m128i)__builtin_ia32_psrav4si((__v4si)__X, (__v4si)__Y);
|
||||||
@ -3855,7 +3855,7 @@ _mm_srav_epi32(__m128i __X, __m128i __Y)
|
|||||||
/// A 256-bit vector of [8 x i32] containing the unsigned shift counts (in
|
/// A 256-bit vector of [8 x i32] containing the unsigned shift counts (in
|
||||||
/// bits).
|
/// bits).
|
||||||
/// \returns A 256-bit vector of [8 x i32] containing the result.
|
/// \returns A 256-bit vector of [8 x i32] containing the result.
|
||||||
static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
|
static __inline__ __m256i __DEFAULT_FN_ATTRS256
|
||||||
_mm256_srlv_epi32(__m256i __X, __m256i __Y)
|
_mm256_srlv_epi32(__m256i __X, __m256i __Y)
|
||||||
{
|
{
|
||||||
return (__m256i)__builtin_ia32_psrlv8si((__v8si)__X, (__v8si)__Y);
|
return (__m256i)__builtin_ia32_psrlv8si((__v8si)__X, (__v8si)__Y);
|
||||||
@ -3877,7 +3877,7 @@ _mm256_srlv_epi32(__m256i __X, __m256i __Y)
|
|||||||
/// A 128-bit vector of [4 x i32] containing the unsigned shift counts (in
|
/// A 128-bit vector of [4 x i32] containing the unsigned shift counts (in
|
||||||
/// bits).
|
/// bits).
|
||||||
/// \returns A 128-bit vector of [4 x i32] containing the result.
|
/// \returns A 128-bit vector of [4 x i32] containing the result.
|
||||||
static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
|
static __inline__ __m128i __DEFAULT_FN_ATTRS128
|
||||||
_mm_srlv_epi32(__m128i __X, __m128i __Y)
|
_mm_srlv_epi32(__m128i __X, __m128i __Y)
|
||||||
{
|
{
|
||||||
return (__m128i)__builtin_ia32_psrlv4si((__v4si)__X, (__v4si)__Y);
|
return (__m128i)__builtin_ia32_psrlv4si((__v4si)__X, (__v4si)__Y);
|
||||||
@ -3899,7 +3899,7 @@ _mm_srlv_epi32(__m128i __X, __m128i __Y)
|
|||||||
/// A 256-bit vector of [4 x i64] containing the unsigned shift counts (in
|
/// A 256-bit vector of [4 x i64] containing the unsigned shift counts (in
|
||||||
/// bits).
|
/// bits).
|
||||||
/// \returns A 256-bit vector of [4 x i64] containing the result.
|
/// \returns A 256-bit vector of [4 x i64] containing the result.
|
||||||
static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR
|
static __inline__ __m256i __DEFAULT_FN_ATTRS256
|
||||||
_mm256_srlv_epi64(__m256i __X, __m256i __Y)
|
_mm256_srlv_epi64(__m256i __X, __m256i __Y)
|
||||||
{
|
{
|
||||||
return (__m256i)__builtin_ia32_psrlv4di((__v4di)__X, (__v4di)__Y);
|
return (__m256i)__builtin_ia32_psrlv4di((__v4di)__X, (__v4di)__Y);
|
||||||
@ -3921,7 +3921,7 @@ _mm256_srlv_epi64(__m256i __X, __m256i __Y)
|
|||||||
/// A 128-bit vector of [2 x i64] containing the unsigned shift counts (in
|
/// A 128-bit vector of [2 x i64] containing the unsigned shift counts (in
|
||||||
/// bits).
|
/// bits).
|
||||||
/// \returns A 128-bit vector of [2 x i64] containing the result.
|
/// \returns A 128-bit vector of [2 x i64] containing the result.
|
||||||
static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR
|
static __inline__ __m128i __DEFAULT_FN_ATTRS128
|
||||||
_mm_srlv_epi64(__m128i __X, __m128i __Y)
|
_mm_srlv_epi64(__m128i __X, __m128i __Y)
|
||||||
{
|
{
|
||||||
return (__m128i)__builtin_ia32_psrlv2di((__v2di)__X, (__v2di)__Y);
|
return (__m128i)__builtin_ia32_psrlv2di((__v2di)__X, (__v2di)__Y);
|
||||||
|
@ -327,6 +327,7 @@ __m256i test_mm256_cvtepi8_epi16(__m128i a) {
|
|||||||
// CHECK: sext <16 x i8> %{{.*}} to <16 x i16>
|
// CHECK: sext <16 x i8> %{{.*}} to <16 x i16>
|
||||||
return _mm256_cvtepi8_epi16(a);
|
return _mm256_cvtepi8_epi16(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CONSTEXPR(match_v16hi(_mm256_cvtepi8_epi16(_mm_setr_epi8(-3, 2, -1, 0, 1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12)), -3, 2, -1, 0, 1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12));
|
TEST_CONSTEXPR(match_v16hi(_mm256_cvtepi8_epi16(_mm_setr_epi8(-3, 2, -1, 0, 1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12)), -3, 2, -1, 0, 1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12));
|
||||||
|
|
||||||
__m256i test_mm256_cvtepi8_epi32(__m128i a) {
|
__m256i test_mm256_cvtepi8_epi32(__m128i a) {
|
||||||
@ -335,6 +336,7 @@ __m256i test_mm256_cvtepi8_epi32(__m128i a) {
|
|||||||
// CHECK: sext <8 x i8> %{{.*}} to <8 x i32>
|
// CHECK: sext <8 x i8> %{{.*}} to <8 x i32>
|
||||||
return _mm256_cvtepi8_epi32(a);
|
return _mm256_cvtepi8_epi32(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CONSTEXPR(match_v8si(_mm256_cvtepi8_epi32(_mm_setr_epi8(-3, 2, -1, 0, 1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12)), -3, 2, -1, 0, 1, -2, 3, -4));
|
TEST_CONSTEXPR(match_v8si(_mm256_cvtepi8_epi32(_mm_setr_epi8(-3, 2, -1, 0, 1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12)), -3, 2, -1, 0, 1, -2, 3, -4));
|
||||||
|
|
||||||
__m256i test_mm256_cvtepi8_epi64(__m128i a) {
|
__m256i test_mm256_cvtepi8_epi64(__m128i a) {
|
||||||
@ -343,6 +345,7 @@ __m256i test_mm256_cvtepi8_epi64(__m128i a) {
|
|||||||
// CHECK: sext <4 x i8> %{{.*}} to <4 x i64>
|
// CHECK: sext <4 x i8> %{{.*}} to <4 x i64>
|
||||||
return _mm256_cvtepi8_epi64(a);
|
return _mm256_cvtepi8_epi64(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CONSTEXPR(match_v4di(_mm256_cvtepi8_epi64(_mm_setr_epi8(-3, 2, -1, 0, 1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12)), -3, 2, -1, 0));
|
TEST_CONSTEXPR(match_v4di(_mm256_cvtepi8_epi64(_mm_setr_epi8(-3, 2, -1, 0, 1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12)), -3, 2, -1, 0));
|
||||||
|
|
||||||
__m256i test_mm256_cvtepi16_epi32(__m128i a) {
|
__m256i test_mm256_cvtepi16_epi32(__m128i a) {
|
||||||
@ -350,6 +353,7 @@ __m256i test_mm256_cvtepi16_epi32(__m128i a) {
|
|||||||
// CHECK: sext <8 x i16> %{{.*}} to <8 x i32>
|
// CHECK: sext <8 x i16> %{{.*}} to <8 x i32>
|
||||||
return _mm256_cvtepi16_epi32(a);
|
return _mm256_cvtepi16_epi32(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CONSTEXPR(match_v8si(_mm256_cvtepi16_epi32(_mm_setr_epi16(-300, 2, -1, 0, 1, -2, 3, -4)), -300, 2, -1, 0, 1, -2, 3, -4));
|
TEST_CONSTEXPR(match_v8si(_mm256_cvtepi16_epi32(_mm_setr_epi16(-300, 2, -1, 0, 1, -2, 3, -4)), -300, 2, -1, 0, 1, -2, 3, -4));
|
||||||
|
|
||||||
__m256i test_mm256_cvtepi16_epi64(__m128i a) {
|
__m256i test_mm256_cvtepi16_epi64(__m128i a) {
|
||||||
@ -358,6 +362,7 @@ __m256i test_mm256_cvtepi16_epi64(__m128i a) {
|
|||||||
// CHECK: sext <4 x i16> %{{.*}} to <4 x i64>
|
// CHECK: sext <4 x i16> %{{.*}} to <4 x i64>
|
||||||
return _mm256_cvtepi16_epi64(a);
|
return _mm256_cvtepi16_epi64(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CONSTEXPR(match_v4di(_mm256_cvtepi16_epi64(_mm_setr_epi16(-300, 2, -1, 0, 1, -2, 3, -4)), -300, 2, -1, 0));
|
TEST_CONSTEXPR(match_v4di(_mm256_cvtepi16_epi64(_mm_setr_epi16(-300, 2, -1, 0, 1, -2, 3, -4)), -300, 2, -1, 0));
|
||||||
|
|
||||||
__m256i test_mm256_cvtepi32_epi64(__m128i a) {
|
__m256i test_mm256_cvtepi32_epi64(__m128i a) {
|
||||||
@ -365,6 +370,7 @@ __m256i test_mm256_cvtepi32_epi64(__m128i a) {
|
|||||||
// CHECK: sext <4 x i32> %{{.*}} to <4 x i64>
|
// CHECK: sext <4 x i32> %{{.*}} to <4 x i64>
|
||||||
return _mm256_cvtepi32_epi64(a);
|
return _mm256_cvtepi32_epi64(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CONSTEXPR(match_v4di(_mm256_cvtepi32_epi64(_mm_setr_epi32(-70000, 2, -1, 0)), -70000, 2, -1, 0));
|
TEST_CONSTEXPR(match_v4di(_mm256_cvtepi32_epi64(_mm_setr_epi32(-70000, 2, -1, 0)), -70000, 2, -1, 0));
|
||||||
|
|
||||||
__m256i test_mm256_cvtepu8_epi16(__m128i a) {
|
__m256i test_mm256_cvtepu8_epi16(__m128i a) {
|
||||||
@ -372,6 +378,7 @@ __m256i test_mm256_cvtepu8_epi16(__m128i a) {
|
|||||||
// CHECK: zext <16 x i8> %{{.*}} to <16 x i16>
|
// CHECK: zext <16 x i8> %{{.*}} to <16 x i16>
|
||||||
return _mm256_cvtepu8_epi16(a);
|
return _mm256_cvtepu8_epi16(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CONSTEXPR(match_v16hi(_mm256_cvtepu8_epi16(_mm_setr_epi8(-3, 2, -1, 0, 1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12)), 253, 2, 255, 0, 1, 254, 3, 252, 5, 250, 7, 248, 9, 246, 11, 244));
|
TEST_CONSTEXPR(match_v16hi(_mm256_cvtepu8_epi16(_mm_setr_epi8(-3, 2, -1, 0, 1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12)), 253, 2, 255, 0, 1, 254, 3, 252, 5, 250, 7, 248, 9, 246, 11, 244));
|
||||||
|
|
||||||
__m256i test_mm256_cvtepu8_epi32(__m128i a) {
|
__m256i test_mm256_cvtepu8_epi32(__m128i a) {
|
||||||
@ -380,6 +387,7 @@ __m256i test_mm256_cvtepu8_epi32(__m128i a) {
|
|||||||
// CHECK: zext <8 x i8> %{{.*}} to <8 x i32>
|
// CHECK: zext <8 x i8> %{{.*}} to <8 x i32>
|
||||||
return _mm256_cvtepu8_epi32(a);
|
return _mm256_cvtepu8_epi32(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CONSTEXPR(match_v8si(_mm256_cvtepu8_epi32(_mm_setr_epi8(-3, 2, -1, 0, 1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12)), 253, 2, 255, 0, 1, 254, 3, 252));
|
TEST_CONSTEXPR(match_v8si(_mm256_cvtepu8_epi32(_mm_setr_epi8(-3, 2, -1, 0, 1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12)), 253, 2, 255, 0, 1, 254, 3, 252));
|
||||||
|
|
||||||
__m256i test_mm256_cvtepu8_epi64(__m128i a) {
|
__m256i test_mm256_cvtepu8_epi64(__m128i a) {
|
||||||
@ -388,6 +396,7 @@ __m256i test_mm256_cvtepu8_epi64(__m128i a) {
|
|||||||
// CHECK: zext <4 x i8> %{{.*}} to <4 x i64>
|
// CHECK: zext <4 x i8> %{{.*}} to <4 x i64>
|
||||||
return _mm256_cvtepu8_epi64(a);
|
return _mm256_cvtepu8_epi64(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CONSTEXPR(match_v4di(_mm256_cvtepu8_epi64(_mm_setr_epi8(-3, 2, -1, 0, 1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12)), 253, 2, 255, 0));
|
TEST_CONSTEXPR(match_v4di(_mm256_cvtepu8_epi64(_mm_setr_epi8(-3, 2, -1, 0, 1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12)), 253, 2, 255, 0));
|
||||||
|
|
||||||
__m256i test_mm256_cvtepu16_epi32(__m128i a) {
|
__m256i test_mm256_cvtepu16_epi32(__m128i a) {
|
||||||
@ -395,6 +404,7 @@ __m256i test_mm256_cvtepu16_epi32(__m128i a) {
|
|||||||
// CHECK: zext <8 x i16> {{.*}} to <8 x i32>
|
// CHECK: zext <8 x i16> {{.*}} to <8 x i32>
|
||||||
return _mm256_cvtepu16_epi32(a);
|
return _mm256_cvtepu16_epi32(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CONSTEXPR(match_v8si(_mm256_cvtepu16_epi32(_mm_setr_epi16(-300, 2, -1, 0, 1, -2, 3, -4)), 65236, 2, 65535, 0, 1, 65534, 3, 65532));
|
TEST_CONSTEXPR(match_v8si(_mm256_cvtepu16_epi32(_mm_setr_epi16(-300, 2, -1, 0, 1, -2, 3, -4)), 65236, 2, 65535, 0, 1, 65534, 3, 65532));
|
||||||
|
|
||||||
__m256i test_mm256_cvtepu16_epi64(__m128i a) {
|
__m256i test_mm256_cvtepu16_epi64(__m128i a) {
|
||||||
@ -403,6 +413,7 @@ __m256i test_mm256_cvtepu16_epi64(__m128i a) {
|
|||||||
// CHECK: zext <4 x i16> %{{.*}} to <4 x i64>
|
// CHECK: zext <4 x i16> %{{.*}} to <4 x i64>
|
||||||
return _mm256_cvtepu16_epi64(a);
|
return _mm256_cvtepu16_epi64(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CONSTEXPR(match_v4di(_mm256_cvtepu16_epi64(_mm_setr_epi16(-300, 2, -1, 0, 1, -2, 3, -4)), 65236, 2, 65535, 0));
|
TEST_CONSTEXPR(match_v4di(_mm256_cvtepu16_epi64(_mm_setr_epi16(-300, 2, -1, 0, 1, -2, 3, -4)), 65236, 2, 65535, 0));
|
||||||
|
|
||||||
__m256i test_mm256_cvtepu32_epi64(__m128i a) {
|
__m256i test_mm256_cvtepu32_epi64(__m128i a) {
|
||||||
@ -410,6 +421,7 @@ __m256i test_mm256_cvtepu32_epi64(__m128i a) {
|
|||||||
// CHECK: zext <4 x i32> %{{.*}} to <4 x i64>
|
// CHECK: zext <4 x i32> %{{.*}} to <4 x i64>
|
||||||
return _mm256_cvtepu32_epi64(a);
|
return _mm256_cvtepu32_epi64(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CONSTEXPR(match_v4di(_mm256_cvtepu32_epi64(_mm_setr_epi32(-70000, 2, -1, 0)), 4294897296, 2, 4294967295, 0));
|
TEST_CONSTEXPR(match_v4di(_mm256_cvtepu32_epi64(_mm_setr_epi32(-70000, 2, -1, 0)), 4294897296, 2, 4294967295, 0));
|
||||||
|
|
||||||
__m128i test0_mm256_extracti128_si256_0(__m256i a) {
|
__m128i test0_mm256_extracti128_si256_0(__m256i a) {
|
||||||
@ -1108,28 +1120,24 @@ __m128i test_mm_sllv_epi32(__m128i a, __m128i b) {
|
|||||||
// CHECK: call <4 x i32> @llvm.x86.avx2.psllv.d(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
|
// CHECK: call <4 x i32> @llvm.x86.avx2.psllv.d(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
|
||||||
return _mm_sllv_epi32(a, b);
|
return _mm_sllv_epi32(a, b);
|
||||||
}
|
}
|
||||||
TEST_CONSTEXPR(match_v4si(_mm_sllv_epi32((__m128i)(__v4si){1, -2, 3, -4}, (__m128i)(__v4si){1, 2, 3, -4}), 2, -8, 24, 0));
|
|
||||||
|
|
||||||
__m256i test_mm256_sllv_epi32(__m256i a, __m256i b) {
|
__m256i test_mm256_sllv_epi32(__m256i a, __m256i b) {
|
||||||
// CHECK-LABEL: test_mm256_sllv_epi32
|
// CHECK-LABEL: test_mm256_sllv_epi32
|
||||||
// CHECK: call <8 x i32> @llvm.x86.avx2.psllv.d.256(<8 x i32> %{{.*}}, <8 x i32> %{{.*}})
|
// CHECK: call <8 x i32> @llvm.x86.avx2.psllv.d.256(<8 x i32> %{{.*}}, <8 x i32> %{{.*}})
|
||||||
return _mm256_sllv_epi32(a, b);
|
return _mm256_sllv_epi32(a, b);
|
||||||
}
|
}
|
||||||
TEST_CONSTEXPR(match_v8si(_mm256_sllv_epi32((__m256i)(__v8si){1, -2, 3, -4, 5, -6, 7, -8}, (__m256i)(__v8si){1, 2, 3, 4, -17, 31, 33, 29}), 2, -8, 24, -64, 0, 0, 0, 0));
|
|
||||||
|
|
||||||
__m128i test_mm_sllv_epi64(__m128i a, __m128i b) {
|
__m128i test_mm_sllv_epi64(__m128i a, __m128i b) {
|
||||||
// CHECK-LABEL: test_mm_sllv_epi64
|
// CHECK-LABEL: test_mm_sllv_epi64
|
||||||
// CHECK: call {{.*}}<2 x i64> @llvm.x86.avx2.psllv.q(<2 x i64> %{{.*}}, <2 x i64> %{{.*}})
|
// CHECK: call {{.*}}<2 x i64> @llvm.x86.avx2.psllv.q(<2 x i64> %{{.*}}, <2 x i64> %{{.*}})
|
||||||
return _mm_sllv_epi64(a, b);
|
return _mm_sllv_epi64(a, b);
|
||||||
}
|
}
|
||||||
TEST_CONSTEXPR(match_m128i(_mm_sllv_epi64((__m128i)(__v2di){1, -3}, (__m128i)(__v2di){8, 63}), 256, 0x8000000000000000ULL));
|
|
||||||
|
|
||||||
__m256i test_mm256_sllv_epi64(__m256i a, __m256i b) {
|
__m256i test_mm256_sllv_epi64(__m256i a, __m256i b) {
|
||||||
// CHECK-LABEL: test_mm256_sllv_epi64
|
// CHECK-LABEL: test_mm256_sllv_epi64
|
||||||
// CHECK: call {{.*}}<4 x i64> @llvm.x86.avx2.psllv.q.256(<4 x i64> %{{.*}}, <4 x i64> %{{.*}})
|
// CHECK: call {{.*}}<4 x i64> @llvm.x86.avx2.psllv.q.256(<4 x i64> %{{.*}}, <4 x i64> %{{.*}})
|
||||||
return _mm256_sllv_epi64(a, b);
|
return _mm256_sllv_epi64(a, b);
|
||||||
}
|
}
|
||||||
TEST_CONSTEXPR(match_m256i(_mm256_sllv_epi64((__m256i)(__v4di){1, -2, 3, -4}, (__m256i)(__v4di){1, 2, 3, -4}), 2, -8, 24, 0));
|
|
||||||
|
|
||||||
__m256i test_mm256_sra_epi16(__m256i a, __m128i b) {
|
__m256i test_mm256_sra_epi16(__m256i a, __m128i b) {
|
||||||
// CHECK-LABEL: test_mm256_sra_epi16
|
// CHECK-LABEL: test_mm256_sra_epi16
|
||||||
@ -1172,14 +1180,12 @@ __m128i test_mm_srav_epi32(__m128i a, __m128i b) {
|
|||||||
// CHECK: call <4 x i32> @llvm.x86.avx2.psrav.d(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
|
// CHECK: call <4 x i32> @llvm.x86.avx2.psrav.d(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
|
||||||
return _mm_srav_epi32(a, b);
|
return _mm_srav_epi32(a, b);
|
||||||
}
|
}
|
||||||
TEST_CONSTEXPR(match_v4si(_mm_srav_epi32((__m128i)(__v4si){1, -2, 3, -4}, (__m128i)(__v4si){1, 2, 3, -4}), 0, -1, 0, -1));
|
|
||||||
|
|
||||||
__m256i test_mm256_srav_epi32(__m256i a, __m256i b) {
|
__m256i test_mm256_srav_epi32(__m256i a, __m256i b) {
|
||||||
// CHECK-LABEL: test_mm256_srav_epi32
|
// CHECK-LABEL: test_mm256_srav_epi32
|
||||||
// CHECK: call <8 x i32> @llvm.x86.avx2.psrav.d.256(<8 x i32> %{{.*}}, <8 x i32> %{{.*}})
|
// CHECK: call <8 x i32> @llvm.x86.avx2.psrav.d.256(<8 x i32> %{{.*}}, <8 x i32> %{{.*}})
|
||||||
return _mm256_srav_epi32(a, b);
|
return _mm256_srav_epi32(a, b);
|
||||||
}
|
}
|
||||||
TEST_CONSTEXPR(match_v8si(_mm256_srav_epi32((__m256i)(__v8si){1, -2, 3, -4, 5, -6, 7, -8}, (__m256i)(__v8si){1, 2, 3, 4, -17, 31, 33, 29}), 0, -1, 0, -1, 0, -1, 0, -1));
|
|
||||||
|
|
||||||
__m256i test_mm256_srl_epi16(__m256i a, __m128i b) {
|
__m256i test_mm256_srl_epi16(__m256i a, __m128i b) {
|
||||||
// CHECK-LABEL: test_mm256_srl_epi16
|
// CHECK-LABEL: test_mm256_srl_epi16
|
||||||
@ -1246,28 +1252,24 @@ __m128i test_mm_srlv_epi32(__m128i a, __m128i b) {
|
|||||||
// CHECK: call <4 x i32> @llvm.x86.avx2.psrlv.d(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
|
// CHECK: call <4 x i32> @llvm.x86.avx2.psrlv.d(<4 x i32> %{{.*}}, <4 x i32> %{{.*}})
|
||||||
return _mm_srlv_epi32(a, b);
|
return _mm_srlv_epi32(a, b);
|
||||||
}
|
}
|
||||||
TEST_CONSTEXPR(match_v4si(_mm_srlv_epi32((__m128i)(__v4si){1, -2, 3, -4}, (__m128i)(__v4si){1, 2, 3, -4}), 0, 1073741823, 0, 0));
|
|
||||||
|
|
||||||
__m256i test_mm256_srlv_epi32(__m256i a, __m256i b) {
|
__m256i test_mm256_srlv_epi32(__m256i a, __m256i b) {
|
||||||
// CHECK-LABEL: test_mm256_srlv_epi32
|
// CHECK-LABEL: test_mm256_srlv_epi32
|
||||||
// CHECK: call <8 x i32> @llvm.x86.avx2.psrlv.d.256(<8 x i32> %{{.*}}, <8 x i32> %{{.*}})
|
// CHECK: call <8 x i32> @llvm.x86.avx2.psrlv.d.256(<8 x i32> %{{.*}}, <8 x i32> %{{.*}})
|
||||||
return _mm256_srlv_epi32(a, b);
|
return _mm256_srlv_epi32(a, b);
|
||||||
}
|
}
|
||||||
TEST_CONSTEXPR(match_v8si(_mm256_srlv_epi32((__m256i)(__v8si){1, -2, 3, -4, 5, -6, 7, -8}, (__m256i)(__v8si){1, 2, 3, 4, -17, 31, 33, 29}), 0, 1073741823, 0, 268435455, 0, 1, 0, 7));
|
|
||||||
|
|
||||||
__m128i test_mm_srlv_epi64(__m128i a, __m128i b) {
|
__m128i test_mm_srlv_epi64(__m128i a, __m128i b) {
|
||||||
// CHECK-LABEL: test_mm_srlv_epi64
|
// CHECK-LABEL: test_mm_srlv_epi64
|
||||||
// CHECK: call {{.*}}<2 x i64> @llvm.x86.avx2.psrlv.q(<2 x i64> %{{.*}}, <2 x i64> %{{.*}})
|
// CHECK: call {{.*}}<2 x i64> @llvm.x86.avx2.psrlv.q(<2 x i64> %{{.*}}, <2 x i64> %{{.*}})
|
||||||
return _mm_srlv_epi64(a, b);
|
return _mm_srlv_epi64(a, b);
|
||||||
}
|
}
|
||||||
TEST_CONSTEXPR(match_m128i(_mm_srlv_epi64((__m128i)(__v2di){1, -3}, (__m128i)(__v2di){8, 63}), 0, 1));
|
|
||||||
|
|
||||||
__m256i test_mm256_srlv_epi64(__m256i a, __m256i b) {
|
__m256i test_mm256_srlv_epi64(__m256i a, __m256i b) {
|
||||||
// CHECK-LABEL: test_mm256_srlv_epi64
|
// CHECK-LABEL: test_mm256_srlv_epi64
|
||||||
// CHECK: call {{.*}}<4 x i64> @llvm.x86.avx2.psrlv.q.256(<4 x i64> %{{.*}}, <4 x i64> %{{.*}})
|
// CHECK: call {{.*}}<4 x i64> @llvm.x86.avx2.psrlv.q.256(<4 x i64> %{{.*}}, <4 x i64> %{{.*}})
|
||||||
return _mm256_srlv_epi64(a, b);
|
return _mm256_srlv_epi64(a, b);
|
||||||
}
|
}
|
||||||
TEST_CONSTEXPR(match_m256i(_mm256_srlv_epi64((__m256i)(__v4di){1, -2, 3, -4}, (__m256i)(__v4di){1, 2, 3, -4}), 0, 0x3FFFFFFFFFFFFFFFULL, 0, 0));
|
|
||||||
|
|
||||||
__m256i test_mm256_stream_load_si256(__m256i const *a) {
|
__m256i test_mm256_stream_load_si256(__m256i const *a) {
|
||||||
// CHECK-LABEL: test_mm256_stream_load_si256
|
// CHECK-LABEL: test_mm256_stream_load_si256
|
||||||
|
@ -1622,14 +1622,6 @@
|
|||||||
// RUN: %clang_cc1 -x c -std=c99 -E -dM -ffreestanding -triple=amd64-unknown-openbsd < /dev/null | FileCheck -match-full-lines -check-prefix OPENBSD-STDC-N %s
|
// RUN: %clang_cc1 -x c -std=c99 -E -dM -ffreestanding -triple=amd64-unknown-openbsd < /dev/null | FileCheck -match-full-lines -check-prefix OPENBSD-STDC-N %s
|
||||||
// OPENBSD-STDC-N-NOT:#define __STDC_NO_THREADS__ 1
|
// OPENBSD-STDC-N-NOT:#define __STDC_NO_THREADS__ 1
|
||||||
//
|
//
|
||||||
// RUN: %clang_cc1 -x c -std=c11 -E -dM -ffreestanding -triple=x86_64-unknown-dragonfly < /dev/null | FileCheck -match-full-lines -check-prefix DRAGONFLY-STDC %s
|
|
||||||
// RUN: %clang_cc1 -x c -std=gnu11 -E -dM -ffreestanding -triple=x86_64-unknown-dragonfly < /dev/null | FileCheck -match-full-lines -check-prefix DRAGONFLY-STDC %s
|
|
||||||
// RUN: %clang_cc1 -x c -std=c17 -E -dM -ffreestanding -triple=x86_64-unknown-dragonfly < /dev/null | FileCheck -match-full-lines -check-prefix DRAGONFLY-STDC %s
|
|
||||||
// DRAGONFLY-STDC:#define __STDC_NO_THREADS__ 1
|
|
||||||
//
|
|
||||||
// RUN: %clang_cc1 -x c -std=c99 -E -dM -ffreestanding -triple=x86_64-unknown-dragonfly < /dev/null | FileCheck -match-full-lines -check-prefix DRAGONFLY-STDC-N %s
|
|
||||||
// DRAGONFLY-STDC-N-NOT:#define __STDC_NO_THREADS__ 1
|
|
||||||
//
|
|
||||||
// RUN: %clang_cc1 -triple=aarch64-unknown-managarm-mlibc -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix MANAGARM %s
|
// RUN: %clang_cc1 -triple=aarch64-unknown-managarm-mlibc -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix MANAGARM %s
|
||||||
// RUN: %clang_cc1 -triple=riscv64-unknown-managarm-mlibc -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix MANAGARM %s
|
// RUN: %clang_cc1 -triple=riscv64-unknown-managarm-mlibc -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix MANAGARM %s
|
||||||
// RUN: %clang_cc1 -triple=x86_64-unknown-managarm-mlibc -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix MANAGARM %s
|
// RUN: %clang_cc1 -triple=x86_64-unknown-managarm-mlibc -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix MANAGARM %s
|
||||||
|
@ -106,12 +106,6 @@ if(MSVC)
|
|||||||
endif()
|
endif()
|
||||||
set(ASAN_CFLAGS ${SANITIZER_COMMON_CFLAGS})
|
set(ASAN_CFLAGS ${SANITIZER_COMMON_CFLAGS})
|
||||||
|
|
||||||
# Win/ASan relies on the runtime functions being hotpatchable. See
|
|
||||||
# https://github.com/llvm/llvm-project/pull/149444
|
|
||||||
if(MSVC)
|
|
||||||
list(APPEND ASAN_CFLAGS /hotpatch)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
append_list_if(MSVC /Zl ASAN_CFLAGS)
|
append_list_if(MSVC /Zl ASAN_CFLAGS)
|
||||||
|
|
||||||
set(ASAN_COMMON_DEFINITIONS "")
|
set(ASAN_COMMON_DEFINITIONS "")
|
||||||
|
@ -2917,11 +2917,10 @@ mlir::Value IntrinsicLibrary::genAtand(mlir::Type resultType,
|
|||||||
mlir::FunctionType::get(context, {resultType}, {args[0].getType()});
|
mlir::FunctionType::get(context, {resultType}, {args[0].getType()});
|
||||||
atan = getRuntimeCallGenerator("atan", ftype)(builder, loc, args);
|
atan = getRuntimeCallGenerator("atan", ftype)(builder, loc, args);
|
||||||
}
|
}
|
||||||
const llvm::fltSemantics &fltSem =
|
llvm::APFloat pi = llvm::APFloat(llvm::numbers::pi);
|
||||||
llvm::cast<mlir::FloatType>(resultType).getFloatSemantics();
|
mlir::Value dfactor = builder.createRealConstant(
|
||||||
llvm::APFloat pi = llvm::APFloat(fltSem, llvm::numbers::pis);
|
loc, mlir::Float64Type::get(context), llvm::APFloat(180.0) / pi);
|
||||||
mlir::Value factor = builder.createRealConstant(
|
mlir::Value factor = builder.createConvert(loc, resultType, dfactor);
|
||||||
loc, resultType, llvm::APFloat(fltSem, "180.0") / pi);
|
|
||||||
return mlir::arith::MulFOp::create(builder, loc, atan, factor);
|
return mlir::arith::MulFOp::create(builder, loc, atan, factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,19 +1,21 @@
|
|||||||
! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s --check-prefixes="CHECK,CHECK-FAST"
|
! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s --check-prefixes="CHECK,CHECK-FAST"
|
||||||
! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir %s -o - | FileCheck %s --check-prefixes="CHECK,CHECK-FAST"
|
! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir %s -o - | FileCheck %s --check-prefixes="CHECK,CHECK-FAST"
|
||||||
|
|
||||||
function test_real4(y, x)
|
|
||||||
|
function test_real4(y,x)
|
||||||
real(4) :: x, y, test_real4
|
real(4) :: x, y, test_real4
|
||||||
test_real4 = atan2d(y, x)
|
test_real4 = atan2d(y,x)
|
||||||
end function
|
end function
|
||||||
|
|
||||||
! CHECK-LABEL: @_QPtest_real4
|
! CHECK-LABEL: @_QPtest_real4
|
||||||
! CHECK-FAST: %[[atan2:.*]] = math.atan2 %{{.*}}, %{{.*}}: f32
|
! CHECK-FAST: %[[atan2:.*]] = math.atan2 %{{.*}}, %{{.*}}: f32
|
||||||
! CHECK: %[[factor:.*]] = arith.constant 57.2957763 : f32
|
! CHECK: %[[dfactor:.*]] = arith.constant 57.295779513082323 : f64
|
||||||
|
! CHECK: %[[factor:.*]] = fir.convert %[[dfactor]] : (f64) -> f32
|
||||||
! CHECK: %{{.*}} = arith.mulf %[[atan2]], %[[factor]] fastmath<contract> : f32
|
! CHECK: %{{.*}} = arith.mulf %[[atan2]], %[[factor]] fastmath<contract> : f32
|
||||||
|
|
||||||
function test_real8(y, x)
|
function test_real8(y,x)
|
||||||
real(8) :: x, y, test_real8
|
real(8) :: x, y, test_real8
|
||||||
test_real8 = atan2d(y, x)
|
test_real8 = atan2d(y,x)
|
||||||
end function
|
end function
|
||||||
|
|
||||||
! CHECK-LABEL: @_QPtest_real8
|
! CHECK-LABEL: @_QPtest_real8
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
! REQUIRES: flang-supports-f128-math
|
|
||||||
! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s --check-prefixes="CHECK,CHECK-FAST"
|
! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s --check-prefixes="CHECK,CHECK-FAST"
|
||||||
! RUN: bbc --math-runtime=precise -emit-fir -hlfir=false %s -o - | FileCheck %s --check-prefixes="CHECK,CHECK-PRECISE"
|
! RUN: bbc --math-runtime=precise -emit-fir -hlfir=false %s -o - | FileCheck %s --check-prefixes="CHECK,CHECK-PRECISE"
|
||||||
! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir %s -o - | FileCheck %s --check-prefixes="CHECK,CHECK-FAST"
|
! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir %s -o - | FileCheck %s --check-prefixes="CHECK,CHECK-FAST"
|
||||||
@ -11,7 +10,8 @@ end function
|
|||||||
! CHECK-LABEL: @_QPtest_real4
|
! CHECK-LABEL: @_QPtest_real4
|
||||||
! CHECK-PRECISE: %[[atan:.*]] = fir.call @atanf({{%[A-Za-z0-9._]+}}) fastmath<contract> : (f32) -> f32
|
! CHECK-PRECISE: %[[atan:.*]] = fir.call @atanf({{%[A-Za-z0-9._]+}}) fastmath<contract> : (f32) -> f32
|
||||||
! CHECK-FAST: %[[atan:.*]] = math.atan %{{.*}} : f32
|
! CHECK-FAST: %[[atan:.*]] = math.atan %{{.*}} : f32
|
||||||
! CHECK: %[[factor:.*]] = arith.constant 57.2957763 : f32
|
! CHECK: %[[dfactor:.*]] = arith.constant 57.295779513082323 : f64
|
||||||
|
! CHECK: %[[factor:.*]] = fir.convert %[[dfactor]] : (f64) -> f32
|
||||||
! CHECK: %{{.*}} = arith.mulf %[[atan]], %[[factor]] fastmath<contract> : f32
|
! CHECK: %{{.*}} = arith.mulf %[[atan]], %[[factor]] fastmath<contract> : f32
|
||||||
|
|
||||||
function test_real8(x)
|
function test_real8(x)
|
||||||
@ -25,42 +25,23 @@ end function
|
|||||||
! CHECK: %[[factor:.*]] = arith.constant 57.295779513082323 : f64
|
! CHECK: %[[factor:.*]] = arith.constant 57.295779513082323 : f64
|
||||||
! CHECK: %{{.*}} = arith.mulf %[[atan]], %[[factor]] fastmath<contract> : f64
|
! CHECK: %{{.*}} = arith.mulf %[[atan]], %[[factor]] fastmath<contract> : f64
|
||||||
|
|
||||||
function test_real16(x)
|
function test_real4_yx(y,x)
|
||||||
real(16) :: x, test_real16
|
|
||||||
test_real16 = atand(x)
|
|
||||||
end function
|
|
||||||
|
|
||||||
! CHECK-LABEL: @_QPtest_real16
|
|
||||||
! CHECK: %[[atan:.*]] = fir.call @_FortranAAtanF128({{.*}}) fastmath<contract> : (f128) -> f128
|
|
||||||
! CHECK: %[[factor:.*]] = arith.constant 57.295779513082320876798154814105{{.*}} : f128
|
|
||||||
! CHECK: %{{.*}} = arith.mulf %[[atan]], %[[factor]] fastmath<contract> : f128
|
|
||||||
|
|
||||||
function test_real4_yx(y, x)
|
|
||||||
real(4) :: x, y, test_real4
|
real(4) :: x, y, test_real4
|
||||||
test_real4 = atand(y, x)
|
test_real4 = atand(y,x)
|
||||||
end function
|
end function
|
||||||
|
|
||||||
! CHECK-LABEL: @_QPtest_real4_yx
|
! CHECK-LABEL: @_QPtest_real4_yx
|
||||||
! CHECK: %[[atan2:.*]] = math.atan2 %{{.*}}, %{{.*}}: f32
|
! CHECK: %[[atan2:.*]] = math.atan2 %{{.*}}, %{{.*}}: f32
|
||||||
! CHECK: %[[factor:.*]] = arith.constant 57.2957763 : f32
|
! CHECK: %[[dfactor:.*]] = arith.constant 57.295779513082323 : f64
|
||||||
|
! CHECK: %[[factor:.*]] = fir.convert %[[dfactor]] : (f64) -> f32
|
||||||
! CHECK: %{{.*}} = arith.mulf %[[atan2]], %[[factor]] fastmath<contract> : f32
|
! CHECK: %{{.*}} = arith.mulf %[[atan2]], %[[factor]] fastmath<contract> : f32
|
||||||
|
|
||||||
function test_real8_yx(y, x)
|
function test_real8_yx(y,x)
|
||||||
real(8) :: x, y, test_real8
|
real(8) :: x, y, test_real8
|
||||||
test_real8 = atand(y, x)
|
test_real8 = atand(y,x)
|
||||||
end function
|
end function
|
||||||
|
|
||||||
! CHECK-LABEL: @_QPtest_real8_yx
|
! CHECK-LABEL: @_QPtest_real8_yx
|
||||||
! CHECK: %[[atan2:.*]] = math.atan2 %{{.*}}, %{{.*}}: f64
|
! CHECK: %[[atan2:.*]] = math.atan2 %{{.*}}, %{{.*}}: f64
|
||||||
! CHECK: %[[factor:.*]] = arith.constant 57.295779513082323 : f64
|
! CHECK: %[[factor:.*]] = arith.constant 57.295779513082323 : f64
|
||||||
! CHECK: %{{.*}} = arith.mulf %[[atan2]], %[[factor]] fastmath<contract> : f64
|
! CHECK: %{{.*}} = arith.mulf %[[atan2]], %[[factor]] fastmath<contract> : f64
|
||||||
|
|
||||||
function test_real16_yx(y, x)
|
|
||||||
real(16) :: x, y, test_real16
|
|
||||||
test_real16 = atand(y, x)
|
|
||||||
end function
|
|
||||||
|
|
||||||
! CHECK-LABEL: @_QPtest_real16_yx
|
|
||||||
! CHECK: %[[atan2:.*]] = math.atan2 %{{.*}}, %{{.*}}: f128
|
|
||||||
! CHECK: %[[factor:.*]] = arith.constant 57.295779513082320876798154814105{{.*}} : f128
|
|
||||||
! CHECK: %{{.*}} = arith.mulf %[[atan]], %[[factor]] fastmath<contract> : f128
|
|
||||||
|
@ -280,7 +280,6 @@ set(TARGET_LIBC_ENTRYPOINTS
|
|||||||
|
|
||||||
set(TARGET_LIBM_ENTRYPOINTS
|
set(TARGET_LIBM_ENTRYPOINTS
|
||||||
# math.h entrypoints
|
# math.h entrypoints
|
||||||
libc.src.math.acos
|
|
||||||
libc.src.math.acosf
|
libc.src.math.acosf
|
||||||
libc.src.math.acoshf
|
libc.src.math.acoshf
|
||||||
libc.src.math.asin
|
libc.src.math.asin
|
||||||
|
@ -2432,6 +2432,14 @@ functions:
|
|||||||
return_type: double
|
return_type: double
|
||||||
arguments:
|
arguments:
|
||||||
- type: double
|
- type: double
|
||||||
|
- name: sincosf
|
||||||
|
standards:
|
||||||
|
- gnu
|
||||||
|
return_type: void
|
||||||
|
arguments:
|
||||||
|
- type: float
|
||||||
|
- type: float *
|
||||||
|
- type: float *
|
||||||
- name: sinf
|
- name: sinf
|
||||||
standards:
|
standards:
|
||||||
- stdc
|
- stdc
|
||||||
@ -2445,22 +2453,6 @@ functions:
|
|||||||
arguments:
|
arguments:
|
||||||
- type: _Float16
|
- type: _Float16
|
||||||
guard: LIBC_TYPES_HAS_FLOAT16
|
guard: LIBC_TYPES_HAS_FLOAT16
|
||||||
- name: sincos
|
|
||||||
standards:
|
|
||||||
- gnu
|
|
||||||
return_type: void
|
|
||||||
arguments:
|
|
||||||
- type: double
|
|
||||||
- type: double *
|
|
||||||
- type: double *
|
|
||||||
- name: sincosf
|
|
||||||
standards:
|
|
||||||
- gnu
|
|
||||||
return_type: void
|
|
||||||
arguments:
|
|
||||||
- type: float
|
|
||||||
- type: float *
|
|
||||||
- type: float *
|
|
||||||
- name: sinhf
|
- name: sinhf
|
||||||
standards:
|
standards:
|
||||||
- stdc
|
- stdc
|
||||||
|
@ -978,11 +978,11 @@ public:
|
|||||||
|
|
||||||
# ifndef _LIBCPP_CXX03_LANG
|
# ifndef _LIBCPP_CXX03_LANG
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI map(map&& __m) = default;
|
_LIBCPP_HIDE_FROM_ABI map(map&& __m) noexcept(is_nothrow_move_constructible<__base>::value) = default;
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI map(map&& __m, const allocator_type& __a);
|
_LIBCPP_HIDE_FROM_ABI map(map&& __m, const allocator_type& __a);
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI map& operator=(map&& __m) = default;
|
_LIBCPP_HIDE_FROM_ABI map& operator=(map&& __m) noexcept(is_nothrow_move_assignable<__base>::value) = default;
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI map(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
|
_LIBCPP_HIDE_FROM_ABI map(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
|
||||||
: __tree_(__vc(__comp)) {
|
: __tree_(__vc(__comp)) {
|
||||||
@ -1646,11 +1646,12 @@ public:
|
|||||||
|
|
||||||
# ifndef _LIBCPP_CXX03_LANG
|
# ifndef _LIBCPP_CXX03_LANG
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI multimap(multimap&& __m) = default;
|
_LIBCPP_HIDE_FROM_ABI multimap(multimap&& __m) noexcept(is_nothrow_move_constructible<__base>::value) = default;
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI multimap(multimap&& __m, const allocator_type& __a);
|
_LIBCPP_HIDE_FROM_ABI multimap(multimap&& __m, const allocator_type& __a);
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI multimap& operator=(multimap&& __m) = default;
|
_LIBCPP_HIDE_FROM_ABI multimap&
|
||||||
|
operator=(multimap&& __m) noexcept(is_nothrow_move_assignable<__base>::value) = default;
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI multimap(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
|
_LIBCPP_HIDE_FROM_ABI multimap(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
|
||||||
: __tree_(__vc(__comp)) {
|
: __tree_(__vc(__comp)) {
|
||||||
|
@ -667,7 +667,7 @@ public:
|
|||||||
_LIBCPP_HIDE_FROM_ABI set& operator=(const set& __s) = default;
|
_LIBCPP_HIDE_FROM_ABI set& operator=(const set& __s) = default;
|
||||||
|
|
||||||
# ifndef _LIBCPP_CXX03_LANG
|
# ifndef _LIBCPP_CXX03_LANG
|
||||||
_LIBCPP_HIDE_FROM_ABI set(set&& __s) = default;
|
_LIBCPP_HIDE_FROM_ABI set(set&& __s) noexcept(is_nothrow_move_constructible<__base>::value) = default;
|
||||||
# endif // _LIBCPP_CXX03_LANG
|
# endif // _LIBCPP_CXX03_LANG
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI explicit set(const allocator_type& __a) : __tree_(__a) {}
|
_LIBCPP_HIDE_FROM_ABI explicit set(const allocator_type& __a) : __tree_(__a) {}
|
||||||
@ -699,7 +699,10 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI set& operator=(set&& __s) = default;
|
_LIBCPP_HIDE_FROM_ABI set& operator=(set&& __s) noexcept(is_nothrow_move_assignable<__base>::value) {
|
||||||
|
__tree_ = std::move(__s.__tree_);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
# endif // _LIBCPP_CXX03_LANG
|
# endif // _LIBCPP_CXX03_LANG
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI ~set() { static_assert(sizeof(std::__diagnose_non_const_comparator<_Key, _Compare>()), ""); }
|
_LIBCPP_HIDE_FROM_ABI ~set() { static_assert(sizeof(std::__diagnose_non_const_comparator<_Key, _Compare>()), ""); }
|
||||||
@ -1123,7 +1126,7 @@ public:
|
|||||||
_LIBCPP_HIDE_FROM_ABI multiset& operator=(const multiset& __s) = default;
|
_LIBCPP_HIDE_FROM_ABI multiset& operator=(const multiset& __s) = default;
|
||||||
|
|
||||||
# ifndef _LIBCPP_CXX03_LANG
|
# ifndef _LIBCPP_CXX03_LANG
|
||||||
_LIBCPP_HIDE_FROM_ABI multiset(multiset&& __s) = default;
|
_LIBCPP_HIDE_FROM_ABI multiset(multiset&& __s) noexcept(is_nothrow_move_constructible<__base>::value) = default;
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI multiset(multiset&& __s, const allocator_type& __a);
|
_LIBCPP_HIDE_FROM_ABI multiset(multiset&& __s, const allocator_type& __a);
|
||||||
# endif // _LIBCPP_CXX03_LANG
|
# endif // _LIBCPP_CXX03_LANG
|
||||||
@ -1155,7 +1158,10 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI multiset& operator=(multiset&& __s) = default;
|
_LIBCPP_HIDE_FROM_ABI multiset& operator=(multiset&& __s) _NOEXCEPT_(is_nothrow_move_assignable<__base>::value) {
|
||||||
|
__tree_ = std::move(__s.__tree_);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
# endif // _LIBCPP_CXX03_LANG
|
# endif // _LIBCPP_CXX03_LANG
|
||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI ~multiset() {
|
_LIBCPP_HIDE_FROM_ABI ~multiset() {
|
||||||
|
@ -1049,7 +1049,8 @@ public:
|
|||||||
_LIBCPP_HIDE_FROM_ABI unordered_map(const unordered_map& __u) = default;
|
_LIBCPP_HIDE_FROM_ABI unordered_map(const unordered_map& __u) = default;
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_map(const unordered_map& __u, const allocator_type& __a);
|
_LIBCPP_HIDE_FROM_ABI unordered_map(const unordered_map& __u, const allocator_type& __a);
|
||||||
# ifndef _LIBCPP_CXX03_LANG
|
# ifndef _LIBCPP_CXX03_LANG
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_map(unordered_map&& __u) = default;
|
_LIBCPP_HIDE_FROM_ABI unordered_map(unordered_map&& __u)
|
||||||
|
_NOEXCEPT_(is_nothrow_move_constructible<__table>::value) = default;
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_map(unordered_map&& __u, const allocator_type& __a);
|
_LIBCPP_HIDE_FROM_ABI unordered_map(unordered_map&& __u, const allocator_type& __a);
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_map(initializer_list<value_type> __il);
|
_LIBCPP_HIDE_FROM_ABI unordered_map(initializer_list<value_type> __il);
|
||||||
_LIBCPP_HIDE_FROM_ABI
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
@ -1101,7 +1102,8 @@ public:
|
|||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_map& operator=(const unordered_map& __u) = default;
|
_LIBCPP_HIDE_FROM_ABI unordered_map& operator=(const unordered_map& __u) = default;
|
||||||
# ifndef _LIBCPP_CXX03_LANG
|
# ifndef _LIBCPP_CXX03_LANG
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_map& operator=(unordered_map&& __u) = default;
|
_LIBCPP_HIDE_FROM_ABI unordered_map& operator=(unordered_map&& __u)
|
||||||
|
_NOEXCEPT_(is_nothrow_move_assignable<__table>::value) = default;
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_map& operator=(initializer_list<value_type> __il);
|
_LIBCPP_HIDE_FROM_ABI unordered_map& operator=(initializer_list<value_type> __il);
|
||||||
# endif // _LIBCPP_CXX03_LANG
|
# endif // _LIBCPP_CXX03_LANG
|
||||||
|
|
||||||
@ -1821,7 +1823,8 @@ public:
|
|||||||
_LIBCPP_HIDE_FROM_ABI unordered_multimap(const unordered_multimap& __u) = default;
|
_LIBCPP_HIDE_FROM_ABI unordered_multimap(const unordered_multimap& __u) = default;
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_multimap(const unordered_multimap& __u, const allocator_type& __a);
|
_LIBCPP_HIDE_FROM_ABI unordered_multimap(const unordered_multimap& __u, const allocator_type& __a);
|
||||||
# ifndef _LIBCPP_CXX03_LANG
|
# ifndef _LIBCPP_CXX03_LANG
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_multimap(unordered_multimap&& __u) = default;
|
_LIBCPP_HIDE_FROM_ABI unordered_multimap(unordered_multimap&& __u)
|
||||||
|
_NOEXCEPT_(is_nothrow_move_constructible<__table>::value) = default;
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_multimap(unordered_multimap&& __u, const allocator_type& __a);
|
_LIBCPP_HIDE_FROM_ABI unordered_multimap(unordered_multimap&& __u, const allocator_type& __a);
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_multimap(initializer_list<value_type> __il);
|
_LIBCPP_HIDE_FROM_ABI unordered_multimap(initializer_list<value_type> __il);
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_multimap(
|
_LIBCPP_HIDE_FROM_ABI unordered_multimap(
|
||||||
@ -1873,7 +1876,8 @@ public:
|
|||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_multimap& operator=(const unordered_multimap& __u) = default;
|
_LIBCPP_HIDE_FROM_ABI unordered_multimap& operator=(const unordered_multimap& __u) = default;
|
||||||
# ifndef _LIBCPP_CXX03_LANG
|
# ifndef _LIBCPP_CXX03_LANG
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_multimap& operator=(unordered_multimap&& __u) = default;
|
_LIBCPP_HIDE_FROM_ABI unordered_multimap& operator=(unordered_multimap&& __u)
|
||||||
|
_NOEXCEPT_(is_nothrow_move_assignable<__table>::value) = default;
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_multimap& operator=(initializer_list<value_type> __il);
|
_LIBCPP_HIDE_FROM_ABI unordered_multimap& operator=(initializer_list<value_type> __il);
|
||||||
# endif // _LIBCPP_CXX03_LANG
|
# endif // _LIBCPP_CXX03_LANG
|
||||||
|
|
||||||
|
@ -706,7 +706,7 @@ public:
|
|||||||
_LIBCPP_HIDE_FROM_ABI unordered_set(const unordered_set& __u) = default;
|
_LIBCPP_HIDE_FROM_ABI unordered_set(const unordered_set& __u) = default;
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_set(const unordered_set& __u, const allocator_type& __a);
|
_LIBCPP_HIDE_FROM_ABI unordered_set(const unordered_set& __u, const allocator_type& __a);
|
||||||
# ifndef _LIBCPP_CXX03_LANG
|
# ifndef _LIBCPP_CXX03_LANG
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_set(unordered_set&& __u) = default;
|
_LIBCPP_HIDE_FROM_ABI unordered_set(unordered_set&& __u) _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_set(unordered_set&& __u, const allocator_type& __a);
|
_LIBCPP_HIDE_FROM_ABI unordered_set(unordered_set&& __u, const allocator_type& __a);
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_set(initializer_list<value_type> __il);
|
_LIBCPP_HIDE_FROM_ABI unordered_set(initializer_list<value_type> __il);
|
||||||
_LIBCPP_HIDE_FROM_ABI
|
_LIBCPP_HIDE_FROM_ABI
|
||||||
@ -735,7 +735,8 @@ public:
|
|||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_set& operator=(const unordered_set& __u) = default;
|
_LIBCPP_HIDE_FROM_ABI unordered_set& operator=(const unordered_set& __u) = default;
|
||||||
# ifndef _LIBCPP_CXX03_LANG
|
# ifndef _LIBCPP_CXX03_LANG
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_set& operator=(unordered_set&& __u) = default;
|
_LIBCPP_HIDE_FROM_ABI unordered_set& operator=(unordered_set&& __u)
|
||||||
|
_NOEXCEPT_(is_nothrow_move_assignable<__table>::value) = default;
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_set& operator=(initializer_list<value_type> __il);
|
_LIBCPP_HIDE_FROM_ABI unordered_set& operator=(initializer_list<value_type> __il);
|
||||||
# endif // _LIBCPP_CXX03_LANG
|
# endif // _LIBCPP_CXX03_LANG
|
||||||
|
|
||||||
@ -1075,6 +1076,11 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(const unordered_set&
|
|||||||
|
|
||||||
# ifndef _LIBCPP_CXX03_LANG
|
# ifndef _LIBCPP_CXX03_LANG
|
||||||
|
|
||||||
|
template <class _Value, class _Hash, class _Pred, class _Alloc>
|
||||||
|
inline unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(unordered_set&& __u)
|
||||||
|
_NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
|
||||||
|
: __table_(std::move(__u.__table_)) {}
|
||||||
|
|
||||||
template <class _Value, class _Hash, class _Pred, class _Alloc>
|
template <class _Value, class _Hash, class _Pred, class _Alloc>
|
||||||
unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(unordered_set&& __u, const allocator_type& __a)
|
unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(unordered_set&& __u, const allocator_type& __a)
|
||||||
: __table_(std::move(__u.__table_), __a) {
|
: __table_(std::move(__u.__table_), __a) {
|
||||||
@ -1288,7 +1294,8 @@ public:
|
|||||||
_LIBCPP_HIDE_FROM_ABI unordered_multiset(const unordered_multiset& __u) = default;
|
_LIBCPP_HIDE_FROM_ABI unordered_multiset(const unordered_multiset& __u) = default;
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_multiset(const unordered_multiset& __u, const allocator_type& __a);
|
_LIBCPP_HIDE_FROM_ABI unordered_multiset(const unordered_multiset& __u, const allocator_type& __a);
|
||||||
# ifndef _LIBCPP_CXX03_LANG
|
# ifndef _LIBCPP_CXX03_LANG
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_multiset(unordered_multiset&& __u) = default;
|
_LIBCPP_HIDE_FROM_ABI unordered_multiset(unordered_multiset&& __u)
|
||||||
|
_NOEXCEPT_(is_nothrow_move_constructible<__table>::value);
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_multiset(unordered_multiset&& __u, const allocator_type& __a);
|
_LIBCPP_HIDE_FROM_ABI unordered_multiset(unordered_multiset&& __u, const allocator_type& __a);
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_multiset(initializer_list<value_type> __il);
|
_LIBCPP_HIDE_FROM_ABI unordered_multiset(initializer_list<value_type> __il);
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_multiset(
|
_LIBCPP_HIDE_FROM_ABI unordered_multiset(
|
||||||
@ -1317,7 +1324,8 @@ public:
|
|||||||
|
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_multiset& operator=(const unordered_multiset& __u) = default;
|
_LIBCPP_HIDE_FROM_ABI unordered_multiset& operator=(const unordered_multiset& __u) = default;
|
||||||
# ifndef _LIBCPP_CXX03_LANG
|
# ifndef _LIBCPP_CXX03_LANG
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_multiset& operator=(unordered_multiset&& __u) = default;
|
_LIBCPP_HIDE_FROM_ABI unordered_multiset& operator=(unordered_multiset&& __u)
|
||||||
|
_NOEXCEPT_(is_nothrow_move_assignable<__table>::value) = default;
|
||||||
_LIBCPP_HIDE_FROM_ABI unordered_multiset& operator=(initializer_list<value_type> __il);
|
_LIBCPP_HIDE_FROM_ABI unordered_multiset& operator=(initializer_list<value_type> __il);
|
||||||
# endif // _LIBCPP_CXX03_LANG
|
# endif // _LIBCPP_CXX03_LANG
|
||||||
|
|
||||||
@ -1667,6 +1675,11 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
|
|||||||
|
|
||||||
# ifndef _LIBCPP_CXX03_LANG
|
# ifndef _LIBCPP_CXX03_LANG
|
||||||
|
|
||||||
|
template <class _Value, class _Hash, class _Pred, class _Alloc>
|
||||||
|
inline unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(unordered_multiset&& __u)
|
||||||
|
_NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
|
||||||
|
: __table_(std::move(__u.__table_)) {}
|
||||||
|
|
||||||
template <class _Value, class _Hash, class _Pred, class _Alloc>
|
template <class _Value, class _Hash, class _Pred, class _Alloc>
|
||||||
unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
|
unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
|
||||||
unordered_multiset&& __u, const allocator_type& __a)
|
unordered_multiset&& __u, const allocator_type& __a)
|
||||||
|
@ -1399,7 +1399,6 @@ void SymbolTable::resolveAlternateNames() {
|
|||||||
auto toUndef = dyn_cast<Undefined>(toSym);
|
auto toUndef = dyn_cast<Undefined>(toSym);
|
||||||
if (toUndef && (!toUndef->weakAlias || toUndef->isAntiDep))
|
if (toUndef && (!toUndef->weakAlias || toUndef->isAntiDep))
|
||||||
continue;
|
continue;
|
||||||
toSym->isUsedInRegularObj = true;
|
|
||||||
if (toSym->isLazy())
|
if (toSym->isLazy())
|
||||||
forceLazy(toSym);
|
forceLazy(toSym);
|
||||||
u->setWeakAlias(toSym);
|
u->setWeakAlias(toSym);
|
||||||
|
@ -39,7 +39,6 @@ public:
|
|||||||
void relocate(uint8_t *loc, const Relocation &rel,
|
void relocate(uint8_t *loc, const Relocation &rel,
|
||||||
uint64_t val) const override;
|
uint64_t val) const override;
|
||||||
bool relaxOnce(int pass) const override;
|
bool relaxOnce(int pass) const override;
|
||||||
bool synthesizeAlign(uint64_t &dot, InputSection *sec) override;
|
|
||||||
RelExpr adjustTlsExpr(RelType type, RelExpr expr) const override;
|
RelExpr adjustTlsExpr(RelType type, RelExpr expr) const override;
|
||||||
void relocateAlloc(InputSectionBase &sec, uint8_t *buf) const override;
|
void relocateAlloc(InputSectionBase &sec, uint8_t *buf) const override;
|
||||||
void finalizeRelax(int passes) const override;
|
void finalizeRelax(int passes) const override;
|
||||||
@ -49,19 +48,6 @@ private:
|
|||||||
void tlsdescToLe(uint8_t *loc, const Relocation &rel, uint64_t val) const;
|
void tlsdescToLe(uint8_t *loc, const Relocation &rel, uint64_t val) const;
|
||||||
bool tryGotToPCRel(uint8_t *loc, const Relocation &rHi20,
|
bool tryGotToPCRel(uint8_t *loc, const Relocation &rHi20,
|
||||||
const Relocation &rLo12, uint64_t secAddr) const;
|
const Relocation &rLo12, uint64_t secAddr) const;
|
||||||
template <class ELFT, class RelTy>
|
|
||||||
bool synthesizeAlignForInput(uint64_t &dot, InputSection *sec,
|
|
||||||
Relocs<RelTy> rels);
|
|
||||||
template <class ELFT, class RelTy>
|
|
||||||
void finalizeSynthesizeAligns(uint64_t &dot, InputSection *sec,
|
|
||||||
Relocs<RelTy> rels);
|
|
||||||
template <class ELFT>
|
|
||||||
bool synthesizeAlignAux(uint64_t &dot, InputSection *sec);
|
|
||||||
|
|
||||||
// The following two variables are used by synthesized ALIGN relocations.
|
|
||||||
InputSection *baseSec = nullptr;
|
|
||||||
// r_offset and r_addend pairs.
|
|
||||||
SmallVector<std::pair<uint64_t, uint64_t>, 0> synthesizedAligns;
|
|
||||||
};
|
};
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
@ -780,117 +766,6 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the section alignment is > 4, advance `dot` to insert NOPs and synthesize
|
|
||||||
// an ALIGN relocation. Otherwise, return false to use default handling.
|
|
||||||
template <class ELFT, class RelTy>
|
|
||||||
bool LoongArch::synthesizeAlignForInput(uint64_t &dot, InputSection *sec,
|
|
||||||
Relocs<RelTy> rels) {
|
|
||||||
if (!baseSec) {
|
|
||||||
// Record the first input section with RELAX relocations. We will synthesize
|
|
||||||
// ALIGN relocations here.
|
|
||||||
for (auto rel : rels) {
|
|
||||||
if (rel.getType(false) == R_LARCH_RELAX) {
|
|
||||||
baseSec = sec;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (sec->addralign > 4) {
|
|
||||||
// If the alignment is > 4 and the section does not start with an ALIGN
|
|
||||||
// relocation, synthesize one.
|
|
||||||
bool hasAlignRel = llvm::any_of(rels, [](const RelTy &rel) {
|
|
||||||
return rel.r_offset == 0 && rel.getType(false) == R_LARCH_ALIGN;
|
|
||||||
});
|
|
||||||
if (!hasAlignRel) {
|
|
||||||
synthesizedAligns.emplace_back(dot - baseSec->getVA(),
|
|
||||||
sec->addralign - 4);
|
|
||||||
dot += sec->addralign - 4;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finalize the relocation section by appending synthesized ALIGN relocations
|
|
||||||
// after processing all input sections.
|
|
||||||
template <class ELFT, class RelTy>
|
|
||||||
void LoongArch::finalizeSynthesizeAligns(uint64_t &dot, InputSection *sec,
|
|
||||||
Relocs<RelTy> rels) {
|
|
||||||
auto *f = cast<ObjFile<ELFT>>(baseSec->file);
|
|
||||||
auto shdr = f->template getELFShdrs<ELFT>()[baseSec->relSecIdx];
|
|
||||||
// Create a copy of InputSection.
|
|
||||||
sec = make<InputSection>(*f, shdr, baseSec->name);
|
|
||||||
auto *baseRelSec = cast<InputSection>(f->getSections()[baseSec->relSecIdx]);
|
|
||||||
*sec = *baseRelSec;
|
|
||||||
baseSec = nullptr;
|
|
||||||
|
|
||||||
// Allocate buffer for original and synthesized relocations in RELA format.
|
|
||||||
// If CREL is used, OutputSection::finalizeNonAllocCrel will convert RELA to
|
|
||||||
// CREL.
|
|
||||||
auto newSize = rels.size() + synthesizedAligns.size();
|
|
||||||
auto *relas = makeThreadLocalN<typename ELFT::Rela>(newSize);
|
|
||||||
sec->size = newSize * sizeof(typename ELFT::Rela);
|
|
||||||
sec->content_ = reinterpret_cast<uint8_t *>(relas);
|
|
||||||
sec->type = SHT_RELA;
|
|
||||||
// Copy original relocations to the new buffer, potentially converting CREL to
|
|
||||||
// RELA.
|
|
||||||
for (auto [i, r] : llvm::enumerate(rels)) {
|
|
||||||
relas[i].r_offset = r.r_offset;
|
|
||||||
relas[i].setSymbolAndType(r.getSymbol(0), r.getType(0), false);
|
|
||||||
if constexpr (RelTy::HasAddend)
|
|
||||||
relas[i].r_addend = r.r_addend;
|
|
||||||
}
|
|
||||||
// Append synthesized ALIGN relocations to the buffer.
|
|
||||||
for (auto [i, r] : llvm::enumerate(synthesizedAligns)) {
|
|
||||||
auto &rela = relas[rels.size() + i];
|
|
||||||
rela.r_offset = r.first;
|
|
||||||
rela.setSymbolAndType(0, R_LARCH_ALIGN, false);
|
|
||||||
rela.r_addend = r.second;
|
|
||||||
}
|
|
||||||
synthesizedAligns.clear();
|
|
||||||
// Replace the old relocation section with the new one in the output section.
|
|
||||||
// addOrphanSections ensures that the output relocation section is processed
|
|
||||||
// after osec.
|
|
||||||
for (SectionCommand *cmd : sec->getParent()->commands) {
|
|
||||||
auto *isd = dyn_cast<InputSectionDescription>(cmd);
|
|
||||||
if (!isd)
|
|
||||||
continue;
|
|
||||||
for (auto *&isec : isd->sections)
|
|
||||||
if (isec == baseRelSec)
|
|
||||||
isec = sec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class ELFT>
|
|
||||||
bool LoongArch::synthesizeAlignAux(uint64_t &dot, InputSection *sec) {
|
|
||||||
bool ret = false;
|
|
||||||
if (sec) {
|
|
||||||
invokeOnRelocs(*sec, ret = synthesizeAlignForInput<ELFT>, dot, sec);
|
|
||||||
} else if (baseSec) {
|
|
||||||
invokeOnRelocs(*baseSec, finalizeSynthesizeAligns<ELFT>, dot, sec);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Without linker relaxation enabled for a particular relocatable file or
|
|
||||||
// section, the assembler will not generate R_LARCH_ALIGN relocations for
|
|
||||||
// alignment directives. This becomes problematic in a two-stage linking
|
|
||||||
// process: ld -r a.o b.o -o ab.o; ld ab.o -o ab. This function synthesizes an
|
|
||||||
// R_LARCH_ALIGN relocation at section start when needed.
|
|
||||||
//
|
|
||||||
// When called with an input section (`sec` is not null): If the section
|
|
||||||
// alignment is > 4, advance `dot` to insert NOPs and synthesize an ALIGN
|
|
||||||
// relocation.
|
|
||||||
//
|
|
||||||
// When called after all input sections are processed (`sec` is null): The
|
|
||||||
// output relocation section is updated with all the newly synthesized ALIGN
|
|
||||||
// relocations.
|
|
||||||
bool LoongArch::synthesizeAlign(uint64_t &dot, InputSection *sec) {
|
|
||||||
assert(ctx.arg.relocatable);
|
|
||||||
if (ctx.arg.is64)
|
|
||||||
return synthesizeAlignAux<ELF64LE>(dot, sec);
|
|
||||||
return synthesizeAlignAux<ELF32LE>(dot, sec);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool relaxable(ArrayRef<Relocation> relocs, size_t i) {
|
static bool relaxable(ArrayRef<Relocation> relocs, size_t i) {
|
||||||
return i + 1 < relocs.size() && relocs[i + 1].type == R_LARCH_RELAX;
|
return i + 1 < relocs.size() && relocs[i + 1].type == R_LARCH_RELAX;
|
||||||
}
|
}
|
||||||
|
@ -1230,9 +1230,9 @@ bool LinkerScript::assignOffsets(OutputSection *sec) {
|
|||||||
if (sec->firstInOverlay)
|
if (sec->firstInOverlay)
|
||||||
state->overlaySize = 0;
|
state->overlaySize = 0;
|
||||||
|
|
||||||
bool synthesizeAlign =
|
bool synthesizeAlign = ctx.arg.relocatable && ctx.arg.relax &&
|
||||||
ctx.arg.relocatable && ctx.arg.relax && (sec->flags & SHF_EXECINSTR) &&
|
(sec->flags & SHF_EXECINSTR) &&
|
||||||
(ctx.arg.emachine == EM_LOONGARCH || ctx.arg.emachine == EM_RISCV);
|
ctx.arg.emachine == EM_RISCV;
|
||||||
// We visited SectionsCommands from processSectionCommands to
|
// We visited SectionsCommands from processSectionCommands to
|
||||||
// layout sections. Now, we visit SectionsCommands again to fix
|
// layout sections. Now, we visit SectionsCommands again to fix
|
||||||
// section offsets.
|
// section offsets.
|
||||||
|
@ -899,8 +899,6 @@ std::array<uint8_t, 4> OutputSection::getFiller(Ctx &ctx) {
|
|||||||
return {1, 0, 1, 0};
|
return {1, 0, 1, 0};
|
||||||
return {0x13, 0, 0, 0};
|
return {0x13, 0, 0, 0};
|
||||||
}
|
}
|
||||||
if (ctx.arg.relocatable && ctx.arg.emachine == EM_LOONGARCH)
|
|
||||||
return {0, 0, 0x40, 0x03};
|
|
||||||
return ctx.target->trapInstr;
|
return ctx.target->trapInstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
; REQUIRES: x86
|
|
||||||
; RUN: mkdir -p %t.dir
|
|
||||||
; RUN: llvm-as -o %t.obj %s
|
|
||||||
; RUN: lld-link -out:%t.dll -dll -noentry %t.obj -export:test
|
|
||||||
|
|
||||||
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
|
|
||||||
target triple = "x86_64-unknown-windows-msvc19.33.0"
|
|
||||||
|
|
||||||
$alt = comdat any
|
|
||||||
|
|
||||||
@alt = weak_odr dso_local global i32 0, comdat, align 4
|
|
||||||
@ext = external dso_local global i32, align 4
|
|
||||||
|
|
||||||
; Function Attrs: noinline nounwind optnone uwtable
|
|
||||||
define dso_local i32 @test() #0 {
|
|
||||||
entry:
|
|
||||||
%0 = load i32, ptr @ext, align 4
|
|
||||||
ret i32 %0
|
|
||||||
}
|
|
||||||
|
|
||||||
attributes #0 = { noinline nounwind optnone uwtable }
|
|
||||||
|
|
||||||
!llvm.linker.options = !{!0}
|
|
||||||
|
|
||||||
!0 = !{!"/alternatename:ext=alt"}
|
|
@ -1,147 +0,0 @@
|
|||||||
# REQUIRES: loongarch
|
|
||||||
|
|
||||||
## Test LA64.
|
|
||||||
# RUN: rm -rf %t && split-file %s %t && cd %t
|
|
||||||
# RUN: llvm-mc -filetype=obj -triple=loongarch64 -mattr=+relax a.s -o a.o
|
|
||||||
# RUN: llvm-mc -filetype=obj -triple=loongarch64 -mattr=+relax --defsym ELF64=1 b.s -o b.o
|
|
||||||
# RUN: llvm-mc -filetype=obj -triple=loongarch64 -mattr=+relax b1.s -o b1.o
|
|
||||||
# RUN: llvm-mc -filetype=obj -triple=loongarch64 -mattr=+relax c.s -o c.o
|
|
||||||
# RUN: llvm-mc -filetype=obj -triple=loongarch64 d.s -o d.o
|
|
||||||
|
|
||||||
## No RELAX. Don't synthesize ALIGN.
|
|
||||||
# RUN: ld.lld -r b.o d.o -o bd.ro
|
|
||||||
# RUN: llvm-readelf -r bd.ro | FileCheck %s --check-prefix=NOREL
|
|
||||||
|
|
||||||
# NOREL: no relocations
|
|
||||||
|
|
||||||
# RUN: ld.lld -r b.o b.o a.o b.o b1.o c.o d.o -o out.ro
|
|
||||||
# RUN: llvm-objdump -dr --no-show-raw-insn out.ro | FileCheck %s
|
|
||||||
# RUN: llvm-readelf -r out.ro | FileCheck %s --check-prefix=CHECK-REL
|
|
||||||
|
|
||||||
# CHECK: <b0>:
|
|
||||||
# CHECK-NEXT: 0: addi.d $a0, $a1, 1
|
|
||||||
# CHECK-NEXT: 4: nop
|
|
||||||
# CHECK-EMPTY:
|
|
||||||
# CHECK-NEXT: <b0>:
|
|
||||||
# CHECK-NEXT: 8: addi.d $a0, $a1, 1
|
|
||||||
# CHECK-EMPTY:
|
|
||||||
# CHECK-NEXT: <_start>:
|
|
||||||
# CHECK-NEXT: c: pcalau12i $a0, 0
|
|
||||||
# CHECK-NEXT: 000000000000000c: R_LARCH_PCALA_HI20 .Ltext1_start
|
|
||||||
# CHECK-NEXT: 000000000000000c: R_LARCH_RELAX *ABS*
|
|
||||||
# CHECK-NEXT: 10: addi.d $a0, $a0, 0
|
|
||||||
# CHECK-NEXT: 0000000000000010: R_LARCH_PCALA_LO12 .Ltext1_start
|
|
||||||
# CHECK-NEXT: 0000000000000010: R_LARCH_RELAX *ABS*
|
|
||||||
# CHECK-NEXT: 14: nop
|
|
||||||
# CHECK-NEXT: 0000000000000014: R_LARCH_ALIGN *ABS*+0x4
|
|
||||||
# CHECK-EMPTY:
|
|
||||||
# CHECK-NEXT: <b0>:
|
|
||||||
# CHECK-NEXT: 18: addi.d $a0, $a1, 1
|
|
||||||
# CHECK-NEXT: 1c: nop
|
|
||||||
# CHECK-NEXT: 20: nop
|
|
||||||
# CHECK-NEXT: 0000000000000020: R_LARCH_ALIGN *ABS*+0x4
|
|
||||||
# CHECK-NEXT: 24: nop
|
|
||||||
# CHECK-EMPTY:
|
|
||||||
# CHECK-NEXT: <b1>:
|
|
||||||
# CHECK-NEXT: 28: addi.d $a0, $a1, 3
|
|
||||||
# CHECK-EMPTY:
|
|
||||||
# CHECK-NEXT: <c0>:
|
|
||||||
# CHECK-NEXT: 2c: addi.d $a0, $a1, 4
|
|
||||||
# CHECK-NEXT: 30: nop
|
|
||||||
# CHECK-NEXT: 0000000000000030: R_LARCH_ALIGN *ABS*+0x4
|
|
||||||
# CHECK-EMPTY:
|
|
||||||
# CHECK-NEXT: <d0>:
|
|
||||||
# CHECK-NEXT: 34: addi.d $a0, $a1, 5
|
|
||||||
|
|
||||||
# CHECK-REL: Relocation section '.rela.text' at offset {{.*}} contains 7 entries:
|
|
||||||
# CHECK-REL: Relocation section '.rela.text1' at offset {{.*}} contains 5 entries:
|
|
||||||
|
|
||||||
## Test LA32.
|
|
||||||
# RUN: llvm-mc -filetype=obj -triple=loongarch32 -mattr=+relax a.s -o a.32.o
|
|
||||||
# RUN: llvm-mc -filetype=obj -triple=loongarch32 -mattr=+relax b.s -o b.32.o
|
|
||||||
# RUN: ld.lld -r a.32.o b.32.o -o out.32.ro
|
|
||||||
# RUN: ld.lld -Ttext=0x10000 out.32.ro -o out32
|
|
||||||
# RUN: llvm-objdump -dr --no-show-raw-insn out32 | FileCheck %s --check-prefix=CHECK32
|
|
||||||
|
|
||||||
# CHECK32: <_start>:
|
|
||||||
# CHECK32-NEXT: 10000: pcaddi $a0, 4
|
|
||||||
# CHECK32-NEXT: 10004: nop
|
|
||||||
# CHECK32-EMPTY:
|
|
||||||
# CHECK32-NEXT: <b0>:
|
|
||||||
# CHECK32-NEXT: 10008: addi.w $a0, $a1, 1
|
|
||||||
# CHECK32: <.Ltext1_start>:
|
|
||||||
# CHECK32-NEXT: 10010: pcaddi $a1, 0
|
|
||||||
# CHECK32-NEXT: 10014: nop
|
|
||||||
# CHECK32-NEXT: 10018: addi.w $a0, $a1, 2
|
|
||||||
|
|
||||||
## Test CREL.
|
|
||||||
# RUN: llvm-mc -filetype=obj -triple=loongarch64 -mattr=+relax --crel a.s -o acrel.o
|
|
||||||
# RUN: ld.lld -r acrel.o b.o -o out.crel.ro
|
|
||||||
# RUN: llvm-objdump -dr --no-show-raw-insn out.crel.ro | FileCheck %s --check-prefix=CHECKC
|
|
||||||
|
|
||||||
# CHECKC: <_start>:
|
|
||||||
# CHECKC-NEXT: 0: pcalau12i $a0, 0
|
|
||||||
# CHECKC-NEXT: 0000000000000000: R_LARCH_PCALA_HI20 .Ltext1_start
|
|
||||||
# CHECKC-NEXT: 0000000000000000: R_LARCH_RELAX *ABS*
|
|
||||||
# CHECKC-NEXT: 4: addi.d $a0, $a0, 0
|
|
||||||
# CHECKC-NEXT: 0000000000000004: R_LARCH_PCALA_LO12 .Ltext1_start
|
|
||||||
# CHECKC-NEXT: 0000000000000004: R_LARCH_RELAX *ABS*
|
|
||||||
# CHECKC-NEXT: 8: nop
|
|
||||||
# CHECKC-NEXT: 0000000000000008: R_LARCH_ALIGN *ABS*+0x4
|
|
||||||
# CHECKC-EMPTY:
|
|
||||||
# CHECKC-NEXT: <b0>:
|
|
||||||
# CHECKC-NEXT: c: addi.d $a0, $a1, 1
|
|
||||||
|
|
||||||
#--- a.s
|
|
||||||
.globl _start
|
|
||||||
_start:
|
|
||||||
la.pcrel $a0, .Ltext1_start
|
|
||||||
|
|
||||||
.section .text1,"ax"
|
|
||||||
.Ltext1_start:
|
|
||||||
la.pcrel $a1, .Ltext1_start
|
|
||||||
|
|
||||||
#--- b.s
|
|
||||||
.macro addi dst, src1, src2
|
|
||||||
.ifdef ELF64
|
|
||||||
addi.d \dst, \src1, \src2
|
|
||||||
.else
|
|
||||||
addi.w \dst, \src1, \src2
|
|
||||||
.endif
|
|
||||||
.endm
|
|
||||||
|
|
||||||
## Needs synthesized ALIGN.
|
|
||||||
.option push
|
|
||||||
.option norelax
|
|
||||||
.balign 8
|
|
||||||
b0:
|
|
||||||
addi $a0, $a1, 1
|
|
||||||
|
|
||||||
.section .text1,"ax"
|
|
||||||
.balign 8
|
|
||||||
addi $a0, $a1, 2
|
|
||||||
|
|
||||||
.option pop
|
|
||||||
|
|
||||||
#--- b1.s
|
|
||||||
# Starts with an ALIGN relocation, don't need synthesized ALIGN.
|
|
||||||
.option push
|
|
||||||
.option norelax
|
|
||||||
.reloc ., R_LARCH_ALIGN, 4
|
|
||||||
nop
|
|
||||||
.balign 8
|
|
||||||
b1:
|
|
||||||
addi.d $a0, $a1, 3
|
|
||||||
.option pop
|
|
||||||
|
|
||||||
#--- c.s
|
|
||||||
## Alignment == 4, don't need synthesized ALIGN.
|
|
||||||
.balign 4
|
|
||||||
c0:
|
|
||||||
addi.d $a0, $a1, 4
|
|
||||||
|
|
||||||
#--- d.s
|
|
||||||
## Needs synthesized ALIGN.
|
|
||||||
.balign 8
|
|
||||||
d0:
|
|
||||||
addi.d $a0, $a1, 5
|
|
@ -1540,19 +1540,13 @@ def load_crashlog_in_scripted_process(debugger, crashlog_path, options, result):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
crashlog_sd = lldb.SBStructuredData()
|
|
||||||
crashlog_sd.SetGenericValue(
|
|
||||||
lldb.SBScriptObject(crashlog, lldb.eScriptLanguagePython)
|
|
||||||
)
|
|
||||||
structured_data.SetValueForKey("crashlog", crashlog_sd)
|
|
||||||
|
|
||||||
launch_info = lldb.SBLaunchInfo(None)
|
launch_info = lldb.SBLaunchInfo(None)
|
||||||
launch_info.SetProcessPluginName("ScriptedProcess")
|
launch_info.SetProcessPluginName("ScriptedProcess")
|
||||||
launch_info.SetScriptedProcessClassName(
|
launch_info.SetScriptedProcessClassName(
|
||||||
"crashlog_scripted_process.CrashLogScriptedProcess"
|
"crashlog_scripted_process.CrashLogScriptedProcess"
|
||||||
)
|
)
|
||||||
launch_info.SetScriptedProcessDictionary(structured_data)
|
launch_info.SetScriptedProcessDictionary(structured_data)
|
||||||
|
launch_info.SetLaunchFlags(lldb.eLaunchFlagStopAtEntry)
|
||||||
|
|
||||||
error = lldb.SBError()
|
error = lldb.SBError()
|
||||||
process = target.Launch(launch_info, error)
|
process = target.Launch(launch_info, error)
|
||||||
@ -1560,6 +1554,9 @@ def load_crashlog_in_scripted_process(debugger, crashlog_path, options, result):
|
|||||||
if not process or error.Fail():
|
if not process or error.Fail():
|
||||||
raise InteractiveCrashLogException("couldn't launch Scripted Process", error)
|
raise InteractiveCrashLogException("couldn't launch Scripted Process", error)
|
||||||
|
|
||||||
|
process.GetScriptedImplementation().set_crashlog(crashlog)
|
||||||
|
process.Continue()
|
||||||
|
|
||||||
if not options.skip_status:
|
if not options.skip_status:
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
|
@ -10,7 +10,8 @@ from lldb.macosx.crashlog import CrashLog, CrashLogParser
|
|||||||
|
|
||||||
|
|
||||||
class CrashLogScriptedProcess(ScriptedProcess):
|
class CrashLogScriptedProcess(ScriptedProcess):
|
||||||
def parse_crashlog(self):
|
def set_crashlog(self, crashlog):
|
||||||
|
self.crashlog = crashlog
|
||||||
if self.crashlog.process_id:
|
if self.crashlog.process_id:
|
||||||
if type(self.crashlog.process_id) is int:
|
if type(self.crashlog.process_id) is int:
|
||||||
self.pid = self.crashlog.process_id
|
self.pid = self.crashlog.process_id
|
||||||
@ -28,6 +29,8 @@ class CrashLogScriptedProcess(ScriptedProcess):
|
|||||||
if hasattr(self.crashlog, "asb"):
|
if hasattr(self.crashlog, "asb"):
|
||||||
self.extended_thread_info = self.crashlog.asb
|
self.extended_thread_info = self.crashlog.asb
|
||||||
|
|
||||||
|
crashlog.load_images(self.options, self.loaded_images)
|
||||||
|
|
||||||
for thread in self.crashlog.threads:
|
for thread in self.crashlog.threads:
|
||||||
if (
|
if (
|
||||||
hasattr(thread, "app_specific_backtrace")
|
hasattr(thread, "app_specific_backtrace")
|
||||||
@ -89,21 +92,10 @@ class CrashLogScriptedProcess(ScriptedProcess):
|
|||||||
no_parallel_image_loading.GetBooleanValue()
|
no_parallel_image_loading.GetBooleanValue()
|
||||||
)
|
)
|
||||||
|
|
||||||
self.crashlog = None
|
|
||||||
crashlog = args.GetValueForKey("crashlog")
|
|
||||||
if crashlog and crashlog.IsValid():
|
|
||||||
if crashlog.GetType() == lldb.eStructuredDataTypeGeneric:
|
|
||||||
self.crashlog = crashlog.GetGenericValue()
|
|
||||||
|
|
||||||
if not self.crashlog:
|
|
||||||
# Return error
|
|
||||||
return
|
|
||||||
|
|
||||||
self.pid = super().get_process_id()
|
self.pid = super().get_process_id()
|
||||||
self.crashed_thread_idx = 0
|
self.crashed_thread_idx = 0
|
||||||
self.exception = None
|
self.exception = None
|
||||||
self.extended_thread_info = None
|
self.extended_thread_info = None
|
||||||
self.parse_crashlog()
|
|
||||||
|
|
||||||
def read_memory_at_address(
|
def read_memory_at_address(
|
||||||
self, addr: int, size: int, error: lldb.SBError
|
self, addr: int, size: int, error: lldb.SBError
|
||||||
@ -112,8 +104,8 @@ class CrashLogScriptedProcess(ScriptedProcess):
|
|||||||
return lldb.SBData()
|
return lldb.SBData()
|
||||||
|
|
||||||
def get_loaded_images(self):
|
def get_loaded_images(self):
|
||||||
if len(self.loaded_images) == 0:
|
# TODO: Iterate over corefile_target modules and build a data structure
|
||||||
self.crashlog.load_images(self.options, self.loaded_images)
|
# from it.
|
||||||
return self.loaded_images
|
return self.loaded_images
|
||||||
|
|
||||||
def should_stop(self) -> bool:
|
def should_stop(self) -> bool:
|
||||||
|
@ -85,6 +85,12 @@ public:
|
|||||||
|
|
||||||
SymbolType GetType();
|
SymbolType GetType();
|
||||||
|
|
||||||
|
/// Get the ID of this symbol, usually the original symbol table index.
|
||||||
|
///
|
||||||
|
/// \returns
|
||||||
|
/// Returns the ID of this symbol.
|
||||||
|
uint32_t GetID();
|
||||||
|
|
||||||
bool operator==(const lldb::SBSymbol &rhs) const;
|
bool operator==(const lldb::SBSymbol &rhs) const;
|
||||||
|
|
||||||
bool operator!=(const lldb::SBSymbol &rhs) const;
|
bool operator!=(const lldb::SBSymbol &rhs) const;
|
||||||
@ -99,6 +105,15 @@ public:
|
|||||||
// other than the actual symbol table itself in the object file.
|
// other than the actual symbol table itself in the object file.
|
||||||
bool IsSynthetic();
|
bool IsSynthetic();
|
||||||
|
|
||||||
|
/// Returns true if the symbol is a debug symbol.
|
||||||
|
bool IsDebug();
|
||||||
|
|
||||||
|
/// Get the string representation of a symbol type.
|
||||||
|
static const char *GetTypeAsString(lldb::SymbolType symbol_type);
|
||||||
|
|
||||||
|
/// Get the symbol type from a string representation.
|
||||||
|
static lldb::SymbolType GetTypeFromString(const char *str);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
lldb_private::Symbol *get();
|
lldb_private::Symbol *get();
|
||||||
|
|
||||||
|
@ -324,6 +324,16 @@ public:
|
|||||||
|
|
||||||
lldb::SBModule FindModule(const lldb::SBFileSpec &file_spec);
|
lldb::SBModule FindModule(const lldb::SBFileSpec &file_spec);
|
||||||
|
|
||||||
|
/// Find a module with the given module specification.
|
||||||
|
///
|
||||||
|
/// \param[in] module_spec
|
||||||
|
/// A lldb::SBModuleSpec object that contains module specification.
|
||||||
|
///
|
||||||
|
/// \return
|
||||||
|
/// A lldb::SBModule object that represents the found module, or an
|
||||||
|
/// invalid SBModule object if no module was found.
|
||||||
|
lldb::SBModule FindModule(const lldb::SBModuleSpec &module_spec);
|
||||||
|
|
||||||
/// Find compile units related to *this target and passed source
|
/// Find compile units related to *this target and passed source
|
||||||
/// file.
|
/// file.
|
||||||
///
|
///
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "lldb/Symbol/SymbolContextScope.h"
|
#include "lldb/Symbol/SymbolContextScope.h"
|
||||||
#include "lldb/Utility/Stream.h"
|
#include "lldb/Utility/Stream.h"
|
||||||
#include "lldb/Utility/UserID.h"
|
#include "lldb/Utility/UserID.h"
|
||||||
|
#include "lldb/lldb-enumerations.h"
|
||||||
#include "lldb/lldb-private.h"
|
#include "lldb/lldb-private.h"
|
||||||
#include "llvm/Support/JSON.h"
|
#include "llvm/Support/JSON.h"
|
||||||
|
|
||||||
@ -301,6 +302,10 @@ public:
|
|||||||
|
|
||||||
bool operator==(const Symbol &rhs) const;
|
bool operator==(const Symbol &rhs) const;
|
||||||
|
|
||||||
|
static const char *GetTypeAsString(lldb::SymbolType symbol_type);
|
||||||
|
|
||||||
|
static lldb::SymbolType GetTypeFromString(const char *str);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// This is the internal guts of ResolveReExportedSymbol, it assumes
|
// This is the internal guts of ResolveReExportedSymbol, it assumes
|
||||||
// reexport_name is not null, and that module_spec is valid. We track the
|
// reexport_name is not null, and that module_spec is valid. We track the
|
||||||
|
@ -1299,6 +1299,25 @@ class DebugCommunication(object):
|
|||||||
{"command": "modules", "type": "request", "arguments": args_dict}
|
{"command": "modules", "type": "request", "arguments": args_dict}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def request_moduleSymbols(
|
||||||
|
self,
|
||||||
|
moduleId: str = "",
|
||||||
|
moduleName: str = "",
|
||||||
|
startIndex: int = 0,
|
||||||
|
count: int = 0,
|
||||||
|
):
|
||||||
|
command_dict = {
|
||||||
|
"command": "__lldb_moduleSymbols",
|
||||||
|
"type": "request",
|
||||||
|
"arguments": {
|
||||||
|
"moduleId": moduleId,
|
||||||
|
"moduleName": moduleName,
|
||||||
|
"startIndex": startIndex,
|
||||||
|
"count": count,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return self._send_recv(command_dict)
|
||||||
|
|
||||||
def request_stackTrace(
|
def request_stackTrace(
|
||||||
self, threadId=None, startFrame=None, levels=None, format=None, dump=False
|
self, threadId=None, startFrame=None, levels=None, format=None, dump=False
|
||||||
):
|
):
|
||||||
|
@ -193,6 +193,14 @@ SymbolType SBSymbol::GetType() {
|
|||||||
return eSymbolTypeInvalid;
|
return eSymbolTypeInvalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t SBSymbol::GetID() {
|
||||||
|
LLDB_INSTRUMENT_VA(this);
|
||||||
|
|
||||||
|
if (m_opaque_ptr)
|
||||||
|
return m_opaque_ptr->GetID();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool SBSymbol::IsExternal() {
|
bool SBSymbol::IsExternal() {
|
||||||
LLDB_INSTRUMENT_VA(this);
|
LLDB_INSTRUMENT_VA(this);
|
||||||
|
|
||||||
@ -208,3 +216,23 @@ bool SBSymbol::IsSynthetic() {
|
|||||||
return m_opaque_ptr->IsSynthetic();
|
return m_opaque_ptr->IsSynthetic();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SBSymbol::IsDebug() {
|
||||||
|
LLDB_INSTRUMENT_VA(this);
|
||||||
|
|
||||||
|
if (m_opaque_ptr)
|
||||||
|
return m_opaque_ptr->IsDebug();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *SBSymbol::GetTypeAsString(lldb::SymbolType symbol_type) {
|
||||||
|
LLDB_INSTRUMENT_VA(symbol_type);
|
||||||
|
|
||||||
|
return Symbol::GetTypeAsString(symbol_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
lldb::SymbolType SBSymbol::GetTypeFromString(const char *str) {
|
||||||
|
LLDB_INSTRUMENT_VA(str);
|
||||||
|
|
||||||
|
return Symbol::GetTypeFromString(str);
|
||||||
|
}
|
||||||
|
@ -1570,6 +1570,18 @@ SBModule SBTarget::FindModule(const SBFileSpec &sb_file_spec) {
|
|||||||
return sb_module;
|
return sb_module;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SBModule SBTarget::FindModule(const SBModuleSpec &sb_module_spec) {
|
||||||
|
LLDB_INSTRUMENT_VA(this, sb_module_spec);
|
||||||
|
|
||||||
|
SBModule sb_module;
|
||||||
|
if (TargetSP target_sp = GetSP(); target_sp && sb_module_spec.IsValid()) {
|
||||||
|
// The module list is thread safe, no need to lock.
|
||||||
|
sb_module.SetSP(
|
||||||
|
target_sp->GetImages().FindFirstModule(*sb_module_spec.m_opaque_up));
|
||||||
|
}
|
||||||
|
return sb_module;
|
||||||
|
}
|
||||||
|
|
||||||
SBSymbolContextList SBTarget::FindCompileUnits(const SBFileSpec &sb_file_spec) {
|
SBSymbolContextList SBTarget::FindCompileUnits(const SBFileSpec &sb_file_spec) {
|
||||||
LLDB_INSTRUMENT_VA(this, sb_file_spec);
|
LLDB_INSTRUMENT_VA(this, sb_file_spec);
|
||||||
|
|
||||||
|
@ -347,9 +347,6 @@ Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
|
|||||||
else
|
else
|
||||||
data.SetAddressByteSize(sizeof(void *));
|
data.SetAddressByteSize(sizeof(void *));
|
||||||
|
|
||||||
if (!type_size)
|
|
||||||
return Status::FromErrorString("type does not have a size");
|
|
||||||
|
|
||||||
uint32_t result_byte_size = *type_size;
|
uint32_t result_byte_size = *type_size;
|
||||||
if (m_value.GetData(data, result_byte_size))
|
if (m_value.GetData(data, result_byte_size))
|
||||||
return error; // Success;
|
return error; // Success;
|
||||||
|
@ -392,45 +392,8 @@ bool Symbol::Compare(ConstString name, SymbolType type) const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ENUM_TO_CSTRING(x) \
|
|
||||||
case eSymbolType##x: \
|
|
||||||
return #x;
|
|
||||||
|
|
||||||
const char *Symbol::GetTypeAsString() const {
|
const char *Symbol::GetTypeAsString() const {
|
||||||
switch (m_type) {
|
return GetTypeAsString(static_cast<lldb::SymbolType>(m_type));
|
||||||
ENUM_TO_CSTRING(Invalid);
|
|
||||||
ENUM_TO_CSTRING(Absolute);
|
|
||||||
ENUM_TO_CSTRING(Code);
|
|
||||||
ENUM_TO_CSTRING(Resolver);
|
|
||||||
ENUM_TO_CSTRING(Data);
|
|
||||||
ENUM_TO_CSTRING(Trampoline);
|
|
||||||
ENUM_TO_CSTRING(Runtime);
|
|
||||||
ENUM_TO_CSTRING(Exception);
|
|
||||||
ENUM_TO_CSTRING(SourceFile);
|
|
||||||
ENUM_TO_CSTRING(HeaderFile);
|
|
||||||
ENUM_TO_CSTRING(ObjectFile);
|
|
||||||
ENUM_TO_CSTRING(CommonBlock);
|
|
||||||
ENUM_TO_CSTRING(Block);
|
|
||||||
ENUM_TO_CSTRING(Local);
|
|
||||||
ENUM_TO_CSTRING(Param);
|
|
||||||
ENUM_TO_CSTRING(Variable);
|
|
||||||
ENUM_TO_CSTRING(VariableType);
|
|
||||||
ENUM_TO_CSTRING(LineEntry);
|
|
||||||
ENUM_TO_CSTRING(LineHeader);
|
|
||||||
ENUM_TO_CSTRING(ScopeBegin);
|
|
||||||
ENUM_TO_CSTRING(ScopeEnd);
|
|
||||||
ENUM_TO_CSTRING(Additional);
|
|
||||||
ENUM_TO_CSTRING(Compiler);
|
|
||||||
ENUM_TO_CSTRING(Instrumentation);
|
|
||||||
ENUM_TO_CSTRING(Undefined);
|
|
||||||
ENUM_TO_CSTRING(ObjCClass);
|
|
||||||
ENUM_TO_CSTRING(ObjCMetaClass);
|
|
||||||
ENUM_TO_CSTRING(ObjCIVar);
|
|
||||||
ENUM_TO_CSTRING(ReExported);
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return "<unknown SymbolType>";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Symbol::CalculateSymbolContext(SymbolContext *sc) {
|
void Symbol::CalculateSymbolContext(SymbolContext *sc) {
|
||||||
@ -774,6 +737,79 @@ bool Symbol::operator==(const Symbol &rhs) const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ENUM_TO_CSTRING(x) \
|
||||||
|
case eSymbolType##x: \
|
||||||
|
return #x;
|
||||||
|
|
||||||
|
const char *Symbol::GetTypeAsString(lldb::SymbolType symbol_type) {
|
||||||
|
switch (symbol_type) {
|
||||||
|
ENUM_TO_CSTRING(Invalid);
|
||||||
|
ENUM_TO_CSTRING(Absolute);
|
||||||
|
ENUM_TO_CSTRING(Code);
|
||||||
|
ENUM_TO_CSTRING(Resolver);
|
||||||
|
ENUM_TO_CSTRING(Data);
|
||||||
|
ENUM_TO_CSTRING(Trampoline);
|
||||||
|
ENUM_TO_CSTRING(Runtime);
|
||||||
|
ENUM_TO_CSTRING(Exception);
|
||||||
|
ENUM_TO_CSTRING(SourceFile);
|
||||||
|
ENUM_TO_CSTRING(HeaderFile);
|
||||||
|
ENUM_TO_CSTRING(ObjectFile);
|
||||||
|
ENUM_TO_CSTRING(CommonBlock);
|
||||||
|
ENUM_TO_CSTRING(Block);
|
||||||
|
ENUM_TO_CSTRING(Local);
|
||||||
|
ENUM_TO_CSTRING(Param);
|
||||||
|
ENUM_TO_CSTRING(Variable);
|
||||||
|
ENUM_TO_CSTRING(VariableType);
|
||||||
|
ENUM_TO_CSTRING(LineEntry);
|
||||||
|
ENUM_TO_CSTRING(LineHeader);
|
||||||
|
ENUM_TO_CSTRING(ScopeBegin);
|
||||||
|
ENUM_TO_CSTRING(ScopeEnd);
|
||||||
|
ENUM_TO_CSTRING(Additional);
|
||||||
|
ENUM_TO_CSTRING(Compiler);
|
||||||
|
ENUM_TO_CSTRING(Instrumentation);
|
||||||
|
ENUM_TO_CSTRING(Undefined);
|
||||||
|
ENUM_TO_CSTRING(ObjCClass);
|
||||||
|
ENUM_TO_CSTRING(ObjCMetaClass);
|
||||||
|
ENUM_TO_CSTRING(ObjCIVar);
|
||||||
|
ENUM_TO_CSTRING(ReExported);
|
||||||
|
}
|
||||||
|
return "<unknown SymbolType>";
|
||||||
|
}
|
||||||
|
|
||||||
|
lldb::SymbolType Symbol::GetTypeFromString(const char *str) {
|
||||||
|
std::string str_lower = llvm::StringRef(str).lower();
|
||||||
|
return llvm::StringSwitch<lldb::SymbolType>(str_lower)
|
||||||
|
.Case("absolute", eSymbolTypeAbsolute)
|
||||||
|
.Case("code", eSymbolTypeCode)
|
||||||
|
.Case("resolver", eSymbolTypeResolver)
|
||||||
|
.Case("data", eSymbolTypeData)
|
||||||
|
.Case("trampoline", eSymbolTypeTrampoline)
|
||||||
|
.Case("runtime", eSymbolTypeRuntime)
|
||||||
|
.Case("exception", eSymbolTypeException)
|
||||||
|
.Case("sourcefile", eSymbolTypeSourceFile)
|
||||||
|
.Case("headerfile", eSymbolTypeHeaderFile)
|
||||||
|
.Case("objectfile", eSymbolTypeObjectFile)
|
||||||
|
.Case("commonblock", eSymbolTypeCommonBlock)
|
||||||
|
.Case("block", eSymbolTypeBlock)
|
||||||
|
.Case("local", eSymbolTypeLocal)
|
||||||
|
.Case("param", eSymbolTypeParam)
|
||||||
|
.Case("variable", eSymbolTypeVariable)
|
||||||
|
.Case("variableType", eSymbolTypeVariableType)
|
||||||
|
.Case("lineentry", eSymbolTypeLineEntry)
|
||||||
|
.Case("lineheader", eSymbolTypeLineHeader)
|
||||||
|
.Case("scopebegin", eSymbolTypeScopeBegin)
|
||||||
|
.Case("scopeend", eSymbolTypeScopeEnd)
|
||||||
|
.Case("additional,", eSymbolTypeAdditional)
|
||||||
|
.Case("compiler", eSymbolTypeCompiler)
|
||||||
|
.Case("instrumentation", eSymbolTypeInstrumentation)
|
||||||
|
.Case("undefined", eSymbolTypeUndefined)
|
||||||
|
.Case("objcclass", eSymbolTypeObjCClass)
|
||||||
|
.Case("objcmetaclass", eSymbolTypeObjCMetaClass)
|
||||||
|
.Case("objcivar", eSymbolTypeObjCIVar)
|
||||||
|
.Case("reexported", eSymbolTypeReExported)
|
||||||
|
.Default(eSymbolTypeInvalid);
|
||||||
|
}
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
namespace json {
|
namespace json {
|
||||||
|
|
||||||
@ -804,36 +840,8 @@ bool fromJSON(const llvm::json::Value &value, lldb_private::JSONSymbol &symbol,
|
|||||||
bool fromJSON(const llvm::json::Value &value, lldb::SymbolType &type,
|
bool fromJSON(const llvm::json::Value &value, lldb::SymbolType &type,
|
||||||
llvm::json::Path path) {
|
llvm::json::Path path) {
|
||||||
if (auto str = value.getAsString()) {
|
if (auto str = value.getAsString()) {
|
||||||
type = llvm::StringSwitch<lldb::SymbolType>(*str)
|
llvm::StringRef str_ref = str.value_or("");
|
||||||
.Case("absolute", eSymbolTypeAbsolute)
|
type = Symbol::GetTypeFromString(str_ref.data());
|
||||||
.Case("code", eSymbolTypeCode)
|
|
||||||
.Case("resolver", eSymbolTypeResolver)
|
|
||||||
.Case("data", eSymbolTypeData)
|
|
||||||
.Case("trampoline", eSymbolTypeTrampoline)
|
|
||||||
.Case("runtime", eSymbolTypeRuntime)
|
|
||||||
.Case("exception", eSymbolTypeException)
|
|
||||||
.Case("sourcefile", eSymbolTypeSourceFile)
|
|
||||||
.Case("headerfile", eSymbolTypeHeaderFile)
|
|
||||||
.Case("objectfile", eSymbolTypeObjectFile)
|
|
||||||
.Case("commonblock", eSymbolTypeCommonBlock)
|
|
||||||
.Case("block", eSymbolTypeBlock)
|
|
||||||
.Case("local", eSymbolTypeLocal)
|
|
||||||
.Case("param", eSymbolTypeParam)
|
|
||||||
.Case("variable", eSymbolTypeVariable)
|
|
||||||
.Case("variableType", eSymbolTypeVariableType)
|
|
||||||
.Case("lineentry", eSymbolTypeLineEntry)
|
|
||||||
.Case("lineheader", eSymbolTypeLineHeader)
|
|
||||||
.Case("scopebegin", eSymbolTypeScopeBegin)
|
|
||||||
.Case("scopeend", eSymbolTypeScopeEnd)
|
|
||||||
.Case("additional,", eSymbolTypeAdditional)
|
|
||||||
.Case("compiler", eSymbolTypeCompiler)
|
|
||||||
.Case("instrumentation", eSymbolTypeInstrumentation)
|
|
||||||
.Case("undefined", eSymbolTypeUndefined)
|
|
||||||
.Case("objcclass", eSymbolTypeObjCClass)
|
|
||||||
.Case("objcmetaClass", eSymbolTypeObjCMetaClass)
|
|
||||||
.Case("objcivar", eSymbolTypeObjCIVar)
|
|
||||||
.Case("reexporte", eSymbolTypeReExported)
|
|
||||||
.Default(eSymbolTypeInvalid);
|
|
||||||
|
|
||||||
if (type == eSymbolTypeInvalid) {
|
if (type == eSymbolTypeInvalid) {
|
||||||
path.report("invalid symbol type");
|
path.report("invalid symbol type");
|
||||||
|
3
lldb/test/API/tools/lldb-dap/moduleSymbols/Makefile
Normal file
3
lldb/test/API/tools/lldb-dap/moduleSymbols/Makefile
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
C_SOURCES := main.c
|
||||||
|
|
||||||
|
include Makefile.rules
|
@ -0,0 +1,37 @@
|
|||||||
|
"""
|
||||||
|
Test lldb-dap moduleSymbols request
|
||||||
|
"""
|
||||||
|
|
||||||
|
import lldbdap_testcase
|
||||||
|
|
||||||
|
|
||||||
|
class TestDAP_moduleSymbols(lldbdap_testcase.DAPTestCaseBase):
|
||||||
|
def test_moduleSymbols(self):
|
||||||
|
"""
|
||||||
|
Test that the moduleSymbols request returns correct symbols from the module.
|
||||||
|
"""
|
||||||
|
program = self.getBuildArtifact("a.out")
|
||||||
|
self.build_and_launch(program)
|
||||||
|
|
||||||
|
symbol_names = []
|
||||||
|
i = 0
|
||||||
|
while True:
|
||||||
|
next_symbol = self.dap_server.request_moduleSymbols(
|
||||||
|
moduleName="a.out", startIndex=i, count=1
|
||||||
|
)
|
||||||
|
self.assertIn("symbols", next_symbol["body"])
|
||||||
|
result_symbols = next_symbol["body"]["symbols"]
|
||||||
|
self.assertLessEqual(len(result_symbols), 1)
|
||||||
|
if len(result_symbols) == 0:
|
||||||
|
break
|
||||||
|
|
||||||
|
self.assertIn("name", result_symbols[0])
|
||||||
|
symbol_names.append(result_symbols[0]["name"])
|
||||||
|
i += 1
|
||||||
|
if i >= 1000:
|
||||||
|
break
|
||||||
|
|
||||||
|
self.assertGreater(len(symbol_names), 0)
|
||||||
|
self.assertIn("main", symbol_names)
|
||||||
|
self.assertIn("func1", symbol_names)
|
||||||
|
self.assertIn("func2", symbol_names)
|
9
lldb/test/API/tools/lldb-dap/moduleSymbols/main.c
Normal file
9
lldb/test/API/tools/lldb-dap/moduleSymbols/main.c
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
int func1() { return 42; }
|
||||||
|
|
||||||
|
int func2() { return 84; }
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
func1();
|
||||||
|
func2();
|
||||||
|
return 0;
|
||||||
|
}
|
@ -792,39 +792,6 @@ void show_usage_and_exit(int exit_code) {
|
|||||||
DEBUGSERVER_PROGRAM_NAME);
|
DEBUGSERVER_PROGRAM_NAME);
|
||||||
RNBLogSTDERR(" %s /path/file --attach=<process_name>\n",
|
RNBLogSTDERR(" %s /path/file --attach=<process_name>\n",
|
||||||
DEBUGSERVER_PROGRAM_NAME);
|
DEBUGSERVER_PROGRAM_NAME);
|
||||||
RNBLogSTDERR("\n");
|
|
||||||
RNBLogSTDERR(" -a | --attach <pid>\n");
|
|
||||||
RNBLogSTDERR(" -w | --waitfor <name>\n");
|
|
||||||
RNBLogSTDERR(" -A | --arch <arch>\n");
|
|
||||||
RNBLogSTDERR(" -g | --debug\n");
|
|
||||||
RNBLogSTDERR(" -K | --kill-on-error\n");
|
|
||||||
RNBLogSTDERR(" -v | --verbose\n");
|
|
||||||
RNBLogSTDERR(" -V | --version\n");
|
|
||||||
RNBLogSTDERR(" -k | --lockdown\n");
|
|
||||||
RNBLogSTDERR(" -t | --applist\n");
|
|
||||||
RNBLogSTDERR(" -l | --log-file\n");
|
|
||||||
RNBLogSTDERR(" -f | --log-flags\n");
|
|
||||||
RNBLogSTDERR(" -x | --launch <auto|posix-spawn|fork-exec|springboard>\n");
|
|
||||||
RNBLogSTDERR(" -d | --waitfor-duration <seconds>\n");
|
|
||||||
RNBLogSTDERR(" -i | --waitfor-interval <usecs>\n");
|
|
||||||
RNBLogSTDERR(" -r | --native-regs\n");
|
|
||||||
RNBLogSTDERR(" -s | --studio-path <path>\n");
|
|
||||||
RNBLogSTDERR(" -I | --stdin-path <path>\n");
|
|
||||||
RNBLogSTDERR(" -O | --stdout-path <path>\n");
|
|
||||||
RNBLogSTDERR(" -E | --stderr-path <path>\n");
|
|
||||||
RNBLogSTDERR(" -n | --no-stdio\n");
|
|
||||||
RNBLogSTDERR(" -S | --setsid\n");
|
|
||||||
RNBLogSTDERR(" -D | --disable-aslr\n");
|
|
||||||
RNBLogSTDERR(" -W | --working-dir <dir>\n");
|
|
||||||
RNBLogSTDERR(" -p | --platform <arg?>\n");
|
|
||||||
RNBLogSTDERR(" -u | --unix-socket <unix socket name>\n");
|
|
||||||
RNBLogSTDERR(" -2 | --fd <file descriptor number>\n");
|
|
||||||
RNBLogSTDERR(" -P | --named-pipe <pipe>\n");
|
|
||||||
RNBLogSTDERR(" -R | --reverse-connect\n");
|
|
||||||
RNBLogSTDERR(" -e | --env <env>\n");
|
|
||||||
RNBLogSTDERR(" -F | --forward-env <env>\n");
|
|
||||||
RNBLogSTDERR(" -U | --unmask-signals\n");
|
|
||||||
|
|
||||||
exit(exit_code);
|
exit(exit_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ add_lldb_library(lldbDAP
|
|||||||
Handler/LaunchRequestHandler.cpp
|
Handler/LaunchRequestHandler.cpp
|
||||||
Handler/LocationsRequestHandler.cpp
|
Handler/LocationsRequestHandler.cpp
|
||||||
Handler/ModulesRequestHandler.cpp
|
Handler/ModulesRequestHandler.cpp
|
||||||
|
Handler/ModuleSymbolsRequestHandler.cpp
|
||||||
Handler/NextRequestHandler.cpp
|
Handler/NextRequestHandler.cpp
|
||||||
Handler/PauseRequestHandler.cpp
|
Handler/PauseRequestHandler.cpp
|
||||||
Handler/ReadMemoryRequestHandler.cpp
|
Handler/ReadMemoryRequestHandler.cpp
|
||||||
|
@ -1258,6 +1258,27 @@ protocol::Capabilities DAP::GetCapabilities() {
|
|||||||
return capabilities;
|
return capabilities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protocol::Capabilities DAP::GetCustomCapabilities() {
|
||||||
|
protocol::Capabilities capabilities;
|
||||||
|
|
||||||
|
// Add all custom capabilities here.
|
||||||
|
const llvm::DenseSet<AdapterFeature> all_custom_features = {
|
||||||
|
protocol::eAdapterFeatureSupportsModuleSymbolsRequest,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto &kv : request_handlers) {
|
||||||
|
llvm::SmallDenseSet<AdapterFeature, 1> features =
|
||||||
|
kv.second->GetSupportedFeatures();
|
||||||
|
|
||||||
|
for (auto &feature : features) {
|
||||||
|
if (all_custom_features.contains(feature))
|
||||||
|
capabilities.supportedFeatures.insert(feature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return capabilities;
|
||||||
|
}
|
||||||
|
|
||||||
void DAP::StartEventThread() {
|
void DAP::StartEventThread() {
|
||||||
event_thread = std::thread(&DAP::EventThread, this);
|
event_thread = std::thread(&DAP::EventThread, this);
|
||||||
}
|
}
|
||||||
@ -1614,6 +1635,7 @@ void DAP::RegisterRequests() {
|
|||||||
// Custom requests
|
// Custom requests
|
||||||
RegisterRequest<CompileUnitsRequestHandler>();
|
RegisterRequest<CompileUnitsRequestHandler>();
|
||||||
RegisterRequest<ModulesRequestHandler>();
|
RegisterRequest<ModulesRequestHandler>();
|
||||||
|
RegisterRequest<ModuleSymbolsRequestHandler>();
|
||||||
|
|
||||||
// Testing requests
|
// Testing requests
|
||||||
RegisterRequest<TestGetTargetBreakpointsRequestHandler>();
|
RegisterRequest<TestGetTargetBreakpointsRequestHandler>();
|
||||||
|
@ -367,6 +367,9 @@ struct DAP final : private DAPTransport::MessageHandler {
|
|||||||
/// The set of capabilities supported by this adapter.
|
/// The set of capabilities supported by this adapter.
|
||||||
protocol::Capabilities GetCapabilities();
|
protocol::Capabilities GetCapabilities();
|
||||||
|
|
||||||
|
/// The set of custom capabilities supported by this adapter.
|
||||||
|
protocol::Capabilities GetCustomCapabilities();
|
||||||
|
|
||||||
/// Debuggee will continue from stopped state.
|
/// Debuggee will continue from stopped state.
|
||||||
void WillContinue() { variables.Clear(); }
|
void WillContinue() { variables.Clear(); }
|
||||||
|
|
||||||
|
@ -38,25 +38,37 @@ static void SendThreadExitedEvent(DAP &dap, lldb::tid_t tid) {
|
|||||||
dap.SendJSON(llvm::json::Value(std::move(event)));
|
dap.SendJSON(llvm::json::Value(std::move(event)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendTargetBasedCapabilities(DAP &dap) {
|
/// Get capabilities based on the configured target.
|
||||||
|
static llvm::DenseSet<AdapterFeature> GetTargetBasedCapabilities(DAP &dap) {
|
||||||
|
llvm::DenseSet<AdapterFeature> capabilities;
|
||||||
if (!dap.target.IsValid())
|
if (!dap.target.IsValid())
|
||||||
return;
|
return capabilities;
|
||||||
|
|
||||||
protocol::CapabilitiesEventBody body;
|
|
||||||
|
|
||||||
const llvm::StringRef target_triple = dap.target.GetTriple();
|
const llvm::StringRef target_triple = dap.target.GetTriple();
|
||||||
if (target_triple.starts_with("x86"))
|
if (target_triple.starts_with("x86"))
|
||||||
body.capabilities.supportedFeatures.insert(
|
capabilities.insert(protocol::eAdapterFeatureStepInTargetsRequest);
|
||||||
protocol::eAdapterFeatureStepInTargetsRequest);
|
|
||||||
|
|
||||||
// We only support restarting launch requests not attach requests.
|
// We only support restarting launch requests not attach requests.
|
||||||
if (dap.last_launch_request)
|
if (dap.last_launch_request)
|
||||||
body.capabilities.supportedFeatures.insert(
|
capabilities.insert(protocol::eAdapterFeatureRestartRequest);
|
||||||
protocol::eAdapterFeatureRestartRequest);
|
|
||||||
|
return capabilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendExtraCapabilities(DAP &dap) {
|
||||||
|
protocol::Capabilities capabilities = dap.GetCustomCapabilities();
|
||||||
|
llvm::DenseSet<AdapterFeature> target_capabilities =
|
||||||
|
GetTargetBasedCapabilities(dap);
|
||||||
|
|
||||||
|
capabilities.supportedFeatures.insert(target_capabilities.begin(),
|
||||||
|
target_capabilities.end());
|
||||||
|
|
||||||
|
protocol::CapabilitiesEventBody body;
|
||||||
|
body.capabilities = std::move(capabilities);
|
||||||
|
|
||||||
// Only notify the client if supportedFeatures changed.
|
// Only notify the client if supportedFeatures changed.
|
||||||
if (!body.capabilities.supportedFeatures.empty())
|
if (!body.capabilities.supportedFeatures.empty())
|
||||||
dap.Send(protocol::Event{"capabilities", body});
|
dap.Send(protocol::Event{"capabilities", std::move(body)});
|
||||||
}
|
}
|
||||||
|
|
||||||
// "ProcessEvent": {
|
// "ProcessEvent": {
|
||||||
|
@ -17,8 +17,8 @@ struct DAP;
|
|||||||
|
|
||||||
enum LaunchMethod { Launch, Attach, AttachForSuspendedLaunch };
|
enum LaunchMethod { Launch, Attach, AttachForSuspendedLaunch };
|
||||||
|
|
||||||
/// Update capabilities based on the configured target.
|
/// Sends target based capabilities and lldb-dap custom capabilities.
|
||||||
void SendTargetBasedCapabilities(DAP &dap);
|
void SendExtraCapabilities(DAP &dap);
|
||||||
|
|
||||||
void SendProcessEvent(DAP &dap, LaunchMethod launch_method);
|
void SendProcessEvent(DAP &dap, LaunchMethod launch_method);
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "DAP.h"
|
#include "DAP.h"
|
||||||
#include "EventHelper.h"
|
#include "EventHelper.h"
|
||||||
#include "LLDBUtils.h"
|
#include "LLDBUtils.h"
|
||||||
|
#include "Protocol/ProtocolEvents.h"
|
||||||
#include "Protocol/ProtocolRequests.h"
|
#include "Protocol/ProtocolRequests.h"
|
||||||
#include "ProtocolUtils.h"
|
#include "ProtocolUtils.h"
|
||||||
#include "RequestHandler.h"
|
#include "RequestHandler.h"
|
||||||
@ -44,7 +45,10 @@ ConfigurationDoneRequestHandler::Run(const ConfigurationDoneArguments &) const {
|
|||||||
// Waiting until 'configurationDone' to send target based capabilities in case
|
// Waiting until 'configurationDone' to send target based capabilities in case
|
||||||
// the launch or attach scripts adjust the target. The initial dummy target
|
// the launch or attach scripts adjust the target. The initial dummy target
|
||||||
// may have different capabilities than the final target.
|
// may have different capabilities than the final target.
|
||||||
SendTargetBasedCapabilities(dap);
|
|
||||||
|
/// Also send here custom capabilities to the client, which is consumed by the
|
||||||
|
/// lldb-dap specific editor extension.
|
||||||
|
SendExtraCapabilities(dap);
|
||||||
|
|
||||||
// Clients can request a baseline of currently existing threads after
|
// Clients can request a baseline of currently existing threads after
|
||||||
// we acknowledge the configurationDone request.
|
// we acknowledge the configurationDone request.
|
||||||
|
89
lldb/tools/lldb-dap/Handler/ModuleSymbolsRequestHandler.cpp
Normal file
89
lldb/tools/lldb-dap/Handler/ModuleSymbolsRequestHandler.cpp
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// 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 "DAP.h"
|
||||||
|
#include "DAPError.h"
|
||||||
|
#include "Protocol/DAPTypes.h"
|
||||||
|
#include "RequestHandler.h"
|
||||||
|
#include "lldb/API/SBAddress.h"
|
||||||
|
#include "lldb/API/SBFileSpec.h"
|
||||||
|
#include "lldb/API/SBModule.h"
|
||||||
|
#include "lldb/API/SBModuleSpec.h"
|
||||||
|
#include "lldb/Utility/UUID.h"
|
||||||
|
#include "llvm/Support/Error.h"
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
using namespace lldb_dap::protocol;
|
||||||
|
namespace lldb_dap {
|
||||||
|
|
||||||
|
llvm::Expected<ModuleSymbolsResponseBody>
|
||||||
|
ModuleSymbolsRequestHandler::Run(const ModuleSymbolsArguments &args) const {
|
||||||
|
ModuleSymbolsResponseBody response;
|
||||||
|
|
||||||
|
lldb::SBModuleSpec module_spec;
|
||||||
|
if (!args.moduleId.empty()) {
|
||||||
|
llvm::SmallVector<uint8_t, 20> uuid_bytes;
|
||||||
|
if (!lldb_private::UUID::DecodeUUIDBytesFromString(args.moduleId,
|
||||||
|
uuid_bytes)
|
||||||
|
.empty())
|
||||||
|
return llvm::make_error<DAPError>("invalid module ID");
|
||||||
|
|
||||||
|
module_spec.SetUUIDBytes(uuid_bytes.data(), uuid_bytes.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!args.moduleName.empty()) {
|
||||||
|
lldb::SBFileSpec file_spec;
|
||||||
|
file_spec.SetFilename(args.moduleName.c_str());
|
||||||
|
module_spec.SetFileSpec(file_spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Empty request, return empty response.
|
||||||
|
if (!module_spec.IsValid())
|
||||||
|
return response;
|
||||||
|
|
||||||
|
std::vector<Symbol> &symbols = response.symbols;
|
||||||
|
lldb::SBModule module = dap.target.FindModule(module_spec);
|
||||||
|
if (!module.IsValid())
|
||||||
|
return llvm::make_error<DAPError>("module not found");
|
||||||
|
|
||||||
|
const size_t num_symbols = module.GetNumSymbols();
|
||||||
|
const size_t start_index = args.startIndex.value_or(0);
|
||||||
|
const size_t end_index =
|
||||||
|
std::min(start_index + args.count.value_or(num_symbols), num_symbols);
|
||||||
|
for (size_t i = start_index; i < end_index; ++i) {
|
||||||
|
lldb::SBSymbol symbol = module.GetSymbolAtIndex(i);
|
||||||
|
if (!symbol.IsValid())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Symbol dap_symbol;
|
||||||
|
dap_symbol.id = symbol.GetID();
|
||||||
|
dap_symbol.type = symbol.GetType();
|
||||||
|
dap_symbol.isDebug = symbol.IsDebug();
|
||||||
|
dap_symbol.isSynthetic = symbol.IsSynthetic();
|
||||||
|
dap_symbol.isExternal = symbol.IsExternal();
|
||||||
|
|
||||||
|
lldb::SBAddress start_address = symbol.GetStartAddress();
|
||||||
|
if (start_address.IsValid()) {
|
||||||
|
lldb::addr_t file_address = start_address.GetFileAddress();
|
||||||
|
if (file_address != LLDB_INVALID_ADDRESS)
|
||||||
|
dap_symbol.fileAddress = file_address;
|
||||||
|
|
||||||
|
lldb::addr_t load_address = start_address.GetLoadAddress(dap.target);
|
||||||
|
if (load_address != LLDB_INVALID_ADDRESS)
|
||||||
|
dap_symbol.loadAddress = load_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
dap_symbol.size = symbol.GetSize();
|
||||||
|
dap_symbol.name = symbol.GetName();
|
||||||
|
symbols.push_back(std::move(dap_symbol));
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace lldb_dap
|
@ -594,6 +594,20 @@ public:
|
|||||||
llvm::Error Run(const protocol::CancelArguments &args) const override;
|
llvm::Error Run(const protocol::CancelArguments &args) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ModuleSymbolsRequestHandler
|
||||||
|
: public RequestHandler<
|
||||||
|
protocol::ModuleSymbolsArguments,
|
||||||
|
llvm::Expected<protocol::ModuleSymbolsResponseBody>> {
|
||||||
|
public:
|
||||||
|
using RequestHandler::RequestHandler;
|
||||||
|
static llvm::StringLiteral GetCommand() { return "__lldb_moduleSymbols"; }
|
||||||
|
FeatureSet GetSupportedFeatures() const override {
|
||||||
|
return {protocol::eAdapterFeatureSupportsModuleSymbolsRequest};
|
||||||
|
}
|
||||||
|
llvm::Expected<protocol::ModuleSymbolsResponseBody>
|
||||||
|
Run(const protocol::ModuleSymbolsArguments &args) const override;
|
||||||
|
};
|
||||||
|
|
||||||
/// A request used in testing to get the details on all breakpoints that are
|
/// A request used in testing to get the details on all breakpoints that are
|
||||||
/// currently set in the target. This helps us to test "setBreakpoints" and
|
/// currently set in the target. This helps us to test "setBreakpoints" and
|
||||||
/// "setFunctionBreakpoints" requests to verify we have the correct set of
|
/// "setFunctionBreakpoints" requests to verify we have the correct set of
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
#include "Protocol/DAPTypes.h"
|
#include "Protocol/DAPTypes.h"
|
||||||
|
#include "lldb/API/SBSymbol.h"
|
||||||
|
#include "lldb/lldb-enumerations.h"
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
@ -33,4 +35,35 @@ llvm::json::Value toJSON(const SourceLLDBData &SLD) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace lldb_dap::protocol
|
bool fromJSON(const llvm::json::Value &Params, Symbol &DS, llvm::json::Path P) {
|
||||||
|
json::ObjectMapper O(Params, P);
|
||||||
|
std::string type_str;
|
||||||
|
if (!(O && O.map("id", DS.id) && O.map("isDebug", DS.isDebug) &&
|
||||||
|
O.map("isSynthetic", DS.isSynthetic) &&
|
||||||
|
O.map("isExternal", DS.isExternal) && O.map("type", type_str) &&
|
||||||
|
O.map("fileAddress", DS.fileAddress) &&
|
||||||
|
O.mapOptional("loadAddress", DS.loadAddress) &&
|
||||||
|
O.map("size", DS.size) && O.map("name", DS.name)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
DS.type = lldb::SBSymbol::GetTypeFromString(type_str.c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::json::Value toJSON(const Symbol &DS) {
|
||||||
|
json::Object result{
|
||||||
|
{"id", DS.id},
|
||||||
|
{"isDebug", DS.isDebug},
|
||||||
|
{"isSynthetic", DS.isSynthetic},
|
||||||
|
{"isExternal", DS.isExternal},
|
||||||
|
{"type", lldb::SBSymbol::GetTypeAsString(DS.type)},
|
||||||
|
{"fileAddress", DS.fileAddress},
|
||||||
|
{"loadAddress", DS.loadAddress},
|
||||||
|
{"size", DS.size},
|
||||||
|
{"name", DS.name},
|
||||||
|
};
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace lldb_dap::protocol
|
||||||
|
@ -48,6 +48,38 @@ struct SourceLLDBData {
|
|||||||
bool fromJSON(const llvm::json::Value &, SourceLLDBData &, llvm::json::Path);
|
bool fromJSON(const llvm::json::Value &, SourceLLDBData &, llvm::json::Path);
|
||||||
llvm::json::Value toJSON(const SourceLLDBData &);
|
llvm::json::Value toJSON(const SourceLLDBData &);
|
||||||
|
|
||||||
|
struct Symbol {
|
||||||
|
/// The symbol id, usually the original symbol table index.
|
||||||
|
uint32_t id;
|
||||||
|
|
||||||
|
/// True if this symbol is debug information in a symbol.
|
||||||
|
bool isDebug;
|
||||||
|
|
||||||
|
/// True if this symbol is not actually in the symbol table, but synthesized
|
||||||
|
/// from other info in the object file.
|
||||||
|
bool isSynthetic;
|
||||||
|
|
||||||
|
/// True if this symbol is globally visible.
|
||||||
|
bool isExternal;
|
||||||
|
|
||||||
|
/// The symbol type.
|
||||||
|
lldb::SymbolType type;
|
||||||
|
|
||||||
|
/// The symbol file address.
|
||||||
|
lldb::addr_t fileAddress;
|
||||||
|
|
||||||
|
/// The symbol load address.
|
||||||
|
std::optional<lldb::addr_t> loadAddress;
|
||||||
|
|
||||||
|
/// The symbol size.
|
||||||
|
lldb::addr_t size;
|
||||||
|
|
||||||
|
/// The symbol name.
|
||||||
|
std::string name;
|
||||||
|
};
|
||||||
|
bool fromJSON(const llvm::json::Value &, Symbol &, llvm::json::Path);
|
||||||
|
llvm::json::Value toJSON(const Symbol &);
|
||||||
|
|
||||||
} // namespace lldb_dap::protocol
|
} // namespace lldb_dap::protocol
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -598,4 +598,19 @@ json::Value toJSON(const WriteMemoryResponseBody &WMR) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool fromJSON(const llvm::json::Value &Params, ModuleSymbolsArguments &Args,
|
||||||
|
llvm::json::Path P) {
|
||||||
|
json::ObjectMapper O(Params, P);
|
||||||
|
return O && O.map("moduleId", Args.moduleId) &&
|
||||||
|
O.map("moduleName", Args.moduleName) &&
|
||||||
|
O.mapOptional("startIndex", Args.startIndex) &&
|
||||||
|
O.mapOptional("count", Args.count);
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::json::Value toJSON(const ModuleSymbolsResponseBody &DGMSR) {
|
||||||
|
json::Object result;
|
||||||
|
result.insert({"symbols", DGMSR.symbols});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace lldb_dap::protocol
|
} // namespace lldb_dap::protocol
|
||||||
|
@ -981,6 +981,30 @@ struct WriteMemoryResponseBody {
|
|||||||
};
|
};
|
||||||
llvm::json::Value toJSON(const WriteMemoryResponseBody &);
|
llvm::json::Value toJSON(const WriteMemoryResponseBody &);
|
||||||
|
|
||||||
|
struct ModuleSymbolsArguments {
|
||||||
|
/// The module UUID for which to retrieve symbols.
|
||||||
|
std::string moduleId;
|
||||||
|
|
||||||
|
/// The module path.
|
||||||
|
std::string moduleName;
|
||||||
|
|
||||||
|
/// The index of the first symbol to return; if omitted, start at the
|
||||||
|
/// beginning.
|
||||||
|
std::optional<uint32_t> startIndex;
|
||||||
|
|
||||||
|
/// The number of symbols to return; if omitted, all symbols are returned.
|
||||||
|
std::optional<uint32_t> count;
|
||||||
|
};
|
||||||
|
bool fromJSON(const llvm::json::Value &, ModuleSymbolsArguments &,
|
||||||
|
llvm::json::Path);
|
||||||
|
|
||||||
|
/// Response to `getModuleSymbols` request.
|
||||||
|
struct ModuleSymbolsResponseBody {
|
||||||
|
/// The symbols for the specified module.
|
||||||
|
std::vector<Symbol> symbols;
|
||||||
|
};
|
||||||
|
llvm::json::Value toJSON(const ModuleSymbolsResponseBody &);
|
||||||
|
|
||||||
} // namespace lldb_dap::protocol
|
} // namespace lldb_dap::protocol
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -335,6 +335,8 @@ static llvm::StringLiteral ToString(AdapterFeature feature) {
|
|||||||
return "supportsWriteMemoryRequest";
|
return "supportsWriteMemoryRequest";
|
||||||
case eAdapterFeatureTerminateDebuggee:
|
case eAdapterFeatureTerminateDebuggee:
|
||||||
return "supportTerminateDebuggee";
|
return "supportTerminateDebuggee";
|
||||||
|
case eAdapterFeatureSupportsModuleSymbolsRequest:
|
||||||
|
return "supportsModuleSymbolsRequest";
|
||||||
}
|
}
|
||||||
llvm_unreachable("unhandled adapter feature.");
|
llvm_unreachable("unhandled adapter feature.");
|
||||||
}
|
}
|
||||||
@ -406,6 +408,8 @@ bool fromJSON(const llvm::json::Value &Params, AdapterFeature &feature,
|
|||||||
eAdapterFeatureValueFormattingOptions)
|
eAdapterFeatureValueFormattingOptions)
|
||||||
.Case("supportsWriteMemoryRequest", eAdapterFeatureWriteMemoryRequest)
|
.Case("supportsWriteMemoryRequest", eAdapterFeatureWriteMemoryRequest)
|
||||||
.Case("supportTerminateDebuggee", eAdapterFeatureTerminateDebuggee)
|
.Case("supportTerminateDebuggee", eAdapterFeatureTerminateDebuggee)
|
||||||
|
.Case("supportsModuleSymbolsRequest",
|
||||||
|
eAdapterFeatureSupportsModuleSymbolsRequest)
|
||||||
.Default(std::nullopt);
|
.Default(std::nullopt);
|
||||||
|
|
||||||
if (!parsedFeature) {
|
if (!parsedFeature) {
|
||||||
|
@ -242,8 +242,11 @@ enum AdapterFeature : unsigned {
|
|||||||
/// The debug adapter supports the `terminateDebuggee` attribute on the
|
/// The debug adapter supports the `terminateDebuggee` attribute on the
|
||||||
/// `disconnect` request.
|
/// `disconnect` request.
|
||||||
eAdapterFeatureTerminateDebuggee,
|
eAdapterFeatureTerminateDebuggee,
|
||||||
|
/// The debug adapter supports the `supportsModuleSymbols` request.
|
||||||
|
/// This request is a custom request of lldb-dap.
|
||||||
|
eAdapterFeatureSupportsModuleSymbolsRequest,
|
||||||
eAdapterFeatureFirst = eAdapterFeatureANSIStyling,
|
eAdapterFeatureFirst = eAdapterFeatureANSIStyling,
|
||||||
eAdapterFeatureLast = eAdapterFeatureTerminateDebuggee,
|
eAdapterFeatureLast = eAdapterFeatureSupportsModuleSymbolsRequest,
|
||||||
};
|
};
|
||||||
bool fromJSON(const llvm::json::Value &, AdapterFeature &, llvm::json::Path);
|
bool fromJSON(const llvm::json::Value &, AdapterFeature &, llvm::json::Path);
|
||||||
llvm::json::Value toJSON(const AdapterFeature &);
|
llvm::json::Value toJSON(const AdapterFeature &);
|
||||||
|
513
lldb/tools/lldb-dap/package-lock.json
generated
513
lldb/tools/lldb-dap/package-lock.json
generated
@ -1,20 +1,24 @@
|
|||||||
{
|
{
|
||||||
"name": "lldb-dap",
|
"name": "lldb-dap",
|
||||||
"version": "0.2.15",
|
"version": "0.2.16",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "lldb-dap",
|
"name": "lldb-dap",
|
||||||
"version": "0.2.15",
|
"version": "0.2.16",
|
||||||
"license": "Apache 2.0 License with LLVM exceptions",
|
"license": "Apache 2.0 License with LLVM exceptions",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^18.19.41",
|
"@types/node": "^18.19.41",
|
||||||
|
"@types/tabulator-tables": "^6.2.10",
|
||||||
"@types/vscode": "1.75.0",
|
"@types/vscode": "1.75.0",
|
||||||
|
"@types/vscode-webview": "^1.57.5",
|
||||||
"@vscode/debugprotocol": "^1.68.0",
|
"@vscode/debugprotocol": "^1.68.0",
|
||||||
"@vscode/vsce": "^3.2.2",
|
"@vscode/vsce": "^3.2.2",
|
||||||
|
"esbuild": "^0.25.9",
|
||||||
"prettier": "^3.4.2",
|
"prettier": "^3.4.2",
|
||||||
"prettier-plugin-curly": "^0.3.1",
|
"prettier-plugin-curly": "^0.3.1",
|
||||||
|
"tabulator-tables": "^6.3.1",
|
||||||
"typescript": "^5.7.3"
|
"typescript": "^5.7.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -318,6 +322,448 @@
|
|||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@esbuild/aix-ppc64": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==",
|
||||||
|
"cpu": [
|
||||||
|
"ppc64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"aix"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/android-arm": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"android"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/android-arm64": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"android"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/android-x64": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"android"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/darwin-arm64": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/darwin-x64": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/freebsd-arm64": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"freebsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/freebsd-x64": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"freebsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-arm": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==",
|
||||||
|
"cpu": [
|
||||||
|
"arm"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-arm64": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-ia32": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==",
|
||||||
|
"cpu": [
|
||||||
|
"ia32"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-loong64": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==",
|
||||||
|
"cpu": [
|
||||||
|
"loong64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-mips64el": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==",
|
||||||
|
"cpu": [
|
||||||
|
"mips64el"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-ppc64": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==",
|
||||||
|
"cpu": [
|
||||||
|
"ppc64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-riscv64": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==",
|
||||||
|
"cpu": [
|
||||||
|
"riscv64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-s390x": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==",
|
||||||
|
"cpu": [
|
||||||
|
"s390x"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-x64": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/netbsd-arm64": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"netbsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/netbsd-x64": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"netbsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/openbsd-arm64": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"openbsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/openbsd-x64": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"openbsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/openharmony-arm64": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"openharmony"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/sunos-x64": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"sunos"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/win32-arm64": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/win32-ia32": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==",
|
||||||
|
"cpu": [
|
||||||
|
"ia32"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/win32-x64": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@isaacs/cliui": {
|
"node_modules/@isaacs/cliui": {
|
||||||
"version": "8.0.2",
|
"version": "8.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
||||||
@ -399,6 +845,13 @@
|
|||||||
"undici-types": "~5.26.4"
|
"undici-types": "~5.26.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/tabulator-tables": {
|
||||||
|
"version": "6.2.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/tabulator-tables/-/tabulator-tables-6.2.10.tgz",
|
||||||
|
"integrity": "sha512-g6o0gG3lu/ozmxPw9rLY1p57T6rvV8OhbJKyzWwPwjdnN3JuSQ3gWxb06v2+dl2tdoqNXTvlylipSSKpS8UzzQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@types/vscode": {
|
"node_modules/@types/vscode": {
|
||||||
"version": "1.75.0",
|
"version": "1.75.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.75.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.75.0.tgz",
|
||||||
@ -406,6 +859,13 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/vscode-webview": {
|
||||||
|
"version": "1.57.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/vscode-webview/-/vscode-webview-1.57.5.tgz",
|
||||||
|
"integrity": "sha512-iBAUYNYkz+uk1kdsq05fEcoh8gJmwT3lqqFPN7MGyjQ3HVloViMdo7ZJ8DFIP8WOK74PjOEilosqAyxV2iUFUw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@vscode/debugprotocol": {
|
"node_modules/@vscode/debugprotocol": {
|
||||||
"version": "1.68.0",
|
"version": "1.68.0",
|
||||||
"resolved": "https://registry.npmjs.org/@vscode/debugprotocol/-/debugprotocol-1.68.0.tgz",
|
"resolved": "https://registry.npmjs.org/@vscode/debugprotocol/-/debugprotocol-1.68.0.tgz",
|
||||||
@ -1169,6 +1629,48 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/esbuild": {
|
||||||
|
"version": "0.25.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz",
|
||||||
|
"integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==",
|
||||||
|
"dev": true,
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"esbuild": "bin/esbuild"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@esbuild/aix-ppc64": "0.25.9",
|
||||||
|
"@esbuild/android-arm": "0.25.9",
|
||||||
|
"@esbuild/android-arm64": "0.25.9",
|
||||||
|
"@esbuild/android-x64": "0.25.9",
|
||||||
|
"@esbuild/darwin-arm64": "0.25.9",
|
||||||
|
"@esbuild/darwin-x64": "0.25.9",
|
||||||
|
"@esbuild/freebsd-arm64": "0.25.9",
|
||||||
|
"@esbuild/freebsd-x64": "0.25.9",
|
||||||
|
"@esbuild/linux-arm": "0.25.9",
|
||||||
|
"@esbuild/linux-arm64": "0.25.9",
|
||||||
|
"@esbuild/linux-ia32": "0.25.9",
|
||||||
|
"@esbuild/linux-loong64": "0.25.9",
|
||||||
|
"@esbuild/linux-mips64el": "0.25.9",
|
||||||
|
"@esbuild/linux-ppc64": "0.25.9",
|
||||||
|
"@esbuild/linux-riscv64": "0.25.9",
|
||||||
|
"@esbuild/linux-s390x": "0.25.9",
|
||||||
|
"@esbuild/linux-x64": "0.25.9",
|
||||||
|
"@esbuild/netbsd-arm64": "0.25.9",
|
||||||
|
"@esbuild/netbsd-x64": "0.25.9",
|
||||||
|
"@esbuild/openbsd-arm64": "0.25.9",
|
||||||
|
"@esbuild/openbsd-x64": "0.25.9",
|
||||||
|
"@esbuild/openharmony-arm64": "0.25.9",
|
||||||
|
"@esbuild/sunos-x64": "0.25.9",
|
||||||
|
"@esbuild/win32-arm64": "0.25.9",
|
||||||
|
"@esbuild/win32-ia32": "0.25.9",
|
||||||
|
"@esbuild/win32-x64": "0.25.9"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/escape-string-regexp": {
|
"node_modules/escape-string-regexp": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||||
@ -2557,6 +3059,13 @@
|
|||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tabulator-tables": {
|
||||||
|
"version": "6.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tabulator-tables/-/tabulator-tables-6.3.1.tgz",
|
||||||
|
"integrity": "sha512-qFW7kfadtcaISQIibKAIy0f3eeIXUVi8242Vly1iJfMD79kfEGzfczNuPBN/80hDxHzQJXYbmJ8VipI40hQtfA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/tar-fs": {
|
"node_modules/tar-fs": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
|
||||||
|
@ -29,11 +29,15 @@
|
|||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^18.19.41",
|
"@types/node": "^18.19.41",
|
||||||
|
"@types/tabulator-tables": "^6.2.10",
|
||||||
"@types/vscode": "1.75.0",
|
"@types/vscode": "1.75.0",
|
||||||
|
"@types/vscode-webview": "^1.57.5",
|
||||||
"@vscode/debugprotocol": "^1.68.0",
|
"@vscode/debugprotocol": "^1.68.0",
|
||||||
"@vscode/vsce": "^3.2.2",
|
"@vscode/vsce": "^3.2.2",
|
||||||
|
"esbuild": "^0.25.9",
|
||||||
"prettier": "^3.4.2",
|
"prettier": "^3.4.2",
|
||||||
"prettier-plugin-curly": "^0.3.1",
|
"prettier-plugin-curly": "^0.3.1",
|
||||||
|
"tabulator-tables": "^6.3.1",
|
||||||
"typescript": "^5.7.3"
|
"typescript": "^5.7.3"
|
||||||
},
|
},
|
||||||
"activationEvents": [
|
"activationEvents": [
|
||||||
@ -42,8 +46,11 @@
|
|||||||
],
|
],
|
||||||
"main": "./out/extension",
|
"main": "./out/extension",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"vscode:prepublish": "tsc -p ./",
|
"bundle-symbols-table-view": "npx tsc -p src-ts/webview --noEmit && npx esbuild src-ts/webview/symbols-table-view.ts --bundle --format=iife --outdir=./out/webview",
|
||||||
"watch": "tsc -watch -p ./",
|
"bundle-tabulator": "cp node_modules/tabulator-tables/dist/js/tabulator.min.js ./out/webview/ && cp node_modules/tabulator-tables/dist/css/tabulator_midnight.min.css ./out/webview/ && cp node_modules/tabulator-tables/dist/css/tabulator_simple.min.css ./out/webview/",
|
||||||
|
"bundle-webview": "npm run bundle-symbols-table-view && npm run bundle-tabulator",
|
||||||
|
"vscode:prepublish": "npm run bundle-webview && tsc -p ./",
|
||||||
|
"watch": "npm run bundle-webview && tsc -watch -p ./",
|
||||||
"format": "npx prettier './src-ts/' --write",
|
"format": "npx prettier './src-ts/' --write",
|
||||||
"package": "rm -rf ./out/lldb-dap.vsix && vsce package --out ./out/lldb-dap.vsix",
|
"package": "rm -rf ./out/lldb-dap.vsix && vsce package --out ./out/lldb-dap.vsix",
|
||||||
"publish": "vsce publish",
|
"publish": "vsce publish",
|
||||||
@ -259,6 +266,15 @@
|
|||||||
{
|
{
|
||||||
"command": "lldb-dap.modules.copyProperty",
|
"command": "lldb-dap.modules.copyProperty",
|
||||||
"title": "Copy Value"
|
"title": "Copy Value"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "lldb-dap.modules.showSymbols",
|
||||||
|
"title": "Show Module Symbols"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": "lldb-dap",
|
||||||
|
"command": "lldb-dap.debug.showSymbols",
|
||||||
|
"title": "Show Symbols of a Module"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"menus": {
|
"menus": {
|
||||||
@ -266,12 +282,24 @@
|
|||||||
{
|
{
|
||||||
"command": "lldb-dap.modules.copyProperty",
|
"command": "lldb-dap.modules.copyProperty",
|
||||||
"when": "false"
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "lldb-dap.modules.showSymbols",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "lldb-dap.debug.showSymbols",
|
||||||
|
"when": "debuggersAvailable && debugType == 'lldb-dap' && lldb-dap.supportsModuleSymbolsRequest"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"view/item/context": [
|
"view/item/context": [
|
||||||
{
|
{
|
||||||
"command": "lldb-dap.modules.copyProperty",
|
"command": "lldb-dap.modules.copyProperty",
|
||||||
"when": "view == lldb-dap.modules && viewItem == property"
|
"when": "view == lldb-dap.modules && viewItem == property"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "lldb-dap.modules.showSymbols",
|
||||||
|
"when": "view == lldb-dap.modules && viewItem == module && lldb-dap.supportsModuleSymbolsRequest"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -69,6 +69,10 @@ const configurations: Record<string, DefaultConfig> = {
|
|||||||
terminateCommands: { type: "stringArray", default: [] },
|
terminateCommands: { type: "stringArray", default: [] },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function getDefaultConfigKey(key: string): string | number | boolean | string[] | undefined {
|
||||||
|
return configurations[key]?.default;
|
||||||
|
}
|
||||||
|
|
||||||
export class LLDBDapConfigurationProvider
|
export class LLDBDapConfigurationProvider
|
||||||
implements vscode.DebugConfigurationProvider
|
implements vscode.DebugConfigurationProvider
|
||||||
{
|
{
|
||||||
|
@ -1,11 +1,17 @@
|
|||||||
import { DebugProtocol } from "@vscode/debugprotocol";
|
import { DebugProtocol } from "@vscode/debugprotocol";
|
||||||
import * as vscode from "vscode";
|
import * as vscode from "vscode";
|
||||||
|
|
||||||
|
export interface LLDBDapCapabilities extends DebugProtocol.Capabilities {
|
||||||
|
/** The debug adapter supports the `moduleSymbols` request. */
|
||||||
|
supportsModuleSymbolsRequest?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
/** A helper type for mapping event types to their corresponding data type. */
|
/** A helper type for mapping event types to their corresponding data type. */
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
interface EventMap {
|
interface EventMap {
|
||||||
"module": DebugProtocol.ModuleEvent;
|
"module": DebugProtocol.ModuleEvent;
|
||||||
"exited": DebugProtocol.ExitedEvent;
|
"exited": DebugProtocol.ExitedEvent;
|
||||||
|
"capabilities": DebugProtocol.CapabilitiesEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A type assertion to check if a ProtocolMessage is an event or if it is a specific event. */
|
/** A type assertion to check if a ProtocolMessage is an event or if it is a specific event. */
|
||||||
@ -39,6 +45,9 @@ export class DebugSessionTracker
|
|||||||
private modulesChanged = new vscode.EventEmitter<
|
private modulesChanged = new vscode.EventEmitter<
|
||||||
vscode.DebugSession | undefined
|
vscode.DebugSession | undefined
|
||||||
>();
|
>();
|
||||||
|
private sessionReceivedCapabilities =
|
||||||
|
new vscode.EventEmitter<[ vscode.DebugSession, LLDBDapCapabilities ]>();
|
||||||
|
private sessionExited = new vscode.EventEmitter<vscode.DebugSession>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fired when modules are changed for any active debug session.
|
* Fired when modules are changed for any active debug session.
|
||||||
@ -48,6 +57,15 @@ export class DebugSessionTracker
|
|||||||
onDidChangeModules: vscode.Event<vscode.DebugSession | undefined> =
|
onDidChangeModules: vscode.Event<vscode.DebugSession | undefined> =
|
||||||
this.modulesChanged.event;
|
this.modulesChanged.event;
|
||||||
|
|
||||||
|
/** Fired when a debug session is initialized. */
|
||||||
|
onDidReceiveSessionCapabilities:
|
||||||
|
vscode.Event<[ vscode.DebugSession, LLDBDapCapabilities ]> =
|
||||||
|
this.sessionReceivedCapabilities.event;
|
||||||
|
|
||||||
|
/** Fired when a debug session is exiting. */
|
||||||
|
onDidExitSession: vscode.Event<vscode.DebugSession> =
|
||||||
|
this.sessionExited.event;
|
||||||
|
|
||||||
constructor(private logger: vscode.LogOutputChannel) {
|
constructor(private logger: vscode.LogOutputChannel) {
|
||||||
this.onDidChangeModules(this.moduleChangedListener, this);
|
this.onDidChangeModules(this.moduleChangedListener, this);
|
||||||
vscode.debug.onDidChangeActiveDebugSession((session) =>
|
vscode.debug.onDidChangeActiveDebugSession((session) =>
|
||||||
@ -146,6 +164,10 @@ export class DebugSessionTracker
|
|||||||
this.logger.info(
|
this.logger.info(
|
||||||
`Session "${session.name}" exited with code ${exitCode}`,
|
`Session "${session.name}" exited with code ${exitCode}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.sessionExited.fire(session);
|
||||||
|
} else if (isEvent(message, "capabilities")) {
|
||||||
|
this.sessionReceivedCapabilities.fire([ session, message.body.capabilities ]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import {
|
|||||||
ModuleProperty,
|
ModuleProperty,
|
||||||
} from "./ui/modules-data-provider";
|
} from "./ui/modules-data-provider";
|
||||||
import { LogFilePathProvider } from "./logging";
|
import { LogFilePathProvider } from "./logging";
|
||||||
|
import { SymbolsProvider } from "./ui/symbols-provider";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class represents the extension and manages its life cycle. Other extensions
|
* This class represents the extension and manages its life cycle. Other extensions
|
||||||
@ -19,6 +20,7 @@ import { LogFilePathProvider } from "./logging";
|
|||||||
*/
|
*/
|
||||||
export class LLDBDapExtension extends DisposableContext {
|
export class LLDBDapExtension extends DisposableContext {
|
||||||
constructor(
|
constructor(
|
||||||
|
context: vscode.ExtensionContext,
|
||||||
logger: vscode.LogOutputChannel,
|
logger: vscode.LogOutputChannel,
|
||||||
logFilePath: LogFilePathProvider,
|
logFilePath: LogFilePathProvider,
|
||||||
outputChannel: vscode.OutputChannel,
|
outputChannel: vscode.OutputChannel,
|
||||||
@ -52,10 +54,12 @@ export class LLDBDapExtension extends DisposableContext {
|
|||||||
vscode.window.registerUriHandler(new LaunchUriHandler()),
|
vscode.window.registerUriHandler(new LaunchUriHandler()),
|
||||||
);
|
);
|
||||||
|
|
||||||
vscode.commands.registerCommand(
|
this.pushSubscription(vscode.commands.registerCommand(
|
||||||
"lldb-dap.modules.copyProperty",
|
"lldb-dap.modules.copyProperty",
|
||||||
(node: ModuleProperty) => vscode.env.clipboard.writeText(node.value),
|
(node: ModuleProperty) => vscode.env.clipboard.writeText(node.value),
|
||||||
);
|
));
|
||||||
|
|
||||||
|
this.pushSubscription(new SymbolsProvider(sessionTracker, context));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +71,7 @@ export async function activate(context: vscode.ExtensionContext) {
|
|||||||
outputChannel.info("LLDB-DAP extension activating...");
|
outputChannel.info("LLDB-DAP extension activating...");
|
||||||
const logFilePath = new LogFilePathProvider(context, outputChannel);
|
const logFilePath = new LogFilePathProvider(context, outputChannel);
|
||||||
context.subscriptions.push(
|
context.subscriptions.push(
|
||||||
new LLDBDapExtension(outputChannel, logFilePath, outputChannel),
|
new LLDBDapExtension(context, outputChannel, logFilePath, outputChannel),
|
||||||
);
|
);
|
||||||
outputChannel.info("LLDB-DAP extension activated");
|
outputChannel.info("LLDB-DAP extension activated");
|
||||||
}
|
}
|
||||||
|
14
lldb/tools/lldb-dap/src-ts/index.d.ts
vendored
Normal file
14
lldb/tools/lldb-dap/src-ts/index.d.ts
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
export {};
|
||||||
|
|
||||||
|
/// The symbol type we get from the lldb-dap server
|
||||||
|
export declare interface SymbolType {
|
||||||
|
id: number;
|
||||||
|
isDebug: boolean;
|
||||||
|
isSynthetic: boolean;
|
||||||
|
isExternal: boolean;
|
||||||
|
type: string;
|
||||||
|
fileAddress: number;
|
||||||
|
loadAddress?: number;
|
||||||
|
size: number;
|
||||||
|
name: string;
|
||||||
|
}
|
@ -19,6 +19,7 @@ class ModuleItem extends vscode.TreeItem {
|
|||||||
constructor(module: DebugProtocol.Module) {
|
constructor(module: DebugProtocol.Module) {
|
||||||
super(module.name, vscode.TreeItemCollapsibleState.Collapsed);
|
super(module.name, vscode.TreeItemCollapsibleState.Collapsed);
|
||||||
this.description = module.symbolStatus;
|
this.description = module.symbolStatus;
|
||||||
|
this.contextValue = "module";
|
||||||
}
|
}
|
||||||
|
|
||||||
static getProperties(module: DebugProtocol.Module): ModuleProperty[] {
|
static getProperties(module: DebugProtocol.Module): ModuleProperty[] {
|
||||||
|
127
lldb/tools/lldb-dap/src-ts/ui/symbols-provider.ts
Normal file
127
lldb/tools/lldb-dap/src-ts/ui/symbols-provider.ts
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
import * as vscode from "vscode";
|
||||||
|
import { DebugProtocol } from "@vscode/debugprotocol";
|
||||||
|
|
||||||
|
import { DebugSessionTracker } from "../debug-session-tracker";
|
||||||
|
import { DisposableContext } from "../disposable-context";
|
||||||
|
|
||||||
|
import { SymbolType } from "..";
|
||||||
|
import { getSymbolsTableHTMLContent } from "./symbols-webview-html";
|
||||||
|
import { getDefaultConfigKey } from "../debug-configuration-provider";
|
||||||
|
|
||||||
|
export class SymbolsProvider extends DisposableContext {
|
||||||
|
constructor(
|
||||||
|
private readonly tracker: DebugSessionTracker,
|
||||||
|
private readonly extensionContext: vscode.ExtensionContext,
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.pushSubscription(vscode.commands.registerCommand(
|
||||||
|
"lldb-dap.debug.showSymbols",
|
||||||
|
() => {
|
||||||
|
const session = vscode.debug.activeDebugSession;
|
||||||
|
if (!session) return;
|
||||||
|
|
||||||
|
this.SelectModuleAndShowSymbols(session);
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
|
this.pushSubscription(vscode.commands.registerCommand(
|
||||||
|
"lldb-dap.modules.showSymbols",
|
||||||
|
(moduleItem: DebugProtocol.Module) => {
|
||||||
|
const session = vscode.debug.activeDebugSession;
|
||||||
|
if (!session) return;
|
||||||
|
|
||||||
|
this.showSymbolsForModule(session, moduleItem);
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
|
this.tracker.onDidReceiveSessionCapabilities(([ _session, capabilities ]) => {
|
||||||
|
if (capabilities.supportsModuleSymbolsRequest) {
|
||||||
|
vscode.commands.executeCommand(
|
||||||
|
"setContext", "lldb-dap.supportsModuleSymbolsRequest", true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.tracker.onDidExitSession((_session) => {
|
||||||
|
vscode.commands.executeCommand("setContext", "lldb-dap.supportsModuleSymbolsRequest", false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async SelectModuleAndShowSymbols(session: vscode.DebugSession) {
|
||||||
|
const modules = this.tracker.debugSessionModules(session);
|
||||||
|
if (!modules || modules.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let the user select a module to show symbols for
|
||||||
|
const selectedModule = await vscode.window.showQuickPick(modules.map(m => new ModuleQuickPickItem(m)), {
|
||||||
|
placeHolder: "Select a module to show symbols for"
|
||||||
|
});
|
||||||
|
if (!selectedModule) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.showSymbolsForModule(session, selectedModule.module);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async showSymbolsForModule(session: vscode.DebugSession, module: DebugProtocol.Module) {
|
||||||
|
try {
|
||||||
|
const symbols = await this.getSymbolsForModule(session, module.id.toString());
|
||||||
|
this.showSymbolsInNewTab(module.name.toString(), symbols);
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
vscode.window.showErrorMessage("Failed to retrieve symbols: " + error.message);
|
||||||
|
} else {
|
||||||
|
vscode.window.showErrorMessage("Failed to retrieve symbols due to an unknown error.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getSymbolsForModule(session: vscode.DebugSession, moduleId: string): Promise<SymbolType[]> {
|
||||||
|
const symbols_response: { symbols: Array<SymbolType> } = await session.customRequest("__lldb_moduleSymbols", { moduleId, moduleName: '' });
|
||||||
|
return symbols_response?.symbols || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
private async showSymbolsInNewTab(moduleName: string, symbols: SymbolType[]) {
|
||||||
|
const panel = vscode.window.createWebviewPanel(
|
||||||
|
"lldb-dap.symbols",
|
||||||
|
`Symbols for ${moduleName}`,
|
||||||
|
vscode.ViewColumn.Active,
|
||||||
|
{
|
||||||
|
enableScripts: true,
|
||||||
|
localResourceRoots: [
|
||||||
|
this.getExtensionResourcePath()
|
||||||
|
]
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
let tabulatorJsFilename = "tabulator_simple.min.css";
|
||||||
|
if (vscode.window.activeColorTheme.kind === vscode.ColorThemeKind.Dark || vscode.window.activeColorTheme.kind === vscode.ColorThemeKind.HighContrast) {
|
||||||
|
tabulatorJsFilename = "tabulator_midnight.min.css";
|
||||||
|
}
|
||||||
|
const tabulatorCssPath = panel.webview.asWebviewUri(vscode.Uri.joinPath(this.getExtensionResourcePath(), tabulatorJsFilename));
|
||||||
|
const tabulatorJsPath = panel.webview.asWebviewUri(vscode.Uri.joinPath(this.getExtensionResourcePath(), "tabulator.min.js"));
|
||||||
|
const symbolsTableScriptPath = panel.webview.asWebviewUri(vscode.Uri.joinPath(this.getExtensionResourcePath(), "symbols-table-view.js"));
|
||||||
|
|
||||||
|
panel.webview.html = getSymbolsTableHTMLContent(tabulatorJsPath, tabulatorCssPath, symbolsTableScriptPath);
|
||||||
|
panel.webview.postMessage({ command: "updateSymbols", symbols: symbols });
|
||||||
|
}
|
||||||
|
|
||||||
|
private getExtensionResourcePath(): vscode.Uri {
|
||||||
|
return vscode.Uri.joinPath(this.extensionContext.extensionUri, "out", "webview");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ModuleQuickPickItem implements vscode.QuickPickItem {
|
||||||
|
constructor(public readonly module: DebugProtocol.Module) {}
|
||||||
|
|
||||||
|
get label(): string {
|
||||||
|
return this.module.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
get description(): string {
|
||||||
|
return this.module.id.toString();
|
||||||
|
}
|
||||||
|
}
|
51
lldb/tools/lldb-dap/src-ts/ui/symbols-webview-html.ts
Normal file
51
lldb/tools/lldb-dap/src-ts/ui/symbols-webview-html.ts
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import * as vscode from "vscode";
|
||||||
|
|
||||||
|
export function getSymbolsTableHTMLContent(tabulatorJsPath: vscode.Uri, tabulatorCssPath: vscode.Uri, symbolsTableScriptPath: vscode.Uri): string {
|
||||||
|
return `<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<link href="${tabulatorCssPath}" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
.tabulator {
|
||||||
|
background-color: var(--vscode-editor-background);
|
||||||
|
color: var(--vscode-editor-foreground);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabulator .tabulator-header .tabulator-col {
|
||||||
|
background-color: var(--vscode-editor-background);
|
||||||
|
color: var(--vscode-editor-foreground);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabulator-row {
|
||||||
|
background-color: var(--vscode-editor-background);
|
||||||
|
color: var(--vscode-editor-foreground);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabulator-row.tabulator-row-even {
|
||||||
|
background-color: var(--vscode-editor-background);
|
||||||
|
color: var(--vscode-editor-foreground);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabulator-row.tabulator-selected {
|
||||||
|
background-color: var(--vscode-editor-background);
|
||||||
|
color: var(--vscode-editor-foreground);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabulator-cell {
|
||||||
|
text-overflow: clip !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#symbols-table {
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="symbols-table"></div>
|
||||||
|
<script src="${tabulatorJsPath}"></script>
|
||||||
|
<script src="${symbolsTableScriptPath}"></script>
|
||||||
|
</body>
|
||||||
|
</html>`;
|
||||||
|
}
|
114
lldb/tools/lldb-dap/src-ts/webview/symbols-table-view.ts
Normal file
114
lldb/tools/lldb-dap/src-ts/webview/symbols-table-view.ts
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
import type { CellComponent, ColumnDefinition } from "tabulator-tables";
|
||||||
|
import type { SymbolType } from ".."
|
||||||
|
|
||||||
|
/// SVG from https://github.com/olifolkerd/tabulator/blob/master/src/js/modules/Format/defaults/formatters/tickCross.js
|
||||||
|
/// but with the default font color.
|
||||||
|
/// hopefully in the future we can set the color as parameter: https://github.com/olifolkerd/tabulator/pull/4791
|
||||||
|
const TICK_ELEMENT = `<svg enable-background="new 0 0 24 24" height="14" width="14" viewBox="0 0 24 24" xml:space="preserve" ><path fill="var(--vscode-editor-foreground)" clip-rule="evenodd" d="M21.652,3.211c-0.293-0.295-0.77-0.295-1.061,0L9.41,14.34 c-0.293,0.297-0.771,0.297-1.062,0L3.449,9.351C3.304,9.203,3.114,9.13,2.923,9.129C2.73,9.128,2.534,9.201,2.387,9.351 l-2.165,1.946C0.078,11.445,0,11.63,0,11.823c0,0.194,0.078,0.397,0.223,0.544l4.94,5.184c0.292,0.296,0.771,0.776,1.062,1.07 l2.124,2.141c0.292,0.293,0.769,0.293,1.062,0l14.366-14.34c0.293-0.294,0.293-0.777,0-1.071L21.652,3.211z" fill-rule="evenodd"/></svg>`;
|
||||||
|
|
||||||
|
function getTabulatorHexaFormatter(padding: number): (cell: CellComponent) => string {
|
||||||
|
return (cell: CellComponent) => {
|
||||||
|
const val = cell.getValue();
|
||||||
|
if (val === undefined || val === null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return val !== undefined ? "0x" + val.toString(16).toLowerCase().padStart(padding, "0") : "";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const SYMBOL_TABLE_COLUMNS: ColumnDefinition[] = [
|
||||||
|
{ title: "ID", field: "id", headerTooltip: true, sorter: "number", widthGrow: 0.6 },
|
||||||
|
{
|
||||||
|
title: "Name",
|
||||||
|
field: "name",
|
||||||
|
headerTooltip: true,
|
||||||
|
sorter: "string",
|
||||||
|
widthGrow: 2.5,
|
||||||
|
minWidth: 200,
|
||||||
|
tooltip : (_event: MouseEvent, cell: CellComponent) => {
|
||||||
|
const rowData = cell.getRow().getData();
|
||||||
|
return rowData.name;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Debug",
|
||||||
|
field: "isDebug",
|
||||||
|
headerTooltip: true,
|
||||||
|
hozAlign: "center",
|
||||||
|
widthGrow: 0.8,
|
||||||
|
formatter: "tickCross",
|
||||||
|
formatterParams: {
|
||||||
|
tickElement: TICK_ELEMENT,
|
||||||
|
crossElement: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Synthetic",
|
||||||
|
field: "isSynthetic",
|
||||||
|
headerTooltip: true,
|
||||||
|
hozAlign: "center",
|
||||||
|
widthGrow: 0.8,
|
||||||
|
formatter: "tickCross",
|
||||||
|
formatterParams: {
|
||||||
|
tickElement: TICK_ELEMENT,
|
||||||
|
crossElement: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "External",
|
||||||
|
field: "isExternal",
|
||||||
|
headerTooltip: true,
|
||||||
|
hozAlign: "center",
|
||||||
|
widthGrow: 0.8,
|
||||||
|
formatter: "tickCross",
|
||||||
|
formatterParams: {
|
||||||
|
tickElement: TICK_ELEMENT,
|
||||||
|
crossElement: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ title: "Type", field: "type", sorter: "string" },
|
||||||
|
{
|
||||||
|
title: "File Address",
|
||||||
|
field: "fileAddress",
|
||||||
|
headerTooltip: true,
|
||||||
|
sorter: "number",
|
||||||
|
widthGrow : 1.25,
|
||||||
|
formatter: getTabulatorHexaFormatter(16),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Load Address",
|
||||||
|
field: "loadAddress",
|
||||||
|
headerTooltip: true,
|
||||||
|
sorter: "number",
|
||||||
|
widthGrow : 1.25,
|
||||||
|
formatter: getTabulatorHexaFormatter(16),
|
||||||
|
},
|
||||||
|
{ title: "Size", field: "size", headerTooltip: true, sorter: "number", formatter: getTabulatorHexaFormatter(8) },
|
||||||
|
];
|
||||||
|
|
||||||
|
const vscode = acquireVsCodeApi();
|
||||||
|
const previousState: any = vscode.getState();
|
||||||
|
|
||||||
|
declare const Tabulator: any; // HACK: real definition comes from tabulator.min.js
|
||||||
|
const SYMBOLS_TABLE = new Tabulator("#symbols-table", {
|
||||||
|
height: "100vh",
|
||||||
|
columns: SYMBOL_TABLE_COLUMNS,
|
||||||
|
layout: "fitColumns",
|
||||||
|
data: previousState?.symbols || [],
|
||||||
|
});
|
||||||
|
|
||||||
|
function updateSymbolsTable(symbols: SymbolType[]) {
|
||||||
|
SYMBOLS_TABLE.setData(symbols);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener("message", (event: MessageEvent<any>) => {
|
||||||
|
const message = event.data;
|
||||||
|
switch (message.command) {
|
||||||
|
case "updateSymbols":
|
||||||
|
vscode.setState({ symbols: message.symbols });
|
||||||
|
updateSymbolsTable(message.symbols);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
15
lldb/tools/lldb-dap/src-ts/webview/tsconfig.json
Normal file
15
lldb/tools/lldb-dap/src-ts/webview/tsconfig.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"module": "esnext",
|
||||||
|
"outDir": "out",
|
||||||
|
"rootDir": ".",
|
||||||
|
"sourceMap": true,
|
||||||
|
"strict": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"target": "es2017"
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"./"
|
||||||
|
],
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"moduleResolution": "node",
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"outDir": "out",
|
"outDir": "out",
|
||||||
"rootDir": "src-ts",
|
"rootDir": "src-ts",
|
||||||
@ -12,5 +13,6 @@
|
|||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"node_modules",
|
"node_modules",
|
||||||
|
"src-ts/webview",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,6 @@ add_lldb_unittest(LLDBCoreTests
|
|||||||
SourceManagerTest.cpp
|
SourceManagerTest.cpp
|
||||||
TelemetryTest.cpp
|
TelemetryTest.cpp
|
||||||
UniqueCStringMapTest.cpp
|
UniqueCStringMapTest.cpp
|
||||||
Value.cpp
|
|
||||||
|
|
||||||
LINK_COMPONENTS
|
LINK_COMPONENTS
|
||||||
Support
|
Support
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
|
||||||
//
|
|
||||||
// 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 "lldb/Core/Value.h"
|
|
||||||
#include "Plugins/Platform/MacOSX/PlatformMacOSX.h"
|
|
||||||
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
|
|
||||||
#include "TestingSupport/SubsystemRAII.h"
|
|
||||||
#include "TestingSupport/Symbol/ClangTestUtils.h"
|
|
||||||
|
|
||||||
#include "lldb/Utility/DataExtractor.h"
|
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
|
||||||
|
|
||||||
using namespace lldb_private;
|
|
||||||
using namespace lldb_private::clang_utils;
|
|
||||||
|
|
||||||
TEST(ValueTest, GetValueAsData) {
|
|
||||||
SubsystemRAII<FileSystem, HostInfo, PlatformMacOSX> subsystems;
|
|
||||||
auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>("test");
|
|
||||||
auto *clang = holder->GetAST();
|
|
||||||
|
|
||||||
Value v(Scalar(42));
|
|
||||||
DataExtractor extractor;
|
|
||||||
|
|
||||||
// no compiler type
|
|
||||||
Status status = v.GetValueAsData(nullptr, extractor, nullptr);
|
|
||||||
ASSERT_TRUE(status.Fail());
|
|
||||||
|
|
||||||
// with compiler type
|
|
||||||
v.SetCompilerType(clang->GetBasicType(lldb::BasicType::eBasicTypeChar));
|
|
||||||
|
|
||||||
status = v.GetValueAsData(nullptr, extractor, nullptr);
|
|
||||||
ASSERT_TRUE(status.Success());
|
|
||||||
}
|
|
@ -1,6 +1,7 @@
|
|||||||
add_lldb_unittest(DAPTests
|
add_lldb_unittest(DAPTests
|
||||||
DAPErrorTest.cpp
|
DAPErrorTest.cpp
|
||||||
DAPTest.cpp
|
DAPTest.cpp
|
||||||
|
DAPTypesTest.cpp
|
||||||
FifoFilesTest.cpp
|
FifoFilesTest.cpp
|
||||||
Handler/DisconnectTest.cpp
|
Handler/DisconnectTest.cpp
|
||||||
Handler/ContinueTest.cpp
|
Handler/ContinueTest.cpp
|
||||||
|
60
lldb/unittests/DAP/DAPTypesTest.cpp
Normal file
60
lldb/unittests/DAP/DAPTypesTest.cpp
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
//===-- DAPTypesTest.cpp ----------------------------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// 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 "Protocol/DAPTypes.h"
|
||||||
|
#include "TestingSupport/TestUtilities.h"
|
||||||
|
#include "lldb/lldb-enumerations.h"
|
||||||
|
#include "llvm/Testing/Support/Error.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
using namespace llvm;
|
||||||
|
using namespace lldb;
|
||||||
|
using namespace lldb_dap;
|
||||||
|
using namespace lldb_dap::protocol;
|
||||||
|
using lldb_private::roundtripJSON;
|
||||||
|
|
||||||
|
TEST(DAPTypesTest, SourceLLDBData) {
|
||||||
|
SourceLLDBData source_data;
|
||||||
|
source_data.persistenceData =
|
||||||
|
PersistenceData{"module_path123", "symbol_name456"};
|
||||||
|
|
||||||
|
llvm::Expected<SourceLLDBData> deserialized_data = roundtripJSON(source_data);
|
||||||
|
ASSERT_THAT_EXPECTED(deserialized_data, llvm::Succeeded());
|
||||||
|
|
||||||
|
EXPECT_EQ(source_data.persistenceData->module_path,
|
||||||
|
deserialized_data->persistenceData->module_path);
|
||||||
|
EXPECT_EQ(source_data.persistenceData->symbol_name,
|
||||||
|
deserialized_data->persistenceData->symbol_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(DAPTypesTest, DAPSymbol) {
|
||||||
|
Symbol symbol;
|
||||||
|
symbol.id = 42;
|
||||||
|
symbol.isDebug = true;
|
||||||
|
symbol.isExternal = false;
|
||||||
|
symbol.isSynthetic = true;
|
||||||
|
symbol.type = lldb::eSymbolTypeTrampoline;
|
||||||
|
symbol.fileAddress = 0x12345678;
|
||||||
|
symbol.loadAddress = 0x87654321;
|
||||||
|
symbol.size = 64;
|
||||||
|
symbol.name = "testSymbol";
|
||||||
|
|
||||||
|
llvm::Expected<Symbol> deserialized_symbol = roundtripJSON(symbol);
|
||||||
|
ASSERT_THAT_EXPECTED(deserialized_symbol, llvm::Succeeded());
|
||||||
|
|
||||||
|
EXPECT_EQ(symbol.id, deserialized_symbol->id);
|
||||||
|
EXPECT_EQ(symbol.isDebug, deserialized_symbol->isDebug);
|
||||||
|
EXPECT_EQ(symbol.isExternal, deserialized_symbol->isExternal);
|
||||||
|
EXPECT_EQ(symbol.isSynthetic, deserialized_symbol->isSynthetic);
|
||||||
|
EXPECT_EQ(symbol.type, deserialized_symbol->type);
|
||||||
|
EXPECT_EQ(symbol.fileAddress, deserialized_symbol->fileAddress);
|
||||||
|
EXPECT_EQ(symbol.loadAddress, deserialized_symbol->loadAddress);
|
||||||
|
EXPECT_EQ(symbol.size, deserialized_symbol->size);
|
||||||
|
EXPECT_EQ(symbol.name, deserialized_symbol->name);
|
||||||
|
}
|
@ -175,24 +175,6 @@ if(LLVM_ENABLE_EXPENSIVE_CHECKS)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
CHECK_CXX_SOURCE_COMPILES("
|
|
||||||
#include <iosfwd>
|
|
||||||
#if !defined(__GLIBCXX__)
|
|
||||||
#error Not libstdc++
|
|
||||||
#endif
|
|
||||||
int main() { return 0; }
|
|
||||||
" LLVM_USES_LIBSTDCXX)
|
|
||||||
|
|
||||||
option(GLIBCXX_USE_CXX11_ABI "Use new libstdc++ CXX11 ABI" ON)
|
|
||||||
|
|
||||||
if (LLVM_USES_LIBSTDCXX)
|
|
||||||
if (GLIBCXX_USE_CXX11_ABI)
|
|
||||||
add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=1)
|
|
||||||
else()
|
|
||||||
add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (LLVM_ENABLE_STRICT_FIXED_SIZE_VECTORS)
|
if (LLVM_ENABLE_STRICT_FIXED_SIZE_VECTORS)
|
||||||
add_compile_definitions(STRICT_FIXED_SIZE_VECTORS)
|
add_compile_definitions(STRICT_FIXED_SIZE_VECTORS)
|
||||||
endif()
|
endif()
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
#include "llvm/MC/MCLinkerOptimizationHint.h"
|
#include "llvm/MC/MCLinkerOptimizationHint.h"
|
||||||
#include "llvm/MC/MCObjectWriter.h"
|
#include "llvm/MC/MCObjectWriter.h"
|
||||||
#include "llvm/MC/MCSectionMachO.h"
|
#include "llvm/MC/MCSectionMachO.h"
|
||||||
#include "llvm/MC/MCSymbolMachO.h"
|
|
||||||
#include "llvm/MC/StringTableBuilder.h"
|
#include "llvm/MC/StringTableBuilder.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
#include "llvm/Support/EndianStream.h"
|
#include "llvm/Support/EndianStream.h"
|
||||||
@ -111,7 +110,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
/// Helper struct for containing some precomputed information on symbols.
|
/// Helper struct for containing some precomputed information on symbols.
|
||||||
struct MachSymbolData {
|
struct MachSymbolData {
|
||||||
const MCSymbolMachO *Symbol;
|
const MCSymbol *Symbol;
|
||||||
uint64_t StringIndex;
|
uint64_t StringIndex;
|
||||||
uint8_t SectionIndex;
|
uint8_t SectionIndex;
|
||||||
|
|
||||||
@ -120,7 +119,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct IndirectSymbolData {
|
struct IndirectSymbolData {
|
||||||
MCSymbolMachO *Symbol;
|
MCSymbol *Symbol;
|
||||||
MCSection *Section;
|
MCSection *Section;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17029,7 +17029,8 @@ SDValue DAGCombiner::visitFADDForFMACombine(SDNode *N) {
|
|||||||
// fadd (G, (fma A, B, (fma (C, D, (fmul (E, F)))))) -->
|
// fadd (G, (fma A, B, (fma (C, D, (fmul (E, F)))))) -->
|
||||||
// fma A, B, (fma C, D, fma (E, F, G)).
|
// fma A, B, (fma C, D, fma (E, F, G)).
|
||||||
// This requires reassociation because it changes the order of operations.
|
// This requires reassociation because it changes the order of operations.
|
||||||
bool CanReassociate = N->getFlags().hasAllowReassociation();
|
bool CanReassociate =
|
||||||
|
Options.UnsafeFPMath || N->getFlags().hasAllowReassociation();
|
||||||
if (CanReassociate) {
|
if (CanReassociate) {
|
||||||
SDValue FMA, E;
|
SDValue FMA, E;
|
||||||
if (isFusedOp(N0) && N0.hasOneUse()) {
|
if (isFusedOp(N0) && N0.hasOneUse()) {
|
||||||
@ -17695,7 +17696,7 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
|
|||||||
// If 'unsafe math' or reassoc and nsz, fold lots of things.
|
// If 'unsafe math' or reassoc and nsz, fold lots of things.
|
||||||
// TODO: break out portions of the transformations below for which Unsafe is
|
// TODO: break out portions of the transformations below for which Unsafe is
|
||||||
// considered and which do not require both nsz and reassoc
|
// considered and which do not require both nsz and reassoc
|
||||||
if ((Options.NoSignedZerosFPMath ||
|
if (((Options.UnsafeFPMath && Options.NoSignedZerosFPMath) ||
|
||||||
(Flags.hasAllowReassociation() && Flags.hasNoSignedZeros())) &&
|
(Flags.hasAllowReassociation() && Flags.hasNoSignedZeros())) &&
|
||||||
AllowNewConst) {
|
AllowNewConst) {
|
||||||
// fadd (fadd x, c1), c2 -> fadd x, c1 + c2
|
// fadd (fadd x, c1), c2 -> fadd x, c1 + c2
|
||||||
@ -17782,7 +17783,7 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
|
|||||||
}
|
}
|
||||||
} // enable-unsafe-fp-math && AllowNewConst
|
} // enable-unsafe-fp-math && AllowNewConst
|
||||||
|
|
||||||
if ((Options.NoSignedZerosFPMath ||
|
if (((Options.UnsafeFPMath && Options.NoSignedZerosFPMath) ||
|
||||||
(Flags.hasAllowReassociation() && Flags.hasNoSignedZeros()))) {
|
(Flags.hasAllowReassociation() && Flags.hasNoSignedZeros()))) {
|
||||||
// Fold fadd(vecreduce(x), vecreduce(y)) -> vecreduce(fadd(x, y))
|
// Fold fadd(vecreduce(x), vecreduce(y)) -> vecreduce(fadd(x, y))
|
||||||
if (SDValue SD = reassociateReduction(ISD::VECREDUCE_FADD, ISD::FADD, DL,
|
if (SDValue SD = reassociateReduction(ISD::VECREDUCE_FADD, ISD::FADD, DL,
|
||||||
@ -17885,7 +17886,7 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((Options.NoSignedZerosFPMath ||
|
if (((Options.UnsafeFPMath && Options.NoSignedZerosFPMath) ||
|
||||||
(Flags.hasAllowReassociation() && Flags.hasNoSignedZeros())) &&
|
(Flags.hasAllowReassociation() && Flags.hasNoSignedZeros())) &&
|
||||||
N1.getOpcode() == ISD::FADD) {
|
N1.getOpcode() == ISD::FADD) {
|
||||||
// X - (X + Y) -> -Y
|
// X - (X + Y) -> -Y
|
||||||
@ -18025,6 +18026,7 @@ SDValue DAGCombiner::visitFMUL(SDNode *N) {
|
|||||||
ConstantFPSDNode *N1CFP = isConstOrConstSplatFP(N1, true);
|
ConstantFPSDNode *N1CFP = isConstOrConstSplatFP(N1, true);
|
||||||
EVT VT = N->getValueType(0);
|
EVT VT = N->getValueType(0);
|
||||||
SDLoc DL(N);
|
SDLoc DL(N);
|
||||||
|
const TargetOptions &Options = DAG.getTarget().Options;
|
||||||
const SDNodeFlags Flags = N->getFlags();
|
const SDNodeFlags Flags = N->getFlags();
|
||||||
SelectionDAG::FlagInserter FlagsInserter(DAG, N);
|
SelectionDAG::FlagInserter FlagsInserter(DAG, N);
|
||||||
|
|
||||||
@ -18048,7 +18050,7 @@ SDValue DAGCombiner::visitFMUL(SDNode *N) {
|
|||||||
if (SDValue NewSel = foldBinOpIntoSelect(N))
|
if (SDValue NewSel = foldBinOpIntoSelect(N))
|
||||||
return NewSel;
|
return NewSel;
|
||||||
|
|
||||||
if (Flags.hasAllowReassociation()) {
|
if (Options.UnsafeFPMath || Flags.hasAllowReassociation()) {
|
||||||
// fmul (fmul X, C1), C2 -> fmul X, C1 * C2
|
// fmul (fmul X, C1), C2 -> fmul X, C1 * C2
|
||||||
if (DAG.isConstantFPBuildVectorOrConstantFP(N1) &&
|
if (DAG.isConstantFPBuildVectorOrConstantFP(N1) &&
|
||||||
N0.getOpcode() == ISD::FMUL) {
|
N0.getOpcode() == ISD::FMUL) {
|
||||||
@ -18225,7 +18227,8 @@ template <class MatchContextClass> SDValue DAGCombiner::visitFMA(SDNode *N) {
|
|||||||
!DAG.isConstantFPBuildVectorOrConstantFP(N1))
|
!DAG.isConstantFPBuildVectorOrConstantFP(N1))
|
||||||
return matcher.getNode(ISD::FMA, DL, VT, N1, N0, N2);
|
return matcher.getNode(ISD::FMA, DL, VT, N1, N0, N2);
|
||||||
|
|
||||||
bool CanReassociate = N->getFlags().hasAllowReassociation();
|
bool CanReassociate =
|
||||||
|
Options.UnsafeFPMath || N->getFlags().hasAllowReassociation();
|
||||||
if (CanReassociate) {
|
if (CanReassociate) {
|
||||||
// (fma x, c1, (fmul x, c2)) -> (fmul x, c1+c2)
|
// (fma x, c1, (fmul x, c2)) -> (fmul x, c1+c2)
|
||||||
if (matcher.match(N2, ISD::FMUL) && N0 == N2.getOperand(0) &&
|
if (matcher.match(N2, ISD::FMUL) && N0 == N2.getOperand(0) &&
|
||||||
@ -18320,8 +18323,9 @@ SDValue DAGCombiner::combineRepeatedFPDivisors(SDNode *N) {
|
|||||||
// TODO: Limit this transform based on optsize/minsize - it always creates at
|
// TODO: Limit this transform based on optsize/minsize - it always creates at
|
||||||
// least 1 extra instruction. But the perf win may be substantial enough
|
// least 1 extra instruction. But the perf win may be substantial enough
|
||||||
// that only minsize should restrict this.
|
// that only minsize should restrict this.
|
||||||
|
bool UnsafeMath = DAG.getTarget().Options.UnsafeFPMath;
|
||||||
const SDNodeFlags Flags = N->getFlags();
|
const SDNodeFlags Flags = N->getFlags();
|
||||||
if (LegalDAG || !Flags.hasAllowReciprocal())
|
if (LegalDAG || (!UnsafeMath && !Flags.hasAllowReciprocal()))
|
||||||
return SDValue();
|
return SDValue();
|
||||||
|
|
||||||
// Skip if current node is a reciprocal/fneg-reciprocal.
|
// Skip if current node is a reciprocal/fneg-reciprocal.
|
||||||
@ -18358,7 +18362,7 @@ SDValue DAGCombiner::combineRepeatedFPDivisors(SDNode *N) {
|
|||||||
|
|
||||||
// This division is eligible for optimization only if global unsafe math
|
// This division is eligible for optimization only if global unsafe math
|
||||||
// is enabled or if this division allows reciprocal formation.
|
// is enabled or if this division allows reciprocal formation.
|
||||||
if (U->getFlags().hasAllowReciprocal())
|
if (UnsafeMath || U->getFlags().hasAllowReciprocal())
|
||||||
Users.insert(U);
|
Users.insert(U);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -18983,9 +18987,7 @@ SDValue DAGCombiner::visitFP_ROUND(SDNode *N) {
|
|||||||
// single-step fp_round we want to fold to.
|
// single-step fp_round we want to fold to.
|
||||||
// In other words, double rounding isn't the same as rounding.
|
// In other words, double rounding isn't the same as rounding.
|
||||||
// Also, this is a value preserving truncation iff both fp_round's are.
|
// Also, this is a value preserving truncation iff both fp_round's are.
|
||||||
if ((N->getFlags().hasAllowContract() &&
|
if (DAG.getTarget().Options.UnsafeFPMath || N0IsTrunc)
|
||||||
N0->getFlags().hasAllowContract()) ||
|
|
||||||
N0IsTrunc)
|
|
||||||
return DAG.getNode(
|
return DAG.getNode(
|
||||||
ISD::FP_ROUND, DL, VT, N0.getOperand(0),
|
ISD::FP_ROUND, DL, VT, N0.getOperand(0),
|
||||||
DAG.getIntPtrConstant(NIsTrunc && N0IsTrunc, DL, /*isTarget=*/true));
|
DAG.getIntPtrConstant(NIsTrunc && N0IsTrunc, DL, /*isTarget=*/true));
|
||||||
|
@ -2340,9 +2340,6 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst,
|
|||||||
|
|
||||||
getAssembler().getEmitter().encodeInstruction(Inst, Code, Fixups, STI);
|
getAssembler().getEmitter().encodeInstruction(Inst, Code, Fixups, STI);
|
||||||
|
|
||||||
// RISC-V instructions are always little-endian, even on BE systems.
|
|
||||||
bool ForceLE = getContext().getTargetTriple().isRISCV();
|
|
||||||
|
|
||||||
// If we are showing fixups, create symbolic markers in the encoded
|
// If we are showing fixups, create symbolic markers in the encoded
|
||||||
// representation. We do this by making a per-bit map to the fixup item index,
|
// representation. We do this by making a per-bit map to the fixup item index,
|
||||||
// then trying to display it as nicely as possible.
|
// then trying to display it as nicely as possible.
|
||||||
@ -2397,10 +2394,7 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst,
|
|||||||
unsigned Bit = (Code[i] >> j) & 1;
|
unsigned Bit = (Code[i] >> j) & 1;
|
||||||
|
|
||||||
unsigned FixupBit;
|
unsigned FixupBit;
|
||||||
// RISC-V instructions are always little-endian.
|
if (MAI->isLittleEndian())
|
||||||
// The FixupMap is indexed by actual bit positions in the LE
|
|
||||||
// instruction.
|
|
||||||
if (MAI->isLittleEndian() || ForceLE)
|
|
||||||
FixupBit = i * 8 + j;
|
FixupBit = i * 8 + j;
|
||||||
else
|
else
|
||||||
FixupBit = i * 8 + (7-j);
|
FixupBit = i * 8 + (7-j);
|
||||||
|
@ -149,7 +149,7 @@ void MCMachOStreamer::emitEHSymAttributes(const MCSymbol *Symbol,
|
|||||||
MCSymbol *EHSymbol) {
|
MCSymbol *EHSymbol) {
|
||||||
auto *Sym = static_cast<const MCSymbolMachO *>(Symbol);
|
auto *Sym = static_cast<const MCSymbolMachO *>(Symbol);
|
||||||
getAssembler().registerSymbol(*Symbol);
|
getAssembler().registerSymbol(*Symbol);
|
||||||
if (Sym->isExternal())
|
if (Symbol->isExternal())
|
||||||
emitSymbolAttribute(EHSymbol, MCSA_Global);
|
emitSymbolAttribute(EHSymbol, MCSA_Global);
|
||||||
if (Sym->isWeakDefinition())
|
if (Sym->isWeakDefinition())
|
||||||
emitSymbolAttribute(EHSymbol, MCSA_WeakDefinition);
|
emitSymbolAttribute(EHSymbol, MCSA_WeakDefinition);
|
||||||
@ -372,13 +372,12 @@ void MCMachOStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
|
|||||||
|
|
||||||
void MCMachOStreamer::emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
|
void MCMachOStreamer::emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
|
||||||
Align ByteAlignment) {
|
Align ByteAlignment) {
|
||||||
auto &Sym = static_cast<MCSymbolMachO &>(*Symbol);
|
|
||||||
// FIXME: Darwin 'as' does appear to allow redef of a .comm by itself.
|
// FIXME: Darwin 'as' does appear to allow redef of a .comm by itself.
|
||||||
assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
|
assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
|
||||||
|
|
||||||
getAssembler().registerSymbol(Sym);
|
getAssembler().registerSymbol(*Symbol);
|
||||||
Sym.setExternal(true);
|
Symbol->setExternal(true);
|
||||||
Sym.setCommon(Size, ByteAlignment);
|
Symbol->setCommon(Size, ByteAlignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCMachOStreamer::emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
|
void MCMachOStreamer::emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
|
||||||
@ -461,8 +460,7 @@ void MCMachOStreamer::finishImpl() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MCMachOStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE) {
|
void MCMachOStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE) {
|
||||||
auto *S =
|
const MCSymbol *S = &SRE->getSymbol();
|
||||||
static_cast<MCSymbolMachO *>(const_cast<MCSymbol *>(&SRE->getSymbol()));
|
|
||||||
if (getAssembler().registerSymbol(*S))
|
if (getAssembler().registerSymbol(*S))
|
||||||
S->setExternal(true);
|
S->setExternal(true);
|
||||||
}
|
}
|
||||||
|
@ -1864,13 +1864,11 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
|
|||||||
Lex();
|
Lex();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MAI.isMachO() && CFIStartProcLoc) {
|
if (MAI.hasSubsectionsViaSymbols() && CFIStartProcLoc &&
|
||||||
auto *SymM = static_cast<MCSymbolMachO *>(Sym);
|
Sym->isExternal() && !static_cast<MCSymbolMachO *>(Sym)->isAltEntry())
|
||||||
if (SymM->isExternal() && !SymM->isAltEntry())
|
return Error(StartTokLoc, "non-private labels cannot appear between "
|
||||||
return Error(StartTokLoc, "non-private labels cannot appear between "
|
".cfi_startproc / .cfi_endproc pairs") &&
|
||||||
".cfi_startproc / .cfi_endproc pairs") &&
|
Error(*CFIStartProcLoc, "previous .cfi_startproc was here");
|
||||||
Error(*CFIStartProcLoc, "previous .cfi_startproc was here");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (discardLTOSymbol(IDVal))
|
if (discardLTOSymbol(IDVal))
|
||||||
return false;
|
return false;
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
#include "llvm/MC/MCSection.h"
|
#include "llvm/MC/MCSection.h"
|
||||||
#include "llvm/MC/MCStreamer.h"
|
#include "llvm/MC/MCStreamer.h"
|
||||||
#include "llvm/MC/MCSubtargetInfo.h"
|
#include "llvm/MC/MCSubtargetInfo.h"
|
||||||
#include "llvm/MC/MCSymbolCOFF.h"
|
#include "llvm/MC/MCSymbol.h"
|
||||||
#include "llvm/MC/MCTargetOptions.h"
|
#include "llvm/MC/MCTargetOptions.h"
|
||||||
#include "llvm/Support/Casting.h"
|
#include "llvm/Support/Casting.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
@ -3009,8 +3009,8 @@ bool MasmParser::parseDirectiveEquate(StringRef IDVal, StringRef Name,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *Sym =
|
MCSymbol *Sym = getContext().getOrCreateSymbol(Var.Name);
|
||||||
static_cast<MCSymbolCOFF *>(getContext().getOrCreateSymbol(Var.Name));
|
|
||||||
const MCConstantExpr *PrevValue =
|
const MCConstantExpr *PrevValue =
|
||||||
Sym->isVariable()
|
Sym->isVariable()
|
||||||
? dyn_cast_or_null<MCConstantExpr>(Sym->getVariableValue())
|
? dyn_cast_or_null<MCConstantExpr>(Sym->getVariableValue())
|
||||||
@ -4521,8 +4521,7 @@ bool MasmParser::parseDirectiveExtern() {
|
|||||||
KnownType[Name.lower()] = Type;
|
KnownType[Name.lower()] = Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *Sym =
|
MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
|
||||||
static_cast<MCSymbolCOFF *>(getContext().getOrCreateSymbol(Name));
|
|
||||||
Sym->setExternal(true);
|
Sym->setExternal(true);
|
||||||
getStreamer().emitSymbolAttribute(Sym, MCSA_Extern);
|
getStreamer().emitSymbolAttribute(Sym, MCSA_Extern);
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user