diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2014-10-09 08:45:04 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2014-10-09 08:45:04 +0000 |
commit | ec4747802ae99edea83b3199df52be5c1f43f048 (patch) | |
tree | 0ab9f13bad64139844298485d5f2e3a62559720d /clang/lib/AST/Expr.cpp | |
parent | a9ee5c06f4c7d6e03aafe2b730f505f901694987 (diff) | |
download | bcm5719-llvm-ec4747802ae99edea83b3199df52be5c1f43f048.tar.gz bcm5719-llvm-ec4747802ae99edea83b3199df52be5c1f43f048.zip |
Fix for bug http://llvm.org/PR17427.
Assertion failed: "Computed __func__ length differs from type!"
Reworked PredefinedExpr representation with internal StringLiteral field for function declaration.
Differential Revision: http://reviews.llvm.org/D5365
llvm-svn: 219393
Diffstat (limited to 'clang/lib/AST/Expr.cpp')
-rw-r--r-- | clang/lib/AST/Expr.cpp | 53 |
1 files changed, 50 insertions, 3 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 0970d59c9c5..8410bad88d9 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -448,6 +448,38 @@ SourceLocation DeclRefExpr::getLocEnd() const { return getNameInfo().getLocEnd(); } +PredefinedExpr::PredefinedExpr(SourceLocation L, QualType FNTy, IdentType IT, + StringLiteral *SL) + : Expr(PredefinedExprClass, FNTy, VK_LValue, OK_Ordinary, + FNTy->isDependentType(), FNTy->isDependentType(), + FNTy->isInstantiationDependentType(), + /*ContainsUnexpandedParameterPack=*/false), + Loc(L), Type(IT), FnName(SL) {} + +StringLiteral *PredefinedExpr::getFunctionName() { + return cast<StringLiteral>(FnName); +} + +StringRef PredefinedExpr::getIdentTypeName(PredefinedExpr::IdentType IT) { + switch (IT) { + case Func: + return "__func__"; + case Function: + return "__FUNCTION__"; + case FuncDName: + return "__FUNCDNAME__"; + case LFunction: + return "L__FUNCTION__"; + case PrettyFunction: + return "__PRETTY_FUNCTION__"; + case FuncSig: + return "__FUNCSIG__"; + case PrettyFunctionNoVirtual: + break; + } + llvm_unreachable("Unknown ident type for PredefinedExpr"); +} + // FIXME: Maybe this should use DeclPrinter with a special "print predefined // expr" policy instead. std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) { @@ -477,6 +509,22 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) { } return ""; } + if (auto *BD = dyn_cast<BlockDecl>(CurrentDecl)) { + std::unique_ptr<MangleContext> MC; + MC.reset(Context.createMangleContext()); + SmallString<256> Buffer; + llvm::raw_svector_ostream Out(Buffer); + auto DC = CurrentDecl->getDeclContext(); + if (DC->isFileContext()) + MC->mangleGlobalBlock(BD, /*ID*/ nullptr, Out); + else if (const auto *CD = dyn_cast<CXXConstructorDecl>(DC)) + MC->mangleCtorBlock(CD, /*CT*/ Ctor_Complete, BD, Out); + else if (const auto *DD = dyn_cast<CXXDestructorDecl>(DC)) + MC->mangleDtorBlock(DD, /*DT*/ Dtor_Complete, BD, Out); + else + MC->mangleBlock(DC, BD, Out); + return Out.str(); + } if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurrentDecl)) { if (IT != PrettyFunction && IT != PrettyFunctionNoVirtual && IT != FuncSig) return FD->getNameAsString(); @@ -600,9 +648,8 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) { // type deduction and lambdas. For trailing return types resolve the // decltype expression. Otherwise print the real type when this is // not a constructor or destructor. - if ((isa<CXXMethodDecl>(FD) && - cast<CXXMethodDecl>(FD)->getParent()->isLambda()) || - (FT && FT->getReturnType()->getAs<AutoType>())) + if (isa<CXXMethodDecl>(FD) && + cast<CXXMethodDecl>(FD)->getParent()->isLambda()) Proto = "auto " + Proto; else if (FT && FT->getReturnType()->getAs<DecltypeType>()) FT->getReturnType() |