Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: m-labs/clang-lm32
base: b8cd269
...
head fork: m-labs/clang-lm32
compare: 0fb7454
  • 19 commits
  • 38 files changed
  • 0 commit comments
  • 8 contributors
Commits on Jun 22, 2011
Douglas Gregor Fix typo in comment
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133617 91177308-0d34-0410-b5e6-96231b3b80d8
45ba8a6
Douglas Gregor Give MaterializeTemporaryExpr the exact type of the lvalue it binds
to, including cv-qualifications.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133618 91177308-0d34-0410-b5e6-96231b3b80d8
b4b7b50
Douglas Gregor When binding a reference to an Automatic Reference Counting temporary,
retain/release the temporary object appropriately. Previously, we
would only perform the retain/release operations when the reference
would extend the lifetime of the temporary, but this does the wrong
thing across calls.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133620 91177308-0d34-0410-b5e6-96231b3b80d8
d7b2316
Douglas Gregor Implement the C++0x move optimization for Automatic Reference Counting
objects, so that we steal the retain count of a temporary __strong
pointer (zeroing out that temporary), eliding a retain/release
pair. Addresses <rdar://problem/9364932>.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133621 91177308-0d34-0410-b5e6-96231b3b80d8
d1bd98a
Fariborz Jahanian objc-arc: Allow unbridged cast of retainable object to
integral as it is not transferring ownership.. 
// rdar://9619861


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133622 91177308-0d34-0410-b5e6-96231b3b80d8
8295b7b
Douglas Gregor Try to silence GCC warning
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133623 91177308-0d34-0410-b5e6-96231b3b80d8
34aace8
Eric Christopher Build and use libcompiler_rt whenever possible.
Patch by Jean-Daniel Dupas!


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133624 91177308-0d34-0410-b5e6-96231b3b80d8
3404fe7
@akyrtzi akyrtzi Change "cannot assign retained object.." warning to "assigning retain…
…ed object.."

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133625 91177308-0d34-0410-b5e6-96231b3b80d8
d26fef0
@akyrtzi akyrtzi Put all ARC-related warnings into the "arc" diagnostic group.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133626 91177308-0d34-0410-b5e6-96231b3b80d8
5b27b6d
@akyrtzi akyrtzi [arcmt] Make -Warc-unsafe-retained-assign an error when migrating. rd…
…ar://8939557

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133627 91177308-0d34-0410-b5e6-96231b3b80d8
7bf952e
Douglas Gregor When instantiating a function template declaration that was expressed
via a typedef of a function, make sure to synthesize parameter
declarations. Fixes PR9654 / <rdar://problem/9257497>.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133628 91177308-0d34-0410-b5e6-96231b3b80d8
1d441ee
Douglas Gregor Fix the starting location of the Fix-It note for suspicious precedence
issues between a bitwise operator and a comparison operator. Fixes
<rdar://problem/9637759>.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133630 91177308-0d34-0410-b5e6-96231b3b80d8
b27c7a1
Douglas Gregor Copy diagnostic pragmas to the preprocessed output, from Richard Osbo…
…rne!

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133633 91177308-0d34-0410-b5e6-96231b3b80d8
c09ce12
@klimek klimek Changes ParenListExpr to always require a type.
Removes dead code found in the process.
Adds a test to verify that ParenListExprs do not have NULL types.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133637 91177308-0d34-0410-b5e6-96231b3b80d8
0d9106f
Fariborz Jahanian Alloa catching Objective-C id's being thrown with C++ throw
in Darwin's fragile abi mode.  // rdar://8940528


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133639 91177308-0d34-0410-b5e6-96231b3b80d8
9d96bce
@ddunbar ddunbar test/Unit: Fixup lit.cfg to allow running inside test/Unit (with llvm…
…-config in

path).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133653 91177308-0d34-0410-b5e6-96231b3b80d8
9c7f469
Fariborz Jahanian Issue warning if weak_import attribute is added to an already
declared variable and ignore it. // rdar://9538608


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133654 91177308-0d34-0410-b5e6-96231b3b80d8
d543130
@scshunt scshunt Fix a think-o that amazingly didn't show up until I started writing
implicit move tests.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133655 91177308-0d34-0410-b5e6-96231b3b80d8
ab183df
@sbourdeauducq sbourdeauducq Merge branch 'master' of http://llvm.org/git/clang 0fb7454
Showing with 639 additions and 153 deletions.
  1. +1 −1  include/clang/AST/Expr.h
  2. +3 −2 include/clang/AST/ExprCXX.h
  3. +8 −1 include/clang/Basic/DiagnosticGroups.td
  4. +11 −5 include/clang/Basic/DiagnosticSemaKinds.td
  5. +1 −1  include/clang/Basic/Specifiers.h
  6. +37 −0 include/clang/Lex/PPCallbacks.h
  7. +2 −0  lib/ARCMigrate/ARCMT.cpp
  8. +3 −3 lib/AST/Expr.cpp
  9. +1 −1  lib/CodeGen/CGException.cpp
  10. +65 −32 lib/CodeGen/CGExpr.cpp
  11. +69 −4 lib/CodeGen/CGObjC.cpp
  12. +2 −2 lib/CodeGen/CGObjCGNU.cpp
  13. +14 −8 lib/CodeGen/CGObjCMac.cpp
  14. +2 −1  lib/CodeGen/CGObjCRuntime.h
  15. +55 −2 lib/CodeGen/CodeGenFunction.h
  16. +19 −18 lib/Driver/ToolChains.cpp
  17. +4 −2 lib/Driver/ToolChains.h
  18. +44 −0 lib/Frontend/PrintPreprocessedOutput.cpp
  19. +13 −4 lib/Lex/Pragma.cpp
  20. +9 −4 lib/Sema/SemaDecl.cpp
  21. +17 −26 lib/Sema/SemaDeclCXX.cpp
  22. +4 −2 lib/Sema/SemaExpr.cpp
  23. +1 −1  lib/Sema/SemaExprObjC.cpp
  24. +13 −14 lib/Sema/SemaInit.cpp
  25. +1 −1  lib/Sema/SemaLookup.cpp
  26. +20 −3 lib/Sema/SemaTemplateInstantiateDecl.cpp
  27. +1 −1  runtime/compiler-rt/Makefile
  28. +12 −0 test/ARCMT/checking.m
  29. +1 −1  test/CodeGen/attr-weak-import.c
  30. +63 −0 test/CodeGenObjCXX/arc-move.mm
  31. +30 −0 test/CodeGenObjCXX/arc-references.mm
  32. +33 −0 test/CodeGenObjCXX/catch-id-type.mm
  33. +26 −0 test/Preprocessor/pragma_diagnostic_output.c
  34. +4 −0 test/Sema/attr-weak.c
  35. +17 −0 test/Sema/paren-list-expr-type.cpp
  36. +13 −4 test/SemaObjC/arc.m
  37. +11 −0 test/SemaTemplate/instantiate-function-2.cpp
  38. +9 −9 test/Unit/lit.cfg
View
2  include/clang/AST/Expr.h
@@ -3750,7 +3750,7 @@ class ParenListExpr : public Expr {
public:
ParenListExpr(ASTContext& C, SourceLocation lparenloc, Expr **exprs,
- unsigned numexprs, SourceLocation rparenloc);
+ unsigned numexprs, SourceLocation rparenloc, QualType T);
/// \brief Build an empty paren list.
explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { }
View
5 include/clang/AST/ExprCXX.h
@@ -3013,8 +3013,9 @@ class MaterializeTemporaryExpr : public Expr {
friend class ASTStmtWriter;
public:
- MaterializeTemporaryExpr(Expr *Temporary, bool BoundToLvalueReference)
- : Expr(MaterializeTemporaryExprClass, Temporary->getType(),
+ MaterializeTemporaryExpr(QualType T, Expr *Temporary,
+ bool BoundToLvalueReference)
+ : Expr(MaterializeTemporaryExprClass, T,
BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary,
Temporary->isTypeDependent(), Temporary->isValueDependent(),
Temporary->containsUnexpandedParameterPack()),
View
9 include/clang/Basic/DiagnosticGroups.td
@@ -171,7 +171,14 @@ def CustomAtomic : DiagGroup<"custom-atomic-properties">;
def AtomicProperties : DiagGroup<"atomic-properties",
[ImplicitAtomic, CustomAtomic]>;
def AutomaticReferenceCountingABI : DiagGroup<"arc-abi">;
-def AutomaticReferenceCounting : DiagGroup<"arc", [AutomaticReferenceCountingABI]>;
+def ARCUnsafeRetainedAssign : DiagGroup<"arc-unsafe-retained-assign">;
+def ARCRetainCycles : DiagGroup<"arc-retain-cycles">;
+def ARCNonPodMemAccess : DiagGroup<"arc-non-pod-memaccess">;
+def AutomaticReferenceCounting : DiagGroup<"arc",
+ [AutomaticReferenceCountingABI,
+ ARCUnsafeRetainedAssign,
+ ARCRetainCycles,
+ ARCNonPodMemAccess]>;
def Selector : DiagGroup<"selector">;
def NonfragileAbi2 : DiagGroup<"nonfragile-abi2">;
def Protocol : DiagGroup<"protocol">;
View
16 include/clang/Basic/DiagnosticSemaKinds.td
@@ -2287,6 +2287,8 @@ def err_inline_declaration_block_scope : Error<
"inline declaration of %0 not allowed in block scope">;
def err_static_non_static : Error<
"static declaration of %0 follows non-static declaration">;
+def warn_weak_import : Warning <
+ "an already-declared variable is made a weak_import declaration %0">;
def warn_static_non_static : ExtWarn<
"static declaration of %0 follows non-static declaration">;
def err_non_static_static : Error<
@@ -2597,7 +2599,8 @@ def warn_arc_non_pod_class_with_object_member : Warning<
"to make it ABI-compatible">, InGroup<AutomaticReferenceCountingABI>,
DefaultIgnore;
def warn_arc_retained_assign : Warning<
- "cannot assign retained object to %select{weak|unsafe_unretained}0 variable">;
+ "assigning retained object to %select{weak|unsafe_unretained}0 variable">,
+ InGroup<ARCUnsafeRetainedAssign>;
def warn_arc_trivial_member_function_with_object_member : Warning<
"%0 cannot be shared between ARC and non-ARC "
"code; add a non-trivial %select{copy constructor|copy assignment operator|"
@@ -2641,7 +2644,7 @@ def err_arc_multiple_method_decl : Error<
"parameter type or attributes">;
def warn_arc_retain_cycle : Warning<
"capturing %0 strongly in this block is likely to lead to a retain cycle">,
- InGroup<DiagGroup<"retain-cycles">>;
+ InGroup<ARCRetainCycles>;
def note_arc_retain_cycle_owner : Note<
"block will be retained by %select{the captured object|an object strongly "
"retained by the captured object}0">;
@@ -2650,7 +2653,7 @@ def note_nontrivial_objc_lifetime : Note<
"lifetime">;
def warn_arc_object_memaccess : Warning<
"%select{destination for|source of}0 this %1 call is a pointer to "
- "lifetime-qualified type %2">, InGroup<DiagGroup<"non-pod-memaccess">>;
+ "lifetime-qualified type %2">, InGroup<ARCNonPodMemAccess>;
def err_arc_strong_property_lifetime : Error<
"existing ivar %1 for strong property %0 may not be "
@@ -3150,9 +3153,12 @@ def err_qualified_objc_catch_parm : Error<
"@catch parameter declarator cannot be qualified">;
def err_objc_pointer_cxx_catch_gnu : Error<
"can't catch Objective C exceptions in C++ in the GNU runtime">;
-def err_objc_pointer_cxx_catch_fragile : Error<
- "can't catch Objective C exceptions in C++ in the non-unified "
+def warn_objc_pointer_cxx_catch_fragile : Warning<
+ "catching Objective C id's exceptions in C++ in the non-unified "
"exception model">;
+def err_objc_pointer_cxx_catch_fragile : Error<
+"can't catch Objective C exceptions in C++ in the non-unified "
+"exception model">;
def err_objc_object_catch : Error<
"can't catch an Objective C object by value">;
def err_incomplete_type_objc_at_encode : Error<
View
2  include/clang/Basic/Specifiers.h
@@ -83,7 +83,7 @@ namespace clang {
/// ExprValueKind - The categorization of expression values,
/// currently following the C++0x scheme.
enum ExprValueKind {
- /// An r-value expression (a gr-value in the C++0x taxonomy)
+ /// An r-value expression (a pr-value in the C++0x taxonomy)
/// produces a temporary value.
VK_RValue,
View
37 include/clang/Lex/PPCallbacks.h
@@ -16,6 +16,7 @@
#include "clang/Lex/DirectoryLookup.h"
#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/DiagnosticIDs.h"
#include "llvm/ADT/StringRef.h"
#include <string>
@@ -124,6 +125,24 @@ class PPCallbacks {
virtual void PragmaMessage(SourceLocation Loc, llvm::StringRef Str) {
}
+ /// PragmaDiagnosticPush - This callback is invoked when a
+ /// #pragma gcc dianostic push directive is read.
+ virtual void PragmaDiagnosticPush(SourceLocation Loc,
+ llvm::StringRef Namespace) {
+ }
+
+ /// PragmaDiagnosticPop - This callback is invoked when a
+ /// #pragma gcc dianostic pop directive is read.
+ virtual void PragmaDiagnosticPop(SourceLocation Loc,
+ llvm::StringRef Namespace) {
+ }
+
+ /// PragmaDiagnostic - This callback is invoked when a
+ /// #pragma gcc dianostic directive is read.
+ virtual void PragmaDiagnostic(SourceLocation Loc, llvm::StringRef Namespace,
+ diag::Mapping mapping, llvm::StringRef Str) {
+ }
+
/// MacroExpands - This is called by
/// Preprocessor::HandleMacroExpandedIdentifier when a macro invocation is
/// found.
@@ -232,6 +251,24 @@ class PPChainedCallbacks : public PPCallbacks {
Second->PragmaMessage(Loc, Str);
}
+ virtual void PragmaDiagnosticPush(SourceLocation Loc,
+ llvm::StringRef Namespace) {
+ First->PragmaDiagnosticPush(Loc, Namespace);
+ Second->PragmaDiagnosticPush(Loc, Namespace);
+ }
+
+ virtual void PragmaDiagnosticPop(SourceLocation Loc,
+ llvm::StringRef Namespace) {
+ First->PragmaDiagnosticPop(Loc, Namespace);
+ Second->PragmaDiagnosticPop(Loc, Namespace);
+ }
+
+ virtual void PragmaDiagnostic(SourceLocation Loc, llvm::StringRef Namespace,
+ diag::Mapping mapping, llvm::StringRef Str) {
+ First->PragmaDiagnostic(Loc, Namespace, mapping, Str);
+ Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
+ }
+
virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI) {
First->MacroExpands(MacroNameTok, MI);
Second->MacroExpands(MacroNameTok, MI);
View
2  lib/ARCMigrate/ARCMT.cpp
@@ -187,6 +187,8 @@ CompilerInvocation *createInvocationForMigration(CompilerInvocation &origCI) {
CInvok->getPreprocessorOpts().addMacroDef(define);
CInvok->getLangOpts().ObjCAutoRefCount = true;
CInvok->getDiagnosticOpts().ErrorLimit = 0;
+ CInvok->getDiagnosticOpts().Warnings.push_back(
+ "error=arc-unsafe-retained-assign");
CInvok->getLangOpts().ObjCNoAutoRefCountRuntime = !HasARCRuntime(origCI);
return CInvok.take();
View
6 lib/AST/Expr.cpp
@@ -3033,11 +3033,11 @@ void DesignatedInitExpr::ExpandDesignator(ASTContext &C, unsigned Idx,
ParenListExpr::ParenListExpr(ASTContext& C, SourceLocation lparenloc,
Expr **exprs, unsigned nexprs,
- SourceLocation rparenloc)
- : Expr(ParenListExprClass, QualType(), VK_RValue, OK_Ordinary,
+ SourceLocation rparenloc, QualType T)
+ : Expr(ParenListExprClass, T, VK_RValue, OK_Ordinary,
false, false, false),
NumExprs(nexprs), LParenLoc(lparenloc), RParenLoc(rparenloc) {
-
+ assert(!T.isNull() && "ParenListExpr must have a valid type");
Exprs = new (C) Stmt*[nexprs];
for (unsigned i = 0; i != nexprs; ++i) {
if (exprs[i]->isTypeDependent())
View
2  lib/CodeGen/CGException.cpp
@@ -521,7 +521,7 @@ void CodeGenFunction::EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
llvm::Value *TypeInfo = 0;
if (CaughtType->isObjCObjectPointerType())
- TypeInfo = CGM.getObjCRuntime().GetEHType(CaughtType);
+ TypeInfo = CGM.getObjCRuntime().GetEHType(CaughtType, this);
else
TypeInfo = CGM.GetAddrOfRTTIDescriptor(CaughtType, /*ForEH=*/true);
CatchScope->setHandler(I, TypeInfo, Handler);
View
97 lib/CodeGen/CGExpr.cpp
@@ -205,11 +205,21 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
const CXXDestructorDecl *&ReferenceTemporaryDtor,
QualType &ObjCARCReferenceLifetimeType,
const NamedDecl *InitializedDecl) {
- ObjCARCReferenceLifetimeType = QualType();
-
// Look through expressions for materialized temporaries (for now).
- if (isa<MaterializeTemporaryExpr>(E))
- E = cast<MaterializeTemporaryExpr>(E)->GetTemporaryExpr();
+ if (const MaterializeTemporaryExpr *M
+ = dyn_cast<MaterializeTemporaryExpr>(E)) {
+ // Objective-C++ ARC:
+ // If we are binding a reference to a temporary that has ownership, we
+ // need to perform retain/release operations on the temporary.
+ if (CGF.getContext().getLangOptions().ObjCAutoRefCount &&
+ E->getType()->isObjCLifetimeType() &&
+ (E->getType().getObjCLifetime() == Qualifiers::OCL_Strong ||
+ E->getType().getObjCLifetime() == Qualifiers::OCL_Weak ||
+ E->getType().getObjCLifetime() == Qualifiers::OCL_Autoreleasing))
+ ObjCARCReferenceLifetimeType = E->getType();
+
+ E = M->GetTemporaryExpr();
+ }
if (const CXXDefaultArgExpr *DAE = dyn_cast<CXXDefaultArgExpr>(E))
E = DAE->getExpr();
@@ -243,6 +253,57 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
// We have to load the lvalue.
RV = CGF.EmitLoadOfLValue(LV, E->getType());
} else {
+ if (!ObjCARCReferenceLifetimeType.isNull()) {
+ ReferenceTemporary = CreateReferenceTemporary(CGF,
+ ObjCARCReferenceLifetimeType,
+ InitializedDecl);
+
+
+ LValue RefTempDst = CGF.MakeAddrLValue(ReferenceTemporary,
+ ObjCARCReferenceLifetimeType);
+
+ CGF.EmitScalarInit(E, dyn_cast_or_null<ValueDecl>(InitializedDecl),
+ RefTempDst, false);
+
+ bool ExtendsLifeOfTemporary = false;
+ if (const VarDecl *Var = dyn_cast_or_null<VarDecl>(InitializedDecl)) {
+ if (Var->extendsLifetimeOfTemporary())
+ ExtendsLifeOfTemporary = true;
+ } else if (InitializedDecl && isa<FieldDecl>(InitializedDecl)) {
+ ExtendsLifeOfTemporary = true;
+ }
+
+ if (!ExtendsLifeOfTemporary) {
+ // Since the lifetime of this temporary isn't going to be extended,
+ // we need to clean it up ourselves at the end of the full expression.
+ switch (ObjCARCReferenceLifetimeType.getObjCLifetime()) {
+ case Qualifiers::OCL_None:
+ case Qualifiers::OCL_ExplicitNone:
+ case Qualifiers::OCL_Autoreleasing:
+ break;
+
+ case Qualifiers::OCL_Strong:
+ CGF.PushARCReleaseCleanup(CGF.getARCCleanupKind(),
+ ObjCARCReferenceLifetimeType,
+ ReferenceTemporary,
+ /*Precise lifetime=*/false,
+ /*For full expression=*/true);
+ break;
+
+ case Qualifiers::OCL_Weak:
+ CGF.PushARCWeakReleaseCleanup(NormalAndEHCleanup,
+ ObjCARCReferenceLifetimeType,
+ ReferenceTemporary,
+ /*For full expression=*/true);
+ break;
+ }
+
+ ObjCARCReferenceLifetimeType = QualType();
+ }
+
+ return ReferenceTemporary;
+ }
+
llvm::SmallVector<SubobjectAdjustment, 2> Adjustments;
while (true) {
E = E->IgnoreParens();
@@ -298,34 +359,6 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
if (!ClassDecl->hasTrivialDestructor())
ReferenceTemporaryDtor = ClassDecl->getDestructor();
}
- else if (CGF.getContext().getLangOptions().ObjCAutoRefCount) {
- if (const ValueDecl *InitVD = dyn_cast<ValueDecl>(InitializedDecl)) {
- if (const ReferenceType *RefType
- = InitVD->getType()->getAs<ReferenceType>()) {
- QualType PointeeType = RefType->getPointeeType();
- if (PointeeType->isObjCLifetimeType() &&
- PointeeType.getObjCLifetime() != Qualifiers::OCL_ExplicitNone) {
- // Objective-C++ ARC: We're binding a reference to
- // lifetime-qualified type to a temporary, so we need to extend
- // the lifetime of the temporary with appropriate retain/release/
- // autorelease calls.
- ObjCARCReferenceLifetimeType = PointeeType;
-
- // Create a temporary variable that we can bind the reference to.
- ReferenceTemporary = CreateReferenceTemporary(CGF, PointeeType,
- InitializedDecl);
-
- unsigned Alignment =
- CGF.getContext().getTypeAlignInChars(PointeeType).getQuantity();
- LValue lvalue =
- CGF.MakeAddrLValue(ReferenceTemporary, PointeeType, Alignment);
-
- CGF.EmitScalarInit(E, InitVD, lvalue, false);
- return ReferenceTemporary;
- }
- }
- }
- }
}
RV = CGF.EmitAnyExpr(E, AggSlot);
View
73 lib/CodeGen/CGObjC.cpp
@@ -1985,6 +1985,22 @@ namespace {
CallReleaseForObject(QualType type, llvm::Value *addr, bool precise)
: ObjCReleasingCleanup(type, addr), precise(precise) {}
+ using ObjCReleasingCleanup::Emit;
+ static void Emit(CodeGenFunction &CGF, bool IsForEH,
+ QualType type, llvm::Value *addr, bool precise) {
+ // EHScopeStack::Cleanup objects can never have their destructors called,
+ // so use placement new to construct our temporary object.
+ union {
+ void* align;
+ char data[sizeof(CallReleaseForObject)];
+ };
+
+ CallReleaseForObject *Object
+ = new (&align) CallReleaseForObject(type, addr, precise);
+ Object->Emit(CGF, IsForEH);
+ (void)data[0];
+ }
+
void release(CodeGenFunction &CGF, QualType type, llvm::Value *addr) {
llvm::Value *ptr = CGF.Builder.CreateLoad(addr, "tmp");
CGF.EmitARCRelease(ptr, precise);
@@ -2033,6 +2049,22 @@ namespace {
CallWeakReleaseForObject(QualType type, llvm::Value *addr)
: ObjCReleasingCleanup(type, addr) {}
+ using ObjCReleasingCleanup::Emit;
+ static void Emit(CodeGenFunction &CGF, bool IsForEH,
+ QualType type, llvm::Value *addr) {
+ // EHScopeStack::Cleanup objects can never have their destructors called,
+ // so use placement new to construct our temporary object.
+ union {
+ void* align;
+ char data[sizeof(CallWeakReleaseForObject)];
+ };
+
+ CallWeakReleaseForObject *Object
+ = new (&align) CallWeakReleaseForObject(type, addr);
+ Object->Emit(CGF, IsForEH);
+ (void)data[0];
+ }
+
void release(CodeGenFunction &CGF, QualType type, llvm::Value *addr) {
CGF.EmitARCDestroyWeak(addr);
}
@@ -2099,16 +2131,24 @@ void CodeGenFunction::EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr) {
void CodeGenFunction::PushARCReleaseCleanup(CleanupKind cleanupKind,
QualType type,
llvm::Value *addr,
- bool precise) {
- EHStack.pushCleanup<CallReleaseForObject>(cleanupKind, type, addr, precise);
+ bool precise,
+ bool forFullExpr) {
+ if (forFullExpr)
+ pushFullExprCleanup<CallReleaseForObject>(cleanupKind, type, addr, precise);
+ else
+ EHStack.pushCleanup<CallReleaseForObject>(cleanupKind, type, addr, precise);
}
/// PushARCWeakReleaseCleanup - Enter a cleanup to perform a weak
/// release on the given object or array of objects.
void CodeGenFunction::PushARCWeakReleaseCleanup(CleanupKind cleanupKind,
QualType type,
- llvm::Value *addr) {
- EHStack.pushCleanup<CallWeakReleaseForObject>(cleanupKind, type, addr);
+ llvm::Value *addr,
+ bool forFullExpr) {
+ if (forFullExpr)
+ pushFullExprCleanup<CallWeakReleaseForObject>(cleanupKind, type, addr);
+ else
+ EHStack.pushCleanup<CallWeakReleaseForObject>(cleanupKind, type, addr);
}
/// PushARCReleaseCleanup - Enter a cleanup to perform a release on a
@@ -2230,6 +2270,31 @@ tryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e) {
// ultimate opaque expression.
const llvm::Type *resultType = 0;
+ // If we're loading retained from a __strong xvalue, we can avoid
+ // an extra retain/release pair by zeroing out the source of this
+ // "move" operation.
+ if (e->isXValue() &&
+ e->getType().getObjCLifetime() == Qualifiers::OCL_Strong) {
+ // Emit the lvalue
+ LValue lv = CGF.EmitLValue(e);
+
+ // Load the object pointer and cast it to the appropriate type.
+ QualType exprType = e->getType();
+ llvm::Value *result = CGF.EmitLoadOfLValue(lv, exprType).getScalarVal();
+
+ if (resultType)
+ result = CGF.Builder.CreateBitCast(result, resultType);
+
+ // Set the source pointer to NULL.
+ llvm::Value *null
+ = llvm::ConstantPointerNull::get(
+ cast<llvm::PointerType>(CGF.ConvertType(exprType)));
+ CGF.EmitStoreOfScalar(null, lv.getAddress(), lv.isVolatileQualified(),
+ lv.getAlignment(), exprType);
+
+ return TryEmitResult(result, true);
+ }
+
while (true) {
e = e->IgnoreParens();
View
4 lib/CodeGen/CGObjCGNU.cpp
@@ -438,7 +438,7 @@ class CGObjCGNU : public CGObjCRuntime {
bool lval = false);
virtual llvm::Value *GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
*Method);
- virtual llvm::Constant *GetEHType(QualType T);
+ virtual llvm::Constant *GetEHType(QualType T, const CodeGenFunction *CGF=0);
virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
const ObjCContainerDecl *CD);
@@ -832,7 +832,7 @@ llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
return GetSelector(Builder, Method->getSelector(), SelTypes, false);
}
-llvm::Constant *CGObjCGNU::GetEHType(QualType T) {
+llvm::Constant *CGObjCGNU::GetEHType(QualType T, const CodeGenFunction *CGF) {
if (!CGM.getLangOptions().CPlusPlus) {
if (T->isObjCIdType()
|| T->isObjCQualifiedIdType()) {
View
22 lib/CodeGen/CGObjCMac.cpp
@@ -200,7 +200,7 @@ class ObjCCommonTypesHelper {
const llvm::Type *CacheTy;
/// CachePtrTy - LLVM type for struct objc_cache *.
const llvm::Type *CachePtrTy;
-
+
llvm::Constant *getGetPropertyFn() {
CodeGen::CodeGenTypes &Types = CGM.getTypes();
ASTContext &Ctx = CGM.getContext();
@@ -452,7 +452,7 @@ class ObjCTypesHelper : public ObjCCommonTypesHelper {
/// ExceptionDataTy - LLVM type for struct _objc_exception_data.
const llvm::Type *ExceptionDataTy;
-
+
/// ExceptionTryEnterFn - LLVM objc_exception_try_enter function.
llvm::Constant *getExceptionTryEnterFn() {
const llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
@@ -633,7 +633,7 @@ class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper {
const llvm::StructType *EHTypeTy;
const llvm::Type *EHTypePtrTy;
-
+
ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);
~ObjCNonFragileABITypesHelper(){}
};
@@ -1010,7 +1010,7 @@ class CGObjCMac : public CGObjCCommonMac {
virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
const ObjCMethodDecl *Method);
- virtual llvm::Constant *GetEHType(QualType T);
+ virtual llvm::Constant *GetEHType(QualType T, const CodeGenFunction *CGF=0);
virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
@@ -1271,7 +1271,7 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
const ObjCProtocolDecl *PD);
- virtual llvm::Constant *GetEHType(QualType T);
+ virtual llvm::Constant *GetEHType(QualType T, const CodeGenFunction *CGF=0);
virtual llvm::Constant *GetPropertyGetFunction() {
return ObjCTypes.getGetPropertyFn();
@@ -1414,7 +1414,12 @@ llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
return EmitSelector(Builder, Method->getSelector());
}
-llvm::Constant *CGObjCMac::GetEHType(QualType T) {
+llvm::Constant *CGObjCMac::GetEHType(QualType T, const CodeGenFunction *CGF) {
+ if (T->isObjCIdType() ||
+ T->isObjCQualifiedIdType()) {
+ return CGM.GetAddrOfRTTIDescriptor(
+ CGF->getContext().ObjCIdRedefinitionType, /*ForEH=*/true);
+ }
llvm_unreachable("asking for catch type for ObjC type in fragile runtime");
return 0;
}
@@ -4176,6 +4181,7 @@ ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
CacheTy = llvm::OpaqueType::get(VMContext);
CGM.getModule().addTypeName("struct._objc_cache", CacheTy);
CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
+
}
ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
@@ -4580,7 +4586,7 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul
// SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy);
-
+
// struct objc_typeinfo {
// const void** vtable; // objc_ehtype_vtable + 2
@@ -6015,7 +6021,7 @@ CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
}
llvm::Constant *
-CGObjCNonFragileABIMac::GetEHType(QualType T) {
+CGObjCNonFragileABIMac::GetEHType(QualType T, const CodeGenFunction *CGF) {
// There's a particular fixed type info for 'id'.
if (T->isObjCIdType() ||
T->isObjCQualifiedIdType()) {
View
3  lib/CodeGen/CGObjCRuntime.h
@@ -128,7 +128,8 @@ class CGObjCRuntime {
/// This is used externally to implement catching ObjC types in C++.
/// Runtimes which don't support this should add the appropriate
/// error to Sema.
- virtual llvm::Constant *GetEHType(QualType T) = 0;
+ virtual llvm::Constant *GetEHType(QualType T,
+ const CodeGenFunction *CGF=0) = 0;
/// Generate a constant string object.
virtual llvm::Constant *GenerateConstantString(const StringLiteral *) = 0;
View
57 lib/CodeGen/CodeGenFunction.h
@@ -223,6 +223,16 @@ class EHScopeStack {
}
};
+ template <class T, class A0, class A1, class A2>
+ class UnconditionalCleanup3 : public Cleanup {
+ A0 a0; A1 a1; A2 a2;
+ public:
+ UnconditionalCleanup3(A0 a0, A1 a1, A2 a2) : a0(a0), a1(a1), a2(a2) {}
+ void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) {
+ T::Emit(CGF, IsForEHCleanup, a0, a1, a2);
+ }
+ };
+
/// ConditionalCleanupN stores the saved form of its N parameters,
/// then restores them and performs the cleanup.
template <class T, class A0>
@@ -258,6 +268,27 @@ class EHScopeStack {
: a0_saved(a0), a1_saved(a1) {}
};
+ template <class T, class A0, class A1, class A2>
+ class ConditionalCleanup3 : public Cleanup {
+ typedef typename DominatingValue<A0>::saved_type A0_saved;
+ typedef typename DominatingValue<A1>::saved_type A1_saved;
+ typedef typename DominatingValue<A2>::saved_type A2_saved;
+ A0_saved a0_saved;
+ A1_saved a1_saved;
+ A2_saved a2_saved;
+
+ void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) {
+ A0 a0 = DominatingValue<A0>::restore(CGF, a0_saved);
+ A1 a1 = DominatingValue<A1>::restore(CGF, a1_saved);
+ A2 a2 = DominatingValue<A2>::restore(CGF, a2_saved);
+ T::Emit(CGF, IsForEHCleanup, a0, a1, a2);
+ }
+
+ public:
+ ConditionalCleanup3(A0_saved a0, A1_saved a1, A2_saved a2)
+ : a0_saved(a0), a1_saved(a1), a2_saved(a2) {}
+ };
+
private:
// The implementation for this class is in CGException.h and
// CGException.cpp; the definition is here because it's used as a
@@ -697,6 +728,27 @@ class CodeGenFunction : public CodeGenTypeCache {
initFullExprCleanup();
}
+ /// pushFullExprCleanup - Push a cleanup to be run at the end of the
+ /// current full-expression. Safe against the possibility that
+ /// we're currently inside a conditionally-evaluated expression.
+ template <class T, class A0, class A1, class A2>
+ void pushFullExprCleanup(CleanupKind kind, A0 a0, A1 a1, A2 a2) {
+ // If we're not in a conditional branch, or if none of the
+ // arguments requires saving, then use the unconditional cleanup.
+ if (!isInConditionalBranch()) {
+ typedef EHScopeStack::UnconditionalCleanup3<T, A0, A1, A2> CleanupType;
+ return EHStack.pushCleanup<CleanupType>(kind, a0, a1, a2);
+ }
+
+ typename DominatingValue<A0>::saved_type a0_saved = saveValueInCond(a0);
+ typename DominatingValue<A1>::saved_type a1_saved = saveValueInCond(a1);
+ typename DominatingValue<A2>::saved_type a2_saved = saveValueInCond(a2);
+
+ typedef EHScopeStack::ConditionalCleanup3<T, A0, A1, A2> CleanupType;
+ EHStack.pushCleanup<CleanupType>(kind, a0_saved, a1_saved, a2_saved);
+ initFullExprCleanup();
+ }
+
/// PushDestructorCleanup - Push a cleanup to call the
/// complete-object destructor of an object of the given type at the
/// given address. Does nothing if T is not a C++ class type with a
@@ -2036,9 +2088,10 @@ class CodeGenFunction : public CodeGenTypeCache {
llvm::Value *EmitARCRetainAutoreleaseScalarExpr(const Expr *expr);
void PushARCReleaseCleanup(CleanupKind kind, QualType type,
- llvm::Value *addr, bool precise);
+ llvm::Value *addr, bool precise,
+ bool forFullExpr = false);
void PushARCWeakReleaseCleanup(CleanupKind kind, QualType type,
- llvm::Value *addr);
+ llvm::Value *addr, bool forFullExpr = false);
void PushARCFieldReleaseCleanup(CleanupKind cleanupKind,
const FieldDecl *Field);
void PushARCFieldWeakReleaseCleanup(CleanupKind cleanupKind,
View
37 lib/Driver/ToolChains.cpp
@@ -365,6 +365,21 @@ void DarwinClang::AddLinkARCArgs(const ArgList &Args,
CmdArgs.push_back(Args.MakeArgString(s));
}
+void DarwinClang::AddLinkRuntimeLib(const ArgList &Args,
+ ArgStringList &CmdArgs,
+ const char *DarwinStaticLib) const {
+ llvm::sys::Path P(getDriver().ResourceDir);
+ P.appendComponent("lib");
+ P.appendComponent("darwin");
+ P.appendComponent(DarwinStaticLib);
+
+ // For now, allow missing resource libraries to support developers who may
+ // not have compiler-rt checked out or integrated into their build.
+ bool Exists;
+ if (!llvm::sys::fs::exists(P.str(), Exists) && Exists)
+ CmdArgs.push_back(Args.MakeArgString(P.str()));
+}
+
void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
// Darwin doesn't support real static executables, don't link any runtime
@@ -386,7 +401,6 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
CmdArgs.push_back("-lSystem");
// Select the dynamic runtime library and the target specific static library.
- const char *DarwinStaticLib = 0;
if (isTargetIPhoneOS()) {
// If we are compiling as iOS / simulator, don't attempt to link libgcc_s.1,
// it never went into the SDK.
@@ -394,7 +408,7 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
CmdArgs.push_back("-lgcc_s.1");
// We currently always need a static runtime library for iOS.
- DarwinStaticLib = "libclang_rt.ios.a";
+ AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ios.a");
} else {
// The dynamic runtime library was merged with libSystem for 10.6 and
// beyond; only 10.4 and 10.5 need an additional runtime library.
@@ -412,26 +426,13 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
// libSystem. Therefore, we still must provide a runtime library just for
// the tiny tiny handful of projects that *might* use that symbol.
if (isMacosxVersionLT(10, 5)) {
- DarwinStaticLib = "libclang_rt.10.4.a";
+ AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.10.4.a");
} else {
if (getTriple().getArch() == llvm::Triple::x86)
- DarwinStaticLib = "libclang_rt.eprintf.a";
+ AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.eprintf.a");
+ AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.osx.a");
}
}
-
- /// Add the target specific static library, if needed.
- if (DarwinStaticLib) {
- llvm::sys::Path P(getDriver().ResourceDir);
- P.appendComponent("lib");
- P.appendComponent("darwin");
- P.appendComponent(DarwinStaticLib);
-
- // For now, allow missing resource libraries to support developers who may
- // not have compiler-rt checked out or integrated into their build.
- bool Exists;
- if (!llvm::sys::fs::exists(P.str(), Exists) && Exists)
- CmdArgs.push_back(Args.MakeArgString(P.str()));
- }
}
static inline llvm::StringRef SimulatorVersionDefineName() {
View
6 lib/Driver/ToolChains.h
@@ -175,7 +175,7 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public ToolChain {
/// runtime library.
virtual void AddLinkRuntimeLibArgs(const ArgList &Args,
ArgStringList &CmdArgs) const = 0;
-
+
/// }
/// @name ToolChain Implementation
/// {
@@ -266,7 +266,9 @@ class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin {
virtual void AddLinkRuntimeLibArgs(const ArgList &Args,
ArgStringList &CmdArgs) const;
-
+ void AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs,
+ const char *DarwinStaticLib) const;
+
virtual void AddCXXStdlibLibArgs(const ArgList &Args,
ArgStringList &CmdArgs) const;
View
44 lib/Frontend/PrintPreprocessedOutput.cpp
@@ -26,6 +26,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Config/config.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/ErrorHandling.h"
#include <cstdio>
using namespace clang;
@@ -122,6 +123,12 @@ class PrintPPOutputPPCallbacks : public PPCallbacks {
virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
const std::string &Str);
virtual void PragmaMessage(SourceLocation Loc, llvm::StringRef Str);
+ virtual void PragmaDiagnosticPush(SourceLocation Loc,
+ llvm::StringRef Namespace);
+ virtual void PragmaDiagnosticPop(SourceLocation Loc,
+ llvm::StringRef Namespace);
+ virtual void PragmaDiagnostic(SourceLocation Loc, llvm::StringRef Namespace,
+ diag::Mapping Map, llvm::StringRef Str);
bool HandleFirstTokOnLine(Token &Tok);
bool MoveToLine(SourceLocation Loc) {
@@ -361,6 +368,43 @@ void PrintPPOutputPPCallbacks::PragmaMessage(SourceLocation Loc,
EmittedTokensOnThisLine = true;
}
+void PrintPPOutputPPCallbacks::
+PragmaDiagnosticPush(SourceLocation Loc, llvm::StringRef Namespace) {
+ MoveToLine(Loc);
+ OS << "#pragma " << Namespace << " diagnostic push";
+ EmittedTokensOnThisLine = true;
+}
+
+void PrintPPOutputPPCallbacks::
+PragmaDiagnosticPop(SourceLocation Loc, llvm::StringRef Namespace) {
+ MoveToLine(Loc);
+ OS << "#pragma " << Namespace << " diagnostic pop";
+ EmittedTokensOnThisLine = true;
+}
+
+void PrintPPOutputPPCallbacks::
+PragmaDiagnostic(SourceLocation Loc, llvm::StringRef Namespace,
+ diag::Mapping Map, llvm::StringRef Str) {
+ MoveToLine(Loc);
+ OS << "#pragma " << Namespace << " diagnostic ";
+ switch (Map) {
+ default: llvm_unreachable("unexpected diagnostic kind");
+ case diag::MAP_WARNING:
+ OS << "warning";
+ break;
+ case diag::MAP_ERROR:
+ OS << "error";
+ break;
+ case diag::MAP_IGNORE:
+ OS << "ignored";
+ break;
+ case diag::MAP_FATAL:
+ OS << "fatal";
+ break;
+ }
+ OS << " \"" << Str << '"';
+ EmittedTokensOnThisLine = true;
+}
/// HandleFirstTokOnLine - When emitting a preprocessed file in -E mode, this
/// is called for the first token on each new line. If this really is the start
View
17 lib/Lex/Pragma.cpp
@@ -836,8 +836,11 @@ struct PragmaDebugHandler : public PragmaHandler {
/// PragmaDiagnosticHandler - e.g. '#pragma GCC diagnostic ignored "-Wformat"'
struct PragmaDiagnosticHandler : public PragmaHandler {
+private:
+ const char *Namespace;
public:
- explicit PragmaDiagnosticHandler() : PragmaHandler("diagnostic") {}
+ explicit PragmaDiagnosticHandler(const char *NS) :
+ PragmaHandler("diagnostic"), Namespace(NS) {}
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
Token &DiagToken) {
SourceLocation DiagLoc = DiagToken.getLocation();
@@ -848,6 +851,7 @@ struct PragmaDiagnosticHandler : public PragmaHandler {
return;
}
IdentifierInfo *II = Tok.getIdentifierInfo();
+ PPCallbacks *Callbacks = PP.getPPCallbacks();
diag::Mapping Map;
if (II->isStr("warning"))
@@ -861,10 +865,13 @@ struct PragmaDiagnosticHandler : public PragmaHandler {
else if (II->isStr("pop")) {
if (!PP.getDiagnostics().popMappings(DiagLoc))
PP.Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
-
+ else if (Callbacks)
+ Callbacks->PragmaDiagnosticPop(DiagLoc, Namespace);
return;
} else if (II->isStr("push")) {
PP.getDiagnostics().pushMappings(DiagLoc);
+ if (Callbacks)
+ Callbacks->PragmaDiagnosticPush(DiagLoc, Namespace);
return;
} else {
PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
@@ -916,6 +923,8 @@ struct PragmaDiagnosticHandler : public PragmaHandler {
Map, DiagLoc))
PP.Diag(StrToks[0].getLocation(),
diag::warn_pragma_diagnostic_unknown_warning) << WarningName;
+ else if (Callbacks)
+ Callbacks->PragmaDiagnostic(DiagLoc, Namespace, Map, WarningName);
}
};
@@ -1010,13 +1019,13 @@ void Preprocessor::RegisterBuiltinPragmas() {
AddPragmaHandler("GCC", new PragmaPoisonHandler());
AddPragmaHandler("GCC", new PragmaSystemHeaderHandler());
AddPragmaHandler("GCC", new PragmaDependencyHandler());
- AddPragmaHandler("GCC", new PragmaDiagnosticHandler());
+ AddPragmaHandler("GCC", new PragmaDiagnosticHandler("GCC"));
// #pragma clang ...
AddPragmaHandler("clang", new PragmaPoisonHandler());
AddPragmaHandler("clang", new PragmaSystemHeaderHandler());
AddPragmaHandler("clang", new PragmaDebugHandler());
AddPragmaHandler("clang", new PragmaDependencyHandler());
- AddPragmaHandler("clang", new PragmaDiagnosticHandler());
+ AddPragmaHandler("clang", new PragmaDiagnosticHandler("clang"));
AddPragmaHandler("STDC", new PragmaSTDC_FENV_ACCESSHandler());
AddPragmaHandler("STDC", new PragmaSTDC_CX_LIMITED_RANGEHandler());
View
13 lib/Sema/SemaDecl.cpp
@@ -2039,12 +2039,17 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
}
mergeDeclAttributes(New, Old, Context);
- // weak_import on current declaration is applied to previous
- // tentative definiton.
+ // Warn if an already-declared variable is made a weak_import in a subsequent declaration
if (New->getAttr<WeakImportAttr>() &&
Old->getStorageClass() == SC_None &&
- !Old->getAttr<WeakImportAttr>())
- Old->addAttr(::new (Context) WeakImportAttr(SourceLocation(), Context));
+ !Old->getAttr<WeakImportAttr>()) {
+ Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName();
+ Diag(Old->getLocation(), diag::note_previous_definition);
+ // Remove weak_import attribute on new declaration.
+ // I am just dropping all attributes in curernt decl. We have
+ // already issued a warning, so we are OK.
+ New->dropAttrs();
+ }
// Merge the types.
MergeVarDeclTypes(New, Old);
View
43 lib/Sema/SemaDeclCXX.cpp
@@ -1610,7 +1610,8 @@ Sema::BuildMemberInitializer(ValueDecl *Member, Expr **Args,
// Can't check initialization for a member of dependent type or when
// any of the arguments are type-dependent expressions.
Init = new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
- RParenLoc);
+ RParenLoc,
+ Member->getType().getNonReferenceType());
DiscardCleanupsInEvaluationContext();
} else {
@@ -1646,8 +1647,9 @@ Sema::BuildMemberInitializer(ValueDecl *Member, Expr **Args,
// initializer. However, deconstructing the ASTs is a dicey process,
// and this approach is far more likely to get the corner cases right.
if (CurContext->isDependentContext())
- Init = new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
- RParenLoc);
+ Init = new (Context) ParenListExpr(
+ Context, LParenLoc, Args, NumArgs, RParenLoc,
+ Member->getType().getNonReferenceType());
else
Init = MemberInit.get();
}
@@ -1703,22 +1705,7 @@ Sema::BuildDelegatingInitializer(TypeSourceInfo *TInfo,
if (DelegationInit.isInvalid())
return true;
- // If we are in a dependent context, template instantiation will
- // perform this type-checking again. Just save the arguments that we
- // received in a ParenListExpr.
- // FIXME: This isn't quite ideal, since our ASTs don't capture all
- // of the information that we have about the base
- // initializer. However, deconstructing the ASTs is a dicey process,
- // and this approach is far more likely to get the corner cases right.
- if (CurContext->isDependentContext()) {
- ExprResult Init
- = Owned(new (Context) ParenListExpr(Context, LParenLoc, Args,
- NumArgs, RParenLoc));
- return new (Context) CXXCtorInitializer(Context, Loc, LParenLoc,
- Constructor, Init.takeAs<Expr>(),
- RParenLoc);
- }
-
+ assert(!CurContext->isDependentContext());
return new (Context) CXXCtorInitializer(Context, Loc, LParenLoc, Constructor,
DelegationInit.takeAs<Expr>(),
RParenLoc);
@@ -1803,7 +1790,7 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
// any of the arguments are type-dependent expressions.
ExprResult BaseInit
= Owned(new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
- RParenLoc));
+ RParenLoc, BaseType));
DiscardCleanupsInEvaluationContext();
@@ -1861,7 +1848,7 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
if (CurContext->isDependentContext()) {
ExprResult Init
= Owned(new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
- RParenLoc));
+ RParenLoc, BaseType));
return new (Context) CXXCtorInitializer(Context, BaseTInfo,
BaseSpec->isVirtual(),
LParenLoc,
@@ -7520,9 +7507,9 @@ void Sema::AddCXXDirectInitializerToDecl(Decl *RealDecl,
// Store the initialization expressions as a ParenListExpr.
unsigned NumExprs = Exprs.size();
- VDecl->setInit(new (Context) ParenListExpr(Context, LParenLoc,
- (Expr **)Exprs.release(),
- NumExprs, RParenLoc));
+ VDecl->setInit(new (Context) ParenListExpr(
+ Context, LParenLoc, (Expr **)Exprs.release(), NumExprs, RParenLoc,
+ VDecl->getType().getNonReferenceType()));
return;
}
@@ -8059,8 +8046,12 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S,
Invalid = true;
} else if (T->isObjCObjectPointerType()) {
if (!getLangOptions().ObjCNonFragileABI) {
- Diag(Loc, diag::err_objc_pointer_cxx_catch_fragile);
- Invalid = true;
+ if (T->isObjCIdType() || T->isObjCQualifiedIdType())
+ Diag(Loc, diag::warn_objc_pointer_cxx_catch_fragile);
+ else {
+ Diag(Loc, diag::err_objc_pointer_cxx_catch_fragile);
+ Invalid = true;
+ }
}
}
}
View
6 lib/Sema/SemaExpr.cpp
@@ -5846,7 +5846,8 @@ ExprResult Sema::ActOnParenOrParenListExpr(SourceLocation L,
if (nexprs == 1 && TypeOfCast && !TypeIsVectorType(TypeOfCast))
expr = new (Context) ParenExpr(L, R, exprs[0]);
else
- expr = new (Context) ParenListExpr(Context, L, exprs, nexprs, R);
+ expr = new (Context) ParenListExpr(Context, L, exprs, nexprs, R,
+ exprs[nexprs-1]->getType());
return Owned(expr);
}
@@ -9142,7 +9143,8 @@ static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperatorKind Opc,
SuggestParentheses(Self, OpLoc,
Self.PDiag(diag::note_precedence_bitwise_first)
<< BinOp::getOpcodeStr(Opc),
- SourceRange(lhs->getLocEnd(), cast<BinOp>(rhs)->getLHS()->getLocStart()));
+ SourceRange(lhs->getLocStart(),
+ cast<BinOp>(rhs)->getLHS()->getLocStart()));
}
}
View
2  lib/Sema/SemaExprObjC.cpp
@@ -1620,7 +1620,7 @@ Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
ARCConversionTypeClass exprACTC = classifyTypeForARCConversion(castExprType);
ARCConversionTypeClass castACTC = classifyTypeForARCConversion(castType);
if (exprACTC == castACTC) return;
- if (exprACTC && castType->isBooleanType()) return;
+ if (exprACTC && castType->isIntegralType(Context)) return;
// Allow casts between pointers to lifetime types (e.g., __strong id*)
// and pointers to void (e.g., cv void *). Casting from void* to lifetime*
View
27 lib/Sema/SemaInit.cpp
@@ -3915,19 +3915,9 @@ InitializationSequence::Perform(Sema &S,
}
}
-
- if (Kind.getKind() == InitializationKind::IK_Copy || Kind.isExplicitCast())
- return ExprResult(Args.release()[0]);
-
- if (Args.size() == 0)
- return S.Owned((Expr *)0);
-
- unsigned NumArgs = Args.size();
- return S.Owned(new (S.Context) ParenListExpr(S.Context,
- SourceLocation(),
- (Expr **)Args.release(),
- NumArgs,
- SourceLocation()));
+ assert(Kind.getKind() == InitializationKind::IK_Copy ||
+ Kind.isExplicitCast());
+ return ExprResult(Args.release()[0]);
}
// No steps means no initialization.
@@ -4080,8 +4070,17 @@ InitializationSequence::Perform(Sema &S,
return ExprError();
// Materialize the temporary into memory.
- CurInit = new (S.Context) MaterializeTemporaryExpr(CurInit.get(),
+ CurInit = new (S.Context) MaterializeTemporaryExpr(
+ Entity.getType().getNonReferenceType(),
+ CurInit.get(),
Entity.getType()->isLValueReferenceType());
+
+ // If we're binding to an Objective-C object that has lifetime, we
+ // need cleanups.
+ if (S.getLangOptions().ObjCAutoRefCount &&
+ CurInit.get()->getType()->isObjCLifetimeType())
+ S.ExprNeedsCleanups = true;
+
break;
case SK_ExtraneousCopyToTemporary:
View
2  lib/Sema/SemaLookup.cpp
@@ -2225,7 +2225,7 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *D,
// there is no semantic difference for class types in this restricted
// case.
ExprValueKind VK;
- if (SM == CXXCopyAssignment || SM == CXXMoveAssignment)
+ if (SM == CXXCopyConstructor || SM == CXXCopyAssignment)
VK = VK_LValue;
else
VK = VK_RValue;
View
23 lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1090,9 +1090,26 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
Function->setLexicalDeclContext(LexicalDC);
// Attach the parameters
- for (unsigned P = 0; P < Params.size(); ++P)
- if (Params[P])
- Params[P]->setOwningFunction(Function);
+ if (isa<FunctionProtoType>(Function->getType())) {
+ // Adopt the already-instantiated parameters into our own context.
+ for (unsigned P = 0; P < Params.size(); ++P)
+ if (Params[P])
+ Params[P]->setOwningFunction(Function);
+ } else {
+ // Since we were instantiated via a typedef of a function type, create
+ // new parameters.
+ const FunctionProtoType *Proto
+ = Function->getType()->getAs<FunctionProtoType>();
+ assert(Proto && "No function prototype in template instantiation?");
+ for (FunctionProtoType::arg_type_iterator AI = Proto->arg_type_begin(),
+ AE = Proto->arg_type_end(); AI != AE; ++AI) {
+ ParmVarDecl *Param
+ = SemaRef.BuildParmVarDeclForTypedef(Function, Function->getLocation(),
+ *AI);
+ Param->setScopeInfo(0, Params.size());
+ Params.push_back(Param);
+ }
+ }
Function->setParams(Params.data(), Params.size());
SourceLocation InstantiateAtPOI;
View
2  runtime/compiler-rt/Makefile
@@ -42,7 +42,7 @@ ifeq ($(shell test -d $(COMPILERRT_SRC_ROOT) && echo OK),OK)
RuntimeDirs :=
ifeq ($(OS),Darwin)
RuntimeDirs += darwin
-RuntimeLibrary.darwin.Configs = eprintf 10.4 ios cc_kext
+RuntimeLibrary.darwin.Configs = eprintf 10.4 osx ios cc_kext
# On Darwin, fake Clang into using the iOS assembler (since compiler-rt wants to
# build ARM bits).
View
12 test/ARCMT/checking.m
@@ -253,3 +253,15 @@ void rdar9491791(int p) {
void rdar9504750(id p) {
RELEASE_MACRO(p); // expected-error {{ARC forbids explicit message send of 'release'}}
}
+
+// rdar://8939557
+@interface TestReadonlyProperty : NSObject
+@property(assign,readonly) NSObject *value;
+@end
+
+@implementation TestReadonlyProperty
+@synthesize value;
+- (void)viewDidLoad {
+ value = [NSObject new]; // expected-error {{assigning retained object}}
+}
+@end
View
2  test/CodeGen/attr-weak-import.c
@@ -20,7 +20,7 @@ extern int E __attribute__((weak_import));
// CHECK: @A = global i32
// CHECK-NOT: @B =
-// CHECK: @C = global i32
+// CHECK: @C = common global i32
// CHECK: @D = global i32
// CHECK: @E = global i32
View
63 test/CodeGenObjCXX/arc-move.mm
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-nonfragile-abi -fblocks -fobjc-arc -O2 -std=c++0x -disable-llvm-optzns -o - %s | FileCheck %s
+
+// define void @_Z11simple_moveRU8__strongP11objc_objectS2_
+void simple_move(__strong id &x, __strong id &y) {
+ // CHECK: = load i8**
+ // CHECK: store i8* null
+ // CHECK: = load i8**
+ // CHECK: store i8*
+ // CHECK-NEXT: call void @objc_release
+ x = static_cast<__strong id&&>(y);
+ // CHECK-NEXT: ret void
+}
+
+template<typename T>
+struct remove_reference {
+ typedef T type;
+};
+
+template<typename T>
+struct remove_reference<T&> {
+ typedef T type;
+};
+
+template<typename T>
+struct remove_reference<T&&> {
+ typedef T type;
+};
+
+template<typename T>
+typename remove_reference<T>::type&& move(T &&x) {
+ return static_cast<typename remove_reference<T>::type&&>(x);
+}
+
+// CHECK: define void @_Z12library_moveRU8__strongP11objc_objectS2_
+void library_move(__strong id &x, __strong id &y) {
+ // CHECK: call i8** @_Z4moveIRU8__strongP11objc_objectEON16remove_referenceIT_E4typeEOS5_
+ // CHECK: load i8**
+ // CHECK: store i8* null, i8**
+ // CHECK: load i8***
+ // CHECK-NEXT: load i8**
+ // CHECK-NEXT: store i8*
+ // CHECK-NEXT: call void @objc_release
+ // CHECK-NEXT: ret void
+ x = move(y);
+}
+
+// CHECK: define void @_Z12library_moveRU8__strongP11objc_object
+void library_move(__strong id &y) {
+ // CHECK: [[Y:%[a-zA-Z0-9]+]] = call i8** @_Z4moveIRU8__strongP11objc_objectEON16remove_referenceIT_E4typeEOS5_
+ // Load the object
+ // CHECK-NEXT: [[OBJ:%[a-zA-Z0-9]+]] = load i8** [[Y]]
+ // Null out y
+ // CHECK-NEXT: store i8* null, i8** [[Y]]
+ // Initialize x with the object
+ // CHECK-NEXT: store i8* [[OBJ]], i8** [[X:%[a-zA-Z0-9]+]]
+ id x = move(y);
+
+ // CHECK-NEXT: store i32 17
+ int i = 17;
+ // CHECK-NEXT: [[OBJ:%[a-zA-Z0-9]+]] = load i8** [[X]]
+ // CHECK-NEXT: call void @objc_release(i8* [[OBJ]])
+ // CHECK-NEXT: ret void
+}
View
30 test/CodeGenObjCXX/arc-references.mm
@@ -1,5 +1,8 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-nonfragile-abi -fblocks -fobjc-arc -O2 -disable-llvm-optzns -o - %s | FileCheck %s
+@interface A
+@end
+
id getObject();
void callee();
@@ -44,6 +47,33 @@ void test3() {
// CHECK-NEXT: ret void
}
+// CHECK: define void @_Z5test4RU8__strongP11objc_object
+void test4(__strong id &x) {
+ // CHECK: call i8* @objc_retain
+ __strong A* const &ar = x;
+ // CHECK: store i32 17, i32*
+ int i = 17;
+ // CHECK: call void @objc_release(
+ // CHECK: ret void
+}
+
+void sink(__strong A* &&);
+
+// CHECK: define void @_Z5test5RU8__strongP11objc_object
+void test5(__strong id &x) {
+ // CHECK: [[OBJ_ID:%[a-zA-Z0-9]+]] = call i8* @objc_retain
+ // CHECK-NEXT: [[OBJ_A:%[a-zA-Z0-9]+]] = bitcast i8* [[OBJ_ID]] to [[A:%[a-zA-Z0-9]+]]*
+ // CHECK-NEXT: store [[A]]* [[OBJ_A]], [[A]]** [[REFTMP:%[a-zA-Z0-9]+]]
+ // CHECK-NEXT: call void @_Z4sinkOU8__strongP1A
+ sink(x);
+ // CHECK-NEXT: [[OBJ_A:%[a-zA-Z0-9]+]] = load [[A]]** [[REFTMP]]
+ // CHECK-NEXT: [[OBJ_ID:%[a-zA-Z0-9]+]] = bitcast [[A]]* [[OBJ_A]] to i8*
+ // CHECK-NEXT: call void @objc_release
+ // CHECK-NEXT: store i32 17, i32
+ int i = 17;
+ // CHECK-NEXT: ret void
+}
+
// CHECK: define internal void @__cxx_global_var_init(
// CHECK: call i8* @_Z9getObjectv
// CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue
View
33 test/CodeGenObjCXX/catch-id-type.mm
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple i386-apple-macosx10.6.6 -emit-llvm -fobjc-exceptions -fcxx-exceptions -fexceptions -o - %s | FileCheck %s
+// rdar://8940528
+
+@interface ns_array
++ (id) array;
+@end
+
+@implementation ns_array
++ (id) array { return 0; }
+@end
+
+id Groups();
+
+id FUNC() {
+ id groups;
+ try
+ {
+ groups = Groups(); // throws on errors.
+ }
+ catch( id error )
+ {
+ // CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector({{.*}} @__gxx_personality_v0 {{.*}} @_ZTIP11objc_object
+ error = error;
+ groups = [ns_array array];
+ }
+ return groups;
+
+}
+
+int main() {
+ FUNC();
+ return 0;
+}
View
26 test/Preprocessor/pragma_diagnostic_output.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -E %s | FileCheck %s
+// CHECK: #pragma GCC diagnostic warning "-Wall"
+#pragma GCC diagnostic warning "-Wall"
+// CHECK: #pragma GCC diagnostic ignored "-Wall"
+#pragma GCC diagnostic ignored "-Wall"
+// CHECK: #pragma GCC diagnostic error "-Wall"
+#pragma GCC diagnostic error "-Wall"
+// CHECK: #pragma GCC diagnostic fatal "-Wall"
+#pragma GCC diagnostic fatal "-Wall"
+// CHECK: #pragma GCC diagnostic push
+#pragma GCC diagnostic push
+// CHECK: #pragma GCC diagnostic pop
+#pragma GCC diagnostic pop
+
+// CHECK: #pragma clang diagnostic warning "-Wall"
+#pragma clang diagnostic warning "-Wall"
+// CHECK: #pragma clang diagnostic ignored "-Wall"
+#pragma clang diagnostic ignored "-Wall"
+// CHECK: #pragma clang diagnostic error "-Wall"
+#pragma clang diagnostic error "-Wall"
+// CHECK: #pragma clang diagnostic fatal "-Wall"
+#pragma clang diagnostic fatal "-Wall"
+// CHECK: #pragma clang diagnostic push
+#pragma clang diagnostic push
+// CHECK: #pragma clang diagnostic pop
+#pragma clang diagnostic pop
View
4 test/Sema/attr-weak.c
@@ -12,3 +12,7 @@ struct __attribute__((weak)) s0 {}; // expected-warning {{'weak' attribute only
struct __attribute__((weak_import)) s1 {}; // expected-warning {{'weak_import' attribute only applies to variables and functions}}
static int x __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
+
+// rdar://9538608
+int C; // expected-note {{previous definition is here}}
+extern int C __attribute__((weak_import)); // expected-warning {{an already-declared variable is made a weak_import declaration}}
View
17 test/Sema/paren-list-expr-type.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang -cc1 -ast-dump %s | not grep NULL
+// Makes sure that we don't introduce null types when handling
+// ParenListExpr.
+
+template<typename T> class X { void f() { X x(*this); } };
+
+template<typename T> class Y { Y() : t(1) {} T t; };
+
+template<typename T> class Z { Z() : b(true) {} const bool b; };
+
+template<typename T> class A : public Z<T> { A() : Z<T>() {} };
+
+class C {};
+template<typename T> class D : public C { D(): C() {} };
+
+void f() { (int)(1, 2); }
+
View
17 test/SemaObjC/arc.m
@@ -525,11 +525,11 @@ - (void)Meth;
@implementation Test30
- (id) new { return 0; }
- (void) Meth {
- __weak id x = [Test30 new]; // expected-warning {{cannot assign retained object to weak variable}}
- id __unsafe_unretained u = [Test30 new]; // expected-warning {{cannot assign retained object to unsafe_unretained variable}}
+ __weak id x = [Test30 new]; // expected-warning {{assigning retained object to weak variable}}
+ id __unsafe_unretained u = [Test30 new]; // expected-warning {{assigning retained object to unsafe_unretained variable}}
id y = [Test30 new];
- x = [Test30 new]; // expected-warning {{cannot assign retained object to weak variable}}
- u = [Test30 new]; // expected-warning {{cannot assign retained object to unsafe_unretained variable}}
+ x = [Test30 new]; // expected-warning {{assigning retained object to weak variable}}
+ u = [Test30 new]; // expected-warning {{assigning retained object to unsafe_unretained variable}}
y = [Test30 new];
}
@end
@@ -563,3 +563,12 @@ id Test32(__weak ITest32 *x) {
: (*x).ivar; // expected-error {{dereferencing a __weak pointer is not allowed}}
}
+// rdar://9619861
+extern int printf(const char*, ...);
+typedef long intptr_t;
+
+int Test33(id someid) {
+ printf( "Hello%ld", (intptr_t)someid);
+ return (int)someid;
+}
+
View
11 test/SemaTemplate/instantiate-function-2.cpp
@@ -31,3 +31,14 @@ namespace UsedAttr {
foo<int>(); // expected-note{{instantiation of}}
}
}
+
+namespace PR9654 {
+ typedef void ftype(int);
+
+ template<typename T>
+ ftype f;
+
+ void g() {
+ f<int>(0);
+ }
+}
View
18 test/Unit/lit.cfg
@@ -30,14 +30,6 @@ if 'TEMP' in os.environ:
###
-# If necessary, point the dynamic loader at libLLVM.so.
-if config.enable_shared:
- shlibpath = config.environment.get(config.shlibpath_var,'')
- if shlibpath:
- shlibpath = os.pathsep + shlibpath
- shlibpath = config.shlibdir + shlibpath
- config.environment[config.shlibpath_var] = shlibpath
-
# Check that the object root is known.
if config.test_exec_root is None:
# Otherwise, we haven't loaded the site specific configuration (the user is
@@ -71,7 +63,7 @@ if config.test_exec_root is None:
# Validate that we got a tree which points to here, using the standard
# tools/clang layout.
- this_src_root = os.path.dirname(config.test_source_root)
+ this_src_root = os.path.join(os.path.dirname(__file__),'..','..')
if os.path.realpath(clang_src_root) != os.path.realpath(this_src_root):
lit.fatal('No site specific configuration available!')
@@ -84,3 +76,11 @@ if config.test_exec_root is None:
lit.note('using out-of-tree build at %r' % clang_obj_root)
lit.load_config(config, site_cfg)
raise SystemExit
+
+# If necessary, point the dynamic loader at libLLVM.so.
+if config.enable_shared:
+ shlibpath = config.environment.get(config.shlibpath_var,'')
+ if shlibpath:
+ shlibpath = os.pathsep + shlibpath
+ shlibpath = config.shlibdir + shlibpath
+ config.environment[config.shlibpath_var] = shlibpath

No commit comments for this range

Something went wrong with that request. Please try again.