diff options
Diffstat (limited to 'clang/lib/Sema/SemaExceptionSpec.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExceptionSpec.cpp | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index c35de6b8eda..7175c016734 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -35,6 +35,33 @@ static const FunctionProtoType *GetUnderlyingFunction(QualType T) return T->getAs<FunctionProtoType>(); } +/// HACK: libstdc++ has a bug where it shadows std::swap with a member +/// swap function then tries to call std::swap unqualified from the exception +/// specification of that function. This function detects whether we're in +/// such a case and turns off delay-parsing of exception specifications. +bool Sema::isLibstdcxxEagerExceptionSpecHack(const Declarator &D) { + auto *RD = dyn_cast<CXXRecordDecl>(CurContext); + + // All the problem cases are member functions named "swap" within class + // templates declared directly within namespace std. + if (!RD || RD->getEnclosingNamespaceContext() != getStdNamespace() || + !RD->getIdentifier() || !RD->getDescribedClassTemplate() || + !D.getIdentifier() || !D.getIdentifier()->isStr("swap")) + return false; + + // Only apply this hack within a system header. + if (!Context.getSourceManager().isInSystemHeader(D.getLocStart())) + return false; + + return llvm::StringSwitch<bool>(RD->getIdentifier()->getName()) + .Case("array", true) + .Case("pair", true) + .Case("priority_queue", true) + .Case("stack", true) + .Case("queue", true) + .Default(false); +} + /// CheckSpecifiedExceptionType - Check if the given type is valid in an /// exception specification. Incomplete types, or pointers to incomplete types /// other than void are not allowed. |