summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authored <ed@FreeBSD.org>2009-06-08 15:36:55 +0000
committered <ed@FreeBSD.org>2009-06-08 15:36:55 +0000
commit6514d87c1aa5b544d02c3822fe41217e2051673d (patch)
tree7ab9fa5634c95f5df8575db81b24ea5586e65b28
parent2ae812c77b393190175c91233c3348f526ddab1b (diff)
downloadFreeBSD-src-6514d87c1aa5b544d02c3822fe41217e2051673d.zip
FreeBSD-src-6514d87c1aa5b544d02c3822fe41217e2051673d.tar.gz
Import Clang r73070.
-rw-r--r--docs/UsersManual.html47
-rw-r--r--include/clang/AST/ASTContext.h1
-rw-r--r--include/clang/AST/ExprObjC.h9
-rw-r--r--include/clang/AST/X86Builtins.def3
-rw-r--r--include/clang/Basic/DiagnosticGroups.td11
-rw-r--r--include/clang/Basic/TokenKinds.def6
-rw-r--r--include/clang/Parse/AttributeList.h4
-rw-r--r--include/clang/Parse/Parser.h2
-rw-r--r--lib/AST/ASTContext.cpp24
-rw-r--r--lib/AST/Expr.cpp16
-rw-r--r--lib/Basic/SourceManager.cpp3
-rw-r--r--lib/Basic/Targets.cpp15
-rw-r--r--lib/CodeGen/CGBuiltin.cpp23
-rw-r--r--lib/Frontend/InitPreprocessor.cpp1
-rw-r--r--lib/Frontend/RewriteBlocks.cpp8
-rw-r--r--lib/Headers/emmintrin.h2
-rw-r--r--lib/Parse/AttributeList.cpp4
-rw-r--r--lib/Parse/ParseDecl.cpp54
-rw-r--r--lib/Parse/ParseDeclCXX.cpp3
-rw-r--r--lib/Sema/Sema.h4
-rw-r--r--lib/Sema/SemaExpr.cpp10
-rw-r--r--lib/Sema/SemaExprObjC.cpp37
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp31
-rw-r--r--lib/Sema/SemaTemplateInstantiateExpr.cpp25
-rw-r--r--test/CodeGen/builtins-x86.c5
-rw-r--r--test/Sema/block-args.c2
-rw-r--r--test/Sema/block-call.c4
-rw-r--r--test/Sema/block-misc.c6
-rw-r--r--test/SemaObjC/blocks.m2
-rw-r--r--test/SemaTemplate/instantiate-objc-1.mm47
-rw-r--r--test/SemaTemplate/temp_class_spec.cpp32
-rw-r--r--tools/clang-cc/clang-cc.cpp3
32 files changed, 306 insertions, 138 deletions
diff --git a/docs/UsersManual.html b/docs/UsersManual.html
index e7072da..221e07c 100644
--- a/docs/UsersManual.html
+++ b/docs/UsersManual.html
@@ -52,22 +52,16 @@ td {
</ul>
</li>
<li><a href="#cxx">C++ Language Features</a>
- <ul>
- <li>...</li>
- </ul>
</li>
<li><a href="#objcxx">Objective C++ Language Features</a>
- <ul>
- <li>...</li>
- </ul>
</li>
<li><a href="#target_features">Target-Specific Features and Limitations</a>
<ul>
<li><a href="#target_arch">CPU Architectures Features and Limitations</a>
<ul>
<li><a href="#target_arch_x86">X86</a></li>
- <li>PPC</li>
- <li>ARM</li>
+ <li><a href="#target_arch_arm">ARM</a></li>
+ <li><a href="#target_arch_other">Other platforms</a></li>
</ul>
</li>
<li><a href="#target_os">Operating System Features and Limitations</a>
@@ -612,9 +606,10 @@ translation units.</p>
<p>clang has some experimental support for extensions from
Microsoft Visual C++; to enable it, use the -fms-extensions command-line
-option. Eventually, this will be the default for Windows targets.
-These extensions are not anywhere near complete, so please do not
-file bugs; patches are welcome, though.</p>
+option. This is the default for Windows targets. Note that the
+support is incomplete; enabling Microsoft extensions will silently drop
+certain constructs (including __declspec and Microsoft-style asm statements).
+</p>
<li>clang does not support the Microsoft extension where anonymous
record members can be declared using user defined typedefs.</li>
@@ -670,7 +665,37 @@ more information.</p>
<!-- ======================== -->
<h4 id="target_arch_x86">X86</h4>
<!-- ======================== -->
+<p>The support for X86 (both 32-bit and 64-bit) is considered stable
+on Darwin (Mac OS/X), Linux, FreeBSD, and Dragonfly BSD: it has been tested to
+correctly compile large C and Objective-C codebases. (FIXME: Anything specific
+we want to say here? Possibly mention some LLVM x86 limitations?)
+<!-- ======================== -->
+<h4 id="target_arch_arm">ARM</h4>
+<!-- ======================== -->
+ARM support is mostly feature-complete, but still experimental; it hasn't
+undergone significant testing.
+
+<!-- ======================== -->
+<h4 id="target_arch_other">Other platforms</h4>
+<!-- ======================== -->
+clang currently contains some support for PPC and Sparc; however, significant
+pieces of code generation are still missing, and they haven't undergone
+significant testing.
+
+<p>clang contains some support for the embedded PIC16 processor
+(FIXME: I haven't been keeping track of this; what should this say?).
+
+<p>clang contains limited support for the MSP430 embedded processor, but both
+the clang support and the LLVM backend support are highly experimental.
+
+<p>Other platforms are completely unsupported at the moment. Adding the
+minimal support needed for parsing and semantic analysis on a new platform
+is quite easy; see lib/Basic/Targets.cpp in the clang source tree. This level
+of support is also sufficient for conversion to LLVM IR for simple programs.
+Proper support for conversion to LLVM IR requires adding code to
+lib/CodeGen/CGCall.cpp at the moment; this is likely to change soon, though.
+Generating assembly requires a suitable LLVM backend.
<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
<h3 id="target_os">Operating System Features and Limitations</h3>
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index cad5487..b02faa8 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -696,7 +696,6 @@ public:
/// Compatibility predicates used to check assignment expressions.
bool typesAreCompatible(QualType, QualType); // C99 6.2.7p1
- bool typesAreBlockCompatible(QualType lhs, QualType rhs);
bool isObjCIdType(QualType T) const {
return T == ObjCIdType;
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
index 51b9961..ef78c40 100644
--- a/include/clang/AST/ExprObjC.h
+++ b/include/clang/AST/ExprObjC.h
@@ -34,6 +34,8 @@ public:
explicit ObjCStringLiteral(EmptyShell Empty)
: Expr(ObjCStringLiteralClass, Empty) {}
+ ObjCStringLiteral* Clone(ASTContext &C) const;
+
StringLiteral *getString() { return cast<StringLiteral>(String); }
const StringLiteral *getString() const { return cast<StringLiteral>(String); }
void setString(StringLiteral *S) { String = S; }
@@ -64,7 +66,8 @@ class ObjCEncodeExpr : public Expr {
public:
ObjCEncodeExpr(QualType T, QualType ET,
SourceLocation at, SourceLocation rp)
- : Expr(ObjCEncodeExprClass, T), EncType(ET), AtLoc(at), RParenLoc(rp) {}
+ : Expr(ObjCEncodeExprClass, T, ET->isDependentType(),
+ ET->isDependentType()), EncType(ET), AtLoc(at), RParenLoc(rp) {}
explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}
@@ -103,6 +106,8 @@ public:
explicit ObjCSelectorExpr(EmptyShell Empty)
: Expr(ObjCSelectorExprClass, Empty) {}
+ ObjCSelectorExpr *Clone(ASTContext &C) const;
+
Selector getSelector() const { return SelName; }
void setSelector(Selector S) { SelName = S; }
@@ -143,6 +148,8 @@ public:
explicit ObjCProtocolExpr(EmptyShell Empty)
: Expr(ObjCProtocolExprClass, Empty) {}
+ ObjCProtocolExpr *Clone(ASTContext &C) const;
+
ObjCProtocolDecl *getProtocol() const { return Protocol; }
void setProtocol(ObjCProtocolDecl *P) { Protocol = P; }
diff --git a/include/clang/AST/X86Builtins.def b/include/clang/AST/X86Builtins.def
index 95d0003..85381c0 100644
--- a/include/clang/AST/X86Builtins.def
+++ b/include/clang/AST/X86Builtins.def
@@ -249,14 +249,11 @@ BUILTIN(__builtin_ia32_psradi128, "V4iV4ii", "")
BUILTIN(__builtin_ia32_pmaddwd128, "V8sV8sV8s", "")
BUILTIN(__builtin_ia32_monitor, "vv*UiUi", "")
BUILTIN(__builtin_ia32_mwait, "vUiUi", "")
-BUILTIN(__builtin_ia32_movshdup, "V4fV4f", "")
-BUILTIN(__builtin_ia32_movsldup, "V4fV4f", "")
BUILTIN(__builtin_ia32_lddqu, "V16ccC*", "")
BUILTIN(__builtin_ia32_palignr128, "V2LLiV2LLiV2LLii", "")
BUILTIN(__builtin_ia32_palignr, "V1LLiV1LLiV1LLis", "")
BUILTIN(__builtin_ia32_insertps128, "V4fV4fV4fi", "")
-BUILTIN(__builtin_ia32_loadlv4si, "V4iV2i*", "")
BUILTIN(__builtin_ia32_storelv4si, "vV2i*V2LLi", "")
BUILTIN(__builtin_ia32_pblendvb128, "V16cV16cV16cV16c", "")
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 7c6b090..501807d 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -85,9 +85,10 @@ def Trigraphs : DiagGroup<"trigraphs">;
def : DiagGroup<"type-limits">;
def Uninitialized : DiagGroup<"uninitialized">;
def UnknownPragmas : DiagGroup<"unknown-pragmas">;
-def : DiagGroup<"unused-function">;
-def : DiagGroup<"unused-label">;
-def : DiagGroup<"unused-parameter">;
+def UnusedArgument : DiagGroup<"unused-argument">;
+def UnusedFunction : DiagGroup<"unused-function">;
+def UnusedLabel : DiagGroup<"unused-label">;
+def UnusedParameter : DiagGroup<"unused-parameter">;
def UnusedValue : DiagGroup<"unused-value">;
def UnusedVariable : DiagGroup<"unused-variable">;
def : DiagGroup<"variadic-macros">;
@@ -98,6 +99,10 @@ def : DiagGroup<"write-strings">;
// Aggregation warning settings.
+def Unused : DiagGroup<"unused",
+ [UnusedArgument, UnusedFunction, UnusedLabel,
+ UnusedParameter, UnusedValue, UnusedVariable]>;
+
// Format settings.
def Format : DiagGroup<"format", [FormatExtraArgs, FormatZeroLength, NonNull]>;
def FormatSecurity : DiagGroup<"format-security", [Format]>;
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index 9b65288..497b188 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -341,7 +341,6 @@ ALIAS("__attribute__", __attribute, KEYALL)
ALIAS("__const" , const , KEYALL)
ALIAS("__const__" , const , KEYALL)
ALIAS("__alignof__" , __alignof , KEYALL)
-ALIAS("_asm" , asm , KEYMS)
ALIAS("__asm" , asm , KEYALL)
ALIAS("__asm__" , asm , KEYALL)
ALIAS("__complex" , _Complex , KEYALL)
@@ -359,6 +358,11 @@ ALIAS("__typeof__" , typeof , KEYALL)
ALIAS("__volatile" , volatile , KEYALL)
ALIAS("__volatile__" , volatile , KEYALL)
+// Microsoft extensions which should be disabled in strict conformance mode
+ALIAS("_asm" , asm , KEYMS)
+ALIAS("_cdecl" , __cdecl , KEYMS)
+ALIAS("_fastcall" , __fastcall , KEYMS)
+ALIAS("_stdcall" , __stdcall , KEYMS)
//===----------------------------------------------------------------------===//
// Objective-C @-preceeded keywords.
diff --git a/include/clang/Parse/AttributeList.h b/include/clang/Parse/AttributeList.h
index 8225c9d..26cebf0 100644
--- a/include/clang/Parse/AttributeList.h
+++ b/include/clang/Parse/AttributeList.h
@@ -38,13 +38,14 @@ class AttributeList {
ActionBase::ExprTy **Args;
unsigned NumArgs;
AttributeList *Next;
+ bool DeclspecAttribute;
AttributeList(const AttributeList &); // DO NOT IMPLEMENT
void operator=(const AttributeList &); // DO NOT IMPLEMENT
public:
AttributeList(IdentifierInfo *AttrName, SourceLocation AttrLoc,
IdentifierInfo *ParmName, SourceLocation ParmLoc,
ActionBase::ExprTy **args, unsigned numargs,
- AttributeList *Next);
+ AttributeList *Next, bool declspec = false);
~AttributeList();
enum Kind { // Please keep this list alphabetized.
@@ -103,6 +104,7 @@ public:
IdentifierInfo *getName() const { return AttrName; }
SourceLocation getLoc() const { return AttrLoc; }
IdentifierInfo *getParameterName() const { return ParmName; }
+ bool isDeclspecAttribute() const { return DeclspecAttribute; }
Kind getKind() const { return getKind(getName()); }
static Kind getKind(const IdentifierInfo *Name);
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 6218ade..6125fc6 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -1064,7 +1064,7 @@ private:
// EndLoc, if non-NULL, is filled with the location of the last token of
// the attribute list.
AttributeList *ParseAttributes(SourceLocation *EndLoc = 0);
- void FuzzyParseMicrosoftDeclSpec();
+ AttributeList *ParseMicrosoftDeclSpec();
void ParseTypeofSpecifier(DeclSpec &DS);
/// DeclaratorScopeObj - RAII object used in Parser::ParseDirectDeclarator to
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index e6dea7c..fb28fd4 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -2838,30 +2838,6 @@ QualType::GCAttrTypes ASTContext::getObjCGCAttrKind(const QualType &Ty) const {
// Type Compatibility Testing
//===----------------------------------------------------------------------===//
-/// typesAreBlockCompatible - This routine is called when comparing two
-/// block types. Types must be strictly compatible here. For example,
-/// C unfortunately doesn't produce an error for the following:
-///
-/// int (*emptyArgFunc)();
-/// int (*intArgList)(int) = emptyArgFunc;
-///
-/// For blocks, we will produce an error for the following (similar to C++):
-///
-/// int (^emptyArgBlock)();
-/// int (^intArgBlock)(int) = emptyArgBlock;
-///
-/// FIXME: When the dust settles on this integration, fold this into mergeTypes.
-///
-bool ASTContext::typesAreBlockCompatible(QualType lhs, QualType rhs) {
- const FunctionType *lbase = lhs->getAsFunctionType();
- const FunctionType *rbase = rhs->getAsFunctionType();
- const FunctionProtoType *lproto = dyn_cast<FunctionProtoType>(lbase);
- const FunctionProtoType *rproto = dyn_cast<FunctionProtoType>(rbase);
- if (lproto && rproto == 0)
- return false;
- return !mergeTypes(lhs, rhs).isNull();
-}
-
/// areCompatVectorTypes - Return true if the two specified vector types are
/// compatible.
static bool areCompatVectorTypes(const VectorType *LHS,
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 4a53a41..c12dd67 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -1556,6 +1556,22 @@ ObjCMessageExpr::ObjCMessageExpr(Expr *receiver, Selector selInfo,
RBracloc = RBrac;
}
+ObjCStringLiteral* ObjCStringLiteral::Clone(ASTContext &C) const {
+ // Clone the string literal.
+ StringLiteral *NewString =
+ String ? cast<StringLiteral>(String)->Clone(C) : 0;
+
+ return new (C) ObjCStringLiteral(NewString, getType(), AtLoc);
+}
+
+ObjCSelectorExpr *ObjCSelectorExpr::Clone(ASTContext &C) const {
+ return new (C) ObjCSelectorExpr(getType(), SelName, AtLoc, RParenLoc);
+}
+
+ObjCProtocolExpr *ObjCProtocolExpr::Clone(ASTContext &C) const {
+ return new (C) ObjCProtocolExpr(getType(), Protocol, AtLoc, RParenLoc);
+}
+
// constructor for class messages.
// FIXME: clsName should be typed to ObjCInterfaceType
ObjCMessageExpr::ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo,
diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp
index 7d2d0ae..ed5eb46 100644
--- a/lib/Basic/SourceManager.cpp
+++ b/lib/Basic/SourceManager.cpp
@@ -347,9 +347,6 @@ FileID SourceManager::createFileID(const ContentCache *File,
SrcMgr::CharacteristicKind FileCharacter,
unsigned PreallocatedID,
unsigned Offset) {
- SLocEntry NewEntry = SLocEntry::get(NextOffset,
- FileInfo::get(IncludePos, File,
- FileCharacter));
if (PreallocatedID) {
// If we're filling in a preallocated ID, just load in the file
// entry and return.
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 120d525..b4e32e9 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -244,6 +244,11 @@ static void GetDarwinLanguageOptions(LangOptions &Opts,
Opts.ObjCNonFragileABI = 1;
}
+/// GetWindowsLanguageOptions - Set the default language options for Windows.
+static void GetWindowsLanguageOptions(LangOptions &Opts,
+ const char *Triple) {
+ Opts.Microsoft = true;
+}
//===----------------------------------------------------------------------===//
// Specific target implementations.
@@ -924,9 +929,8 @@ public:
WindowsX86_32TargetInfo(const std::string& triple)
: X86_32TargetInfo(triple) {
TLSSupported = false;
- // FIXME: Fix wchar_t.
- // FIXME: We should probably enable -fms-extensions by default for
- // this target.
+ WCharType = SignedShort;
+ WCharWidth = WCharAlign = 16;
}
virtual void getTargetDefines(const LangOptions &Opts,
std::vector<char> &Defines) const {
@@ -938,6 +942,11 @@ public:
Define(Defines, "_X86_");
Define(Defines, "__MSVCRT__");
}
+
+ virtual void getDefaultLangOptions(LangOptions &Opts) {
+ X86_32TargetInfo::getDefaultLangOptions(Opts);
+ GetWindowsLanguageOptions(Opts, getTargetTriple());
+ }
};
} // end anonymous namespace
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index 3c7c5e5..f9c44c8 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -782,29 +782,6 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy);
return Builder.CreateStore(Ops[1], Ops[0]);
}
- case X86::BI__builtin_ia32_loadlv4si: {
- // load i64
- const llvm::Type *EltTy = llvm::Type::Int64Ty;
- llvm::Type *PtrTy = llvm::PointerType::getUnqual(EltTy);
- Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy);
- Ops[0] = Builder.CreateLoad(Ops[0], "load");
-
- // scalar to vector: insert i64 into 2 x i64 undef
- llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2);
- llvm::Value *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
- Ops[0] = Builder.CreateInsertElement(llvm::UndefValue::get(VecTy),
- Ops[0], Zero, "s2v");
-
- // shuffle into zero vector.
- std::vector<llvm::Constant *>Elts;
- Elts.resize(2, llvm::ConstantInt::get(EltTy, 0));
- llvm::Value *ZV = ConstantVector::get(Elts);
- Ops[0] = EmitShuffleVector(ZV, Ops[0], 2, 1, "loadl");
-
- // bitcast to result.
- return Builder.CreateBitCast(Ops[0],
- llvm::VectorType::get(llvm::Type::Int32Ty, 4));
- }
}
}
diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp
index 01729fa..6cff75d 100644
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -310,7 +310,6 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
// Filter out some microsoft extensions when trying to parse in ms-compat
// mode.
if (LangOpts.Microsoft) {
- DefineBuiltinMacro(Buf, "_cdecl=__cdecl");
DefineBuiltinMacro(Buf, "__int8=__INT8_TYPE__");
DefineBuiltinMacro(Buf, "__int16=__INT16_TYPE__");
DefineBuiltinMacro(Buf, "__int32=__INT32_TYPE__");
diff --git a/lib/Frontend/RewriteBlocks.cpp b/lib/Frontend/RewriteBlocks.cpp
index 9d73d90..8393574 100644
--- a/lib/Frontend/RewriteBlocks.cpp
+++ b/lib/Frontend/RewriteBlocks.cpp
@@ -1011,9 +1011,7 @@ Stmt *RewriteBlocks::RewriteFunctionBody(Stmt *S) {
CI != E; ++CI)
if (*CI) {
if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) {
- Stmt *newStmt = RewriteFunctionBody(CBE->getBody());
- if (newStmt)
- *CI = newStmt;
+ RewriteFunctionBody(CBE->getBody());
// We've just rewritten the block body in place.
// Now we snarf the rewritten text and stash it away for later use.
@@ -1023,9 +1021,7 @@ Stmt *RewriteBlocks::RewriteFunctionBody(Stmt *S) {
// Do the rewrite, using S.size() which contains the rewritten size.
ReplaceText(CBE->getLocStart(), S.size(), Init.c_str(), Init.size());
} else {
- Stmt *newStmt = RewriteFunctionBody(*CI);
- if (newStmt)
- *CI = newStmt;
+ RewriteFunctionBody(*CI);
}
}
// Handle specific things.
diff --git a/lib/Headers/emmintrin.h b/lib/Headers/emmintrin.h
index 23a61a0..72710be 100644
--- a/lib/Headers/emmintrin.h
+++ b/lib/Headers/emmintrin.h
@@ -1020,7 +1020,7 @@ _mm_loadu_si128(__m128i const *p)
static inline __m128i __attribute__((__always_inline__, __nodebug__))
_mm_loadl_epi64(__m128i const *p)
{
- return (__m128i)__builtin_ia32_loadlv4si((__v2si *)p);
+ return (__m128i) { *(long long*)p, 0};
}
static inline __m128i __attribute__((__always_inline__, __nodebug__))
diff --git a/lib/Parse/AttributeList.cpp b/lib/Parse/AttributeList.cpp
index 0170a06..3fb6f95 100644
--- a/lib/Parse/AttributeList.cpp
+++ b/lib/Parse/AttributeList.cpp
@@ -18,9 +18,9 @@ using namespace clang;
AttributeList::AttributeList(IdentifierInfo *aName, SourceLocation aLoc,
IdentifierInfo *pName, SourceLocation pLoc,
ActionBase::ExprTy **ExprList, unsigned numArgs,
- AttributeList *n)
+ AttributeList *n, bool declspec)
: AttrName(aName), AttrLoc(aLoc), ParmName(pName), ParmLoc(pLoc),
- NumArgs(numArgs), Next(n) {
+ NumArgs(numArgs), Next(n), DeclspecAttribute(declspec) {
if (numArgs == 0)
Args = 0;
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 39eaf36..9aab3b9 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -200,18 +200,50 @@ AttributeList *Parser::ParseAttributes(SourceLocation *EndLoc) {
return CurrAttr;
}
-/// FuzzyParseMicrosoftDeclSpec. When -fms-extensions is enabled, this
-/// routine is called to skip/ignore tokens that comprise the MS declspec.
-void Parser::FuzzyParseMicrosoftDeclSpec() {
+/// ParseMicrosoftDeclSpec - Parse an __declspec construct
+///
+/// [MS] decl-specifier:
+/// __declspec ( extended-decl-modifier-seq )
+///
+/// [MS] extended-decl-modifier-seq:
+/// extended-decl-modifier[opt]
+/// extended-decl-modifier extended-decl-modifier-seq
+
+AttributeList* Parser::ParseMicrosoftDeclSpec() {
assert(Tok.is(tok::kw___declspec) && "Not a declspec!");
+
+ AttributeList *CurrAttr = 0;
ConsumeToken();
- if (Tok.is(tok::l_paren)) {
- unsigned short savedParenCount = ParenCount;
- do {
- ConsumeAnyToken();
- } while (ParenCount > savedParenCount && Tok.isNot(tok::eof));
- }
- return;
+ if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
+ "declspec")) {
+ SkipUntil(tok::r_paren, true); // skip until ) or ;
+ return CurrAttr;
+ }
+ while (Tok.is(tok::identifier) || Tok.is(tok::kw_restrict)) {
+ IdentifierInfo *AttrName = Tok.getIdentifierInfo();
+ SourceLocation AttrNameLoc = ConsumeToken();
+ if (Tok.is(tok::l_paren)) {
+ ConsumeParen();
+ // FIXME: This doesn't parse __declspec(property(get=get_func_name))
+ // correctly.
+ OwningExprResult ArgExpr(ParseAssignmentExpression());
+ if (!ArgExpr.isInvalid()) {
+ ExprTy* ExprList = ArgExpr.take();
+ CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0,
+ SourceLocation(), &ExprList, 1,
+ CurrAttr, true);
+ }
+ if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
+ SkipUntil(tok::r_paren, false);
+ } else {
+ CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, SourceLocation(),
+ 0, 0, CurrAttr, true);
+ }
+ }
+ if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
+ SkipUntil(tok::r_paren, false);
+ // FIXME: Return the attributes once we have some Sema support!
+ return 0;
}
/// ParseDeclaration - Parse a full 'declaration', which consists of
@@ -809,7 +841,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
case tok::kw___declspec:
if (!PP.getLangOptions().Microsoft)
goto DoneWithDeclSpec;
- FuzzyParseMicrosoftDeclSpec();
+ DS.AddAttributes(ParseMicrosoftDeclSpec());
continue;
// Microsoft single token adornments.
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 809dc10..0e8eebc 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -410,7 +410,8 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
// If declspecs exist after tag, parse them.
if (Tok.is(tok::kw___declspec) && PP.getLangOptions().Microsoft)
- FuzzyParseMicrosoftDeclSpec();
+ // FIXME: Need to do something with the attributes!
+ ParseMicrosoftDeclSpec();
// Parse the (optional) nested-name-specifier.
CXXScopeSpec SS;
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index d3bfef6..c558293 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1696,6 +1696,10 @@ public:
virtual ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
ExprTy **Strings,
unsigned NumStrings);
+
+ Expr *BuildObjCEncodeExpression(SourceLocation AtLoc,
+ QualType EncodedType,
+ SourceLocation RParenLoc);
virtual ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc,
SourceLocation EncodeLoc,
SourceLocation LParenLoc,
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index ee5132a..da32d4e 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -3003,8 +3003,8 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
compositeType = Context.getObjCIdType();
} else if (LHSBPT || RHSBPT) {
if (!sameKind
- || !Context.typesAreBlockCompatible(lhptee.getUnqualifiedType(),
- rhptee.getUnqualifiedType()))
+ || !Context.typesAreCompatible(lhptee.getUnqualifiedType(),
+ rhptee.getUnqualifiedType()))
Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
<< LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
return QualType();
@@ -3218,7 +3218,7 @@ Sema::CheckBlockPointerTypesForAssignment(QualType lhsType,
if (lhptee.getCVRQualifiers() != rhptee.getCVRQualifiers())
ConvTy = CompatiblePointerDiscardsQualifiers;
- if (!Context.typesAreBlockCompatible(lhptee, rhptee))
+ if (!Context.typesAreCompatible(lhptee, rhptee))
return IncompatibleBlockPointer;
return ConvTy;
}
@@ -3978,7 +3978,7 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
QualType rpointee = rType->getAsBlockPointerType()->getPointeeType();
if (!LHSIsNull && !RHSIsNull &&
- !Context.typesAreBlockCompatible(lpointee, rpointee)) {
+ !Context.typesAreCompatible(lpointee, rpointee)) {
Diag(Loc, diag::err_typecheck_comparison_of_distinct_blocks)
<< lType << rType << lex->getSourceRange() << rex->getSourceRange();
}
@@ -5220,7 +5220,7 @@ Sema::OwningExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
QualType BlockTy;
if (!BSI->hasPrototype)
- BlockTy = Context.getFunctionNoProtoType(RetTy);
+ BlockTy = Context.getFunctionType(RetTy, 0, 0, false, 0);
else
BlockTy = Context.getFunctionType(RetTy, ArgTypes.data(), ArgTypes.size(),
BSI->isVariadic, 0);
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index eabc87d..b6cf9d8 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -92,6 +92,29 @@ Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
return new (Context) ObjCStringLiteral(S, Ty, AtLocs[0]);
}
+Expr *Sema::BuildObjCEncodeExpression(SourceLocation AtLoc,
+ QualType EncodedType,
+ SourceLocation RParenLoc) {
+ QualType StrTy;
+ if (EncodedType->isDependentType())
+ StrTy = Context.DependentTy;
+ else {
+ std::string Str;
+ Context.getObjCEncodingForType(EncodedType, Str);
+
+ // The type of @encode is the same as the type of the corresponding string,
+ // which is an array type.
+ StrTy = Context.CharTy;
+ // A C++ string literal has a const-qualified element type (C++ 2.13.4p1).
+ if (getLangOptions().CPlusPlus)
+ StrTy.addConst();
+ StrTy = Context.getConstantArrayType(StrTy, llvm::APInt(32, Str.size()+1),
+ ArrayType::Normal, 0);
+ }
+
+ return new (Context) ObjCEncodeExpr(StrTy, EncodedType, AtLoc, RParenLoc);
+}
+
Sema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
SourceLocation EncodeLoc,
SourceLocation LParenLoc,
@@ -99,19 +122,7 @@ Sema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
SourceLocation RParenLoc) {
QualType EncodedType = QualType::getFromOpaquePtr(ty);
- std::string Str;
- Context.getObjCEncodingForType(EncodedType, Str);
-
- // The type of @encode is the same as the type of the corresponding string,
- // which is an array type.
- QualType StrTy = Context.CharTy;
- // A C++ string literal has a const-qualified element type (C++ 2.13.4p1).
- if (getLangOptions().CPlusPlus)
- StrTy.addConst();
- StrTy = Context.getConstantArrayType(StrTy, llvm::APInt(32, Str.size()+1),
- ArrayType::Normal, 0);
-
- return new (Context) ObjCEncodeExpr(StrTy, EncodedType, AtLoc, RParenLoc);
+ return BuildObjCEncodeExpression(AtLoc, EncodedType, RParenLoc);
}
Sema::ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index 812b319..db7e622 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -265,6 +265,37 @@ static bool DeduceTemplateArguments(ASTContext &Context, QualType Param,
return false;
}
+ case Type::FunctionProto: {
+ const FunctionProtoType *FunctionProtoArg =
+ dyn_cast<FunctionProtoType>(Arg);
+ if (!FunctionProtoArg)
+ return false;
+
+ const FunctionProtoType *FunctionProtoParam =
+ cast<FunctionProtoType>(Param);
+
+ // Check return types.
+ if (!DeduceTemplateArguments(Context,
+ FunctionProtoParam->getResultType(),
+ FunctionProtoArg->getResultType(),
+ Deduced))
+ return false;
+
+ if (FunctionProtoParam->getNumArgs() != FunctionProtoArg->getNumArgs())
+ return false;
+
+ for (unsigned I = 0, N = FunctionProtoParam->getNumArgs(); I != N; ++I) {
+ // Check argument types.
+ if (!DeduceTemplateArguments(Context,
+ FunctionProtoParam->getArgType(I),
+ FunctionProtoArg->getArgType(I),
+ Deduced))
+ return false;
+ }
+
+ return true;
+ }
+
default:
break;
}
diff --git a/lib/Sema/SemaTemplateInstantiateExpr.cpp b/lib/Sema/SemaTemplateInstantiateExpr.cpp
index 5ba42f2..fa5fdee 100644
--- a/lib/Sema/SemaTemplateInstantiateExpr.cpp
+++ b/lib/Sema/SemaTemplateInstantiateExpr.cpp
@@ -1216,15 +1216,22 @@ TemplateExprInstantiator::VisitCXXUnresolvedMemberExpr(
// Objective-C Expressions
//----------------------------------------------------------------------------
Sema::OwningExprResult
-TemplateExprInstantiator::VisitObjCStringLiteral(ObjCStringLiteral *E) {
- assert(false && "FIXME: Template instantiations for ObjC expressions");
- return SemaRef.ExprError();
+TemplateExprInstantiator::VisitObjCStringLiteral(ObjCStringLiteral *E) {
+ return SemaRef.Owned(E->Clone(SemaRef.Context));
}
Sema::OwningExprResult
-TemplateExprInstantiator::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
- assert(false && "FIXME: Template instantiations for ObjC expressions");
- return SemaRef.ExprError();
+TemplateExprInstantiator::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
+ QualType EncodedType = SemaRef.InstantiateType(E->getEncodedType(),
+ TemplateArgs,
+ /*FIXME:*/E->getAtLoc(),
+ DeclarationName());
+ if (EncodedType.isNull())
+ return SemaRef.ExprError();
+
+ return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(E->getAtLoc(),
+ EncodedType,
+ E->getRParenLoc()));
}
Sema::OwningExprResult
@@ -1235,14 +1242,12 @@ TemplateExprInstantiator::VisitObjCMessageExpr(ObjCMessageExpr *E) {
Sema::OwningExprResult
TemplateExprInstantiator::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
- assert(false && "FIXME: Template instantiations for ObjC expressions");
- return SemaRef.ExprError();
+ return SemaRef.Owned(E->Clone(SemaRef.Context));
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
- assert(false && "FIXME: Template instantiations for ObjC expressions");
- return SemaRef.ExprError();
+ return SemaRef.Owned(E->Clone(SemaRef.Context));
}
Sema::OwningExprResult
diff --git a/test/CodeGen/builtins-x86.c b/test/CodeGen/builtins-x86.c
index 8d4bcbf..f49e7b6 100644
--- a/test/CodeGen/builtins-x86.c
+++ b/test/CodeGen/builtins-x86.c
@@ -325,14 +325,9 @@ void f0() {
tmp_V8s = __builtin_ia32_pmaddwd128(tmp_V8s, tmp_V8s);
(void) __builtin_ia32_monitor(tmp_vp, tmp_Ui, tmp_Ui);
(void) __builtin_ia32_mwait(tmp_Ui, tmp_Ui);
-#ifdef USE_ALL
- tmp_V4f = __builtin_ia32_movshdup(tmp_V4f);
- tmp_V4f = __builtin_ia32_movsldup(tmp_V4f);
-#endif
tmp_V16c = __builtin_ia32_lddqu(tmp_cCp);
tmp_V2LLi = __builtin_ia32_palignr128(tmp_V2LLi, tmp_V2LLi, imm_i);
tmp_V1LLi = __builtin_ia32_palignr(tmp_V1LLi, tmp_V1LLi, imm_i);
- tmp_V4i = __builtin_ia32_loadlv4si(tmp_V2ip);
(void) __builtin_ia32_storelv4si(tmp_V2ip, tmp_V2LLi);
#ifdef USE_SSE4
tmp_V16c = __builtin_ia32_pblendvb128(tmp_V16c, tmp_V16c, tmp_V16c);
diff --git a/test/Sema/block-args.c b/test/Sema/block-args.c
index a2d8e5a..27bee77 100644
--- a/test/Sema/block-args.c
+++ b/test/Sema/block-args.c
@@ -18,7 +18,7 @@ void test() {
^{return 1;}();
^{return 2;}(arg); // expected-error {{too many arguments to block call}}
^(void){return 3;}(1); // expected-error {{too many arguments to block call}}
- ^(){return 4;}(arg); // C style (...), ok.
+ ^(){return 4;}(arg); // expected-error {{too many arguments to block call}}
^(int x, ...){return 5;}(arg, arg); // Explicit varargs, ok.
}
diff --git a/test/Sema/block-call.c b/test/Sema/block-call.c
index 9d3ff71..c42b642 100644
--- a/test/Sema/block-call.c
+++ b/test/Sema/block-call.c
@@ -7,10 +7,10 @@ int main() {
int (*FPL) (int) = FP; // C doesn't consider this an error.
// For Blocks, the ASTContext::typesAreBlockCompatible() makes sure this is an error.
- int (^PFR) (int) = IFP; // expected-error {{incompatible block pointer types initializing 'int (^)()', expected 'int (^)(int)'}}
+ int (^PFR) (int) = IFP; // OK
PFR = II; // OK
- int (^IFP) () = PFR;
+ int (^IFP) () = PFR; // OK
const int (^CIC) () = IFP; // expected-error {{incompatible block pointer types initializing 'int (^)()', expected 'int const (^)()'}}
diff --git a/test/Sema/block-misc.c b/test/Sema/block-misc.c
index 93ca3c4..294c295 100644
--- a/test/Sema/block-misc.c
+++ b/test/Sema/block-misc.c
@@ -10,7 +10,7 @@ int test1() {
if (PFR == II) // OK
donotwarn();
- if (PFR == IFP) // expected-error {{comparison of distinct block types}}
+ if (PFR == IFP) // OK
donotwarn();
if (PFR == (int (^) (int))IFP) // OK
@@ -25,7 +25,7 @@ int test1() {
if (!PFR) // OK
donotwarn();
- return PFR != IFP; // expected-error {{comparison of distinct block types}}
+ return PFR != IFP; // OK
}
int test2(double (^S)()) {
@@ -165,7 +165,7 @@ void test17() {
f(1 ? bp : vp);
f(1 ? vp : bp);
- f(1 ? bp : bp1); // expected-error {{incompatible operand types ('void (^)(int)' and 'void (^)()')}}
+ f(1 ? bp : bp1);
(void)(bp > rp); // expected-error {{invalid operands}}
(void)(bp > 0); // expected-error {{invalid operands}}
(void)(bp > bp); // expected-error {{invalid operands}}
diff --git a/test/SemaObjC/blocks.m b/test/SemaObjC/blocks.m
index baadbde..6dab289 100644
--- a/test/SemaObjC/blocks.m
+++ b/test/SemaObjC/blocks.m
@@ -28,7 +28,7 @@ void foo5(id (^objectCreationBlock)(int)) {
void bar6(id(^)(int));
void foo6(id (^objectCreationBlock)()) {
- return bar6(objectCreationBlock); // expected-error {{incompatible block pointer types passing 'id (^)()', expected 'id (^)(int)'}}
+ return bar6(objectCreationBlock);
}
void foo7(id (^x)(int)) {
diff --git a/test/SemaTemplate/instantiate-objc-1.mm b/test/SemaTemplate/instantiate-objc-1.mm
new file mode 100644
index 0000000..829acb2
--- /dev/null
+++ b/test/SemaTemplate/instantiate-objc-1.mm
@@ -0,0 +1,47 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+// Obj-C string literal expressions
+template <typename T> struct StringTest {
+ void f() {
+ (void)@"Hello";
+ }
+};
+
+template struct StringTest<int>;
+template struct StringTest<double>;
+
+// @selector expressions
+template <typename T> struct SelectorTest {
+ SEL f() {
+ return @selector(multiple:arguments:);
+ }
+ SEL f2() {
+ return @selector(multiple:arguments:);
+ }
+};
+
+template struct SelectorTest<int>;
+template struct SelectorTest<double>;
+
+// @protocol expressions
+@protocol P
+@end
+
+template <typename T> struct ProtocolTest {
+ void f() {
+ (void)@protocol(P);
+ }
+};
+
+template struct ProtocolTest<int>;
+template struct ProtocolTest<double>;
+
+// @encode expressions
+template <typename T> struct EncodeTest {
+ static const char *encode(T t) {
+ return @encode(T);
+ }
+};
+
+template struct EncodeTest<int>;
+template struct EncodeTest<double>;
diff --git a/test/SemaTemplate/temp_class_spec.cpp b/test/SemaTemplate/temp_class_spec.cpp
index 8cb46cf..4e4f556 100644
--- a/test/SemaTemplate/temp_class_spec.cpp
+++ b/test/SemaTemplate/temp_class_spec.cpp
@@ -102,3 +102,35 @@ struct get_array_size<T[N]> {
};
int array_size0[get_array_size<int[12]>::value == 12? 1 : -1];
+
+template<typename T>
+struct is_unary_function {
+ static const bool value = false;
+};
+
+template<typename T, typename U>
+struct is_unary_function<T (*)(U)> {
+ static const bool value = true;
+};
+
+int is_unary_function0[is_unary_function<int>::value ? -1 : 1];
+int is_unary_function1[is_unary_function<int (*)()>::value ? -1 : 1];
+int is_unary_function2[is_unary_function<int (*)(int, bool)>::value ? -1 : 1];
+int is_unary_function3[is_unary_function<int (*)(bool)>::value ? 1 : -1];
+int is_unary_function4[is_unary_function<int (*)(int)>::value ? 1 : -1];
+
+template<typename T>
+struct is_unary_function_with_same_return_type_as_argument_type {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_unary_function_with_same_return_type_as_argument_type<T (*)(T)> {
+ static const bool value = true;
+};
+
+int is_unary_function5[is_unary_function_with_same_return_type_as_argument_type<int>::value ? -1 : 1];
+int is_unary_function6[is_unary_function_with_same_return_type_as_argument_type<int (*)()>::value ? -1 : 1];
+int is_unary_function7[is_unary_function_with_same_return_type_as_argument_type<int (*)(int, bool)>::value ? -1 : 1];
+int is_unary_function8[is_unary_function_with_same_return_type_as_argument_type<int (*)(bool)>::value ? -1 : 1];
+int is_unary_function9[is_unary_function_with_same_return_type_as_argument_type<int (*)(int)>::value ? 1 : -1];
diff --git a/tools/clang-cc/clang-cc.cpp b/tools/clang-cc/clang-cc.cpp
index f38c6bd..c58340c 100644
--- a/tools/clang-cc/clang-cc.cpp
+++ b/tools/clang-cc/clang-cc.cpp
@@ -808,7 +808,8 @@ static void InitializeLanguageStandard(LangOptions &Options, LangKind LK,
if (PascalStrings.getPosition())
Options.PascalStrings = PascalStrings;
- Options.Microsoft = MSExtensions;
+ if (MSExtensions.getPosition())
+ Options.Microsoft = MSExtensions;
Options.WritableStrings = WritableStrings;
if (NoLaxVectorConversions.getPosition())
Options.LaxVectorConversions = 0;
OpenPOWER on IntegriCloud