aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2010-04-03 07:51:34 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2010-04-03 07:51:34 +0000
commit2c56c396ce5990954f85194029eeb391bc3529ff (patch)
tree1e9c2f464daf7966d11aa31cf069fa1bc63fdb21
parent11d2b2d2bb706fca0656f2760839721bb7f6cb6f (diff)
downloadsrc-2c56c396ce5990954f85194029eeb391bc3529ff.tar.gz
src-2c56c396ce5990954f85194029eeb391bc3529ff.zip
Update clang to r100285.
Notes
Notes: svn path=/vendor/clang/dist/; revision=206125
-rw-r--r--include/clang/AST/DeclObjC.h12
-rw-r--r--include/clang/AST/Expr.h9
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td2
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td4
-rw-r--r--include/clang/Driver/Options.td2
-rw-r--r--lib/AST/ASTImporter.cpp3
-rw-r--r--lib/AST/DeclObjC.cpp41
-rw-r--r--lib/AST/Expr.cpp65
-rw-r--r--lib/Basic/Targets.cpp22
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp10
-rw-r--r--lib/CodeGen/CGExprCXX.cpp18
-rw-r--r--lib/CodeGen/CGObjCMac.cpp72
-rw-r--r--lib/CodeGen/CGVtable.cpp9
-rw-r--r--lib/Parse/ParseObjc.cpp68
-rw-r--r--lib/Sema/SemaDecl.cpp12
-rw-r--r--lib/Sema/SemaDeclCXX.cpp42
-rw-r--r--lib/Sema/SemaDeclObjC.cpp5
-rw-r--r--lib/Sema/SemaExpr.cpp5
-rw-r--r--lib/Sema/SemaInit.cpp109
-rw-r--r--lib/Sema/SemaObjCProperty.cpp20
-rw-r--r--test/CodeGen/enum.c4
-rw-r--r--test/CodeGen/indirect-goto.c2
-rw-r--r--test/CodeGen/rdr-6098585-default-after-caserange.c18
-rw-r--r--test/CodeGen/rdr-6098585-default-fallthrough-to-caserange.c20
-rw-r--r--test/CodeGen/rdr-6098585-empty-case-range.c23
-rw-r--r--test/CodeGen/rdr-6098585-fallthrough-to-empty-range.c15
-rw-r--r--test/CodeGen/rdr-6098585-unsigned-caserange.c12
-rw-r--r--test/CodeGen/switch.c94
-rw-r--r--test/CodeGenCXX/copy-initialization.cpp29
-rw-r--r--test/CodeGenCXX/derived-to-base-conv.cpp12
-rw-r--r--test/CodeGenCXX/virt.cpp3
-rw-r--r--test/CodeGenCXX/vtable-linkage.cpp6
-rw-r--r--test/Parser/check-syntax-1.m10
-rw-r--r--test/SemaCXX/conditional-expr.cpp27
-rw-r--r--test/SemaCXX/copy-initialization.cpp20
-rw-r--r--test/SemaObjC/class-extension-after-implementation.m11
-rw-r--r--test/SemaObjC/default-synthesize.m16
37 files changed, 530 insertions, 322 deletions
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index a1f565341e2c..9b2b6096e81d 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -624,17 +624,23 @@ public:
};
private:
- ObjCIvarDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
+ ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation L, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW)
: FieldDecl(ObjCIvar, DC, L, Id, T, TInfo, BW, /*Mutable=*/false),
DeclAccess(ac) {}
public:
- static ObjCIvarDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T,
+ static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
+ SourceLocation L, IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo,
AccessControl ac, Expr *BW = NULL);
+ /// \brief Return the class interface that this ivar is logically contained
+ /// in; this is either the interface where the ivar was declared, or the
+ /// interface the ivar is conceptually a part of in the case of synthesized
+ /// ivars.
+ const ObjCInterfaceDecl *getContainingInterface() const;
+
void setAccessControl(AccessControl ac) { DeclAccess = ac; }
AccessControl getAccessControl() const { return AccessControl(DeclAccess); }
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 507a61c6d7a6..a687ee5f01c8 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -322,6 +322,15 @@ public:
/// the expression is a default argument.
bool isDefaultArgument() const;
+ /// \brief Determine whether this expression directly creates a
+ /// temporary object (of class type).
+ bool isTemporaryObject() const { return getTemporaryObject() != 0; }
+
+ /// \brief If this expression directly creates a temporary object of
+ /// class type, return the expression that actually constructs that
+ /// temporary object.
+ const Expr *getTemporaryObject() const;
+
const Expr* IgnoreParens() const {
return const_cast<Expr*>(this)->IgnoreParens();
}
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index facf15f52e85..3e0956fb9460 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -182,6 +182,8 @@ def err_unexected_colon_in_nested_name_spec : Error<
"unexpected ':' in nested name specifier">;
/// Objective-C parser diagnostics
+def err_expected_minus_or_plus : Error<
+ "method type specifier must start with '-' or '+'">;
def err_objc_no_attributes_on_category : Error<
"attributes may not be specified on a category">;
def err_objc_missing_end : Error<"missing @end">;
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index be00972dac5c..b66d6cc6e5a3 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -256,6 +256,10 @@ def warn_property_attribute : Warning<
def warn_property_types_are_incompatible : Warning<
"property type %0 is incompatible with type %1 inherited from %2">;
def err_undef_interface : Error<"cannot find interface declaration for %0">;
+def err_class_extension_after_impl : Error<
+ "cannot declare class extension for %0 after class implementation">;
+def note_implementation_declared : Note<
+ "class implementation is declared here">;
def warn_dup_category_def : Warning<
"duplicate definition of category %1 on interface %0">;
def err_conflicting_super_class : Error<"conflicting super class name %0">;
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index d088be04c03e..ed68d68dd621 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -431,6 +431,7 @@ def mno_sse4_1 : Flag<"-mno-sse4.1">, Group<m_x86_Features_Group>;
def mno_sse4_2 : Flag<"-mno-sse4.2">, Group<m_x86_Features_Group>;
def mno_sse : Flag<"-mno-sse">, Group<m_x86_Features_Group>;
def mno_ssse3 : Flag<"-mno-ssse3">, Group<m_x86_Features_Group>;
+def mno_aes : Flag<"-mno-aes">, Group<m_x86_Features_Group>;
def mno_thumb : Flag<"-mno-thumb">, Group<m_Group>;
def marm : Flag<"-marm">, Alias<mno_thumb>;
@@ -447,6 +448,7 @@ def msse4_1 : Flag<"-msse4.1">, Group<m_x86_Features_Group>;
def msse4_2 : Flag<"-msse4.2">, Group<m_x86_Features_Group>;
def msse : Flag<"-msse">, Group<m_x86_Features_Group>;
def mssse3 : Flag<"-mssse3">, Group<m_x86_Features_Group>;
+def maes : Flag<"-maes">, Group<m_x86_Features_Group>;
def mthumb : Flag<"-mthumb">, Group<m_Group>;
def mtune_EQ : Joined<"-mtune=">, Group<m_Group>;
def multi__module : Flag<"-multi_module">;
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 75cf1380a112..f7d08e8b77bb 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -2013,7 +2013,8 @@ Decl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
if (!BitWidth && D->getBitWidth())
return 0;
- ObjCIvarDecl *ToIvar = ObjCIvarDecl::Create(Importer.getToContext(), DC,
+ ObjCIvarDecl *ToIvar = ObjCIvarDecl::Create(Importer.getToContext(),
+ cast<ObjCContainerDecl>(DC),
Loc, Name.getAsIdentifierInfo(),
T, TInfo, D->getAccessControl(),
BitWidth);
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index ab6b9e1f45ad..821e38bdacfd 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -561,14 +561,53 @@ bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
// ObjCIvarDecl
//===----------------------------------------------------------------------===//
-ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, DeclContext *DC,
+ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
SourceLocation L, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo,
AccessControl ac, Expr *BW) {
+ if (DC) {
+ // Ivar's can only appear in interfaces, implementations (via synthesized
+ // properties), and class extensions (via direct declaration, or synthesized
+ // properties).
+ //
+ // FIXME: This should really be asserting this:
+ // (isa<ObjCCategoryDecl>(DC) &&
+ // cast<ObjCCategoryDecl>(DC)->IsClassExtension()))
+ // but unfortunately we sometimes place ivars into non-class extension
+ // categories on error. This breaks an AST invariant, and should not be
+ // fixed.
+ assert((isa<ObjCInterfaceDecl>(DC) || isa<ObjCImplementationDecl>(DC) ||
+ isa<ObjCCategoryDecl>(DC)) &&
+ "Invalid ivar decl context!");
+ }
+
return new (C) ObjCIvarDecl(DC, L, Id, T, TInfo, ac, BW);
}
+const ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() const {
+ const ObjCContainerDecl *DC = cast<ObjCContainerDecl>(getDeclContext());
+
+ switch (DC->getKind()) {
+ default:
+ case ObjCCategoryImpl:
+ case ObjCProtocol:
+ assert(0 && "invalid ivar container!");
+ return 0;
+ // Ivars can only appear in class extension categories.
+ case ObjCCategory: {
+ const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(DC);
+ assert(CD->IsClassExtension() && "invalid container for ivar!");
+ return CD->getClassInterface();
+ }
+
+ case ObjCImplementation:
+ return cast<ObjCImplementationDecl>(DC)->getClassInterface();
+
+ case ObjCInterface:
+ return cast<ObjCInterfaceDecl>(DC);
+ }
+}
//===----------------------------------------------------------------------===//
// ObjCAtDefsFieldDecl
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 6764612c80b6..ae4bc8c80128 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -1476,6 +1476,71 @@ bool Expr::isDefaultArgument() const {
return isa<CXXDefaultArgExpr>(E);
}
+/// \brief Skip over any no-op casts and any temporary-binding
+/// expressions.
+static const Expr *skipTemporaryBindingsAndNoOpCasts(const Expr *E) {
+ while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
+ if (ICE->getCastKind() == CastExpr::CK_NoOp)
+ E = ICE->getSubExpr();
+ else
+ break;
+ }
+
+ while (const CXXBindTemporaryExpr *BE = dyn_cast<CXXBindTemporaryExpr>(E))
+ E = BE->getSubExpr();
+
+ while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
+ if (ICE->getCastKind() == CastExpr::CK_NoOp)
+ E = ICE->getSubExpr();
+ else
+ break;
+ }
+
+ return E;
+}
+
+const Expr *Expr::getTemporaryObject() const {
+ const Expr *E = skipTemporaryBindingsAndNoOpCasts(this);
+
+ // A cast can produce a temporary object. The object's construction
+ // is represented as a CXXConstructExpr.
+ if (const CastExpr *Cast = dyn_cast<CastExpr>(E)) {
+ // Only user-defined and constructor conversions can produce
+ // temporary objects.
+ if (Cast->getCastKind() != CastExpr::CK_ConstructorConversion &&
+ Cast->getCastKind() != CastExpr::CK_UserDefinedConversion)
+ return 0;
+
+ // Strip off temporary bindings and no-op casts.
+ const Expr *Sub = skipTemporaryBindingsAndNoOpCasts(Cast->getSubExpr());
+
+ // If this is a constructor conversion, see if we have an object
+ // construction.
+ if (Cast->getCastKind() == CastExpr::CK_ConstructorConversion)
+ return dyn_cast<CXXConstructExpr>(Sub);
+
+ // If this is a user-defined conversion, see if we have a call to
+ // a function that itself returns a temporary object.
+ if (Cast->getCastKind() == CastExpr::CK_UserDefinedConversion)
+ if (const CallExpr *CE = dyn_cast<CallExpr>(Sub))
+ if (CE->getCallReturnType()->isRecordType())
+ return CE;
+
+ return 0;
+ }
+
+ // A call returning a class type returns a temporary.
+ if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
+ if (CE->getCallReturnType()->isRecordType())
+ return CE;
+
+ return 0;
+ }
+
+ // Explicit temporary object constructors create temporaries.
+ return dyn_cast<CXXTemporaryObjectExpr>(E);
+}
+
/// hasAnyTypeDependentArguments - Determines if any of the expressions
/// in Exprs is type-dependent.
bool Expr::hasAnyTypeDependentArguments(Expr** Exprs, unsigned NumExprs) {
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index e3d9ed3335a7..1797804a7aab 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -765,9 +765,12 @@ class X86TargetInfo : public TargetInfo {
NoAMD3DNow, AMD3DNow, AMD3DNowAthlon
} AMD3DNowLevel;
+ bool HasAES;
+
public:
X86TargetInfo(const std::string& triple)
- : TargetInfo(triple), SSELevel(NoMMXSSE), AMD3DNowLevel(NoAMD3DNow) {
+ : TargetInfo(triple), SSELevel(NoMMXSSE), AMD3DNowLevel(NoAMD3DNow),
+ HasAES(false) {
LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
}
virtual void getTargetBuiltins(const Builtin::Info *&Records,
@@ -813,6 +816,7 @@ void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
Features["ssse3"] = false;
Features["sse41"] = false;
Features["sse42"] = false;
+ Features["aes"] = false;
// LLVM does not currently recognize this.
// Features["sse4a"] = false;
@@ -841,8 +845,10 @@ void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
Features["sse42"] = false;
} else if (CPU == "atom")
setFeatureEnabled(Features, "sse3", true);
- else if (CPU == "corei7")
+ else if (CPU == "corei7") {
setFeatureEnabled(Features, "sse4", true);
+ setFeatureEnabled(Features, "aes", true);
+ }
else if (CPU == "k6" || CPU == "winchip-c6")
setFeatureEnabled(Features, "mmx", true);
else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" ||
@@ -892,6 +898,8 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
Features["3dnowa"] = true;
else if (Name == "3dnowa")
Features["3dnow"] = Features["3dnowa"] = true;
+ else if (Name == "aes")
+ Features["aes"] = true;
} else {
if (Name == "mmx")
Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
@@ -917,6 +925,8 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
Features["3dnow"] = Features["3dnowa"] = false;
else if (Name == "3dnowa")
Features["3dnowa"] = false;
+ else if (Name == "aes")
+ Features["aes"] = false;
}
return true;
@@ -931,6 +941,11 @@ void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) {
if (Features[i][0] == '-')
continue;
+ if (Features[i].substr(1) == "aes") {
+ HasAES = true;
+ continue;
+ }
+
assert(Features[i][0] == '+' && "Invalid target feature!");
X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Features[i].substr(1))
.Case("sse42", SSE42)
@@ -969,6 +984,9 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
DefineStd(Builder, "i386", Opts);
}
+ if (HasAES)
+ Builder.defineMacro("__AES__");
+
// Target properties.
Builder.defineMacro("__LITTLE_ENDIAN__");
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 58acd3c2e172..4f14f94388fc 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -1390,9 +1390,9 @@ void CGDebugInfo::EmitStopPoint(llvm::Function *Fn, CGBuilderTy &Builder) {
PresumedLoc PLoc = SM.getPresumedLoc(CurLoc);
llvm::MDNode *Scope = RegionStack.back();
- Builder.SetCurrentDebugLocation(llvm::NewDebugLoc::get(PLoc.getLine(),
- PLoc.getColumn(),
- Scope));
+ Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(PLoc.getLine(),
+ PLoc.getColumn(),
+ Scope));
}
/// EmitRegionStart- Constructs the debug code for entering a declarative
@@ -1596,7 +1596,7 @@ void CGDebugInfo::EmitDeclare(const VarDecl *VD, unsigned Tag,
DebugFactory.InsertDeclare(Storage, D, Builder.GetInsertBlock());
llvm::MDNode *Scope = RegionStack.back();
- Call->setDebugLoc(llvm::NewDebugLoc::get(Line, Column, Scope));
+ Call->setDebugLoc(llvm::DebugLoc::get(Line, Column, Scope));
}
/// EmitDeclare - Emit local variable declaration debug info.
@@ -1660,7 +1660,7 @@ void CGDebugInfo::EmitDeclare(const BlockDeclRefExpr *BDRE, unsigned Tag,
DebugFactory.InsertDeclare(Storage, D, Builder.GetInsertBlock());
llvm::MDNode *Scope = RegionStack.back();
- Call->setDebugLoc(llvm::NewDebugLoc::get(Line, PLoc.getColumn(), Scope));
+ Call->setDebugLoc(llvm::DebugLoc::get(Line, PLoc.getColumn(), Scope));
}
void CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *VD,
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
index d9585c9c6d20..1fd1da858193 100644
--- a/lib/CodeGen/CGExprCXX.cpp
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -307,23 +307,7 @@ CodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest,
// Code gen optimization to eliminate copy constructor and return
// its first argument instead.
if (getContext().getLangOptions().ElideConstructors && E->isElidable()) {
- const Expr *Arg = E->getArg(0);
-
- if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) {
- assert((ICE->getCastKind() == CastExpr::CK_NoOp ||
- ICE->getCastKind() == CastExpr::CK_ConstructorConversion ||
- ICE->getCastKind() == CastExpr::CK_UserDefinedConversion) &&
- "Unknown implicit cast kind in constructor elision");
- Arg = ICE->getSubExpr();
- }
-
- if (const CXXFunctionalCastExpr *FCE = dyn_cast<CXXFunctionalCastExpr>(Arg))
- Arg = FCE->getSubExpr();
-
- if (const CXXBindTemporaryExpr *BindExpr =
- dyn_cast<CXXBindTemporaryExpr>(Arg))
- Arg = BindExpr->getSubExpr();
-
+ const Expr *Arg = E->getArg(0)->getTemporaryObject();
EmitAggExpr(Arg, Dest, false);
return;
}
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 883ed98511e7..5373390ef7e8 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -42,41 +42,15 @@ using namespace CodeGen;
// don't belong in CGObjCRuntime either so we will live with it for
// now.
-/// FindIvarInterface - Find the interface containing the ivar.
-///
-/// FIXME: We shouldn't need to do this, the containing context should
-/// be fixed.
-static const ObjCInterfaceDecl *FindIvarInterface(ASTContext &Context,
- const ObjCInterfaceDecl *OID,
- const ObjCIvarDecl *OIVD,
- unsigned &Index) {
- // FIXME: The index here is closely tied to how
- // ASTContext::getObjCLayout is implemented. This should be fixed to
- // get the information from the layout directly.
- Index = 0;
- llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
- Context.ShallowCollectObjCIvars(OID, Ivars);
- for (unsigned k = 0, e = Ivars.size(); k != e; ++k) {
- if (OIVD == Ivars[k])
- return OID;
- ++Index;
- }
-
- // Otherwise check in the super class.
- if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
- return FindIvarInterface(Context, Super, OIVD, Index);
-
- return 0;
-}
-
static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM,
const ObjCInterfaceDecl *OID,
const ObjCImplementationDecl *ID,
const ObjCIvarDecl *Ivar) {
- unsigned Index;
- const ObjCInterfaceDecl *Container =
- FindIvarInterface(CGM.getContext(), OID, Ivar, Index);
- assert(Container && "Unable to find ivar container");
+ const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
+
+ // FIXME: We should eliminate the need to have ObjCImplementationDecl passed
+ // in here; it should never be necessary because that should be the lexical
+ // decl context for the ivar.
// If we know have an implementation (and the ivar is in it) then
// look up in the implementation layout.
@@ -85,6 +59,22 @@ static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM,
RL = &CGM.getContext().getASTObjCImplementationLayout(ID);
else
RL = &CGM.getContext().getASTObjCInterfaceLayout(Container);
+
+ // Compute field index.
+ //
+ // FIXME: The index here is closely tied to how ASTContext::getObjCLayout is
+ // implemented. This should be fixed to get the information from the layout
+ // directly.
+ unsigned Index = 0;
+ llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
+ CGM.getContext().ShallowCollectObjCIvars(Container, Ivars);
+ for (unsigned k = 0, e = Ivars.size(); k != e; ++k) {
+ if (Ivar == Ivars[k])
+ break;
+ ++Index;
+ }
+ assert(Index != Ivars.size() && "Ivar is not inside container!");
+
return RL->getFieldOffset(Index);
}
@@ -4727,14 +4717,10 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitMethodList(llvm::Twine Name,
/// ObjCIvarOffsetVariable - Returns the ivar offset variable for
/// the given ivar.
-llvm::GlobalVariable * CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(
- const ObjCInterfaceDecl *ID,
- const ObjCIvarDecl *Ivar) {
- // FIXME: We shouldn't need to do this lookup.
- unsigned Index;
- const ObjCInterfaceDecl *Container =
- FindIvarInterface(CGM.getContext(), ID, Ivar, Index);
- assert(Container && "Unable to find ivar container!");
+llvm::GlobalVariable *
+CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
+ const ObjCIvarDecl *Ivar) {
+ const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
std::string Name = "OBJC_IVAR_$_" + Container->getNameAsString() +
'.' + Ivar->getNameAsString();
llvm::GlobalVariable *IvarOffsetGV =
@@ -4749,10 +4735,10 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(
return IvarOffsetGV;
}
-llvm::Constant * CGObjCNonFragileABIMac::EmitIvarOffsetVar(
- const ObjCInterfaceDecl *ID,
- const ObjCIvarDecl *Ivar,
- unsigned long int Offset) {
+llvm::Constant *
+CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
+ const ObjCIvarDecl *Ivar,
+ unsigned long int Offset) {
llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
IvarOffsetGV->setInitializer(llvm::ConstantInt::get(ObjCTypes.LongTy,
Offset));
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp
index 2d1c73440bbe..fc6d1a8e3709 100644
--- a/lib/CodeGen/CGVtable.cpp
+++ b/lib/CodeGen/CGVtable.cpp
@@ -3146,11 +3146,16 @@ void CodeGenVTables::EmitVTableRelatedData(GlobalDecl GD) {
if (KeyFunction->getCanonicalDecl() != MD->getCanonicalDecl())
return;
} else {
+ // If we have no key funcion and this is a explicit instantiation declaration,
+ // we will produce a vtable at the explicit instantiation. We don't need one
+ // here.
+ if (RDKind == clang::TSK_ExplicitInstantiationDeclaration)
+ return;
+
// If this is an explicit instantiation of a method, we don't need a vtable.
// Since we have no key function, we will emit the vtable when we see
// a use, and just defining a function is not an use.
- if ((RDKind == TSK_ImplicitInstantiation ||
- RDKind == TSK_ExplicitInstantiationDeclaration) &&
+ if (RDKind == TSK_ImplicitInstantiation &&
MDKind == TSK_ExplicitInstantiationDefinition)
return;
}
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index 9a3473f042ed..243be0ed45ae 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -142,12 +142,11 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
// We have a class or category name - consume it.
IdentifierInfo *nameId = Tok.getIdentifierInfo();
SourceLocation nameLoc = ConsumeToken();
-
+ bool Err = false;
if (Tok.is(tok::l_paren)) { // we have a category.
SourceLocation lparenLoc = ConsumeParen();
SourceLocation categoryLoc, rparenLoc;
IdentifierInfo *categoryId = 0;
-
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteObjCInterfaceCategory(CurScope, nameId);
ConsumeToken();
@@ -157,7 +156,14 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
if (Tok.is(tok::identifier)) {
categoryId = Tok.getIdentifierInfo();
categoryLoc = ConsumeToken();
- } else if (!getLang().ObjC2) {
+ }
+ else if (isKnownToBeTypeSpecifier(Tok)) {
+ // Fall thru after diagnosing for better error recovery.
+ Diag(Tok, diag::err_expected_minus_or_plus);
+ ConsumeToken();
+ Err = true;
+ }
+ else if (!getLang().ObjC2) {
Diag(Tok, diag::err_expected_ident); // missing category name.
return DeclPtrTy();
}
@@ -167,33 +173,34 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
return DeclPtrTy();
}
rparenLoc = ConsumeParen();
-
- // Next, we need to check for any protocol references.
- SourceLocation LAngleLoc, EndProtoLoc;
- llvm::SmallVector<DeclPtrTy, 8> ProtocolRefs;
- llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
- if (Tok.is(tok::less) &&
- ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true,
+ if (!Err) {
+ // Next, we need to check for any protocol references.
+ SourceLocation LAngleLoc, EndProtoLoc;
+ llvm::SmallVector<DeclPtrTy, 8> ProtocolRefs;
+ llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
+ if (Tok.is(tok::less) &&
+ ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true,
LAngleLoc, EndProtoLoc))
- return DeclPtrTy();
+ return DeclPtrTy();
- if (attrList) // categories don't support attributes.
- Diag(Tok, diag::err_objc_no_attributes_on_category);
-
- DeclPtrTy CategoryType =
- Actions.ActOnStartCategoryInterface(atLoc,
- nameId, nameLoc,
- categoryId, categoryLoc,
- ProtocolRefs.data(),
- ProtocolRefs.size(),
- ProtocolLocs.data(),
- EndProtoLoc);
- if (Tok.is(tok::l_brace))
+ if (attrList) // categories don't support attributes.
+ Diag(Tok, diag::err_objc_no_attributes_on_category);
+
+ DeclPtrTy CategoryType =
+ Actions.ActOnStartCategoryInterface(atLoc,
+ nameId, nameLoc,
+ categoryId, categoryLoc,
+ ProtocolRefs.data(),
+ ProtocolRefs.size(),
+ ProtocolLocs.data(),
+ EndProtoLoc);
+ if (Tok.is(tok::l_brace))
ParseObjCClassInstanceVariables(CategoryType, tok::objc_private,
atLoc);
- ParseObjCInterfaceDeclList(CategoryType, tok::objc_not_keyword);
- return CategoryType;
+ ParseObjCInterfaceDeclList(CategoryType, tok::objc_not_keyword);
+ return CategoryType;
+ }
}
// Parse a class interface.
IdentifierInfo *superClassId = 0;
@@ -235,7 +242,7 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, atLoc);
ParseObjCInterfaceDeclList(ClsType, tok::objc_interface);
- return ClsType;
+ return Err ? DeclPtrTy() : ClsType;
}
/// The Objective-C property callback. This should be defined where
@@ -328,7 +335,14 @@ void Parser::ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl,
"", tok::semi);
continue;
}
-
+ if (Tok.is(tok::l_paren)) {
+ Diag(Tok, diag::err_expected_minus_or_plus);
+ DeclPtrTy methodPrototype = ParseObjCMethodDecl(Tok.getLocation(),
+ tok::minus,
+ interfaceDecl,
+ MethodImplKind);
+ continue;
+ }
// Ignore excess semicolons.
if (Tok.is(tok::semi)) {
ConsumeToken();
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index f3d0dcff20c7..541c27169a7c 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -5740,17 +5740,15 @@ Sema::DeclPtrTy Sema::ActOnIvar(Scope *S,
Visibility != tok::objc_not_keyword ? TranslateIvarVisibility(Visibility)
: ObjCIvarDecl::None;
// Must set ivar's DeclContext to its enclosing interface.
- Decl *EnclosingDecl = IntfDecl.getAs<Decl>();
- DeclContext *EnclosingContext;
+ ObjCContainerDecl *EnclosingDecl = IntfDecl.getAs<ObjCContainerDecl>();
+ ObjCContainerDecl *EnclosingContext;
if (ObjCImplementationDecl *IMPDecl =
dyn_cast<ObjCImplementationDecl>(EnclosingDecl)) {
// Case of ivar declared in an implementation. Context is that of its class.
- ObjCInterfaceDecl* IDecl = IMPDecl->getClassInterface();
- assert(IDecl && "No class- ActOnIvar");
- EnclosingContext = cast_or_null<DeclContext>(IDecl);
+ EnclosingContext = IMPDecl->getClassInterface();
+ assert(EnclosingContext && "Implementation has no class interface!");
} else
- EnclosingContext = dyn_cast<DeclContext>(EnclosingDecl);
- assert(EnclosingContext && "null DeclContext for ivar - ActOnIvar");
+ EnclosingContext = EnclosingDecl;
// Construct the decl.
ObjCIvarDecl *NewID = ObjCIvarDecl::Create(Context,
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 47df43516c2f..39e3739878f9 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -3965,33 +3965,21 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
bool BaseInitialization) {
bool Elidable = false;
- // C++ [class.copy]p15:
- // Whenever a temporary class object is copied using a copy constructor, and
- // this object and the copy have the same cv-unqualified type, an
- // implementation is permitted to treat the original and the copy as two
- // different ways of referring to the same object and not perform a copy at
- // all, even if the class copy constructor or destructor have side effects.
-
- // FIXME: Is this enough?
- if (Constructor->isCopyConstructor()) {
- Expr *E = ((Expr **)ExprArgs.get())[0];
- if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E))
- if (ICE->getCastKind() == CastExpr::CK_NoOp)
- E = ICE->getSubExpr();
- if (CXXFunctionalCastExpr *FCE = dyn_cast<CXXFunctionalCastExpr>(E))
- E = FCE->getSubExpr();
- while (CXXBindTemporaryExpr *BE = dyn_cast<CXXBindTemporaryExpr>(E))
- E = BE->getSubExpr();
- if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E))
- if (ICE->getCastKind() == CastExpr::CK_NoOp)
- E = ICE->getSubExpr();
-
- if (CallExpr *CE = dyn_cast<CallExpr>(E))
- Elidable = !CE->getCallReturnType()->isReferenceType();
- else if (isa<CXXTemporaryObjectExpr>(E))
- Elidable = true;
- else if (isa<CXXConstructExpr>(E))
- Elidable = true;
+ // C++0x [class.copy]p34:
+ // When certain criteria are met, an implementation is allowed to
+ // omit the copy/move construction of a class object, even if the
+ // copy/move constructor and/or destructor for the object have
+ // side effects. [...]
+ // - when a temporary class object that has not been bound to a
+ // reference (12.2) would be copied/moved to a class object
+ // with the same cv-unqualified type, the copy/move operation
+ // can be omitted by constructing the temporary object
+ // directly into the target of the omitted copy/move
+ if (Constructor->isCopyConstructor() && ExprArgs.size() >= 1) {
+ Expr *SubExpr = ((Expr **)ExprArgs.get())[0];
+ Elidable = SubExpr->isTemporaryObject() &&
+ Context.hasSameUnqualifiedType(SubExpr->getType(),
+ Context.getTypeDeclType(Constructor->getParent()));
}
return BuildCXXConstructExpr(ConstructLoc, DeclInitType, Constructor,
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 9bc0846901aa..0c47e63d99eb 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -431,6 +431,11 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
// Class extensions require a special treatment. Use an existing one.
// Note that 'getClassExtension()' can return NULL.
CDecl = IDecl->getClassExtension();
+ if (IDecl->getImplementation()) {
+ Diag(ClassLoc, diag::err_class_extension_after_impl) << ClassName;
+ Diag(IDecl->getImplementation()->getLocation(),
+ diag::note_implementation_declared);
+ }
}
if (!CDecl) {
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index fbdf080bc4a7..2dfb95435dda 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1345,11 +1345,6 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
}
}
}
- if (LangOpts.ObjCNonFragileABI2 && LookForIvars && Lookup.empty()) {
- ObjCIvarDecl *Ivar = SynthesizeNewPropertyIvar(IFace, II);
- if (Ivar)
- return LookupInObjCMethod(Lookup, S, II, AllowBuiltinCreation);
- }
// Sentinel value saying that we didn't do anything special.
return Owned((Expr*) 0);
}
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 648e43bdb48a..1d0575cd1c12 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -2583,10 +2583,7 @@ static void TryConstructorInitialization(Sema &S,
Expr **Args, unsigned NumArgs,
QualType DestType,
InitializationSequence &Sequence) {
- if (Kind.getKind() == InitializationKind::IK_Copy)
- Sequence.setSequenceKind(InitializationSequence::UserDefinedConversion);
- else
- Sequence.setSequenceKind(InitializationSequence::ConstructorInitialization);
+ Sequence.setSequenceKind(InitializationSequence::ConstructorInitialization);
// Build the candidate set directly in the initialization sequence
// structure, so that it will persist if we fail.
@@ -2597,7 +2594,7 @@ static void TryConstructorInitialization(Sema &S,
// explicit conversion operators.
bool AllowExplicit = (Kind.getKind() == InitializationKind::IK_Direct ||
Kind.getKind() == InitializationKind::IK_Value ||
- Kind.getKind() == InitializationKind::IK_Default);
+ Kind.getKind() == InitializationKind::IK_Default);
// The type we're converting to is a class type. Enumerate its constructors
// to see if one is suitable.
@@ -2661,14 +2658,10 @@ static void TryConstructorInitialization(Sema &S,
// Add the constructor initialization step. Any cv-qualification conversion is
// subsumed by the initialization.
- if (Kind.getKind() == InitializationKind::IK_Copy) {
- Sequence.AddUserConversionStep(Best->Function, Best->FoundDecl, DestType);
- } else {
- Sequence.AddConstructorInitializationStep(
+ Sequence.AddConstructorInitializationStep(
cast<CXXConstructorDecl>(Best->Function),
Best->FoundDecl.getAccess(),
DestType);
- }
}
/// \brief Attempt value initialization (C++ [dcl.init]p7).
@@ -3085,14 +3078,11 @@ getAssignmentAction(const InitializedEntity &Entity) {
return Sema::AA_Converting;
}
-static bool shouldBindAsTemporary(const InitializedEntity &Entity,
- bool IsCopy) {
+static bool shouldBindAsTemporary(const InitializedEntity &Entity) {
switch (Entity.getKind()) {
- case InitializedEntity::EK_Result:
case InitializedEntity::EK_ArrayElement:
case InitializedEntity::EK_Member:
- return !IsCopy;
-
+ case InitializedEntity::EK_Result:
case InitializedEntity::EK_New:
case InitializedEntity::EK_Variable:
case InitializedEntity::EK_Base:
@@ -3108,21 +3098,38 @@ static bool shouldBindAsTemporary(const InitializedEntity &Entity,
llvm_unreachable("missed an InitializedEntity kind?");
}
-/// \brief If we need to perform an additional copy of the initialized object
-/// for this kind of entity (e.g., the result of a function or an object being
-/// thrown), make the copy.
-static Sema::OwningExprResult CopyIfRequiredForEntity(Sema &S,
- const InitializedEntity &Entity,
- const InitializationKind &Kind,
- Sema::OwningExprResult CurInit) {
+static Sema::OwningExprResult CopyObject(Sema &S,
+ const InitializedEntity &Entity,
+ const InitializationKind &Kind,
+ Sema::OwningExprResult CurInit) {
+ // Determine which class type we're copying.
Expr *CurInitExpr = (Expr *)CurInit.get();
-
+ CXXRecordDecl *Class = 0;
+ if (const RecordType *Record = CurInitExpr->getType()->getAs<RecordType>())
+ Class = cast<CXXRecordDecl>(Record->getDecl());
+ if (!Class)
+ return move(CurInit);
+
+ // C++0x [class.copy]p34:
+ // When certain criteria are met, an implementation is allowed to
+ // omit the copy/move construction of a class object, even if the
+ // copy/move constructor and/or destructor for the object have
+ // side effects. [...]
+ // - when a temporary class object that has not been bound to a
+ // reference (12.2) would be copied/moved to a class object
+ // with the same cv-unqualified type, the copy/move operation
+ // can be omitted by constructing the temporary object
+ // directly into the target of the omitted copy/move
+ //
+ // Note that the other three bullets are handled elsewhere. Copy
+ // elision for return statements and throw expressions are (FIXME:
+ // not yet) handled as part of constructor initialization, while
+ // copy elision for exception handlers is handled by the run-time.
+ bool Elidable = CurInitExpr->isTemporaryObject() &&
+ S.Context.hasSameUnqualifiedType(Entity.getType(), CurInitExpr->getType());
SourceLocation Loc;
-
switch (Entity.getKind()) {
case InitializedEntity::EK_Result:
- if (Entity.getType()->isReferenceType())
- return move(CurInit);
Loc = Entity.getReturnLoc();
break;
@@ -3131,38 +3138,20 @@ static Sema::OwningExprResult CopyIfRequiredForEntity(Sema &S,
break;
case InitializedEntity::EK_Variable:
- if (Entity.getType()->isReferenceType() ||
- Kind.getKind() != InitializationKind::IK_Copy)
- return move(CurInit);
Loc = Entity.getDecl()->getLocation();
break;
case InitializedEntity::EK_ArrayElement:
case InitializedEntity::EK_Member:
- if (Entity.getType()->isReferenceType() ||
- Kind.getKind() != InitializationKind::IK_Copy)
- return move(CurInit);
- Loc = CurInitExpr->getLocStart();
- break;
-
case InitializedEntity::EK_Parameter:
- // FIXME: Do we need this initialization for a parameter?
- return move(CurInit);
-
- case InitializedEntity::EK_New:
case InitializedEntity::EK_Temporary:
+ case InitializedEntity::EK_New:
case InitializedEntity::EK_Base:
case InitializedEntity::EK_VectorElement:
- // We don't need to copy for any of these initialized entities.
- return move(CurInit);
+ Loc = CurInitExpr->getLocStart();
+ break;
}
-
- CXXRecordDecl *Class = 0;
- if (const RecordType *Record = CurInitExpr->getType()->getAs<RecordType>())
- Class = cast<CXXRecordDecl>(Record->getDecl());
- if (!Class)
- return move(CurInit);
-
+
// Perform overload resolution using the class's copy constructors.
DeclarationName ConstructorName
= S.Context.DeclarationNames.getCXXConstructorName(
@@ -3171,7 +3160,7 @@ static Sema::OwningExprResult CopyIfRequiredForEntity(Sema &S,
OverloadCandidateSet CandidateSet(Loc);
for (llvm::tie(Con, ConEnd) = Class->lookup(ConstructorName);
Con != ConEnd; ++Con) {
- // Find the constructor (which may be a template).
+ // Only consider copy constructors.
CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(*Con);
if (!Constructor || Constructor->isInvalidDecl() ||
!Constructor->isCopyConstructor())
@@ -3181,7 +3170,7 @@ static Sema::OwningExprResult CopyIfRequiredForEntity(Sema &S,
= DeclAccessPair::make(Constructor, Constructor->getAccess());
S.AddOverloadCandidate(Constructor, FoundDecl,
&CurInitExpr, 1, CandidateSet);
- }
+ }
OverloadCandidateSet::iterator Best;
switch (S.BestViableFunction(CandidateSet, Loc, Best)) {
@@ -3218,9 +3207,9 @@ static Sema::OwningExprResult CopyIfRequiredForEntity(Sema &S,
Best->FoundDecl.getAccess());
CurInit.release();
- return S.BuildCXXConstructExpr(Loc, CurInitExpr->getType(),
+ return S.BuildCXXConstructExpr(Loc, Entity.getType().getNonReferenceType(),
cast<CXXConstructorDecl>(Best->Function),
- /*Elidable=*/true,
+ Elidable,
Sema::MultiExprArg(S,
(void**)&CurInitExpr, 1));
}
@@ -3474,7 +3463,9 @@ InitializationSequence::Perform(Sema &S,
CastKind = CastExpr::CK_UserDefinedConversion;
}
- if (shouldBindAsTemporary(Entity, IsCopy))
+ bool RequiresCopy = !IsCopy &&
+ getKind() != InitializationSequence::ReferenceBinding;
+ if (RequiresCopy || shouldBindAsTemporary(Entity))
CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());
CurInitExpr = CurInit.takeAs<Expr>();
@@ -3483,8 +3474,8 @@ InitializationSequence::Perform(Sema &S,
CurInitExpr,
IsLvalue));
- if (!IsCopy)
- CurInit = CopyIfRequiredForEntity(S, Entity, Kind, move(CurInit));
+ if (RequiresCopy)
+ CurInit = CopyObject(S, Entity, Kind, move(CurInit));
break;
}
@@ -3560,13 +3551,9 @@ InitializationSequence::Perform(Sema &S,
S.CheckConstructorAccess(Loc, Constructor,
Step->Function.FoundDecl.getAccess());
- bool Elidable
- = cast<CXXConstructExpr>((Expr *)CurInit.get())->isElidable();
- if (shouldBindAsTemporary(Entity, Elidable))
+ if (shouldBindAsTemporary(Entity))
CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());
-
- if (!Elidable)
- CurInit = CopyIfRequiredForEntity(S, Entity, Kind, move(CurInit));
+
break;
}
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index f815068fac2d..52b9bcf86c8d 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -281,7 +281,7 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
DeclPtrTy ClassCatImpDecl,
IdentifierInfo *PropertyId,
IdentifierInfo *PropertyIvar) {
- Decl *ClassImpDecl = ClassCatImpDecl.getAs<Decl>();
+ ObjCContainerDecl *ClassImpDecl = ClassCatImpDecl.getAs<ObjCContainerDecl>();
// Make sure we have a context for the property implementation declaration.
if (!ClassImpDecl) {
Diag(AtLoc, diag::error_missing_property_context);
@@ -353,14 +353,11 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
ObjCInterfaceDecl *ClassDeclared;
Ivar = IDecl->lookupInstanceVariable(PropertyIvar, ClassDeclared);
if (!Ivar) {
- DeclContext *EnclosingContext = cast_or_null<DeclContext>(ClassImpDecl);
- assert(EnclosingContext &&
- "null DeclContext for synthesized ivar - ActOnPropertyImplDecl");
- Ivar = ObjCIvarDecl::Create(Context, EnclosingContext, PropertyLoc,
+ Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl, PropertyLoc,
PropertyIvar, PropType, /*Dinfo=*/0,
ObjCIvarDecl::Public,
(Expr *)0);
- EnclosingContext->addDecl(Ivar);
+ ClassImpDecl->addDecl(Ivar);
IDecl->makeDeclVisibleInContext(Ivar, false);
property->setPropertyIvarDecl(Ivar);
@@ -1072,15 +1069,10 @@ Sema::SynthesizeNewPropertyIvar(ObjCInterfaceDecl *IDecl,
ObjCIvarDecl *Ivar = 0;
ObjCPropertyDecl *Prop = LookupPropertyDecl(IDecl, NameII);
if (Prop && !Prop->isInvalidDecl()) {
- DeclContext *EnclosingContext = cast_or_null<DeclContext>(IDecl);
QualType PropType = Context.getCanonicalType(Prop->getType());
- assert(EnclosingContext &&
- "null DeclContext for synthesized ivar - SynthesizeNewPropertyIvar");
- Ivar = ObjCIvarDecl::Create(Context, EnclosingContext,
- Prop->getLocation(),
- NameII, PropType, /*Dinfo=*/0,
- ObjCIvarDecl::Public,
- (Expr *)0);
+ Ivar = ObjCIvarDecl::Create(Context, IDecl, Prop->getLocation(), NameII,
+ PropType, /*Dinfo=*/0,
+ ObjCIvarDecl::Public, (Expr *)0);
Ivar->setLexicalDeclContext(IDecl);
IDecl->addDecl(Ivar);
Prop->setPropertyIvarDecl(Ivar);
diff --git a/test/CodeGen/enum.c b/test/CodeGen/enum.c
index eab32c102518..87b0e1e67144 100644
--- a/test/CodeGen/enum.c
+++ b/test/CodeGen/enum.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm-bc -o - | opt -std-compile-opts | llvm-dis | grep 'ret i32 6'
-// RUN: %clang_cc1 -triple i386-unknown-unknown -x c++ %s -emit-llvm-bc -o - | opt -std-compile-opts | llvm-dis | grep 'ret i32 7'
+// RUN: %clang_cc1 -triple i386-unknown-unknown %s -O3 -emit-llvm -o - | grep 'ret i32 6'
+// RUN: %clang_cc1 -triple i386-unknown-unknown -x c++ %s -O3 -emit-llvm -o - | grep 'ret i32 7'
static enum { foo, bar = 1U } z;
diff --git a/test/CodeGen/indirect-goto.c b/test/CodeGen/indirect-goto.c
index 9fd8cfacecbf..7a3d7176519a 100644
--- a/test/CodeGen/indirect-goto.c
+++ b/test/CodeGen/indirect-goto.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm-bc -o - %s | opt -std-compile-opts -S | grep "ret i32 2520"
+// RUN: %clang_cc1 -triple i386-unknown-unknown -O3 -emit-llvm -o - %s | grep "ret i32 2520"
static int foo(unsigned i) {
void *addrs[] = { &&L1, &&L2, &&L3, &&L4, &&L5 };
diff --git a/test/CodeGen/rdr-6098585-default-after-caserange.c b/test/CodeGen/rdr-6098585-default-after-caserange.c
deleted file mode 100644
index 3a89aa39a0d7..000000000000
--- a/test/CodeGen/rdr-6098585-default-after-caserange.c
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm-bc -o - %s | opt -std-compile-opts | llvm-dis > %t
-// RUN: grep "ret i32" %t | count 1
-// RUN: grep "ret i32 10" %t | count 1
-
-// Ensure that default after a case range is not ignored.
-
-static int f1(unsigned x) {
- switch(x) {
- case 10 ... 0xFFFFFFFF:
- return 0;
- default:
- return 10;
- }
-}
-
-int g() {
- return f1(2);
-}
diff --git a/test/CodeGen/rdr-6098585-default-fallthrough-to-caserange.c b/test/CodeGen/rdr-6098585-default-fallthrough-to-caserange.c
deleted file mode 100644
index ba41b519fcca..000000000000
--- a/test/CodeGen/rdr-6098585-default-fallthrough-to-caserange.c
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm-bc -o - %s | opt -std-compile-opts | llvm-dis > %t
-// RUN: grep "ret i32 10" %t
-
-// Ensure that this doesn't compile to infinite loop in g() due to
-// miscompilation of fallthrough from default to a (tested) case
-// range.
-
-static int f0(unsigned x) {
- switch(x) {
- default:
- x += 1;
- case 10 ... 0xFFFFFFFF:
- return 0;
- }
-}
-
-int g() {
- f0(1);
- return 10;
-}
diff --git a/test/CodeGen/rdr-6098585-empty-case-range.c b/test/CodeGen/rdr-6098585-empty-case-range.c
deleted file mode 100644
index 1cf77ac6aa56..000000000000
--- a/test/CodeGen/rdr-6098585-empty-case-range.c
+++ /dev/null
@@ -1,23 +0,0 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm-bc -o - %s | opt -std-compile-opts | llvm-dis > %t
-// RUN: grep "ret i32" %t | count 2
-// RUN: grep "ret i32 3" %t | count 2
-
-// This generated incorrect code because of poor switch chaining.
-int f1(int x) {
- switch(x) {
- default:
- return 3;
- case 10 ... 0xFFFFFFFF:
- return 0;
- }
-}
-
-// This just asserted because of the way case ranges were calculated.
-int f2(int x) {
- switch (x) {
- default:
- return 3;
- case 10 ... -1:
- return 0;
- }
-}
diff --git a/test/CodeGen/rdr-6098585-fallthrough-to-empty-range.c b/test/CodeGen/rdr-6098585-fallthrough-to-empty-range.c
deleted file mode 100644
index 48a6cc228558..000000000000
--- a/test/CodeGen/rdr-6098585-fallthrough-to-empty-range.c
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm-bc -o - %s | opt -std-compile-opts | llvm-dis > %t
-// RUN: grep "ret i32 %" %t
-
-// Make sure return is not constant (if empty range is skipped or miscompiled)
-
-int f0(unsigned x) {
- switch(x) {
- case 2:
- // fallthrough empty range
- case 10 ... 9:
- return 10;
- default:
- return 0;
- }
-}
diff --git a/test/CodeGen/rdr-6098585-unsigned-caserange.c b/test/CodeGen/rdr-6098585-unsigned-caserange.c
deleted file mode 100644
index 6f577df188c5..000000000000
--- a/test/CodeGen/rdr-6098585-unsigned-caserange.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm-bc -o - %s | opt -std-compile-opts | llvm-dis > %t
-// RUN: grep "ret i32" %t | count 1
-// RUN: grep "ret i32 3" %t | count 1
-
-int f2(unsigned x) {
- switch(x) {
- default:
- return 3;
- case 0xFFFFFFFF ... 1: // This range should be empty because x is unsigned.
- return 0;
- }
-}
diff --git a/test/CodeGen/switch.c b/test/CodeGen/switch.c
index 519ccbac0159..dc2d27bc16da 100644
--- a/test/CodeGen/switch.c
+++ b/test/CodeGen/switch.c
@@ -100,3 +100,97 @@ void foo7(){
}
}
+
+// CHECK: define i32 @f8(
+// CHECK: ret i32 3
+// CHECK: }
+int f8(unsigned x) {
+ switch(x) {
+ default:
+ return 3;
+ case 0xFFFFFFFF ... 1: // This range should be empty because x is unsigned.
+ return 0;
+ }
+}
+
+// Ensure that default after a case range is not ignored.
+//
+// CHECK: define i32 @f9()
+// CHECK: ret i32 10
+// CHECK: }
+static int f9_0(unsigned x) {
+ switch(x) {
+ case 10 ... 0xFFFFFFFF:
+ return 0;
+ default:
+ return 10;
+ }
+}
+int f9() {
+ return f9_0(2);
+}
+
+// Ensure that this doesn't compile to infinite loop in g() due to
+// miscompilation of fallthrough from default to a (tested) case
+// range.
+//
+// CHECK: define i32 @f10()
+// CHECK: ret i32 10
+// CHECK: }
+static int f10_0(unsigned x) {
+ switch(x) {
+ default:
+ x += 1;
+ case 10 ... 0xFFFFFFFF:
+ return 0;
+ }
+}
+
+int f10() {
+ f10_0(1);
+ return 10;
+}
+
+// This generated incorrect code because of poor switch chaining.
+//
+// CHECK: define i32 @f11(
+// CHECK: ret i32 3
+// CHECK: }
+int f11(int x) {
+ switch(x) {
+ default:
+ return 3;
+ case 10 ... 0xFFFFFFFF:
+ return 0;
+ }
+}
+
+// This just asserted because of the way case ranges were calculated.
+//
+// CHECK: define i32 @f12(
+// CHECK: ret i32 3
+// CHECK: }
+int f12(int x) {
+ switch (x) {
+ default:
+ return 3;
+ case 10 ... -1:
+ return 0;
+ }
+}
+
+// Make sure return is not constant (if empty range is skipped or miscompiled)
+//
+// CHECK: define i32 @f13(
+// CHECK: ret i32 %
+// CHECK: }
+int f13(unsigned x) {
+ switch(x) {
+ case 2:
+ // fallthrough empty range
+ case 10 ... 9:
+ return 10;
+ default:
+ return 0;
+ }
+}
diff --git a/test/CodeGenCXX/copy-initialization.cpp b/test/CodeGenCXX/copy-initialization.cpp
new file mode 100644
index 000000000000..62b9f2678a43
--- /dev/null
+++ b/test/CodeGenCXX/copy-initialization.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+
+struct Foo {
+ Foo();
+ Foo(const Foo&);
+};
+
+struct Bar {
+ Bar();
+ operator const Foo&() const;
+};
+
+void f(Foo);
+
+// CHECK: define void @_Z1g3Foo(%struct.Bar* %foo)
+void g(Foo foo) {
+ // CHECK: call void @_ZN3BarC1Ev
+ // CHECK: @_ZNK3BarcvRK3FooEv
+ // CHECK: call void @_Z1f3Foo
+ f(Bar());
+ // CHECK: call void @_ZN3FooC1Ev
+ // CHECK: call void @_Z1f3Foo
+ f(Foo());
+ // CHECK: call void @_ZN3FooC1ERKS_
+ // CHECK: call void @_Z1f3Foo
+ f(foo);
+ // CHECK: ret
+}
+
diff --git a/test/CodeGenCXX/derived-to-base-conv.cpp b/test/CodeGenCXX/derived-to-base-conv.cpp
index c1a0caa7584f..f2835b7a299e 100644
--- a/test/CodeGenCXX/derived-to-base-conv.cpp
+++ b/test/CodeGenCXX/derived-to-base-conv.cpp
@@ -7,16 +7,21 @@ extern "C" int printf(...);
extern "C" void exit(int);
struct A {
- A (const A&) { printf("A::A(const A&)\n"); }
- A() {};
+ A (const A&) { printf("A::A(const A&)\n"); }
+ A() {};
+ ~A() { printf("A::~A()\n"); }
};
struct B : public A {
B() {};
-};
+ B(const B& Other) : A(Other) { printf("B::B(const B&)\n"); }
+ ~B() { printf("B::~B()\n"); }
+};
struct C : public B {
C() {};
+ C(const C& Other) : B(Other) { printf("C::C(const C&)\n"); }
+ ~C() { printf("C::~C()\n"); }
};
struct X {
@@ -24,6 +29,7 @@ struct X {
operator C&() {printf("X::operator C&()\n"); return c; }
X (const X&) { printf("X::X(const X&)\n"); }
X () { printf("X::X()\n"); }
+ ~X () { printf("X::~X()\n"); }
B b;
C c;
};
diff --git a/test/CodeGenCXX/virt.cpp b/test/CodeGenCXX/virt.cpp
index c40412963097..874ffb1ddf29 100644
--- a/test/CodeGenCXX/virt.cpp
+++ b/test/CodeGenCXX/virt.cpp
@@ -104,7 +104,8 @@ struct test7_B1 : virtual test7_B2 { virtual void funcB1(); };
struct test7_D : test7_B2, virtual test7_B1 {
};
-// CHECK-LP64: .zerofill __DATA,__common,_d7,16,3
+// FIXME: we were checking for an alignment of 3 (?)
+// CHECK-LP64: .zerofill __DATA,__common,_d7,16,
struct test3_B3 { virtual void funcB3(); };
diff --git a/test/CodeGenCXX/vtable-linkage.cpp b/test/CodeGenCXX/vtable-linkage.cpp
index a4ea2a19c238..c75efe228dff 100644
--- a/test/CodeGenCXX/vtable-linkage.cpp
+++ b/test/CodeGenCXX/vtable-linkage.cpp
@@ -128,10 +128,8 @@ void use_F(F<char> &fc) {
// CHECK: @_ZTI1FIlE = weak_odr constant
// F<int> is an explicit template instantiation declaration without a
-// key function, so its vtable should have weak_odr linkage.
-// CHECK: @_ZTV1FIiE = weak_odr constant
-// CHECK: @_ZTS1FIiE = weak_odr constant
-// CHECK: @_ZTI1FIiE = weak_odr constant
+// key function, so its vtable should have external linkage.
+// CHECK: @_ZTV1FIiE = external constant
// E<int> is an explicit template instantiation declaration. It has a
// key function that is not instantiated, so we should only reference
diff --git a/test/Parser/check-syntax-1.m b/test/Parser/check-syntax-1.m
index a1999def5982..085ff4cf67a1 100644
--- a/test/Parser/check-syntax-1.m
+++ b/test/Parser/check-syntax-1.m
@@ -9,3 +9,13 @@ typedef float CGFloat;
// expected-error {{ expected ';' after method prototype}}
@end
+// rdar: // 7822196
+@interface A
+(void) x; // expected-error {{method type specifier must start with '-' or '+'}} \
+ // expected-warning {{type specifier missing, defaults to 'int' [-Wimplicit-int]}} \
+ // expected-error {{cannot declare variable inside @interface or @protocol}}
+(int)im; // expected-error {{method type specifier must start with '-' or '+'}} \
+- ok;
+@end
+
+
diff --git a/test/SemaCXX/conditional-expr.cpp b/test/SemaCXX/conditional-expr.cpp
index e2a966bdd95d..49bcd99fb695 100644
--- a/test/SemaCXX/conditional-expr.cpp
+++ b/test/SemaCXX/conditional-expr.cpp
@@ -213,3 +213,30 @@ namespace PR6595 {
(void)(Cond? a : S);
}
}
+
+namespace PR6757 {
+ struct Foo1 {
+ Foo1();
+ Foo1(const Foo1&);
+ };
+
+ struct Foo2 { };
+
+ struct Foo3 {
+ Foo3();
+ Foo3(Foo3&);
+ };
+
+ struct Bar {
+ operator const Foo1&() const;
+ operator const Foo2&() const;
+ operator const Foo3&() const;
+ };
+
+ void f() {
+ (void)(true ? Bar() : Foo1()); // okay
+ (void)(true ? Bar() : Foo2()); // okay
+ // FIXME: Diagnostic below could be improved
+ (void)(true ? Bar() : Foo3()); // expected-error{{incompatible operand types ('PR6757::Bar' and 'PR6757::Foo3')}}
+ }
+}
diff --git a/test/SemaCXX/copy-initialization.cpp b/test/SemaCXX/copy-initialization.cpp
index 3a63be0970de..e5b1fd766bbd 100644
--- a/test/SemaCXX/copy-initialization.cpp
+++ b/test/SemaCXX/copy-initialization.cpp
@@ -21,3 +21,23 @@ struct foo {
// PR3600
void test(const foo *P) { P->bar(); } // expected-error{{cannot initialize object parameter of type 'foo' with an expression of type 'foo const'}}
+
+namespace PR6757 {
+ struct Foo {
+ Foo();
+ Foo(Foo&);
+ };
+
+ struct Bar {
+ operator const Foo&() const;
+ };
+
+ void f(Foo); // expected-note{{candidate function not viable: no known conversion from 'PR6757::Bar' to 'PR6757::Foo' for 1st argument}}
+
+ // FIXME: This isn't really the right reason for the failure. We
+ // should fail after overload resolution.
+ void g(Foo foo) {
+ f(Bar()); // expected-error{{no matching function for call to 'f'}}
+ f(foo);
+ }
+}
diff --git a/test/SemaObjC/class-extension-after-implementation.m b/test/SemaObjC/class-extension-after-implementation.m
new file mode 100644
index 000000000000..2d8a5b1d4d80
--- /dev/null
+++ b/test/SemaObjC/class-extension-after-implementation.m
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// rdar://7822210
+
+@interface A @end
+
+@implementation A @end // expected-note {{class implementation is declared here}}
+
+@interface A () // expected-error {{cannot declare class extension for 'A' after class implementation}}
+-(void) im0;
+@end
+
diff --git a/test/SemaObjC/default-synthesize.m b/test/SemaObjC/default-synthesize.m
index be2397bd2007..45a3710dcf5b 100644
--- a/test/SemaObjC/default-synthesize.m
+++ b/test/SemaObjC/default-synthesize.m
@@ -23,12 +23,12 @@
//@synthesize howMany, what;
- (int) howMany {
- return howMany;
+ return self.howMany;
}
// - (void) setHowMany: (int) value
- (NSString*) what {
- return what;
+ return self.what;
}
// - (void) setWhat: (NSString*) value
@end
@@ -44,12 +44,12 @@
// - (int) howMany
- (void) setHowMany: (int) value {
- howMany = value;
+ self.howMany = value;
}
// - (NSString*) what
- (void) setWhat: (NSString*) value {
- if (what != value) {
+ if (self.what != value) {
}
}
@end
@@ -64,17 +64,17 @@
//@synthesize howMany, what; // REM: Redundant anyway
- (int) howMany {
- return howMany;
+ return self.howMany;
}
- (void) setHowMany: (int) value {
- howMany = value;
+ self.howMany = value;
}
- (NSString*) what {
- return what;
+ return self.what;
}
- (void) setWhat: (NSString*) value {
- if (what != value) {
+ if (self.what != value) {
}
}
@end