diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/Decl.cpp | 8 | ||||
-rw-r--r-- | lib/AST/DeclObjC.cpp | 17 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 77 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 17 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 14 |
5 files changed, 91 insertions, 42 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index ca1ae63ff8..4e07b957a7 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -216,6 +216,10 @@ FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC, //===----------------------------------------------------------------------===// std::string NamedDecl::getQualifiedNameAsString() const { + return getQualifiedNameAsString(getASTContext().getLangOptions()); +} + +std::string NamedDecl::getQualifiedNameAsString(const PrintingPolicy &P) const { std::vector<std::string> Names; std::string QualName; const DeclContext *Ctx = getDeclContext(); @@ -232,12 +236,11 @@ std::string NamedDecl::getQualifiedNameAsString() const { if (const ClassTemplateSpecializationDecl *Spec = dyn_cast<ClassTemplateSpecializationDecl>(Ctx)) { const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); - PrintingPolicy Policy(getASTContext().getLangOptions()); std::string TemplateArgsStr = TemplateSpecializationType::PrintTemplateArgumentList( TemplateArgs.getFlatArgumentList(), TemplateArgs.flat_size(), - Policy); + P); Names.push_back(Spec->getIdentifier()->getName() + TemplateArgsStr); } else if (const NamedDecl *ND = dyn_cast<NamedDecl>(Ctx)) Names.push_back(ND->getNameAsString()); @@ -259,7 +262,6 @@ std::string NamedDecl::getQualifiedNameAsString() const { return QualName; } - bool NamedDecl::declarationReplaces(NamedDecl *OldD) const { assert(getDeclName() == OldD->getDeclName() && "Declaration name mismatch"); diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index 8338c48c0b..ee2b81560d 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -290,23 +290,6 @@ void ObjCMethodDecl::createImplicitParams(ASTContext &Context, Context.getObjCSelType())); } - - -/// getSynthesizedMethodSize - Compute size of synthesized method name -/// as done be the rewrite. -/// -unsigned ObjCMethodDecl::getSynthesizedMethodSize() const { - // syntesized method name is a concatenation of -/+[class-name selector] - // Get length of this name. - unsigned length = 3; // _I_ or _C_ - length += getClassInterface()->getNameAsString().size()+1; // extra for _ - if (const ObjCCategoryImplDecl *CID = - dyn_cast<ObjCCategoryImplDecl>(getDeclContext())) - length += CID->getNameAsString().size()+1; - length += getSelector().getAsString().size(); // selector name - return length; -} - ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() { if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext())) return ID; diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index daa98aeeab..7171c79c44 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -22,6 +22,7 @@ #include "clang/AST/StmtVisitor.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/TargetInfo.h" +#include "llvm/Support/raw_ostream.h" #include <algorithm> using namespace clang; @@ -29,6 +30,82 @@ using namespace clang; // Primary Expressions. //===----------------------------------------------------------------------===// +// FIXME: Maybe this should use DeclPrinter with a special "print predefined +// expr" policy instead. +std::string PredefinedExpr::ComputeName(ASTContext &Context, IdentType IT, + const Decl *CurrentDecl) { + if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurrentDecl)) { + if (IT != PrettyFunction) + return FD->getNameAsString(); + + llvm::SmallString<256> Name; + llvm::raw_svector_ostream Out(Name); + + if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) { + if (MD->isVirtual()) + Out << "virtual "; + } + + PrintingPolicy Policy(Context.getLangOptions()); + Policy.SuppressTagKind = true; + + std::string Proto = FD->getQualifiedNameAsString(Policy); + + const FunctionType *AFT = FD->getType()->getAsFunctionType(); + const FunctionProtoType *FT = 0; + if (FD->hasWrittenPrototype()) + FT = dyn_cast<FunctionProtoType>(AFT); + + Proto += "("; + if (FT) { + llvm::raw_string_ostream POut(Proto); + for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) { + if (i) POut << ", "; + std::string Param; + FD->getParamDecl(i)->getType().getAsStringInternal(Param, Policy); + POut << Param; + } + + if (FT->isVariadic()) { + if (FD->getNumParams()) POut << ", "; + POut << "..."; + } + } + Proto += ")"; + + AFT->getResultType().getAsStringInternal(Proto, Policy); + + Out << Proto; + + Out.flush(); + return Name.str().str(); + } + if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CurrentDecl)) { + llvm::SmallString<256> Name; + llvm::raw_svector_ostream Out(Name); + Out << (MD->isInstanceMethod() ? '-' : '+'); + Out << '['; + Out << MD->getClassInterface()->getNameAsString(); + if (const ObjCCategoryImplDecl *CID = + dyn_cast<ObjCCategoryImplDecl>(MD->getDeclContext())) { + Out << '('; + Out << CID->getNameAsString(); + Out << ')'; + } + Out << ' '; + Out << MD->getSelector().getAsString(); + Out << ']'; + + Out.flush(); + return Name.str().str(); + } + if (isa<TranslationUnitDecl>(CurrentDecl) && IT == PrettyFunction) { + // __PRETTY_FUNCTION__ -> "top level", the others produce an empty string. + return "top level"; + } + return ""; +} + /// getValueAsApproximateDouble - This returns the value as an inaccurate /// double. Note that this may cause loss of precision, but is useful for /// debugging dumps, etc. diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 4a8253d9cd..d39e10f1f0 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -845,24 +845,13 @@ LValue CodeGenFunction::EmitPredefinedFunctionName(unsigned Type) { GlobalVarName = "__FUNCTION__."; break; case PredefinedExpr::PrettyFunction: - // FIXME:: Demangle C++ method names GlobalVarName = "__PRETTY_FUNCTION__."; break; } - // FIXME: This isn't right at all. The logic for computing this should go - // into a method on PredefinedExpr. This would allow sema and codegen to be - // consistent for things like sizeof(__func__) etc. - std::string FunctionName; - if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurCodeDecl)) { - FunctionName = CGM.getMangledName(FD); - } else { - // Just get the mangled name; skipping the asm prefix if it - // exists. - FunctionName = CurFn->getName(); - if (FunctionName[0] == '\01') - FunctionName = FunctionName.substr(1, std::string::npos); - } + std::string FunctionName = + PredefinedExpr::ComputeName(getContext(), (PredefinedExpr::IdentType)Type, + CurCodeDecl); GlobalVarName += FunctionName; llvm::Constant *C = diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 7d2e308349..17708346ab 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1151,17 +1151,15 @@ Sema::OwningExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, // Pre-defined identifiers are of type char[x], where x is the length of the // string. - unsigned Length; - if (FunctionDecl *FD = getCurFunctionDecl()) - Length = FD->getIdentifier()->getLength(); - else if (ObjCMethodDecl *MD = getCurMethodDecl()) - Length = MD->getSynthesizedMethodSize(); - else { + + Decl *currentDecl = getCurFunctionOrMethodDecl(); + if (!currentDecl) { Diag(Loc, diag::ext_predef_outside_function); - // __PRETTY_FUNCTION__ -> "top level", the others produce an empty string. - Length = IT == PredefinedExpr::PrettyFunction ? strlen("top level") : 0; + currentDecl = Context.getTranslationUnitDecl(); } + unsigned Length = + PredefinedExpr::ComputeName(Context, IT, currentDecl).length(); llvm::APInt LengthI(32, Length + 1); QualType ResTy = Context.CharTy.getQualifiedType(QualType::Const); |