From be17651f5cd2e94922c1b732bc8589e180698193 Mon Sep 17 00:00:00 2001 From: Roman Divacky Date: Tue, 4 May 2010 20:51:19 +0000 Subject: [PATCH] Update clang to r103052. --- include/clang/AST/ASTDiagnostic.h | 2 +- include/clang/AST/UnresolvedSet.h | 1 + include/clang/Analysis/AnalysisDiagnostic.h | 2 +- include/clang/Basic/Diagnostic.h | 6 +- include/clang/Basic/Diagnostic.td | 8 ++ include/clang/Basic/DiagnosticGroups.td | 10 +-- include/clang/Basic/DiagnosticSemaKinds.td | 2 +- include/clang/Driver/CC1Options.td | 2 + include/clang/Driver/DriverDiagnostic.h | 2 +- include/clang/Driver/Options.td | 2 + include/clang/Frontend/DiagnosticOptions.h | 7 +- include/clang/Frontend/FrontendDiagnostic.h | 2 +- .../clang/Frontend/TextDiagnosticPrinter.h | 7 +- include/clang/Lex/LexDiagnostic.h | 2 +- include/clang/Parse/ParseDiagnostic.h | 2 +- include/clang/Sema/SemaDiagnostic.h | 2 +- lib/AST/StmtDumper.cpp | 7 ++ lib/Basic/Diagnostic.cpp | 10 ++- lib/CodeGen/CGBlocks.cpp | 2 + lib/CodeGen/CGDebugInfo.cpp | 5 +- lib/CodeGen/CGDecl.cpp | 7 +- lib/CodeGen/CGDeclCXX.cpp | 3 + lib/CodeGen/CGObjC.cpp | 26 +++--- lib/Driver/Tools.cpp | 11 ++- lib/Frontend/CompilerInvocation.cpp | 15 +++- lib/Frontend/TextDiagnosticPrinter.cpp | 82 ++++++++++++++----- lib/Sema/SemaDecl.cpp | 6 +- lib/Sema/SemaDeclCXX.cpp | 33 +++++++- lib/Sema/SemaExpr.cpp | 4 +- lib/Sema/SemaOverload.cpp | 2 +- lib/Sema/SemaTemplateInstantiateDecl.cpp | 21 +++++ test/CodeGen/staticinit.c | 10 +++ test/CodeGenCXX/reference-in-blocks.cpp | 24 +++++- test/CodeGenObjCXX/ivar-objects.mm | 15 ++++ test/Misc/macro-backtrace-limit.c | 32 ++++++++ test/Sema/function-redecl.c | 2 +- test/SemaCXX/default-assignment-operator.cpp | 28 +++++++ .../instantiate-function-params.cpp | 12 +++ 38 files changed, 340 insertions(+), 76 deletions(-) create mode 100644 test/Misc/macro-backtrace-limit.c diff --git a/include/clang/AST/ASTDiagnostic.h b/include/clang/AST/ASTDiagnostic.h index 2d314913469e..7cbf3a511705 100644 --- a/include/clang/AST/ASTDiagnostic.h +++ b/include/clang/AST/ASTDiagnostic.h @@ -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 diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h index cad7e61d553c..cbe00827d00a 100644 --- a/include/clang/AST/UnresolvedSet.h +++ b/include/clang/AST/UnresolvedSet.h @@ -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(); } diff --git a/include/clang/Analysis/AnalysisDiagnostic.h b/include/clang/Analysis/AnalysisDiagnostic.h index 114ae74b0c06..e98a3df472a8 100644 --- a/include/clang/Analysis/AnalysisDiagnostic.h +++ b/include/clang/Analysis/AnalysisDiagnostic.h @@ -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 diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h index bf94af6cb60d..6b2912e2e8c2 100644 --- a/include/clang/Basic/Diagnostic.h +++ b/include/clang/Basic/Diagnostic.h @@ -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 { 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; } diff --git a/include/clang/Basic/Diagnostic.td b/include/clang/Basic/Diagnostic.td index 6aa3b438abd8..f6b5d9c5b308 100644 --- a/include/clang/Basic/Diagnostic.td +++ b/include/clang/Basic/Diagnostic.td @@ -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 CategoryName = Name; +} + // Diagnostic Groups. class DiagGroup subgroups = []> { string GroupName = Name; list SubGroups = subgroups; + string CategoryName = ""; } class InGroup { DiagGroup Group = G; } //class IsGroup { DiagGroup Group = DiagGroup; } @@ -48,6 +55,7 @@ class Diagnostic { bit SFINAE = 1; DiagMapping DefaultMapping = defaultmapping; DiagGroup Group; + string CategoryName = ""; } class Error : Diagnostic; diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index c74a48c445fe..1012e91baa77 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -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]>; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 93ab85806540..6b40820da814 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -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">; diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 18b54ef5e072..0badeb9efa54 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -200,6 +200,8 @@ def ftabstop : Separate<"-ftabstop">, MetaVarName<"">, HelpText<"Set the tab stop distance.">; def ferror_limit : Separate<"-ferror-limit">, MetaVarName<"">, HelpText<"Set the maximum number of errors to emit before stopping (0 = no limit).">; +def fmacro_backtrace_limit : Separate<"-fmacro-backtrace-limit">, MetaVarName<"">, + 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<"">, HelpText<"Set the maximum number of entries to print in a template instantiation backtrace (0 = no limit).">; def fmessage_length : Separate<"-fmessage-length">, MetaVarName<"">, diff --git a/include/clang/Driver/DriverDiagnostic.h b/include/clang/Driver/DriverDiagnostic.h index d4a9da7b6d80..c20d807b5811 100644 --- a/include/clang/Driver/DriverDiagnostic.h +++ b/include/clang/Driver/DriverDiagnostic.h @@ -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 diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index 2127e5724f97..f6e69e045444 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -280,6 +280,8 @@ def flat__namespace : Flag<"-flat_namespace">; def flax_vector_conversions : Flag<"-flax-vector-conversions">, Group; def flimited_precision_EQ : Joined<"-flimited-precision=">, Group; def flto : Flag<"-flto">, Group; +def fmacro_backtrace_limit_EQ : Joined<"-fmacro-backtrace-limit=">, + Group; def fmath_errno : Flag<"-fmath-errno">, Group; def fmerge_all_constants : Flag<"-fmerge-all-constants">, Group; def fmessage_length_EQ : Joined<"-fmessage-length=">, Group; diff --git a/include/clang/Frontend/DiagnosticOptions.h b/include/clang/Frontend/DiagnosticOptions.h index 797cb34023db..b4f147bde7b7 100644 --- a/include/clang/Frontend/DiagnosticOptions.h +++ b/include/clang/Frontend/DiagnosticOptions.h @@ -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; } }; diff --git a/include/clang/Frontend/FrontendDiagnostic.h b/include/clang/Frontend/FrontendDiagnostic.h index a044586a8c0a..61ad22cabb0d 100644 --- a/include/clang/Frontend/FrontendDiagnostic.h +++ b/include/clang/Frontend/FrontendDiagnostic.h @@ -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 diff --git a/include/clang/Frontend/TextDiagnosticPrinter.h b/include/clang/Frontend/TextDiagnosticPrinter.h index 336713661a28..ec4392fe5d54 100644 --- a/include/clang/Frontend/TextDiagnosticPrinter.h +++ b/include/clang/Frontend/TextDiagnosticPrinter.h @@ -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 diff --git a/include/clang/Lex/LexDiagnostic.h b/include/clang/Lex/LexDiagnostic.h index a470aa0924fb..2d941e4cf4fe 100644 --- a/include/clang/Lex/LexDiagnostic.h +++ b/include/clang/Lex/LexDiagnostic.h @@ -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 diff --git a/include/clang/Parse/ParseDiagnostic.h b/include/clang/Parse/ParseDiagnostic.h index c702e2fe65b8..d7c5eee8d916 100644 --- a/include/clang/Parse/ParseDiagnostic.h +++ b/include/clang/Parse/ParseDiagnostic.h @@ -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 diff --git a/include/clang/Sema/SemaDiagnostic.h b/include/clang/Sema/SemaDiagnostic.h index d026339b5caf..a5a136427fb9 100644 --- a/include/clang/Sema/SemaDiagnostic.h +++ b/include/clang/Sema/SemaDiagnostic.h @@ -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 diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp index ca62ed12d058..a11e313fa8ae 100644 --- a/lib/AST/StmtDumper.cpp +++ b/lib/AST/StmtDumper.cpp @@ -260,6 +260,13 @@ void StmtDumper::DumpDeclarator(Decl *D) { else ns = ""; OS << '"' << UD->getDeclKindName() << ns << ";\""; + } else if (UsingDecl *UD = dyn_cast(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 1870195ded03..9e6f168f1711 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 db24def216d5..8082b33fd66d 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 4963e73fe464..48ae5113b3af 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(), + 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 ba3a2b47edb4..48198ff5761b 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 f6c805fdcaa0..6afa53868ecc 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 33592501d734..8426f7105be4 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(); CXXRecordDecl *FieldClassDecl = cast(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 176d491bc0ce..5a3916d19ea7 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 8ffdde2aa9b5..729c1dcc15e1 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 28bb17ac3efa..66ed956a22a7 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 << ' '; + } + 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(); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 0e839a9d2d69..a802679b26e1 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 6259b85af480..b9c7d7948f2c 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 c4ab03facb52..869d6df2f094 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(NakedFn)) { if (BO->getOpcode() == BinaryOperator::PtrMemD || BO->getOpcode() == BinaryOperator::PtrMemI) { - if (const FunctionProtoType *FPT = - dyn_cast(BO->getType())) { + if (const FunctionProtoType *FPT + = BO->getType()->getAs()) { QualType ResultTy = FPT->getResultType().getNonReferenceType(); ExprOwningPtr diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 21f2a51040ec..b87fa7d51ea1 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(Method->getType()); + const FunctionProtoType *Proto = Method->getType()->getAs(); if (ConvertArgumentsForCall(&*TheCall, MemExpr, Method, Proto, Args, NumArgs, RParenLoc)) return ExprError(); diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 8b851b21eacd..da8480633d5b 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(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, diff --git a/test/CodeGen/staticinit.c b/test/CodeGen/staticinit.c index cd1f059e570a..8c5cdd05642d 100644 --- a/test/CodeGen/staticinit.c +++ b/test/CodeGen/staticinit.c @@ -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; +} diff --git a/test/CodeGenCXX/reference-in-blocks.cpp b/test/CodeGenCXX/reference-in-blocks.cpp index c020bab0f778..388ec7c4bbca 100644 --- a/test/CodeGenCXX/reference-in-blocks.cpp +++ b/test/CodeGenCXX/reference-in-blocks.cpp @@ -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& ) = ^(range& i){printf("Hello Blocks %d\n", i.get()); }; + + A *a = new A; + a->F(); return 0; } - diff --git a/test/CodeGenObjCXX/ivar-objects.mm b/test/CodeGenObjCXX/ivar-objects.mm index 79c1a397e79e..d0432edf2b29 100644 --- a/test/CodeGenObjCXX/ivar-objects.mm +++ b/test/CodeGenObjCXX/ivar-objects.mm @@ -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 diff --git a/test/Misc/macro-backtrace-limit.c b/test/Misc/macro-backtrace-limit.c new file mode 100644 index 000000000000..bc7a4da93a51 --- /dev/null +++ b/test/Misc/macro-backtrace-limit.c @@ -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)) { } +} diff --git a/test/Sema/function-redecl.c b/test/Sema/function-redecl.c index b8a64af96bcf..633ad214236a 100644 --- a/test/Sema/function-redecl.c +++ b/test/Sema/function-redecl.c @@ -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 *'}} diff --git a/test/SemaCXX/default-assignment-operator.cpp b/test/SemaCXX/default-assignment-operator.cpp index a04de37fcb6a..dee6d131e4ad 100644 --- a/test/SemaCXX/default-assignment-operator.cpp +++ b/test/SemaCXX/default-assignment-operator.cpp @@ -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; } +} diff --git a/test/SemaTemplate/instantiate-function-params.cpp b/test/SemaTemplate/instantiate-function-params.cpp index 45de3425d2a2..54847e419086 100644 --- a/test/SemaTemplate/instantiate-function-params.cpp +++ b/test/SemaTemplate/instantiate-function-params.cpp @@ -76,3 +76,15 @@ namespace PR6990 { { }; } + +namespace InstantiateFunctionTypedef { + template + struct X { + typedef int functype(int, int); + functype func; + }; + + void f(X x) { + (void)x.func(1, 2); + } +}