diff options
32 files changed, 306 insertions, 138 deletions
diff --git a/docs/UsersManual.html b/docs/UsersManual.html index e7072da9fdf1..221e07cdfd52 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 cad5487ea374..b02faa8ff378 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 51b99610cd9d..ef78c4081e34 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 95d000346378..85381c0762d5 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 7c6b090a33a0..501807df77a3 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 9b65288f68e1..497b1884a3d8 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 8225c9d33abb..26cebf0915b4 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 6218ade32300..6125fc633d07 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 e6dea7cca955..fb28fd436700 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 4a53a4123d11..c12dd6747c6d 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 7d2d0ae17253..ed5eb46c2847 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 120d52543c0c..b4e32e9d9f37 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 3c7c5e539879..f9c44c89656e 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 01729fad5e72..6cff75daf3cb 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 9d73d90554ce..8393574d1e66 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 23a61a0b893f..72710be6b79a 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 0170a0671db7..3fb6f950efc4 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 39eaf36c9574..9aab3b9e790d 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 809dc10c3ab8..0e8eebce5c7c 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 d3bfef67cbc8..c5582935db7f 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 ee5132a7d8e0..da32d4ec1061 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 eabc87d7f3b8..b6cf9d8e738c 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 812b319804d7..db7e622f7f68 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 5ba42f2e5af9..fa5fdee2c13c 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 8d4bcbfab17b..f49e7b670dec 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 a2d8e5a86731..27bee77da6c6 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 9d3ff71e2195..c42b642337ca 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 93ca3c49d425..294c295c5f8c 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 baadbde3e040..6dab289ae9f2 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 000000000000..829acb2e199b --- /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 8cb46cf98f84..4e4f5560aef3 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 f38c6bde4183..c58340c3eee7 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;  | 
