summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2010-05-04 20:51:19 +0000
committerrdivacky <rdivacky@FreeBSD.org>2010-05-04 20:51:19 +0000
commit7e411337c0ed226dace6e07f1420486768161308 (patch)
tree938fcb7c80a0402925b5b00fa684a245ab0936a5 /lib
parent8aaf5818a64e9f7687798852af5945b053c68a54 (diff)
downloadFreeBSD-src-7e411337c0ed226dace6e07f1420486768161308.zip
FreeBSD-src-7e411337c0ed226dace6e07f1420486768161308.tar.gz
Update clang to r103052.
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/StmtDumper.cpp7
-rw-r--r--lib/Basic/Diagnostic.cpp10
-rw-r--r--lib/CodeGen/CGBlocks.cpp2
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp5
-rw-r--r--lib/CodeGen/CGDecl.cpp7
-rw-r--r--lib/CodeGen/CGDeclCXX.cpp3
-rw-r--r--lib/CodeGen/CGObjC.cpp26
-rw-r--r--lib/Driver/Tools.cpp11
-rw-r--r--lib/Frontend/CompilerInvocation.cpp15
-rw-r--r--lib/Frontend/TextDiagnosticPrinter.cpp82
-rw-r--r--lib/Sema/SemaDecl.cpp6
-rw-r--r--lib/Sema/SemaDeclCXX.cpp33
-rw-r--r--lib/Sema/SemaExpr.cpp4
-rw-r--r--lib/Sema/SemaOverload.cpp2
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp21
15 files changed, 179 insertions, 55 deletions
diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp
index ca62ed1..a11e313 100644
--- a/lib/AST/StmtDumper.cpp
+++ b/lib/AST/StmtDumper.cpp
@@ -260,6 +260,13 @@ void StmtDumper::DumpDeclarator(Decl *D) {
else
ns = "<anonymous>";
OS << '"' << UD->getDeclKindName() << ns << ";\"";
+ } else if (UsingDecl *UD = dyn_cast<UsingDecl>(D)) {
+ // print using decl (e.g. "using std::string;")
+ const char *tn = UD->isTypeName() ? "typename " : "";
+ OS << '"' << UD->getDeclKindName() << tn;
+ UD->getTargetNestedNameDecl()->print(OS,
+ PrintingPolicy(UD->getASTContext().getLangOptions()));
+ OS << ";\"";
} else {
assert(0 && "Unexpected decl");
}
diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp
index 1870195..9e6f168 100644
--- a/lib/Basic/Diagnostic.cpp
+++ b/lib/Basic/Diagnostic.cpp
@@ -51,6 +51,8 @@ struct StaticDiagInfoRec {
unsigned Mapping : 3;
unsigned Class : 3;
bool SFINAE : 1;
+ unsigned Category : 5;
+
const char *Description;
const char *OptionGroup;
@@ -63,8 +65,8 @@ struct StaticDiagInfoRec {
};
static const StaticDiagInfoRec StaticDiagInfo[] = {
-#define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) \
- { diag::ENUM, DEFAULT_MAPPING, CLASS, SFINAE, DESC, GROUP },
+#define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP,SFINAE, CATEGORY) \
+ { diag::ENUM, DEFAULT_MAPPING, CLASS, SFINAE, CATEGORY, DESC, GROUP },
#include "clang/Basic/DiagnosticCommonKinds.inc"
#include "clang/Basic/DiagnosticDriverKinds.inc"
#include "clang/Basic/DiagnosticFrontendKinds.inc"
@@ -73,7 +75,7 @@ static const StaticDiagInfoRec StaticDiagInfo[] = {
#include "clang/Basic/DiagnosticASTKinds.inc"
#include "clang/Basic/DiagnosticSemaKinds.inc"
#include "clang/Basic/DiagnosticAnalysisKinds.inc"
- { 0, 0, 0, 0, 0, 0}
+ { 0, 0, 0, 0, 0, 0, 0}
};
#undef DIAG
@@ -99,7 +101,7 @@ static const StaticDiagInfoRec *GetDiagInfo(unsigned DiagID) {
#endif
// Search the diagnostic table with a binary search.
- StaticDiagInfoRec Find = { DiagID, 0, 0, 0, 0, 0 };
+ StaticDiagInfoRec Find = { DiagID, 0, 0, 0, 0, 0, 0 };
const StaticDiagInfoRec *Found =
std::lower_bound(StaticDiagInfo, StaticDiagInfo + NumDiagEntries, Find);
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index db24def..8082b33 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -532,6 +532,8 @@ llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const BlockDeclRefExpr *E) {
V = Builder.CreateBitCast(V, PtrStructTy);
V = Builder.CreateStructGEP(V, getByRefValueLLVMField(VD),
VD->getNameAsString());
+ if (VD->getType()->isReferenceType())
+ V = Builder.CreateLoad(V);
} else {
const llvm::Type *Ty = CGM.getTypes().ConvertType(VD->getType());
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 4963e73..48ae511 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -495,7 +495,10 @@ CollectRecordFields(const RecordDecl *RD, llvm::DIFile Unit,
llvm::DIType
CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method,
llvm::DIFile Unit) {
- llvm::DIType FnTy = getOrCreateType(Method->getType(), Unit);
+ llvm::DIType FnTy
+ = getOrCreateType(QualType(Method->getType()->getAs<FunctionProtoType>(),
+ 0),
+ Unit);
// Static methods do not need "this" pointer argument.
if (Method->isStatic())
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index ba3a2b4..48198ff 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -231,9 +231,6 @@ CodeGenFunction::AddInitializerToGlobalBlockVarDecl(const VarDecl &D,
void CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D,
llvm::GlobalValue::LinkageTypes Linkage) {
- // Bail out early if the block is unreachable.
- if (!Builder.GetInsertBlock()) return;
-
llvm::Value *&DMEntry = LocalDeclMap[&D];
assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
@@ -245,9 +242,9 @@ void CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D,
if (getContext().getLangOptions().CPlusPlus)
CGM.setStaticLocalDeclAddress(&D, GV);
+ // We can't have a VLA here, but we can have a pointer to a VLA,
+ // even though that doesn't really make any sense.
// Make sure to evaluate VLA bounds now so that we have them for later.
- //
- // FIXME: Can this happen?
if (D.getType()->isVariablyModifiedType())
EmitVLASize(D.getType());
diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp
index f6c805f..6afa538 100644
--- a/lib/CodeGen/CGDeclCXX.cpp
+++ b/lib/CodeGen/CGDeclCXX.cpp
@@ -279,6 +279,9 @@ static llvm::Constant *getGuardAbortFn(CodeGenFunction &CGF) {
void
CodeGenFunction::EmitStaticCXXBlockVarDeclInit(const VarDecl &D,
llvm::GlobalVariable *GV) {
+ // Bail out early if this initializer isn't reachable.
+ if (!Builder.GetInsertBlock()) return;
+
bool ThreadsafeStatics = getContext().getLangOptions().ThreadsafeStatics;
llvm::SmallString<256> GuardVName;
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index 3359250..8426f71 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -441,18 +441,20 @@ void CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP,
LoadObjCSelf(), Ivar, 0);
const RecordType *RT = FieldType->getAs<RecordType>();
CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
- if (Array) {
- const llvm::Type *BasePtr = ConvertType(FieldType);
- BasePtr = llvm::PointerType::getUnqual(BasePtr);
- llvm::Value *BaseAddrPtr =
- Builder.CreateBitCast(LV.getAddress(), BasePtr);
- EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(getContext()),
- Array, BaseAddrPtr);
- }
- else
- EmitCXXDestructorCall(FieldClassDecl->getDestructor(CGM.getContext()),
- Dtor_Complete, /*ForVirtualBase=*/false,
- LV.getAddress());
+ CXXDestructorDecl *Dtor = FieldClassDecl->getDestructor(getContext());
+ if (!Dtor->isTrivial())
+ if (Array) {
+ const llvm::Type *BasePtr = ConvertType(FieldType);
+ BasePtr = llvm::PointerType::getUnqual(BasePtr);
+ llvm::Value *BaseAddrPtr =
+ Builder.CreateBitCast(LV.getAddress(), BasePtr);
+ EmitCXXAggrDestructorCall(Dtor,
+ Array, BaseAddrPtr);
+ }
+ else
+ EmitCXXDestructorCall(Dtor,
+ Dtor_Complete, /*ForVirtualBase=*/false,
+ LV.getAddress());
}
}
FinishFunction();
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 176d491..5a3916d 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -21,6 +21,7 @@
#include "clang/Driver/Options.h"
#include "clang/Driver/ToolChain.h"
#include "clang/Driver/Util.h"
+#include "clang/Frontend/DiagnosticOptions.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
@@ -1082,11 +1083,19 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
else
CmdArgs.push_back("19");
+ CmdArgs.push_back("-fmacro-backtrace-limit");
+ if (Arg *A = Args.getLastArg(options::OPT_fmacro_backtrace_limit_EQ))
+ CmdArgs.push_back(A->getValue(Args));
+ else
+ CmdArgs.push_back(Args.MakeArgString(
+ llvm::Twine(DiagnosticOptions::DefaultMacroBacktraceLimit)));
+
CmdArgs.push_back("-ftemplate-backtrace-limit");
if (Arg *A = Args.getLastArg(options::OPT_ftemplate_backtrace_limit_EQ))
CmdArgs.push_back(A->getValue(Args));
else
- CmdArgs.push_back("10");
+ CmdArgs.push_back(Args.MakeArgString(
+ llvm::Twine(DiagnosticOptions::DefaultTemplateBacktraceLimit)));
// Pass -fmessage-length=.
CmdArgs.push_back("-fmessage-length");
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 8ffdde2..729c1dc 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -247,7 +247,13 @@ static void DiagnosticOptsToArgs(const DiagnosticOptions &Opts,
Res.push_back("-ferror-limit");
Res.push_back(llvm::utostr(Opts.ErrorLimit));
}
- if (Opts.TemplateBacktraceLimit != 10) {
+ if (Opts.MacroBacktraceLimit
+ != DiagnosticOptions::DefaultMacroBacktraceLimit) {
+ Res.push_back("-fmacro-backtrace-limit");
+ Res.push_back(llvm::utostr(Opts.MacroBacktraceLimit));
+ }
+ if (Opts.TemplateBacktraceLimit
+ != DiagnosticOptions::DefaultTemplateBacktraceLimit) {
Res.push_back("-ftemplate-backtrace-limit");
Res.push_back(llvm::utostr(Opts.TemplateBacktraceLimit));
}
@@ -877,8 +883,13 @@ static void ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
Opts.VerifyDiagnostics = Args.hasArg(OPT_verify);
Opts.BinaryOutput = Args.hasArg(OPT_fdiagnostics_binary);
Opts.ErrorLimit = getLastArgIntValue(Args, OPT_ferror_limit, 0, Diags);
+ Opts.MacroBacktraceLimit
+ = getLastArgIntValue(Args, OPT_fmacro_backtrace_limit,
+ DiagnosticOptions::DefaultMacroBacktraceLimit, Diags);
Opts.TemplateBacktraceLimit
- = getLastArgIntValue(Args, OPT_ftemplate_backtrace_limit, 0, Diags);
+ = getLastArgIntValue(Args, OPT_ftemplate_backtrace_limit,
+ DiagnosticOptions::DefaultTemplateBacktraceLimit,
+ Diags);
Opts.TabStop = getLastArgIntValue(Args, OPT_ftabstop,
DiagnosticOptions::DefaultTabStop, Diags);
if (Opts.TabStop == 0 || Opts.TabStop > DiagnosticOptions::MaxTabStop) {
diff --git a/lib/Frontend/TextDiagnosticPrinter.cpp b/lib/Frontend/TextDiagnosticPrinter.cpp
index 28bb17a..66ed956 100644
--- a/lib/Frontend/TextDiagnosticPrinter.cpp
+++ b/lib/Frontend/TextDiagnosticPrinter.cpp
@@ -285,7 +285,10 @@ void TextDiagnosticPrinter::EmitCaretDiagnostic(SourceLocation Loc,
const SourceManager &SM,
const FixItHint *Hints,
unsigned NumHints,
- unsigned Columns) {
+ unsigned Columns,
+ unsigned OnMacroInst,
+ unsigned MacroSkipStart,
+ unsigned MacroSkipEnd) {
assert(LangOpts && "Unexpected diagnostic outside source file processing");
assert(!Loc.isInvalid() && "must have a valid source location here");
@@ -293,10 +296,16 @@ void TextDiagnosticPrinter::EmitCaretDiagnostic(SourceLocation Loc,
// instantiated (recursively) then emit information about where the token was
// spelled from.
if (!Loc.isFileID()) {
+ // Whether to suppress printing this macro instantiation.
+ bool Suppressed
+ = OnMacroInst >= MacroSkipStart && OnMacroInst < MacroSkipEnd;
+
+
SourceLocation OneLevelUp = SM.getImmediateInstantiationRange(Loc).first;
// FIXME: Map ranges?
- EmitCaretDiagnostic(OneLevelUp, Ranges, NumRanges, SM, 0, 0, Columns);
-
+ EmitCaretDiagnostic(OneLevelUp, Ranges, NumRanges, SM, 0, 0, Columns,
+ OnMacroInst + 1, MacroSkipStart, MacroSkipEnd);
+
// Map the location.
Loc = SM.getImmediateSpellingLoc(Loc);
@@ -308,26 +317,38 @@ void TextDiagnosticPrinter::EmitCaretDiagnostic(SourceLocation Loc,
Ranges[i] = SourceRange(S, E);
}
- // Get the pretty name, according to #line directives etc.
- PresumedLoc PLoc = SM.getPresumedLoc(Loc);
+ if (!Suppressed) {
+ // Get the pretty name, according to #line directives etc.
+ PresumedLoc PLoc = SM.getPresumedLoc(Loc);
- // If this diagnostic is not in the main file, print out the "included from"
- // lines.
- if (LastWarningLoc != PLoc.getIncludeLoc()) {
- LastWarningLoc = PLoc.getIncludeLoc();
- PrintIncludeStack(LastWarningLoc, SM);
- }
+ // If this diagnostic is not in the main file, print out the
+ // "included from" lines.
+ if (LastWarningLoc != PLoc.getIncludeLoc()) {
+ LastWarningLoc = PLoc.getIncludeLoc();
+ PrintIncludeStack(LastWarningLoc, SM);
+ }
- if (DiagOpts->ShowLocation) {
- // Emit the file/line/column that this expansion came from.
- OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':';
- if (DiagOpts->ShowColumn)
- OS << PLoc.getColumn() << ':';
- OS << ' ';
+ if (DiagOpts->ShowLocation) {
+ // Emit the file/line/column that this expansion came from.
+ OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':';
+ if (DiagOpts->ShowColumn)
+ OS << PLoc.getColumn() << ':';
+ OS << ' ';
+ }
+ OS << "note: instantiated from:\n";
+
+ EmitCaretDiagnostic(Loc, Ranges, NumRanges, SM, Hints, NumHints, Columns,
+ OnMacroInst + 1, MacroSkipStart, MacroSkipEnd);
+ return;
}
- OS << "note: instantiated from:\n";
-
- EmitCaretDiagnostic(Loc, Ranges, NumRanges, SM, Hints, NumHints, Columns);
+
+ if (OnMacroInst == MacroSkipStart) {
+ // Tell the user that we've skipped contexts.
+ OS << "note: (skipping " << (MacroSkipEnd - MacroSkipStart)
+ << " contexts in backtrace; use -fmacro-backtrace-limit=0 to see "
+ "all)\n";
+ }
+
return;
}
@@ -866,10 +887,29 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level,
}
}
+ unsigned MacroInstSkipStart = 0, MacroInstSkipEnd = 0;
+ if (DiagOpts && DiagOpts->MacroBacktraceLimit && !LastLoc.isFileID()) {
+ // Compute the length of the macro-instantiation backtrace, so that we
+ // can establish which steps in the macro backtrace we'll skip.
+ SourceLocation Loc = LastLoc;
+ unsigned Depth = 0;
+ do {
+ ++Depth;
+ Loc = LastLoc.getManager().getImmediateInstantiationRange(Loc).first;
+ } while (!Loc.isFileID());
+
+ if (Depth > DiagOpts->MacroBacktraceLimit) {
+ MacroInstSkipStart = DiagOpts->MacroBacktraceLimit / 2 +
+ DiagOpts->MacroBacktraceLimit % 2;
+ MacroInstSkipEnd = Depth - DiagOpts->MacroBacktraceLimit / 2;
+ }
+ }
+
EmitCaretDiagnostic(LastLoc, Ranges, NumRanges, LastLoc.getManager(),
Info.getFixItHints(),
Info.getNumFixItHints(),
- DiagOpts->MessageLength);
+ DiagOpts->MessageLength,
+ 0, MacroInstSkipStart, MacroInstSkipEnd);
}
OS.flush();
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 0e839a9..a802679 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -3243,8 +3243,10 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(),
AE = FT->arg_type_end(); AI != AE; ++AI) {
ParmVarDecl *Param = ParmVarDecl::Create(Context, NewFD,
- SourceLocation(), 0,
- *AI, /*TInfo=*/0,
+ D.getIdentifierLoc(), 0,
+ *AI,
+ Context.getTrivialTypeSourceInfo(*AI,
+ D.getIdentifierLoc()),
VarDecl::None,
VarDecl::None, 0);
Param->setImplicit();
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 6259b85a..b9c7d79 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -4134,13 +4134,16 @@ void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
///
/// \param From The expression we are copying from.
///
+/// \param CopyingBaseSubobject Whether we're copying a base subobject.
+/// Otherwise, it's a non-static member subobject.
+///
/// \param Depth Internal parameter recording the depth of the recursion.
///
/// \returns A statement or a loop that copies the expressions.
static Sema::OwningStmtResult
BuildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T,
Sema::OwningExprResult To, Sema::OwningExprResult From,
- unsigned Depth = 0) {
+ bool CopyingBaseSubobject, unsigned Depth = 0) {
typedef Sema::OwningStmtResult OwningStmtResult;
typedef Sema::OwningExprResult OwningExprResult;
@@ -4172,6 +4175,25 @@ BuildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T,
}
F.done();
+ // Suppress the protected check (C++ [class.protected]) for each of the
+ // assignment operators we found. This strange dance is required when
+ // we're assigning via a base classes's copy-assignment operator. To
+ // ensure that we're getting the right base class subobject (without
+ // ambiguities), we need to cast "this" to that subobject type; to
+ // ensure that we don't go through the virtual call mechanism, we need
+ // to qualify the operator= name with the base class (see below). However,
+ // this means that if the base class has a protected copy assignment
+ // operator, the protected member access check will fail. So, we
+ // rewrite "protected" access to "public" access in this case, since we
+ // know by construction that we're calling from a derived class.
+ if (CopyingBaseSubobject) {
+ for (LookupResult::iterator L = OpLookup.begin(), LEnd = OpLookup.end();
+ L != LEnd; ++L) {
+ if (L.getAccess() == AS_protected)
+ L.setAccess(AS_public);
+ }
+ }
+
// Create the nested-name-specifier that will be used to qualify the
// reference to operator=; this is required to suppress the virtual
// call mechanism.
@@ -4277,7 +4299,8 @@ BuildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T,
// Build the copy for an individual element of the array.
OwningStmtResult Copy = BuildSingleCopyAssign(S, Loc,
ArrayTy->getElementType(),
- move(To), move(From), Depth+1);
+ move(To), move(From),
+ CopyingBaseSubobject, Depth+1);
if (Copy.isInvalid()) {
InitStmt->Destroy(S.Context);
return S.StmtError();
@@ -4381,7 +4404,8 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
// Build the copy.
OwningStmtResult Copy = BuildSingleCopyAssign(*this, Loc, BaseType,
- move(To), Owned(From));
+ move(To), Owned(From),
+ /*CopyingBaseSubobject=*/true);
if (Copy.isInvalid()) {
Invalid = true;
continue;
@@ -4501,7 +4525,8 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
// Build the copy of this field.
OwningStmtResult Copy = BuildSingleCopyAssign(*this, Loc, FieldType,
- move(To), move(From));
+ move(To), move(From),
+ /*CopyingBaseSubobject=*/false);
if (Copy.isInvalid()) {
Invalid = true;
continue;
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index c4ab03f..869d6df 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -3565,8 +3565,8 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(NakedFn)) {
if (BO->getOpcode() == BinaryOperator::PtrMemD ||
BO->getOpcode() == BinaryOperator::PtrMemI) {
- if (const FunctionProtoType *FPT =
- dyn_cast<FunctionProtoType>(BO->getType())) {
+ if (const FunctionProtoType *FPT
+ = BO->getType()->getAs<FunctionProtoType>()) {
QualType ResultTy = FPT->getResultType().getNonReferenceType();
ExprOwningPtr<CXXMemberCallExpr>
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 21f2a51..b87fa7d 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -6513,7 +6513,7 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
MemExpr->setBase(ObjectArg);
// Convert the rest of the arguments
- const FunctionProtoType *Proto = cast<FunctionProtoType>(Method->getType());
+ const FunctionProtoType *Proto = Method->getType()->getAs<FunctionProtoType>();
if (ConvertArgumentsForCall(&*TheCall, MemExpr, Method, Proto, Args, NumArgs,
RParenLoc))
return ExprError();
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 8b851b2..da84806 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1169,6 +1169,27 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
return 0;
QualType T = TInfo->getType();
+ // \brief If the type of this function is not *directly* a function
+ // type, then we're instantiating the a function that was declared
+ // via a typedef, e.g.,
+ //
+ // typedef int functype(int, int);
+ // functype func;
+ //
+ // In this case, we'll just go instantiate the ParmVarDecls that we
+ // synthesized in the method declaration.
+ if (!isa<FunctionProtoType>(T)) {
+ assert(!Params.size() && "Instantiating type could not yield parameters");
+ for (unsigned I = 0, N = D->getNumParams(); I != N; ++I) {
+ ParmVarDecl *P = SemaRef.SubstParmVarDecl(D->getParamDecl(I),
+ TemplateArgs);
+ if (!P)
+ return 0;
+
+ Params.push_back(P);
+ }
+ }
+
NestedNameSpecifier *Qualifier = D->getQualifier();
if (Qualifier) {
Qualifier = SemaRef.SubstNestedNameSpecifier(Qualifier,
OpenPOWER on IntegriCloud