aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/Decl.cpp8
-rw-r--r--lib/AST/DeclObjC.cpp17
-rw-r--r--lib/AST/Expr.cpp77
-rw-r--r--lib/CodeGen/CGExpr.cpp17
-rw-r--r--lib/Sema/SemaExpr.cpp14
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);