Update clang to r103052.
This commit is contained in:
parent
8aaf5818a6
commit
7e411337c0
@ -15,7 +15,7 @@
|
||||
namespace clang {
|
||||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) ENUM,
|
||||
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM,
|
||||
#define ASTSTART
|
||||
#include "clang/Basic/DiagnosticASTKinds.inc"
|
||||
#undef DIAG
|
||||
|
@ -45,6 +45,7 @@ class UnresolvedSetIterator {
|
||||
|
||||
NamedDecl *getDecl() const { return ir->getDecl(); }
|
||||
AccessSpecifier getAccess() const { return ir->getAccess(); }
|
||||
void setAccess(AccessSpecifier AS) { ir->setAccess(AS); }
|
||||
DeclAccessPair getPair() const { return *ir; }
|
||||
|
||||
NamedDecl *operator*() const { return getDecl(); }
|
||||
|
@ -15,7 +15,7 @@
|
||||
namespace clang {
|
||||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) ENUM,
|
||||
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM,
|
||||
#define ANALYSISSTART
|
||||
#include "clang/Basic/DiagnosticAnalysisKinds.inc"
|
||||
#undef DIAG
|
||||
|
@ -60,7 +60,7 @@ namespace clang {
|
||||
|
||||
// Get typedefs for common diagnostics.
|
||||
enum {
|
||||
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) ENUM,
|
||||
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM,
|
||||
#include "clang/Basic/DiagnosticCommonKinds.inc"
|
||||
NUM_BUILTIN_COMMON_DIAGNOSTICS
|
||||
#undef DIAG
|
||||
@ -283,13 +283,13 @@ class Diagnostic : public llvm::RefCountedBase<Diagnostic> {
|
||||
void setTemplateBacktraceLimit(unsigned Limit) {
|
||||
TemplateBacktraceLimit = Limit;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Retrieve the maximum number of template instantiation
|
||||
/// nodes to emit along with a given diagnostic.
|
||||
unsigned getTemplateBacktraceLimit() const {
|
||||
return TemplateBacktraceLimit;
|
||||
}
|
||||
|
||||
|
||||
/// setIgnoreAllWarnings - When set to true, any unmapped warnings are
|
||||
/// ignored. If this and WarningsAsErrors are both set, then this one wins.
|
||||
void setIgnoreAllWarnings(bool Val) { IgnoreAllWarnings = Val; }
|
||||
|
@ -26,10 +26,17 @@ def CLASS_WARNING : DiagClass;
|
||||
def CLASS_EXTENSION : DiagClass;
|
||||
def CLASS_ERROR : DiagClass;
|
||||
|
||||
// Diagnostic Categories. These can be applied to groups or individual
|
||||
// diagnostics to specify a category.
|
||||
class DiagCategory<string Name> {
|
||||
string CategoryName = Name;
|
||||
}
|
||||
|
||||
// Diagnostic Groups.
|
||||
class DiagGroup<string Name, list<DiagGroup> subgroups = []> {
|
||||
string GroupName = Name;
|
||||
list<DiagGroup> SubGroups = subgroups;
|
||||
string CategoryName = "";
|
||||
}
|
||||
class InGroup<DiagGroup G> { DiagGroup Group = G; }
|
||||
//class IsGroup<string Name> { DiagGroup Group = DiagGroup<Name>; }
|
||||
@ -48,6 +55,7 @@ class Diagnostic<string text, DiagClass DC, DiagMapping defaultmapping> {
|
||||
bit SFINAE = 1;
|
||||
DiagMapping DefaultMapping = defaultmapping;
|
||||
DiagGroup Group;
|
||||
string CategoryName = "";
|
||||
}
|
||||
|
||||
class Error<string str> : Diagnostic<str, CLASS_ERROR, MAP_ERROR>;
|
||||
|
@ -15,8 +15,6 @@ def Implicit : DiagGroup<"implicit", [
|
||||
ImplicitFunctionDeclare,
|
||||
ImplicitInt
|
||||
]>;
|
||||
|
||||
|
||||
|
||||
// Empty DiagGroups are recognized by clang but ignored.
|
||||
def : DiagGroup<"address">;
|
||||
@ -102,7 +100,7 @@ def : DiagGroup<"strict-prototypes">;
|
||||
def : DiagGroup<"strict-selector-match">;
|
||||
def SwitchEnum : DiagGroup<"switch-enum">;
|
||||
def Switch : DiagGroup<"switch", [SwitchEnum]>;
|
||||
def Trigraphs : DiagGroup<"trigraphs">;
|
||||
def Trigraphs : DiagGroup<"trigraphs">;
|
||||
|
||||
def : DiagGroup<"type-limits">;
|
||||
def Uninitialized : DiagGroup<"uninitialized">;
|
||||
@ -135,7 +133,8 @@ def Parentheses : DiagGroup<"parentheses", [DiagGroup<"idiomatic-parentheses">]>
|
||||
// -Wconversion has its own warnings, but we split this one out for
|
||||
// legacy reasons.
|
||||
def Conversion : DiagGroup<"conversion",
|
||||
[DiagGroup<"shorten-64-to-32">]>;
|
||||
[DiagGroup<"shorten-64-to-32">]>,
|
||||
DiagCategory<"Value Conversion">;
|
||||
|
||||
def Unused : DiagGroup<"unused",
|
||||
[UnusedArgument, UnusedFunction, UnusedLabel,
|
||||
@ -143,7 +142,8 @@ def Unused : DiagGroup<"unused",
|
||||
UnusedValue, UnusedVariable]>;
|
||||
|
||||
// Format settings.
|
||||
def Format : DiagGroup<"format", [FormatExtraArgs, FormatZeroLength, NonNull]>;
|
||||
def Format : DiagGroup<"format", [FormatExtraArgs, FormatZeroLength, NonNull]>,
|
||||
DiagCategory<"Format String">;
|
||||
def FormatSecurity : DiagGroup<"format-security", [Format]>;
|
||||
def FormatNonLiteral : DiagGroup<"format-nonliteral", [FormatSecurity]>;
|
||||
def FormatY2K : DiagGroup<"format-y2k", [Format]>;
|
||||
|
@ -1457,7 +1457,7 @@ def note_template_default_arg_checking : Note<
|
||||
"while checking a default template argument used here">;
|
||||
def note_instantiation_contexts_suppressed : Note<
|
||||
"(skipping %0 context%s0 in backtrace; use -ftemplate-backtrace-limit=0 to "
|
||||
"see all)">;
|
||||
"see all)">;
|
||||
|
||||
def err_field_instantiates_to_function : Error<
|
||||
"data member instantiated with function type %0">;
|
||||
|
@ -200,6 +200,8 @@ def ftabstop : Separate<"-ftabstop">, MetaVarName<"<N>">,
|
||||
HelpText<"Set the tab stop distance.">;
|
||||
def ferror_limit : Separate<"-ferror-limit">, MetaVarName<"<N>">,
|
||||
HelpText<"Set the maximum number of errors to emit before stopping (0 = no limit).">;
|
||||
def fmacro_backtrace_limit : Separate<"-fmacro-backtrace-limit">, MetaVarName<"<N>">,
|
||||
HelpText<"Set the maximum number of entries to print in a macro instantiation backtrace (0 = no limit).">;
|
||||
def ftemplate_backtrace_limit : Separate<"-ftemplate-backtrace-limit">, MetaVarName<"<N>">,
|
||||
HelpText<"Set the maximum number of entries to print in a template instantiation backtrace (0 = no limit).">;
|
||||
def fmessage_length : Separate<"-fmessage-length">, MetaVarName<"<N>">,
|
||||
|
@ -15,7 +15,7 @@
|
||||
namespace clang {
|
||||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) ENUM,
|
||||
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM,
|
||||
#define DRIVERSTART
|
||||
#include "clang/Basic/DiagnosticDriverKinds.inc"
|
||||
#undef DIAG
|
||||
|
@ -280,6 +280,8 @@ def flat__namespace : Flag<"-flat_namespace">;
|
||||
def flax_vector_conversions : Flag<"-flax-vector-conversions">, Group<f_Group>;
|
||||
def flimited_precision_EQ : Joined<"-flimited-precision=">, Group<f_Group>;
|
||||
def flto : Flag<"-flto">, Group<f_Group>;
|
||||
def fmacro_backtrace_limit_EQ : Joined<"-fmacro-backtrace-limit=">,
|
||||
Group<f_Group>;
|
||||
def fmath_errno : Flag<"-fmath-errno">, Group<f_Group>;
|
||||
def fmerge_all_constants : Flag<"-fmerge-all-constants">, Group<f_Group>;
|
||||
def fmessage_length_EQ : Joined<"-fmessage-length=">, Group<f_Group>;
|
||||
|
@ -39,11 +39,15 @@ class DiagnosticOptions {
|
||||
/// deserialized by, e.g., the CIndex library.
|
||||
|
||||
unsigned ErrorLimit; /// Limit # errors emitted.
|
||||
unsigned MacroBacktraceLimit; /// Limit depth of macro instantiation
|
||||
/// backtrace.
|
||||
unsigned TemplateBacktraceLimit; /// Limit depth of instantiation backtrace.
|
||||
|
||||
/// The distance between tab stops.
|
||||
unsigned TabStop;
|
||||
enum { DefaultTabStop = 8, MaxTabStop = 100 };
|
||||
enum { DefaultTabStop = 8, MaxTabStop = 100,
|
||||
DefaultMacroBacktraceLimit = 6,
|
||||
DefaultTemplateBacktraceLimit = 10 };
|
||||
|
||||
/// Column limit for formatting message diagnostics, or 0 if unused.
|
||||
unsigned MessageLength;
|
||||
@ -75,6 +79,7 @@ class DiagnosticOptions {
|
||||
BinaryOutput = 0;
|
||||
ErrorLimit = 0;
|
||||
TemplateBacktraceLimit = 0;
|
||||
MacroBacktraceLimit = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
namespace clang {
|
||||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) ENUM,
|
||||
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM,
|
||||
#define FRONTENDSTART
|
||||
#include "clang/Basic/DiagnosticFrontendKinds.inc"
|
||||
#undef DIAG
|
||||
|
@ -71,12 +71,15 @@ class TextDiagnosticPrinter : public DiagnosticClient {
|
||||
const SourceManager &SM,
|
||||
const FixItHint *Hints,
|
||||
unsigned NumHints,
|
||||
unsigned Columns);
|
||||
unsigned Columns,
|
||||
unsigned OnMacroInst,
|
||||
unsigned MacroSkipStart,
|
||||
unsigned MacroSkipEnd);
|
||||
|
||||
virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
|
||||
const DiagnosticInfo &Info);
|
||||
};
|
||||
|
||||
} // end namspace clang
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
@ -15,7 +15,7 @@
|
||||
namespace clang {
|
||||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) ENUM,
|
||||
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM,
|
||||
#define LEXSTART
|
||||
#include "clang/Basic/DiagnosticLexKinds.inc"
|
||||
#undef DIAG
|
||||
|
@ -15,7 +15,7 @@
|
||||
namespace clang {
|
||||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) ENUM,
|
||||
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM,
|
||||
#define PARSESTART
|
||||
#include "clang/Basic/DiagnosticParseKinds.inc"
|
||||
#undef DIAG
|
||||
|
@ -15,7 +15,7 @@
|
||||
namespace clang {
|
||||
namespace diag {
|
||||
enum {
|
||||
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE) ENUM,
|
||||
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM,
|
||||
#define SEMASTART
|
||||
#include "clang/Basic/DiagnosticSemaKinds.inc"
|
||||
#undef DIAG
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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())
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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");
|
||||
|
@ -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) {
|
||||
|
@ -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 << ' ';
|
||||
}
|
||||
OS << "note: instantiated from:\n";
|
||||
|
||||
EmitCaretDiagnostic(Loc, Ranges, NumRanges, SM, Hints, NumHints, Columns,
|
||||
OnMacroInst + 1, MacroSkipStart, MacroSkipEnd);
|
||||
return;
|
||||
}
|
||||
|
||||
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 (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";
|
||||
}
|
||||
OS << "note: instantiated from:\n";
|
||||
|
||||
EmitCaretDiagnostic(Loc, Ranges, NumRanges, SM, Hints, NumHints, Columns);
|
||||
|
||||
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();
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
|
@ -29,3 +29,13 @@ void foo(void) {
|
||||
// RUN: grep "f1.l0 = internal global i32 ptrtoint (i32 ()\* @f1 to i32)" %t
|
||||
int f1(void) { static int l0 = (unsigned) f1; }
|
||||
|
||||
// PR7044
|
||||
char *f2(char key) {
|
||||
switch (key) {
|
||||
static char _msg[40];
|
||||
case '\014':
|
||||
return _msg;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -9,6 +9,26 @@ T _i;
|
||||
T get() {return _i;};
|
||||
};
|
||||
|
||||
// rdar: // 7495203
|
||||
class A {
|
||||
public:
|
||||
A() : field(10), d1(3.14) {}
|
||||
void F();
|
||||
void S() {
|
||||
printf(" field = %d\n", field);
|
||||
printf(" field = %f\n", d1);
|
||||
}
|
||||
int field;
|
||||
double d1;
|
||||
};
|
||||
|
||||
void A::F()
|
||||
{
|
||||
__block A &tlc = *this;
|
||||
// crashed in code gen (radar 7495203)
|
||||
^{ tlc.S(); }();
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
// works
|
||||
@ -16,6 +36,8 @@ int main() {
|
||||
|
||||
//crashes in godegen?
|
||||
void (^bl2)(range<int>& ) = ^(range<int>& i){printf("Hello Blocks %d\n", i.get()); };
|
||||
|
||||
A *a = new A;
|
||||
a->F();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -69,3 +69,18 @@ int main() {
|
||||
[a release];
|
||||
}
|
||||
|
||||
// rdar: // 7468090
|
||||
class S {
|
||||
public:
|
||||
S& operator = (const S&);
|
||||
};
|
||||
|
||||
@interface I {
|
||||
S position;
|
||||
}
|
||||
@property(assign, nonatomic) S position;
|
||||
@end
|
||||
|
||||
@implementation I
|
||||
@synthesize position;
|
||||
@end
|
||||
|
32
test/Misc/macro-backtrace-limit.c
Normal file
32
test/Misc/macro-backtrace-limit.c
Normal file
@ -0,0 +1,32 @@
|
||||
// RUN: %clang-cc1 -fsyntax-only -fmacro-backtrace-limit 5 %s > %t 2>&1
|
||||
// RUN: FileCheck %s < %t
|
||||
|
||||
#define M1(A, B) ((A) < (B))
|
||||
#define M2(A, B) M1(A, B)
|
||||
#define M3(A, B) M2(A, B)
|
||||
#define M4(A, B) M3(A, B)
|
||||
#define M5(A, B) M4(A, B)
|
||||
#define M6(A, B) M5(A, B)
|
||||
#define M7(A, B) M6(A, B)
|
||||
#define M8(A, B) M7(A, B)
|
||||
#define M9(A, B) M8(A, B)
|
||||
#define M10(A, B) M9(A, B)
|
||||
#define M11(A, B) M10(A, B)
|
||||
#define M12(A, B) M11(A, B)
|
||||
|
||||
void f(int *ip, float *fp) {
|
||||
// CHECK: macro-backtrace-limit.c:31:7: warning: comparison of distinct pointer types ('int *' and 'float *')
|
||||
// CHECK: if (M12(ip, fp)) { }
|
||||
// CHECK: macro-backtrace-limit.c:15:19: note: instantiated from:
|
||||
// CHECK: #define M12(A, B) M11(A, B)
|
||||
// CHECK: macro-backtrace-limit.c:14:19: note: instantiated from:
|
||||
// CHECK: #define M11(A, B) M10(A, B)
|
||||
// CHECK: note: (skipping 7 contexts in backtrace; use -fmacro-backtrace-limit=0 to see all)
|
||||
// CHECK: macro-backtrace-limit.c:6:18: note: instantiated from:
|
||||
// CHECK: #define M3(A, B) M2(A, B)
|
||||
// CHECK: macro-backtrace-limit.c:5:18: note: instantiated from:
|
||||
// CHECK: #define M2(A, B) M1(A, B)
|
||||
// CHECK: macro-backtrace-limit.c:4:23: note: instantiated from:
|
||||
// CHECK: #define M1(A, B) ((A) < (B))
|
||||
if (M12(ip, fp)) { }
|
||||
}
|
@ -120,7 +120,7 @@ extern __typeof (i1) i1;
|
||||
typedef int a();
|
||||
typedef int a2(int*);
|
||||
a x;
|
||||
a2 x2;
|
||||
a2 x2; // expected-note{{passing argument to parameter here}}
|
||||
void test_x() {
|
||||
x(5);
|
||||
x2(5); // expected-warning{{incompatible integer to pointer conversion passing 'int' to parameter of type 'int *'}}
|
||||
|
@ -89,3 +89,31 @@ void j() {
|
||||
e1 = e2;
|
||||
}
|
||||
|
||||
namespace ProtectedCheck {
|
||||
struct X {
|
||||
protected:
|
||||
X &operator=(const X&); // expected-note{{declared protected here}}
|
||||
};
|
||||
|
||||
struct Y : public X { };
|
||||
|
||||
void f(Y y) { y = y; }
|
||||
|
||||
struct Z { // expected-error{{'operator=' is a protected member of 'ProtectedCheck::X'}}
|
||||
X x;
|
||||
};
|
||||
|
||||
void f(Z z) { z = z; } //
|
||||
}
|
||||
|
||||
namespace MultiplePaths {
|
||||
struct X0 {
|
||||
X0 &operator=(const X0&);
|
||||
};
|
||||
|
||||
struct X1 : public virtual X0 { };
|
||||
|
||||
struct X2 : X0, X1 { };
|
||||
|
||||
void f(X2 x2) { x2 = x2; }
|
||||
}
|
||||
|
@ -76,3 +76,15 @@ namespace PR6990 {
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
namespace InstantiateFunctionTypedef {
|
||||
template<typename T>
|
||||
struct X {
|
||||
typedef int functype(int, int);
|
||||
functype func;
|
||||
};
|
||||
|
||||
void f(X<int> x) {
|
||||
(void)x.func(1, 2);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user