diff --git a/llvm/include/llvm/ADT/TypeSwitch.h b/llvm/include/llvm/ADT/TypeSwitch.h --- a/llvm/include/llvm/ADT/TypeSwitch.h +++ b/llvm/include/llvm/ADT/TypeSwitch.h @@ -35,7 +35,11 @@ /// Invoke a case on the derived class with multiple case types. template - DerivedT &Case(CallableT &&caseFn) { + // This is marked always_inline and nodebug so it doesn't show up in stack + // traces at -O0 (or other optimization levels). Large TypeSwitch's are + // common, are equivalent to a switch, and don't add any value to stack + // traces. + LLVM_ATTRIBUTE_ALWAYS_INLINE LLVM_NODEBUG DerivedT &Case(CallableT &&caseFn) { DerivedT &derived = static_cast(*this); return derived.template Case(caseFn) .template Case(caseFn); diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h --- a/llvm/include/llvm/Support/Compiler.h +++ b/llvm/include/llvm/Support/Compiler.h @@ -248,6 +248,15 @@ #define LLVM_ATTRIBUTE_ALWAYS_INLINE inline #endif +/// LLVM_ATTRIBUTE_NO_DEBUG - On compilers where we have a directive to do +/// so, mark a method "no debug" because debug info makes the debugger +/// experience worse. GCC introduced this in GCC 4.0 +#if __has_attribute(nodebug) || LLVM_GNUC_PREREQ(4, 0, 0) +#define LLVM_NODEBUG __attribute__((nodebug)) +#else +#define LLVM_NODEBUG +#endif + #if __has_attribute(returns_nonnull) || LLVM_GNUC_PREREQ(4, 9, 0) #define LLVM_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull)) #elif defined(_MSC_VER)