Import Clang r73070.

This commit is contained in:
Ed Schouten 2009-06-08 15:36:55 +00:00
parent 70b4596d9d
commit 8ba99c0032
32 changed files with 306 additions and 138 deletions

View File

@ -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>

View File

@ -696,7 +696,6 @@ class ASTContext {
/// 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;

View File

@ -34,6 +34,8 @@ class ObjCStringLiteral : public Expr {
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 @@ class ObjCSelectorExpr : public Expr {
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 @@ class ObjCProtocolExpr : public Expr {
explicit ObjCProtocolExpr(EmptyShell Empty)
: Expr(ObjCProtocolExprClass, Empty) {}
ObjCProtocolExpr *Clone(ASTContext &C) const;
ObjCProtocolDecl *getProtocol() const { return Protocol; }
void setProtocol(ObjCProtocolDecl *P) { Protocol = P; }

View File

@ -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", "")

View File

@ -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]>;

View File

@ -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.

View File

@ -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 @@ class AttributeList {
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);

View File

@ -1064,7 +1064,7 @@ class Parser {
// 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

View File

@ -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,

View File

@ -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,

View File

@ -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.

View File

@ -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 @@ class WindowsX86_32TargetInfo : public X86_32TargetInfo {
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 @@ class WindowsX86_32TargetInfo : public X86_32TargetInfo {
Define(Defines, "_X86_");
Define(Defines, "__MSVCRT__");
}
virtual void getDefaultLangOptions(LangOptions &Opts) {
X86_32TargetInfo::getDefaultLangOptions(Opts);
GetWindowsLanguageOptions(Opts, getTargetTriple());
}
};
} // end anonymous namespace

View File

@ -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));
}
}
}

View File

@ -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__");

View File

@ -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.

View File

@ -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__))

View File

@ -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;

View File

@ -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.

View File

@ -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;

View File

@ -1696,6 +1696,10 @@ class Sema : public Action {
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,

View File

@ -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);

View File

@ -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,

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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.
}

View File

@ -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 (^)()'}}

View File

@ -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}}

View File

@ -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)) {

View File

@ -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>;

View File

@ -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];

View File

@ -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;