Skip to content

Commit

Permalink
Merge branch 'llvm:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
5c4lar authored Jun 25, 2024
2 parents 2b539c2 + 4c87212 commit c625fb0
Show file tree
Hide file tree
Showing 87 changed files with 1,898 additions and 476 deletions.
4 changes: 2 additions & 2 deletions clang-tools-extra/clang-doc/tool/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ set(assets
)

set(asset_dir "${CMAKE_CURRENT_SOURCE_DIR}/../assets")
set(resource_dir "${CMAKE_BINARY_DIR}/share/clang")
set(resource_dir "${CMAKE_BINARY_DIR}/share/clang-doc")
set(out_files)

function(copy_files_to_dst src_dir dst_dir file)
Expand All @@ -42,7 +42,7 @@ endfunction(copy_files_to_dst)

foreach(f ${assets})
install(FILES ${asset_dir}/${f}
DESTINATION "${CMAKE_INSTALL_DATADIR}/clang"
DESTINATION "${CMAKE_INSTALL_DATADIR}/clang-doc"
COMPONENT clang-doc)
copy_files_to_dst(${asset_dir} ${resource_dir} ${f})
endforeach(f)
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ Example usage for a project using a compile commands database:
llvm::sys::path::native(ClangDocPath, NativeClangDocPath);
llvm::SmallString<128> AssetsPath;
AssetsPath = llvm::sys::path::parent_path(NativeClangDocPath);
llvm::sys::path::append(AssetsPath, "..", "share", "clang");
llvm::sys::path::append(AssetsPath, "..", "share", "clang-doc");
llvm::SmallString<128> DefaultStylesheet;
llvm::sys::path::native(AssetsPath, DefaultStylesheet);
llvm::sys::path::append(DefaultStylesheet,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#include "Calculator.h"
#include <stdexcept>

int Calculator::add(int a, int b) {
return a + b;
Expand All @@ -14,8 +13,5 @@ int Calculator::multiply(int a, int b) {
}

double Calculator::divide(int a, int b) {
if (b == 0) {
throw std::invalid_argument("Division by zero");
}
return static_cast<double>(a) / b;
}
8 changes: 4 additions & 4 deletions clang-tools-extra/test/clang-doc/basic-project.test
Original file line number Diff line number Diff line change
Expand Up @@ -139,25 +139,25 @@
// HTML-CALC-NEXT: <div>
// HTML-CALC-NEXT: <h3 id="{{([0-9A-F]{40})}}">add</h3>
// HTML-CALC-NEXT: <p>public int add(int a, int b)</p>
// HTML-CALC-NEXT: <p>Defined at line 4 of file {{.*}}Calculator.cpp</p>
// HTML-CALC-NEXT: <p>Defined at line 3 of file {{.*}}Calculator.cpp</p>
// HTML-CALC-NEXT: <div>
// HTML-CALC-NEXT: <div></div>
// HTML-CALC-NEXT: </div>
// HTML-CALC-NEXT: <h3 id="{{([0-9A-F]{40})}}">subtract</h3>
// HTML-CALC-NEXT: <p>public int subtract(int a, int b)</p>
// HTML-CALC-NEXT: <p>Defined at line 8 of file {{.*}}Calculator.cpp</p>
// HTML-CALC-NEXT: <p>Defined at line 7 of file {{.*}}Calculator.cpp</p>
// HTML-CALC-NEXT: <div>
// HTML-CALC-NEXT: <div></div>
// HTML-CALC-NEXT: </div>
// HTML-CALC-NEXT: <h3 id="{{([0-9A-F]{40})}}">multiply</h3>
// HTML-CALC-NEXT: <p>public int multiply(int a, int b)</p>
// HTML-CALC-NEXT: <p>Defined at line 12 of file {{.*}}Calculator.cpp</p>
// HTML-CALC-NEXT: <p>Defined at line 11 of file {{.*}}Calculator.cpp</p>
// HTML-CALC-NEXT: <div>
// HTML-CALC-NEXT: <div></div>
// HTML-CALC-NEXT: </div>
// HTML-CALC-NEXT: <h3 id="{{([0-9A-F]{40})}}">divide</h3>
// HTML-CALC-NEXT: <p>public double divide(int a, int b)</p>
// HTML-CALC-NEXT: <p>Defined at line 16 of file {{.*}}Calculator.cpp</p>
// HTML-CALC-NEXT: <p>Defined at line 15 of file {{.*}}Calculator.cpp</p>
// HTML-CALC-NEXT: <div>
// HTML-CALC-NEXT: <div></div>
// HTML-CALC-NEXT: </div>
Expand Down
54 changes: 54 additions & 0 deletions clang/docs/LanguageExtensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3483,6 +3483,60 @@ Query for this feature with ``__has_builtin(__builtin_trap)``.
``__builtin_arm_trap`` is lowered to the ``llvm.aarch64.break`` builtin, and then to ``brk #payload``.
``__builtin_verbose_trap``
--------------------------
``__builtin_verbose_trap`` causes the program to stop its execution abnormally
and shows a human-readable description of the reason for the termination when a
debugger is attached or in a symbolicated crash log.
**Syntax**:
.. code-block:: c++
__builtin_verbose_trap(const char *category, const char *reason)
**Description**
``__builtin_verbose_trap`` is lowered to the ` ``llvm.trap`` <https://llvm.org/docs/LangRef.html#llvm-trap-intrinsic>`_ builtin.
Additionally, clang emits debugging information that represents an artificial
inline frame whose name encodes the category and reason strings passed to the builtin,
prefixed by a "magic" prefix.
For example, consider the following code:
.. code-block:: c++
void foo(int* p) {
if (p == nullptr)
__builtin_verbose_trap("check null", "Argument must not be null!");
}
The debugging information would look as if it were produced for the following code:
.. code-block:: c++
__attribute__((always_inline))
inline void "__clang_trap_msg$check null$Argument must not be null!"() {
__builtin_trap();
}
void foo(int* p) {
if (p == nullptr)
"__clang_trap_msg$check null$Argument must not be null!"();
}
However, the generated code would not actually contain a call to the artificial
function — it only exists in the debugging information.
Query for this feature with ``__has_builtin(__builtin_verbose_trap)``. Note that
users need to enable debug information to enable this feature. A call to this
builtin is equivalent to a call to ``__builtin_trap`` if debug information isn't
enabled.
The optimizer can merge calls to trap with different messages, which degrades
the debugging experience.
``__builtin_allow_runtime_check``
---------------------------------
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/AST/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,11 @@ class Expr : public ValueStmt {
const Expr *PtrExpression, ASTContext &Ctx,
EvalResult &Status) const;

/// If the current Expr can be evaluated to a pointer to a null-terminated
/// constant string, return the constant string (without the terminating
/// null).
std::optional<std::string> tryEvaluateString(ASTContext &Ctx) const;

/// Enumeration used to describe the kind of Null pointer constant
/// returned from \c isNullPointerConstant().
enum NullPointerConstantKind {
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Basic/Builtins.td
Original file line number Diff line number Diff line change
Expand Up @@ -1152,6 +1152,12 @@ def Trap : Builtin {
let Prototype = "void()";
}

def VerboseTrap : Builtin {
let Spellings = ["__builtin_verbose_trap"];
let Attributes = [NoThrow, NoReturn];
let Prototype = "void(char const*, char const*)";
}

def Debugtrap : Builtin {
let Spellings = ["__builtin_debugtrap"];
let Attributes = [NoThrow];
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -3246,6 +3246,9 @@ def warn_unsupported_target_attribute
def err_attribute_unsupported
: Error<"%0 attribute is not supported on targets missing %1;"
" specify an appropriate -march= or -mcpu=">;
def err_attribute_unsupported_m_profile
: Error<"on M-profile architectures %0 attribute is not supported on targets missing %1;"
" specify an appropriate -march= or -mcpu=">;
def err_duplicate_target_attribute
: Error<"%select{unsupported|duplicate|unknown}0%select{| CPU|"
" tune CPU}1 '%2' in the '%select{target|target_clones|target_version}3' "
Expand Down Expand Up @@ -8953,6 +8956,8 @@ def err_expected_callable_argument : Error<
"expected a callable expression as %ordinal0 argument to %1, found %2">;
def note_building_builtin_dump_struct_call : Note<
"in call to printing function with arguments '(%0)' while dumping struct">;
def err_builtin_verbose_trap_arg : Error<
"argument to __builtin_verbose_trap must %select{be a pointer to a constant string|not contain $}0">;

def err_atomic_load_store_uses_lib : Error<
"atomic %select{load|store}0 requires runtime support that is not "
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/CodeGen/ModuleBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "clang/AST/ASTConsumer.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"

namespace llvm {
class Constant;
Expand All @@ -27,6 +28,9 @@ namespace llvm {
}
}

// Prefix of the name of the artificial inline frame.
inline constexpr llvm::StringRef ClangTrapPrefix = "__clang_trap_msg";

namespace clang {
class CodeGenOptions;
class CoverageSourceInfo;
Expand Down
21 changes: 18 additions & 3 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1885,7 +1885,8 @@ static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result,
EvalInfo &Info);
static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result);
static bool EvaluateBuiltinStrLen(const Expr *E, uint64_t &Result,
EvalInfo &Info);
EvalInfo &Info,
std::string *StringResult = nullptr);

/// Evaluate an integer or fixed point expression into an APResult.
static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result,
Expand Down Expand Up @@ -17009,7 +17010,7 @@ bool Expr::tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx,
}

static bool EvaluateBuiltinStrLen(const Expr *E, uint64_t &Result,
EvalInfo &Info) {
EvalInfo &Info, std::string *StringResult) {
if (!E->getType()->hasPointerRepresentation() || !E->isPRValue())
return false;

Expand All @@ -17036,6 +17037,8 @@ static bool EvaluateBuiltinStrLen(const Expr *E, uint64_t &Result,
Str = Str.substr(0, Pos);

Result = Str.size();
if (StringResult)
*StringResult = Str;
return true;
}

Expand All @@ -17051,12 +17054,24 @@ static bool EvaluateBuiltinStrLen(const Expr *E, uint64_t &Result,
if (!Char.getInt()) {
Result = Strlen;
return true;
}
} else if (StringResult)
StringResult->push_back(Char.getInt().getExtValue());
if (!HandleLValueArrayAdjustment(Info, E, String, CharTy, 1))
return false;
}
}

std::optional<std::string> Expr::tryEvaluateString(ASTContext &Ctx) const {
Expr::EvalStatus Status;
EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
uint64_t Result;
std::string StringResult;

if (EvaluateBuiltinStrLen(this, Result, Info, &StringResult))
return StringResult;
return {};
}

bool Expr::EvaluateCharRangeAsString(std::string &Result,
const Expr *SizeExpression,
const Expr *PtrExpression, ASTContext &Ctx,
Expand Down
22 changes: 4 additions & 18 deletions clang/lib/AST/Interp/ByteCodeExprGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1234,7 +1234,7 @@ bool ByteCodeExprGen<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
const Record *R = getRecord(E->getType());

if (Inits.size() == 1 && E->getType() == Inits[0]->getType())
return this->visitInitializer(Inits[0]);
return this->delegate(Inits[0]);

auto initPrimitiveField = [=](const Record::Field *FieldToInit,
const Expr *Init, PrimType T) -> bool {
Expand Down Expand Up @@ -1329,22 +1329,8 @@ bool ByteCodeExprGen<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
}

if (T->isArrayType()) {
// Prepare composite return value.
if (!Initializing) {
if (GlobalDecl) {
std::optional<unsigned> GlobalIndex = P.createGlobal(E);
if (!GlobalIndex)
return false;
if (!this->emitGetPtrGlobal(*GlobalIndex, E))
return false;
} else {
std::optional<unsigned> LocalIndex = allocateLocal(E);
if (!LocalIndex)
return false;
if (!this->emitGetPtrLocal(*LocalIndex, E))
return false;
}
}
if (Inits.size() == 1 && E->getType() == Inits[0]->getType())
return this->delegate(Inits[0]);

unsigned ElementIndex = 0;
for (const Expr *Init : Inits) {
Expand Down Expand Up @@ -2150,7 +2136,7 @@ bool ByteCodeExprGen<Emitter>::VisitMaterializeTemporaryExpr(

if (Initializing) {
// We already have a value, just initialize that.
return this->visitInitializer(SubExpr);
return this->delegate(SubExpr);
}
// If we don't end up using the materialized temporary anyway, don't
// bother creating it.
Expand Down
9 changes: 8 additions & 1 deletion clang/lib/AST/Interp/Descriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,14 @@ static void dtorArrayTy(Block *, std::byte *Ptr, const Descriptor *D) {
template <typename T>
static void moveArrayTy(Block *, const std::byte *Src, std::byte *Dst,
const Descriptor *D) {
// FIXME: Need to copy the InitMap?
// FIXME: Get rid of the const_cast.
InitMapPtr &SrcIMP =
*reinterpret_cast<InitMapPtr *>(const_cast<std::byte *>(Src));
if (SrcIMP) {
// We only ever invoke the moveFunc when moving block contents to a
// DeadBlock. DeadBlocks don't need InitMaps, so we destroy them here.
SrcIMP = std::nullopt;
}
Src += sizeof(InitMapPtr);
Dst += sizeof(InitMapPtr);
for (unsigned I = 0, NE = D->getNumElems(); I < NE; ++I) {
Expand Down
12 changes: 12 additions & 0 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3505,6 +3505,18 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI__builtin_trap:
EmitTrapCall(Intrinsic::trap);
return RValue::get(nullptr);
case Builtin::BI__builtin_verbose_trap: {
llvm::DILocation *TrapLocation = Builder.getCurrentDebugLocation();
if (getDebugInfo()) {
TrapLocation = getDebugInfo()->CreateTrapFailureMessageFor(
TrapLocation, *E->getArg(0)->tryEvaluateString(getContext()),
*E->getArg(1)->tryEvaluateString(getContext()));
}
ApplyDebugLocation ApplyTrapDI(*this, TrapLocation);
// Currently no attempt is made to prevent traps from being merged.
EmitTrapCall(Intrinsic::trap);
return RValue::get(nullptr);
}
case Builtin::BI__debugbreak:
EmitTrapCall(Intrinsic::debugtrap);
return RValue::get(nullptr);
Expand Down
40 changes: 40 additions & 0 deletions clang/lib/CodeGen/CGDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/Version.h"
#include "clang/CodeGen/ModuleBuilder.h"
#include "clang/Frontend/FrontendOptions.h"
#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Lex/ModuleMap.h"
Expand Down Expand Up @@ -1731,6 +1732,28 @@ llvm::DIType *CGDebugInfo::createFieldType(
offsetInBits, flags, debugType, Annotations);
}

llvm::DISubprogram *
CGDebugInfo::createInlinedTrapSubprogram(StringRef FuncName,
llvm::DIFile *FileScope) {
// We are caching the subprogram because we don't want to duplicate
// subprograms with the same message. Note that `SPFlagDefinition` prevents
// subprograms from being uniqued.
llvm::DISubprogram *&SP = InlinedTrapFuncMap[FuncName];

if (!SP) {
llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(nullptr);
SP = DBuilder.createFunction(
/*Scope=*/FileScope, /*Name=*/FuncName, /*LinkageName=*/StringRef(),
/*File=*/FileScope, /*LineNo=*/0, /*Ty=*/DIFnTy,
/*ScopeLine=*/0,
/*Flags=*/llvm::DINode::FlagArtificial,
/*SPFlags=*/llvm::DISubprogram::SPFlagDefinition,
/*TParams=*/nullptr, /*ThrownTypes=*/nullptr, /*Annotations=*/nullptr);
}

return SP;
}

void CGDebugInfo::CollectRecordLambdaFields(
const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements,
llvm::DIType *RecordTy) {
Expand Down Expand Up @@ -3527,6 +3550,23 @@ llvm::DIMacroFile *CGDebugInfo::CreateTempMacroFile(llvm::DIMacroFile *Parent,
return DBuilder.createTempMacroFile(Parent, Line, FName);
}

llvm::DILocation *CGDebugInfo::CreateTrapFailureMessageFor(
llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
// Create a debug location from `TrapLocation` that adds an artificial inline
// frame.
SmallString<64> FuncName(ClangTrapPrefix);

FuncName += "$";
FuncName += Category;
FuncName += "$";
FuncName += FailureMsg;

llvm::DISubprogram *TrapSP =
createInlinedTrapSubprogram(FuncName, TrapLocation->getFile());
return llvm::DILocation::get(CGM.getLLVMContext(), /*Line=*/0, /*Column=*/0,
/*Scope=*/TrapSP, /*InlinedAt=*/TrapLocation);
}

static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C) {
Qualifiers Quals;
do {
Expand Down
Loading

0 comments on commit c625fb0

Please sign in to comment.