From xuzhongxing at gmail.com Mon Jan 11 00:52:54 2010 From: xuzhongxing at gmail.com (Zhongxing Xu) Date: Mon, 11 Jan 2010 06:52:54 -0000 Subject: [cfe-commits] r93146 - in /cfe/trunk: lib/Analysis/SVals.cpp test/Analysis/NSString-failed-cases.m test/Analysis/NSString.m Message-ID: <201001110652.o0B6qsIO028359@zion.cs.uiuc.edu> Author: zhongxingxu Date: Mon Jan 11 00:52:53 2010 New Revision: 93146 URL: http://llvm.org/viewvc/llvm-project?rev=93146&view=rev Log: Enhance SVals::getAsRegion: get the region that is converted to an integer. This with previous patch fixes a OSAtomic test case. Modified: cfe/trunk/lib/Analysis/SVals.cpp cfe/trunk/test/Analysis/NSString-failed-cases.m cfe/trunk/test/Analysis/NSString.m Modified: cfe/trunk/lib/Analysis/SVals.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/SVals.cpp?rev=93146&r1=93145&r2=93146&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/SVals.cpp (original) +++ cfe/trunk/lib/Analysis/SVals.cpp Mon Jan 11 00:52:53 2010 @@ -97,6 +97,10 @@ if (const loc::MemRegionVal *X = dyn_cast(this)) return X->getRegion(); + if (const nonloc::LocAsInteger *X = dyn_cast(this)) { + return X->getLoc().getAsRegion(); + } + return 0; } Modified: cfe/trunk/test/Analysis/NSString-failed-cases.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/NSString-failed-cases.m?rev=93146&r1=93145&r2=93146&view=diff ============================================================================== --- cfe/trunk/test/Analysis/NSString-failed-cases.m (original) +++ cfe/trunk/test/Analysis/NSString-failed-cases.m Mon Jan 11 00:52:53 2010 @@ -97,15 +97,6 @@ //===----------------------------------------------------------------------===// // FIXME: THIS TEST CASE INCORRECTLY REPORTS A LEAK. -void testOSCompareAndSwapXXBarrier_parameter(NSString **old) { - NSString *s = [[NSString alloc] init]; // no-warning - if (!COMPARE_SWAP_BARRIER((intptr_t) 0, (intptr_t) s, (intptr_t*) old)) - [s release]; - else - [*old release]; -} - -// FIXME: THIS TEST CASE INCORRECTLY REPORTS A LEAK. void testOSCompareAndSwapXXBarrier_parameter_no_direct_release(NSString **old) { NSString *s = [[NSString alloc] init]; // no-warning if (!COMPARE_SWAP_BARRIER((intptr_t) 0, (intptr_t) s, (intptr_t*) old)) Modified: cfe/trunk/test/Analysis/NSString.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/NSString.m?rev=93146&r1=93145&r2=93146&view=diff ============================================================================== --- cfe/trunk/test/Analysis/NSString.m (original) +++ cfe/trunk/test/Analysis/NSString.m Mon Jan 11 00:52:53 2010 @@ -388,3 +388,11 @@ } } @end + +void testOSCompareAndSwapXXBarrier_parameter(NSString **old) { + NSString *s = [[NSString alloc] init]; // no-warning + if (!COMPARE_SWAP_BARRIER((intptr_t) 0, (intptr_t) s, (intptr_t*) old)) + [s release]; + else + [*old release]; +} From xuzhongxing at gmail.com Mon Jan 11 01:40:01 2010 From: xuzhongxing at gmail.com (Zhongxing Xu) Date: Mon, 11 Jan 2010 07:40:01 -0000 Subject: [cfe-commits] r93148 - in /cfe/trunk: lib/Analysis/GRState.cpp test/Analysis/NSString-failed-cases.m test/Analysis/NSString.m Message-ID: <201001110740.o0B7e1Nm029942@zion.cs.uiuc.edu> Author: zhongxingxu Date: Mon Jan 11 01:40:00 2010 New Revision: 93148 URL: http://llvm.org/viewvc/llvm-project?rev=93148&view=rev Log: Enhance ScanReachableSymbols::scan(). Now another OSAtomic test case passes. The old test case has a little mistake. Removed: cfe/trunk/test/Analysis/NSString-failed-cases.m Modified: cfe/trunk/lib/Analysis/GRState.cpp cfe/trunk/test/Analysis/NSString.m Modified: cfe/trunk/lib/Analysis/GRState.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRState.cpp?rev=93148&r1=93147&r2=93148&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/GRState.cpp (original) +++ cfe/trunk/lib/Analysis/GRState.cpp Mon Jan 11 01:40:00 2010 @@ -267,6 +267,9 @@ if (loc::MemRegionVal *X = dyn_cast(&val)) return scan(X->getRegion()); + if (nonloc::LocAsInteger *X = dyn_cast(&val)) + return scan(X->getLoc()); + if (SymbolRef Sym = val.getAsSymbol()) return visitor.VisitSymbol(Sym); Removed: cfe/trunk/test/Analysis/NSString-failed-cases.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/NSString-failed-cases.m?rev=93147&view=auto ============================================================================== --- cfe/trunk/test/Analysis/NSString-failed-cases.m (original) +++ cfe/trunk/test/Analysis/NSString-failed-cases.m (removed) @@ -1,106 +0,0 @@ -// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=basic -verify %s -// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify %s -// RUN: %clang_cc1 -DTEST_64 -triple x86_64-apple-darwin10 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=basic -verify %s -// RUN: %clang_cc1 -DTEST_64 -triple x86_64-apple-darwin10 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify %s -// XFAIL: * - -//===----------------------------------------------------------------------===// -// The following code is reduced using delta-debugging from -// Foundation.h (Mac OS X). -// -// It includes the basic definitions for the test cases below. -// Not directly including Foundation.h directly makes this test case -// both svelte and portable to non-Mac platforms. -//===----------------------------------------------------------------------===// - -#ifdef TEST_64 -typedef long long int64_t; -_Bool OSAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue ); -#define COMPARE_SWAP_BARRIER OSAtomicCompareAndSwap64Barrier -typedef int64_t intptr_t; -#else -typedef int int32_t; -_Bool OSAtomicCompareAndSwap32Barrier( int32_t __oldValue, int32_t __newValue, volatile int32_t *__theValue ); -#define COMPARE_SWAP_BARRIER OSAtomicCompareAndSwap32Barrier -typedef int32_t intptr_t; -#endif - -typedef const void * CFTypeRef; -typedef const struct __CFString * CFStringRef; -typedef const struct __CFAllocator * CFAllocatorRef; -extern const CFAllocatorRef kCFAllocatorDefault; -extern CFTypeRef CFRetain(CFTypeRef cf); -void CFRelease(CFTypeRef cf); -typedef const struct __CFDictionary * CFDictionaryRef; -const void *CFDictionaryGetValue(CFDictionaryRef theDict, const void *key); -extern CFStringRef CFStringCreateWithFormat(CFAllocatorRef alloc, CFDictionaryRef formatOptions, CFStringRef format, ...); -typedef signed char BOOL; -typedef int NSInteger; -typedef unsigned int NSUInteger; - at class NSString, Protocol; -extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2))); -typedef NSInteger NSComparisonResult; -typedef struct _NSZone NSZone; - at class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; - at protocol NSObject -- (BOOL)isEqual:(id)object; -- (oneway void)release; -- (id)retain; -- (id)autorelease; - at end - at protocol NSCopying -- (id)copyWithZone:(NSZone *)zone; - at end - at protocol NSMutableCopying -- (id)mutableCopyWithZone:(NSZone *)zone; - at end - at protocol NSCoding -- (void)encodeWithCoder:(NSCoder *)aCoder; - at end - at interface NSObject {} -- (id)init; -+ (id)alloc; - at end -extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); -typedef struct {} NSFastEnumerationState; - at protocol NSFastEnumeration -- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len; - at end - at class NSString; -typedef struct _NSRange {} NSRange; - at interface NSArray : NSObject -- (NSUInteger)count; - at end - at interface NSMutableArray : NSArray -- (void)addObject:(id)anObject; -- (id)initWithCapacity:(NSUInteger)numItems; - at end -typedef unsigned short unichar; - at class NSData, NSArray, NSDictionary, NSCharacterSet, NSData, NSURL, NSError, NSLocale; -typedef NSUInteger NSStringCompareOptions; - at interface NSString : NSObject - (NSUInteger)length; -- (NSComparisonResult)compare:(NSString *)string; -- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask; -- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange; -- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange locale:(id)locale; -- (NSComparisonResult)caseInsensitiveCompare:(NSString *)string; -- (NSArray *)componentsSeparatedByCharactersInSet:(NSCharacterSet *)separator; -+ (id)stringWithFormat:(NSString *)format, ... __attribute__((format(__NSString__, 1, 2))); - at end - at interface NSSimpleCString : NSString {} @end - at interface NSConstantString : NSSimpleCString @end -extern void *_NSConstantStringClassReference; - -//===----------------------------------------------------------------------===// -// Test cases. These should all be merged into NSString.m once these tests -// stop reporting leaks. -//===----------------------------------------------------------------------===// - -// FIXME: THIS TEST CASE INCORRECTLY REPORTS A LEAK. -void testOSCompareAndSwapXXBarrier_parameter_no_direct_release(NSString **old) { - NSString *s = [[NSString alloc] init]; // no-warning - if (!COMPARE_SWAP_BARRIER((intptr_t) 0, (intptr_t) s, (intptr_t*) old)) - return; - else - [*old release]; -} Modified: cfe/trunk/test/Analysis/NSString.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/NSString.m?rev=93148&r1=93147&r2=93148&view=diff ============================================================================== --- cfe/trunk/test/Analysis/NSString.m (original) +++ cfe/trunk/test/Analysis/NSString.m Mon Jan 11 01:40:00 2010 @@ -396,3 +396,11 @@ else [*old release]; } + +void testOSCompareAndSwapXXBarrier_parameter_no_direct_release(NSString **old) { + NSString *s = [[NSString alloc] init]; // no-warning + if (!COMPARE_SWAP_BARRIER((intptr_t) 0, (intptr_t) s, (intptr_t*) old)) + [s release]; + else + return; +} From Ken.Dyck at onsemi.com Mon Jan 11 06:52:59 2010 From: Ken.Dyck at onsemi.com (Ken Dyck) Date: Mon, 11 Jan 2010 05:52:59 -0700 Subject: [cfe-commits] [Review] Rolling out ASTContext::getTypeSizeInChars() In-Reply-To: References: <8F2E4A8BCDA0B84DA6C9088EB5B27747D5EFEF@NAMAIL.ad.onsemi.com> Message-ID: <8F2E4A8BCDA0B84DA6C9088EB5B27747DF43FC@NAMAIL.ad.onsemi.com> On Saturday, January 09, 2010 5:05 PM, Chris Lattner wrote: > > On Jan 4, 2010, at 11:08 AM, Ken Dyck wrote: > > > > > The attached patches replace occurrences of > > ASTContext::getTypeSize()/8 with ASTContext::getTypeSizeInChars(), > > converting [u]int64_t variables to CharUnits ones where it seems > > appropriate. No functional changes are intended. The > changes touch the > > AST, Analysis, Sema, and CodeGen libraries and are split > into patches accordingly. > > Sorry for the delay, this code looks great to me. The only > thing that I don't like is the name 'getRaw()'. How about > just 'getValue()' or getAmount()? Sure. How about getQuantity(), in keeping with terminology already used in CharUnits.h? I suppose it would make sense to similarly rename fromRaw() and RawType then, too. If it's all the same to you, I'd like to do this renaming in a follow-up commit as it seems independent of the roll-out of getTypeSizeInChars(). -Ken From sebastian.redl at getdesigned.at Mon Jan 11 09:56:57 2010 From: sebastian.redl at getdesigned.at (Sebastian Redl) Date: Mon, 11 Jan 2010 15:56:57 -0000 Subject: [cfe-commits] r93150 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExpr.cpp test/SemaCXX/member-pointer.cpp Message-ID: <201001111556.o0BFuvxE032008@zion.cs.uiuc.edu> Author: cornedbee Date: Mon Jan 11 09:56:56 2010 New Revision: 93150 URL: http://llvm.org/viewvc/llvm-project?rev=93150&view=rev Log: Make Clang complain about taking the address of an unqualified member function. Fixes PR5985. Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/SemaExpr.cpp cfe/trunk/test/SemaCXX/member-pointer.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=93150&r1=93149&r2=93150&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Jan 11 09:56:56 2010 @@ -1661,6 +1661,8 @@ def err_typecheck_address_of : Error<"address of %0 requested">; def ext_typecheck_addrof_void : Extension< "ISO C forbids taking the address of an expression of type 'void'">; +def err_unqualified_pointer_member_function : Error< + "must explicitly qualify member function %0 when taking its address">; def err_typecheck_invalid_lvalue_addrof : Error< "address expression must be an lvalue or a function designator">; def err_typecheck_unary_expr : Error< Modified: cfe/trunk/lib/Sema/SemaExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=93150&r1=93149&r2=93150&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) +++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Jan 11 09:56:56 2010 @@ -5872,7 +5872,22 @@ NamedDecl *dcl = getPrimaryDecl(op); Expr::isLvalueResult lval = op->isLvalue(Context); - if (lval != Expr::LV_Valid && lval != Expr::LV_IncompleteVoidType) { + MemberExpr *ME = dyn_cast(op); + if (lval == Expr::LV_MemberFunction && ME && + isa(ME->getMemberDecl())) { + ValueDecl *dcl = cast(op)->getMemberDecl(); + // &f where f is a member of the current object, or &o.f, or &p->f + // All these are not allowed, and we need to catch them before the dcl + // branch of the if, below. + Diag(OpLoc, diag::err_unqualified_pointer_member_function) + << dcl; + // FIXME: Improve this diagnostic and provide a fixit. + + // Now recover by acting as if the function had been accessed qualified. + return Context.getMemberPointerType(op->getType(), + Context.getTypeDeclType(cast(dcl->getDeclContext())) + .getTypePtr()); + } else if (lval != Expr::LV_Valid && lval != Expr::LV_IncompleteVoidType) { // C99 6.5.3.2p1 // The operand must be either an l-value or a function designator if (!op->getType()->isFunctionType()) { Modified: cfe/trunk/test/SemaCXX/member-pointer.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/member-pointer.cpp?rev=93150&r1=93149&r2=93150&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/member-pointer.cpp (original) +++ cfe/trunk/test/SemaCXX/member-pointer.cpp Mon Jan 11 09:56:56 2010 @@ -80,7 +80,7 @@ void (HasMembers::*pmf)() = &HasMembers::f; void (*pnf)() = &Fake::f; - &hm.f; // FIXME: needs diagnostic expected-warning{{result unused}} + &hm.f; // expected-error {{must explicitly qualify}} expected-warning{{result unused}} void (HasMembers::*pmgv)() = &HasMembers::g; void (HasMembers::*pmgi)(int) = &HasMembers::g; @@ -136,3 +136,15 @@ OverloadsPtrMem m; int foo = m->*"Awesome!"; } + +namespace pr5985 { + struct c { + void h(); + void f() { + void (c::*p)(); + p = &h; // expected-error {{must explicitly qualify}} + p = &this->h; // expected-error {{must explicitly qualify}} + p = &(*this).h; // expected-error {{must explicitly qualify}} + } + }; +} From clattner at apple.com Mon Jan 11 10:55:13 2010 From: clattner at apple.com (Chris Lattner) Date: Mon, 11 Jan 2010 08:55:13 -0800 Subject: [cfe-commits] [Review] Rolling out ASTContext::getTypeSizeInChars() In-Reply-To: <8F2E4A8BCDA0B84DA6C9088EB5B27747DF43FC@NAMAIL.ad.onsemi.com> References: <8F2E4A8BCDA0B84DA6C9088EB5B27747D5EFEF@NAMAIL.ad.onsemi.com> <8F2E4A8BCDA0B84DA6C9088EB5B27747DF43FC@NAMAIL.ad.onsemi.com> Message-ID: <97EDA563-A518-482C-BF71-16633182C6AB@apple.com> On Jan 11, 2010, at 4:52 AM, Ken Dyck wrote: > > > On Saturday, January 09, 2010 5:05 PM, Chris Lattner wrote: >> >> On Jan 4, 2010, at 11:08 AM, Ken Dyck wrote: >> >>> >>> The attached patches replace occurrences of >>> ASTContext::getTypeSize()/8 with ASTContext::getTypeSizeInChars(), >>> converting [u]int64_t variables to CharUnits ones where it seems >>> appropriate. No functional changes are intended. The >> changes touch the >>> AST, Analysis, Sema, and CodeGen libraries and are split >> into patches accordingly. >> >> Sorry for the delay, this code looks great to me. The only >> thing that I don't like is the name 'getRaw()'. How about >> just 'getValue()' or getAmount()? > > Sure. How about getQuantity(), in keeping with terminology already used > in CharUnits.h? I suppose it would make sense to similarly rename > fromRaw() and RawType then, too. If it's all the same to you, I'd like > to do this renaming in a follow-up commit as it seems independent of the > roll-out of getTypeSizeInChars(). Sounds great! -Chris From ken.dyck at onsemi.com Mon Jan 11 11:06:35 2010 From: ken.dyck at onsemi.com (Ken Dyck) Date: Mon, 11 Jan 2010 17:06:35 -0000 Subject: [cfe-commits] r93153 - in /cfe/trunk: include/clang/AST/CharUnits.h lib/AST/ASTContext.cpp lib/AST/ExprConstant.cpp lib/Analysis/GRExprEngine.cpp lib/Analysis/MemRegion.cpp lib/Analysis/Store.cpp lib/CodeGen/CGBlocks.cpp lib/CodeGen/CGBlocks.h lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDecl.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGExprScalar.cpp lib/CodeGen/CodeGenFunction.cpp lib/CodeGen/CodeGenFunction.h lib/Sema/SemaChecking.cpp Message-ID: <201001111706.o0BH6aT3002216@zion.cs.uiuc.edu> Author: kjdyck Date: Mon Jan 11 11:06:35 2010 New Revision: 93153 URL: http://llvm.org/viewvc/llvm-project?rev=93153&view=rev Log: Roll out ASTContext::getTypeSizeInChars(), replacing instances of "ASTContext::getTypeSize() / 8". Replace [u]int64_t variables with CharUnits ones as appropriate. Also rename RawType, fromRaw(), and getRaw() in CharUnits to QuantityType, fromQuantity(), and getQuantity() for clarity. Modified: cfe/trunk/include/clang/AST/CharUnits.h cfe/trunk/lib/AST/ASTContext.cpp cfe/trunk/lib/AST/ExprConstant.cpp cfe/trunk/lib/Analysis/GRExprEngine.cpp cfe/trunk/lib/Analysis/MemRegion.cpp cfe/trunk/lib/Analysis/Store.cpp cfe/trunk/lib/CodeGen/CGBlocks.cpp cfe/trunk/lib/CodeGen/CGBlocks.h cfe/trunk/lib/CodeGen/CGDebugInfo.cpp cfe/trunk/lib/CodeGen/CGDecl.cpp cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/lib/CodeGen/CGExprScalar.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.h cfe/trunk/lib/Sema/SemaChecking.cpp Modified: cfe/trunk/include/clang/AST/CharUnits.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CharUnits.h?rev=93153&r1=93152&r2=93153&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/CharUnits.h (original) +++ cfe/trunk/include/clang/AST/CharUnits.h Mon Jan 11 11:06:35 2010 @@ -36,12 +36,12 @@ /// in character units. class CharUnits { public: - typedef int64_t RawType; + typedef int64_t QuantityType; private: - RawType Quantity; + QuantityType Quantity; - explicit CharUnits(RawType C) : Quantity(C) {} + explicit CharUnits(QuantityType C) : Quantity(C) {} public: @@ -58,8 +58,8 @@ return CharUnits(1); } - /// fromRaw - Construct a CharUnits quantity from a raw integer type. - static CharUnits fromRaw(RawType Quantity) { + /// fromQuantity - Construct a CharUnits quantity from a raw integer type. + static CharUnits fromQuantity(QuantityType Quantity) { return CharUnits(Quantity); } @@ -103,26 +103,26 @@ /// isOne - Test whether the quantity equals one. bool isOne() const { return Quantity == 1; } - /// isPositive - Test whether the quanity is greater than zero. + /// isPositive - Test whether the quantity is greater than zero. bool isPositive() const { return Quantity > 0; } /// isNegative - Test whether the quantity is less than zero. bool isNegative() const { return Quantity < 0; } // Arithmetic operators. - CharUnits operator* (RawType N) const { + CharUnits operator* (QuantityType N) const { return CharUnits(Quantity * N); } - CharUnits operator/ (RawType N) const { + CharUnits operator/ (QuantityType N) const { return CharUnits(Quantity / N); } - RawType operator/ (const CharUnits &Other) const { + QuantityType operator/ (const CharUnits &Other) const { return Quantity / Other.Quantity; } - CharUnits operator% (RawType N) const { + CharUnits operator% (QuantityType N) const { return CharUnits(Quantity % N); } - RawType operator% (const CharUnits &Other) const { + QuantityType operator% (const CharUnits &Other) const { return Quantity % Other.Quantity; } CharUnits operator+ (const CharUnits &Other) const { @@ -134,14 +134,14 @@ // Conversions. - /// getRaw - Get the raw integer representation of this quantity. - RawType getRaw() const { return Quantity; } + /// getQuantity - Get the raw integer representation of this quantity. + QuantityType getQuantity() const { return Quantity; } }; // class CharUnit } // namespace clang -inline clang::CharUnits operator* (clang::CharUnits::RawType Scale, +inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale, const clang::CharUnits &CU) { return CU * Scale; } Modified: cfe/trunk/lib/AST/ASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=93153&r1=93152&r2=93153&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTContext.cpp (original) +++ cfe/trunk/lib/AST/ASTContext.cpp Mon Jan 11 11:06:35 2010 @@ -814,10 +814,10 @@ /// getTypeSizeInChars - Return the size of the specified type, in characters. /// This method does not work on incomplete types. CharUnits ASTContext::getTypeSizeInChars(QualType T) { - return CharUnits::fromRaw(getTypeSize(T) / getCharWidth()); + return CharUnits::fromQuantity(getTypeSize(T) / getCharWidth()); } CharUnits ASTContext::getTypeSizeInChars(const Type *T) { - return CharUnits::fromRaw(getTypeSize(T) / getCharWidth()); + return CharUnits::fromQuantity(getTypeSize(T) / getCharWidth()); } /// getPreferredTypeAlign - Return the "preferred" alignment of the specified @@ -3138,15 +3138,20 @@ /// getObjCEncodingTypeSize returns size of type for objective-c encoding /// purpose. int ASTContext::getObjCEncodingTypeSize(QualType type) { - uint64_t sz = getTypeSize(type); + CharUnits sz = getTypeSizeInChars(type); // Make all integer and enum types at least as large as an int - if (sz > 0 && type->isIntegralType()) - sz = std::max(sz, getTypeSize(IntTy)); + if (sz.isPositive() && type->isIntegralType()) + sz = std::max(sz, getTypeSizeInChars(IntTy)); // Treat arrays as pointers, since that's how they're passed in. else if (type->isArrayType()) - sz = getTypeSize(VoidPtrTy); - return sz / getTypeSize(CharTy); + sz = getTypeSizeInChars(VoidPtrTy); + return sz.getQuantity(); +} + +static inline +std::string charUnitsToString(const CharUnits &CU) { + return llvm::itostr(CU.getQuantity()); } /// getObjCEncodingForBlockDecl - Return the encoded type for this method @@ -3162,17 +3167,17 @@ // Start with computing size of a pointer in number of bytes. // FIXME: There might(should) be a better way of doing this computation! SourceLocation Loc; - int PtrSize = getTypeSize(VoidPtrTy) / getTypeSize(CharTy); - int ParmOffset = PtrSize; + CharUnits PtrSize = getTypeSizeInChars(VoidPtrTy); + CharUnits ParmOffset = PtrSize; for (ObjCMethodDecl::param_iterator PI = Decl->param_begin(), E = Decl->param_end(); PI != E; ++PI) { QualType PType = (*PI)->getType(); - int sz = getObjCEncodingTypeSize(PType); - assert (sz > 0 && "BlockExpr - Incomplete param type"); + CharUnits sz = CharUnits::fromQuantity(getObjCEncodingTypeSize(PType)); + assert (sz.isPositive() && "BlockExpr - Incomplete param type"); ParmOffset += sz; } // Size of the argument frame - S += llvm::utostr(ParmOffset); + S += charUnitsToString(ParmOffset); // Block pointer and offset. S += "@?0"; ParmOffset = PtrSize; @@ -3192,8 +3197,8 @@ } else if (PType->isFunctionType()) PType = PVDecl->getType(); getObjCEncodingForType(PType, S); - S += llvm::utostr(ParmOffset); - ParmOffset += getObjCEncodingTypeSize(PType); + S += charUnitsToString(ParmOffset); + ParmOffset += CharUnits::fromQuantity(getObjCEncodingTypeSize(PType)); } } @@ -3210,20 +3215,21 @@ // Start with computing size of a pointer in number of bytes. // FIXME: There might(should) be a better way of doing this computation! SourceLocation Loc; - int PtrSize = getTypeSize(VoidPtrTy) / getTypeSize(CharTy); + CharUnits PtrSize = getTypeSizeInChars(VoidPtrTy); // The first two arguments (self and _cmd) are pointers; account for // their size. - int ParmOffset = 2 * PtrSize; + CharUnits ParmOffset = 2 * PtrSize; for (ObjCMethodDecl::param_iterator PI = Decl->param_begin(), E = Decl->param_end(); PI != E; ++PI) { QualType PType = (*PI)->getType(); - int sz = getObjCEncodingTypeSize(PType); - assert (sz > 0 && "getObjCEncodingForMethodDecl - Incomplete param type"); + CharUnits sz = CharUnits::fromQuantity(getObjCEncodingTypeSize(PType)); + assert (sz.isPositive() && + "getObjCEncodingForMethodDecl - Incomplete param type"); ParmOffset += sz; } - S += llvm::utostr(ParmOffset); + S += charUnitsToString(ParmOffset); S += "@0:"; - S += llvm::utostr(PtrSize); + S += charUnitsToString(PtrSize); // Argument types. ParmOffset = 2 * PtrSize; @@ -3243,8 +3249,8 @@ // 'in', 'inout', etc. getObjCEncodingForTypeQualifier(PVDecl->getObjCDeclQualifier(), S); getObjCEncodingForType(PType, S); - S += llvm::utostr(ParmOffset); - ParmOffset += getObjCEncodingTypeSize(PType); + S += charUnitsToString(ParmOffset); + ParmOffset += CharUnits::fromQuantity(getObjCEncodingTypeSize(PType)); } } Modified: cfe/trunk/lib/AST/ExprConstant.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=93153&r1=93152&r2=93153&view=diff ============================================================================== --- cfe/trunk/lib/AST/ExprConstant.cpp (original) +++ cfe/trunk/lib/AST/ExprConstant.cpp Mon Jan 11 11:06:35 2010 @@ -13,6 +13,7 @@ #include "clang/AST/APValue.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/CharUnits.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/StmtVisitor.h" #include "clang/AST/ASTDiagnostic.h" @@ -325,11 +326,11 @@ if (!EvaluateInteger(E->getIdx(), Index, Info)) return APValue(); - uint64_t ElementSize = Info.Ctx.getTypeSize(E->getType()) / 8; + CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(E->getType()); - uint64_t Offset = Index.getSExtValue() * ElementSize; + CharUnits Offset = Index.getSExtValue() * ElementSize; Result.setLValue(Result.getLValueBase(), - Result.getLValueOffset() + Offset); + Result.getLValueOffset() + Offset.getQuantity()); return Result; } @@ -410,22 +411,22 @@ return APValue(); QualType PointeeType = PExp->getType()->getAs()->getPointeeType(); - uint64_t SizeOfPointee; + CharUnits SizeOfPointee; // Explicitly handle GNU void* and function pointer arithmetic extensions. if (PointeeType->isVoidType() || PointeeType->isFunctionType()) - SizeOfPointee = 1; + SizeOfPointee = CharUnits::One(); else - SizeOfPointee = Info.Ctx.getTypeSize(PointeeType) / 8; + SizeOfPointee = Info.Ctx.getTypeSizeInChars(PointeeType); - uint64_t Offset = ResultLValue.getLValueOffset(); + CharUnits Offset = CharUnits::fromQuantity(ResultLValue.getLValueOffset()); if (E->getOpcode() == BinaryOperator::Add) Offset += AdditionalOffset.getLimitedValue() * SizeOfPointee; else Offset -= AdditionalOffset.getLimitedValue() * SizeOfPointee; - return APValue(ResultLValue.getLValueBase(), Offset); + return APValue(ResultLValue.getLValueBase(), Offset.getQuantity()); } APValue PointerExprEvaluator::VisitUnaryAddrOf(const UnaryOperator *E) { @@ -977,13 +978,14 @@ && VD->getType()->isObjectType() && !VD->getType()->isVariablyModifiedType() && !VD->getType()->isDependentType()) { - uint64_t Size = Info.Ctx.getTypeSize(VD->getType()) / 8; - uint64_t Offset = Base.Val.getLValueOffset(); - if (Offset <= Size) - Size -= Base.Val.getLValueOffset(); + CharUnits Size = Info.Ctx.getTypeSizeInChars(VD->getType()); + CharUnits Offset = + CharUnits::fromQuantity(Base.Val.getLValueOffset()); + if (!Offset.isNegative() && Offset <= Size) + Size -= Offset; else - Size = 0; - return Success(Size, E); + Size = CharUnits::Zero(); + return Success(Size.getQuantity(), E); } } } @@ -1175,7 +1177,7 @@ uint64_t D = LHSValue.getLValueOffset() - RHSValue.getLValueOffset(); if (!ElementType->isVoidType() && !ElementType->isFunctionType()) - D /= Info.Ctx.getTypeSize(ElementType) / 8; + D /= Info.Ctx.getTypeSizeInChars(ElementType).getQuantity(); return Success(D, E); } @@ -1335,8 +1337,7 @@ return false; // Get information about the size. - unsigned BitWidth = Info.Ctx.getTypeSize(SrcTy); - return Success(BitWidth / Info.Ctx.Target.getCharWidth(), E); + return Success(Info.Ctx.getTypeSizeInChars(SrcTy).getQuantity(), E); } bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=93153&r1=93152&r2=93153&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original) +++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Mon Jan 11 11:06:35 2010 @@ -17,6 +17,7 @@ #include "clang/Analysis/PathSensitive/GRExprEngine.h" #include "clang/Analysis/PathSensitive/GRExprEngineBuilders.h" #include "clang/Analysis/PathSensitive/Checker.h" +#include "clang/AST/CharUnits.h" #include "clang/AST/ParentMap.h" #include "clang/AST/StmtObjC.h" #include "clang/Basic/Builtins.h" @@ -2421,12 +2422,12 @@ ExplodedNode* Pred, ExplodedNodeSet& Dst) { QualType T = Ex->getTypeOfArgument(); - uint64_t amt; + CharUnits amt; if (Ex->isSizeOf()) { if (T == getContext().VoidTy) { // sizeof(void) == 1 byte. - amt = 1; + amt = CharUnits::One(); } else if (!T.getTypePtr()->isConstantSizeType()) { // FIXME: Add support for VLAs. @@ -2440,14 +2441,15 @@ } else { // All other cases. - amt = getContext().getTypeSize(T) / 8; + amt = getContext().getTypeSizeInChars(T); } } else // Get alignment of the type. - amt = getContext().getTypeAlign(T) / 8; + amt = CharUnits::fromQuantity(getContext().getTypeAlign(T) / 8); MakeNode(Dst, Ex, Pred, - GetState(Pred)->BindExpr(Ex, ValMgr.makeIntVal(amt, Ex->getType()))); + GetState(Pred)->BindExpr(Ex, + ValMgr.makeIntVal(amt.getQuantity(), Ex->getType()))); } Modified: cfe/trunk/lib/Analysis/MemRegion.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/MemRegion.cpp?rev=93153&r1=93152&r2=93153&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/MemRegion.cpp (original) +++ cfe/trunk/lib/Analysis/MemRegion.cpp Mon Jan 11 11:06:35 2010 @@ -17,6 +17,7 @@ #include "clang/Analysis/PathSensitive/MemRegion.h" #include "clang/Analysis/PathSensitive/ValueManager.h" #include "clang/Analysis/PathSensitive/AnalysisContext.h" +#include "clang/AST/CharUnits.h" #include "clang/AST/StmtVisitor.h" using namespace clang; @@ -689,7 +690,7 @@ } RegionRawOffset ElementRegion::getAsRawOffset() const { - int64_t offset = 0; + CharUnits offset = CharUnits::Zero(); const ElementRegion *ER = this; const MemRegion *superR = NULL; ASTContext &C = getContext(); @@ -714,7 +715,7 @@ break; } - int64_t size = (int64_t) (C.getTypeSize(elemType) / 8); + CharUnits size = C.getTypeSizeInChars(elemType); offset += (i * size); } @@ -727,7 +728,7 @@ } assert(superR && "super region cannot be NULL"); - return RegionRawOffset(superR, offset); + return RegionRawOffset(superR, offset.getQuantity()); } //===----------------------------------------------------------------------===// Modified: cfe/trunk/lib/Analysis/Store.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/Store.cpp?rev=93153&r1=93152&r2=93153&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/Store.cpp (original) +++ cfe/trunk/lib/Analysis/Store.cpp Mon Jan 11 11:06:35 2010 @@ -13,6 +13,7 @@ #include "clang/Analysis/PathSensitive/Store.h" #include "clang/Analysis/PathSensitive/GRState.h" +#include "clang/AST/CharUnits.h" using namespace clang; @@ -138,9 +139,9 @@ if (!baseR) return NULL; - int64_t off = rawOff.getByteOffset(); + CharUnits off = CharUnits::fromQuantity(rawOff.getByteOffset()); - if (off == 0) { + if (off.isZero()) { // Edge case: we are at 0 bytes off the beginning of baseR. We // check to see if type we are casting to is the same as the base // region. If so, just return the base region. @@ -168,7 +169,7 @@ // We can only compute sizeof(PointeeTy) if it is a complete type. if (IsCompleteType(Ctx, PointeeTy)) { // Compute the size in **bytes**. - int64_t pointeeTySize = (int64_t) (Ctx.getTypeSize(PointeeTy) / 8); + CharUnits pointeeTySize = Ctx.getTypeSizeInChars(PointeeTy); // Is the offset a multiple of the size? If so, we can layer the // ElementRegion (with elementType == PointeeTy) directly on top of @@ -182,7 +183,7 @@ if (!newSuperR) { // Create an intermediate ElementRegion to represent the raw byte. // This will be the super region of the final ElementRegion. - newSuperR = MakeElementRegion(baseR, Ctx.CharTy, off); + newSuperR = MakeElementRegion(baseR, Ctx.CharTy, off.getQuantity()); } return MakeElementRegion(newSuperR, PointeeTy, newIndex); Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=93153&r1=93152&r2=93153&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original) +++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Mon Jan 11 11:06:35 2010 @@ -24,7 +24,7 @@ using namespace CodeGen; llvm::Constant *CodeGenFunction:: -BuildDescriptorBlockDecl(bool BlockHasCopyDispose, uint64_t Size, +BuildDescriptorBlockDecl(bool BlockHasCopyDispose, CharUnits Size, const llvm::StructType* Ty, std::vector *NoteForHelper) { const llvm::Type *UnsignedLongTy @@ -40,7 +40,7 @@ // FIXME: What is the right way to say this doesn't fit? We should give // a user diagnostic in that case. Better fix would be to change the // API to size_t. - C = llvm::ConstantInt::get(UnsignedLongTy, Size); + C = llvm::ConstantInt::get(UnsignedLongTy, Size.getQuantity()); Elts.push_back(C); if (BlockHasCopyDispose) { @@ -176,7 +176,8 @@ // We run this first so that we set BlockHasCopyDispose from the entire // block literal. // __invoke - uint64_t subBlockSize, subBlockAlign; + CharUnits subBlockSize; + uint64_t subBlockAlign; llvm::SmallVector subBlockDeclRefDecls; bool subBlockHasCopyDispose = false; llvm::Function *Fn @@ -321,13 +322,13 @@ // compared to gcc by not grabbing the forwarding slot as this must // be done during Block_copy for us, and we can postpone the work // until then. - uint64_t offset = BlockDecls[BDRE->getDecl()]; + CharUnits offset = BlockDecls[BDRE->getDecl()]; llvm::Value *BlockLiteral = LoadBlockStruct(); Loc = Builder.CreateGEP(BlockLiteral, llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), - offset), + offset.getQuantity()), "block.literal"); Ty = llvm::PointerType::get(Ty, 0); Loc = Builder.CreateBitCast(Loc, Ty); @@ -513,12 +514,12 @@ return EmitCall(FnInfo, Func, ReturnValue, Args); } -uint64_t CodeGenFunction::AllocateBlockDecl(const BlockDeclRefExpr *E) { +CharUnits CodeGenFunction::AllocateBlockDecl(const BlockDeclRefExpr *E) { const ValueDecl *VD = E->getDecl(); - uint64_t &offset = BlockDecls[VD]; + CharUnits &offset = BlockDecls[VD]; // See if we have already allocated an offset for this variable. - if (offset) + if (offset.isPositive()) return offset; // Don't run the expensive check, unless we have to. @@ -535,13 +536,13 @@ llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const BlockDeclRefExpr *E) { const ValueDecl *VD = E->getDecl(); - uint64_t offset = AllocateBlockDecl(E); + CharUnits offset = AllocateBlockDecl(E); llvm::Value *BlockLiteral = LoadBlockStruct(); llvm::Value *V = Builder.CreateGEP(BlockLiteral, llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), - offset), + offset.getQuantity()), "block.literal"); if (E->isByRef()) { const llvm::Type *PtrStructTy @@ -594,10 +595,10 @@ // Block literal size. For global blocks we just use the size of the generic // block literal struct. - uint64_t BlockLiteralSize = - TheTargetData.getTypeStoreSizeInBits(getGenericBlockLiteralType()) / 8; + CharUnits BlockLiteralSize = CharUnits::fromQuantity( + TheTargetData.getTypeStoreSizeInBits(getGenericBlockLiteralType()) / 8); DescriptorFields[1] = - llvm::ConstantInt::get(UnsignedLongTy,BlockLiteralSize); + llvm::ConstantInt::get(UnsignedLongTy,BlockLiteralSize.getQuantity()); llvm::Constant *DescriptorStruct = llvm::ConstantStruct::get(VMContext, &DescriptorFields[0], 2, false); @@ -615,7 +616,8 @@ std::vector LiteralFields(FieldCount); CodeGenFunction::BlockInfo Info(0, n); - uint64_t subBlockSize, subBlockAlign; + CharUnits subBlockSize; + uint64_t subBlockAlign; llvm::SmallVector subBlockDeclRefDecls; bool subBlockHasCopyDispose = false; llvm::DenseMap LocalDeclMap; @@ -677,7 +679,7 @@ const BlockInfo& Info, const Decl *OuterFuncDecl, llvm::DenseMap ldm, - uint64_t &Size, + CharUnits &Size, uint64_t &Align, llvm::SmallVector &subBlockDeclRefDecls, bool &subBlockHasCopyDispose) { @@ -698,8 +700,9 @@ LocalDeclMap[VD] = i->second; } - BlockOffset = CGM.getTargetData() - .getTypeStoreSizeInBits(CGM.getGenericBlockLiteralType()) / 8; + BlockOffset = CharUnits::fromQuantity( + CGM.getTargetData() + .getTypeStoreSizeInBits(CGM.getGenericBlockLiteralType()) / 8); BlockAlign = getContext().getTypeAlign(getContext().VoidPtrTy) / 8; const FunctionType *BlockFunctionType = BExpr->getFunctionType(); @@ -799,7 +802,8 @@ // The runtime needs a minimum alignment of a void *. uint64_t MinAlign = getContext().getTypeAlign(getContext().VoidPtrTy) / 8; - BlockOffset = llvm::RoundUpToAlignment(BlockOffset, MinAlign); + BlockOffset = CharUnits::fromQuantity( + llvm::RoundUpToAlignment(BlockOffset.getQuantity(), MinAlign)); Size = BlockOffset; Align = BlockAlign; @@ -808,30 +812,32 @@ return Fn; } -uint64_t BlockFunction::getBlockOffset(const BlockDeclRefExpr *BDRE) { +CharUnits BlockFunction::getBlockOffset(const BlockDeclRefExpr *BDRE) { const ValueDecl *D = dyn_cast(BDRE->getDecl()); - uint64_t Size = getContext().getTypeSize(D->getType()) / 8; + CharUnits Size = getContext().getTypeSizeInChars(D->getType()); uint64_t Align = getContext().getDeclAlignInBytes(D); if (BDRE->isByRef()) { - Size = getContext().getTypeSize(getContext().VoidPtrTy) / 8; + Size = getContext().getTypeSizeInChars(getContext().VoidPtrTy); Align = getContext().getTypeAlign(getContext().VoidPtrTy) / 8; } assert ((Align > 0) && "alignment must be 1 byte or more"); - uint64_t OldOffset = BlockOffset; + CharUnits OldOffset = BlockOffset; // Ensure proper alignment, even if it means we have to have a gap - BlockOffset = llvm::RoundUpToAlignment(BlockOffset, Align); + BlockOffset = CharUnits::fromQuantity( + llvm::RoundUpToAlignment(BlockOffset.getQuantity(), Align)); BlockAlign = std::max(Align, BlockAlign); - uint64_t Pad = BlockOffset - OldOffset; - if (Pad) { - llvm::ArrayType::get(llvm::Type::getInt8Ty(VMContext), Pad); + CharUnits Pad = BlockOffset - OldOffset; + if (Pad.isPositive()) { + llvm::ArrayType::get(llvm::Type::getInt8Ty(VMContext), Pad.getQuantity()); QualType PadTy = getContext().getConstantArrayType(getContext().CharTy, - llvm::APInt(32, Pad), + llvm::APInt(32, + Pad.getQuantity()), ArrayType::Normal, 0); ValueDecl *PadDecl = VarDecl::Create(getContext(), 0, SourceLocation(), 0, QualType(PadTy), 0, VarDecl::None); Modified: cfe/trunk/lib/CodeGen/CGBlocks.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.h?rev=93153&r1=93152&r2=93153&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGBlocks.h (original) +++ cfe/trunk/lib/CodeGen/CGBlocks.h Mon Jan 11 11:06:35 2010 @@ -20,6 +20,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "clang/Basic/TargetInfo.h" +#include "clang/AST/CharUnits.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" @@ -175,13 +176,13 @@ /// BlockOffset - The offset in bytes for the next allocation of an /// imported block variable. - uint64_t BlockOffset; + CharUnits BlockOffset; /// BlockAlign - Maximal alignment needed for the Block expressed in bytes. uint64_t BlockAlign; /// getBlockOffset - Allocate an offset for the ValueDecl from a /// BlockDeclRefExpr in a block literal (BlockExpr). - uint64_t getBlockOffset(const BlockDeclRefExpr *E); + CharUnits getBlockOffset(const BlockDeclRefExpr *E); /// BlockHasCopyDispose - True iff the block uses copy/dispose. bool BlockHasCopyDispose; @@ -191,7 +192,7 @@ llvm::SmallVector BlockDeclRefDecls; /// BlockDecls - Offsets for all Decls in BlockDeclRefExprs. - std::map BlockDecls; + std::map BlockDecls; ImplicitParamDecl *BlockStructDecl; ImplicitParamDecl *getBlockStructDecl() { return BlockStructDecl; } Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=93153&r1=93152&r2=93153&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original) +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Mon Jan 11 11:06:35 2010 @@ -1379,7 +1379,7 @@ else Unit = llvm::DICompileUnit(); - uint64_t offset = CGF->BlockDecls[Decl]; + CharUnits offset = CGF->BlockDecls[Decl]; llvm::SmallVector addr; llvm::LLVMContext &VMContext = CGM.getLLVMContext(); addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), @@ -1387,22 +1387,24 @@ addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), llvm::DIFactory::OpPlus)); addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), - offset)); + offset.getQuantity())); if (BDRE->isByRef()) { addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), llvm::DIFactory::OpDeref)); addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), llvm::DIFactory::OpPlus)); - offset = CGF->LLVMPointerWidth/8; // offset of __forwarding field + // offset of __forwarding field + offset = CharUnits::fromQuantity(CGF->LLVMPointerWidth/8); addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), - offset)); + offset.getQuantity())); addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), llvm::DIFactory::OpDeref)); addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), llvm::DIFactory::OpPlus)); - offset = XOffset/8; // offset of x field + // offset of x field + offset = CharUnits::fromQuantity(XOffset/8); addr.push_back(llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), - offset)); + offset.getQuantity())); } // Create the descriptor for the variable. Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=93153&r1=93152&r2=93153&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGDecl.cpp (original) +++ cfe/trunk/lib/CodeGen/CGDecl.cpp Mon Jan 11 11:06:35 2010 @@ -473,7 +473,7 @@ llvm::IntegerType::get(VMContext, LLVMPointerWidth); llvm::Value *SizeVal = llvm::ConstantInt::get(IntPtr, - getContext().getTypeSizeInChars(Ty).getRaw()); + getContext().getTypeSizeInChars(Ty).getQuantity()); const llvm::Type *BP = llvm::Type::getInt8PtrTy(VMContext); if (Loc->getType() != BP) Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=93153&r1=93152&r2=93153&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Mon Jan 11 11:06:35 2010 @@ -1273,16 +1273,16 @@ QualType BaseType = getContext().getBaseElementType(VAT); - uint64_t BaseTypeSize = getContext().getTypeSize(BaseType) / 8; + CharUnits BaseTypeSize = getContext().getTypeSizeInChars(BaseType); Idx = Builder.CreateUDiv(Idx, llvm::ConstantInt::get(Idx->getType(), - BaseTypeSize)); + BaseTypeSize.getQuantity())); Address = Builder.CreateInBoundsGEP(Base, Idx, "arrayidx"); } else if (const ObjCInterfaceType *OIT = dyn_cast(E->getType())) { llvm::Value *InterfaceSize = llvm::ConstantInt::get(Idx->getType(), - getContext().getTypeSize(OIT) / 8); + getContext().getTypeSizeInChars(OIT).getQuantity()); Idx = Builder.CreateMul(Idx, InterfaceSize); Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=93153&r1=93152&r2=93153&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Mon Jan 11 11:06:35 2010 @@ -1310,7 +1310,7 @@ if (const ObjCInterfaceType *OIT = dyn_cast(ElementType)) { llvm::Value *InterfaceSize = llvm::ConstantInt::get(Idx->getType(), - CGF.getContext().getTypeSize(OIT) / 8); + CGF.getContext().getTypeSizeInChars(OIT).getQuantity()); Idx = Builder.CreateMul(Idx, InterfaceSize); const llvm::Type *i8Ty = llvm::Type::getInt8PtrTy(VMContext); Value *Casted = Builder.CreateBitCast(Ptr, i8Ty); @@ -1374,7 +1374,8 @@ dyn_cast(LHSElementType)) { llvm::Value *InterfaceSize = llvm::ConstantInt::get(Idx->getType(), - CGF.getContext().getTypeSize(OIT) / 8); + CGF.getContext(). + getTypeSizeInChars(OIT).getQuantity()); Idx = Builder.CreateMul(Idx, InterfaceSize); const llvm::Type *i8Ty = llvm::Type::getInt8PtrTy(VMContext); Value *LHSCasted = Builder.CreateBitCast(Ops.LHS, i8Ty); @@ -1398,14 +1399,14 @@ Value *LHS = Ops.LHS; Value *RHS = Ops.RHS; - uint64_t ElementSize; + CharUnits ElementSize; // Handle GCC extension for pointer arithmetic on void* and function pointer // types. if (LHSElementType->isVoidType() || LHSElementType->isFunctionType()) { - ElementSize = 1; + ElementSize = CharUnits::One(); } else { - ElementSize = CGF.getContext().getTypeSize(LHSElementType) / 8; + ElementSize = CGF.getContext().getTypeSizeInChars(LHSElementType); } const llvm::Type *ResultType = ConvertType(Ops.Ty); @@ -1414,13 +1415,14 @@ Value *BytesBetween = Builder.CreateSub(LHS, RHS, "sub.ptr.sub"); // Optimize out the shift for element size of 1. - if (ElementSize == 1) + if (ElementSize.isOne()) return BytesBetween; // Otherwise, do a full sdiv. This uses the "exact" form of sdiv, since // pointer difference in C is only defined in the case where both operands // are pointing to elements of an array. - Value *BytesPerElt = llvm::ConstantInt::get(ResultType, ElementSize); + Value *BytesPerElt = + llvm::ConstantInt::get(ResultType, ElementSize.getQuantity()); return Builder.CreateExactSDiv(BytesBetween, BytesPerElt, "sub.ptr.div"); } } Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=93153&r1=93152&r2=93153&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original) +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Mon Jan 11 11:06:35 2010 @@ -578,7 +578,7 @@ ElemSize = EmitVLASize(ElemTy); else ElemSize = llvm::ConstantInt::get(SizeTy, - getContext().getTypeSize(ElemTy) / 8); + getContext().getTypeSizeInChars(ElemTy).getQuantity()); llvm::Value *NumElements = EmitScalarExpr(VAT->getSizeExpr()); NumElements = Builder.CreateIntCast(NumElements, SizeTy, false, "tmp"); Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=93153&r1=93152&r2=93153&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original) +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Mon Jan 11 11:06:35 2010 @@ -17,6 +17,7 @@ #include "clang/AST/Type.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" +#include "clang/AST/CharUnits.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" @@ -463,7 +464,7 @@ llvm::Value *BuildBlockLiteralTmp(const BlockExpr *); llvm::Constant *BuildDescriptorBlockDecl(bool BlockHasCopyDispose, - uint64_t Size, + CharUnits Size, const llvm::StructType *, std::vector *); @@ -471,14 +472,14 @@ const BlockInfo& Info, const Decl *OuterFuncDecl, llvm::DenseMap ldm, - uint64_t &Size, uint64_t &Align, + CharUnits &Size, uint64_t &Align, llvm::SmallVector &subBlockDeclRefDecls, bool &subBlockHasCopyDispose); void BlockForwardSelf(); llvm::Value *LoadBlockStruct(); - uint64_t AllocateBlockDecl(const BlockDeclRefExpr *E); + CharUnits AllocateBlockDecl(const BlockDeclRefExpr *E); llvm::Value *GetAddrOfBlockDecl(const BlockDeclRefExpr *E); const llvm::Type *BuildByRefType(const ValueDecl *D); Modified: cfe/trunk/lib/Sema/SemaChecking.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=93153&r1=93152&r2=93153&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaChecking.cpp (original) +++ cfe/trunk/lib/Sema/SemaChecking.cpp Mon Jan 11 11:06:35 2010 @@ -14,6 +14,7 @@ #include "Sema.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/CharUnits.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" @@ -318,7 +319,7 @@ // Determine the index of the size. unsigned SizeIndex; - switch (Context.getTypeSize(ValType)/8) { + switch (Context.getTypeSizeInChars(ValType).getQuantity()) { case 1: SizeIndex = 0; break; case 2: SizeIndex = 1; break; case 4: SizeIndex = 2; break; From Ken.Dyck at onsemi.com Mon Jan 11 11:16:12 2010 From: Ken.Dyck at onsemi.com (Ken Dyck) Date: Mon, 11 Jan 2010 10:16:12 -0700 Subject: [cfe-commits] [Review] Rolling out ASTContext::getTypeSizeInChars() In-Reply-To: <97EDA563-A518-482C-BF71-16633182C6AB@apple.com> References: <8F2E4A8BCDA0B84DA6C9088EB5B27747D5EFEF@NAMAIL.ad.onsemi.com> <8F2E4A8BCDA0B84DA6C9088EB5B27747DF43FC@NAMAIL.ad.onsemi.com> <97EDA563-A518-482C-BF71-16633182C6AB@apple.com> Message-ID: <8F2E4A8BCDA0B84DA6C9088EB5B27747DF4501@NAMAIL.ad.onsemi.com> On Monday, January 11, 2010 11:55 AM, Chris Lattner wrote: > > On Jan 11, 2010, at 4:52 AM, Ken Dyck wrote: > > > On Saturday, January 09, 2010 5:05 PM, Chris Lattner wrote: > >> > >> On Jan 4, 2010, at 11:08 AM, Ken Dyck wrote: > >> > >>> The attached patches replace occurrences of > >>> ASTContext::getTypeSize()/8 with > ASTContext::getTypeSizeInChars(), > >>> converting [u]int64_t variables to CharUnits ones where it seems > >>> appropriate. No functional changes are intended. The > >> changes touch the > >>> AST, Analysis, Sema, and CodeGen libraries and are split > >> into patches accordingly. > >> > >> Sorry for the delay, this code looks great to me. The only thing > >> that I don't like is the name 'getRaw()'. How about just > >> 'getValue()' or getAmount()? > > > > Sure. How about getQuantity(), in keeping with terminology already > > used in CharUnits.h? I suppose it would make sense to > similarly rename > > fromRaw() and RawType then, too. If it's all the same to > you, I'd like > > to do this renaming in a follow-up commit as it seems > independent of > > the roll-out of getTypeSizeInChars(). > > Sounds great! Committed as r93153. It includes the renaming, too, as I had some extra time to make the changes while awaiting your reply. -Ken From clattner at apple.com Mon Jan 11 11:47:56 2010 From: clattner at apple.com (Chris Lattner) Date: Mon, 11 Jan 2010 09:47:56 -0800 Subject: [cfe-commits] [Review] Rolling out ASTContext::getTypeSizeInChars() In-Reply-To: <8F2E4A8BCDA0B84DA6C9088EB5B27747DF4501@NAMAIL.ad.onsemi.com> References: <8F2E4A8BCDA0B84DA6C9088EB5B27747D5EFEF@NAMAIL.ad.onsemi.com> <8F2E4A8BCDA0B84DA6C9088EB5B27747DF43FC@NAMAIL.ad.onsemi.com> <97EDA563-A518-482C-BF71-16633182C6AB@apple.com> <8F2E4A8BCDA0B84DA6C9088EB5B27747DF4501@NAMAIL.ad.onsemi.com> Message-ID: On Jan 11, 2010, at 9:16 AM, Ken Dyck wrote: >> >> Sounds great! > > Committed as r93153. It includes the renaming, too, as I had some extra > time to make the changes while awaiting your reply. Ok, thanks Ken, -Chris From fjahanian at apple.com Mon Jan 11 11:50:35 2010 From: fjahanian at apple.com (Fariborz Jahanian) Date: Mon, 11 Jan 2010 17:50:35 -0000 Subject: [cfe-commits] r93159 - in /cfe/trunk: lib/Frontend/RewriteObjC.cpp test/Rewriter/rewrite-ivar-use.m Message-ID: <201001111750.o0BHoZuv003794@zion.cs.uiuc.edu> Author: fjahanian Date: Mon Jan 11 11:50:35 2010 New Revision: 93159 URL: http://llvm.org/viewvc/llvm-project?rev=93159&view=rev Log: Fixup rewrite of ivars accessed via an explicit object in a function. Fixes radar 7522803. Modified: cfe/trunk/lib/Frontend/RewriteObjC.cpp cfe/trunk/test/Rewriter/rewrite-ivar-use.m Modified: cfe/trunk/lib/Frontend/RewriteObjC.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/RewriteObjC.cpp?rev=93159&r1=93158&r2=93159&view=diff ============================================================================== --- cfe/trunk/lib/Frontend/RewriteObjC.cpp (original) +++ cfe/trunk/lib/Frontend/RewriteObjC.cpp Mon Jan 11 11:50:35 2010 @@ -1235,8 +1235,9 @@ // Explicit ivar refs need to have a cast inserted. // FIXME: consider sharing some of this code with the code above. - if (const PointerType *pType = IV->getBase()->getType()->getAs()) { - ObjCInterfaceType *iFaceDecl = dyn_cast(pType->getPointeeType()); + if (IV->isArrow()) { + ObjCInterfaceType *iFaceDecl = + dyn_cast(BaseExpr->getType()->getPointeeType()); // lookup which class implements the instance variable. ObjCInterfaceDecl *clsDeclared = 0; iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(), Modified: cfe/trunk/test/Rewriter/rewrite-ivar-use.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Rewriter/rewrite-ivar-use.m?rev=93159&r1=93158&r2=93159&view=diff ============================================================================== --- cfe/trunk/test/Rewriter/rewrite-ivar-use.m (original) +++ cfe/trunk/test/Rewriter/rewrite-ivar-use.m Mon Jan 11 11:50:35 2010 @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -rewrite-objc %s -o - +// RUN: %clang_cc1 -rewrite-objc -fms-extensions %s -o - // radar 7490331 @interface Foo { @@ -10,6 +10,11 @@ @end @implementation Foo +// radar 7522803 +static void foo(id bar) { + int i = ((Foo *)bar)->a; +} + - (void)bar { a = 42; [self baz:b]; From shines_tao at 126.com Mon Jan 11 04:21:35 2010 From: shines_tao at 126.com (shines_tao) Date: Mon, 11 Jan 2010 18:21:35 +0800 (CST) Subject: [cfe-commits] help Message-ID: <29491259.375151263205295092.JavaMail.coremail@bj126app40.126.com> Hello everyone ,I have two questions about clang as follows: 1. In my computer(windows,cmake2.8,vs2008) ,clang&&llvm can be successfully built,but when I run them ,it failed.It told me that clang++ - Debug Win32 is out of date,whether should I build it or not. But when I choose either of the two choice ,it would fail.The failed information is that stringstream.exe can't be found or doesn't match . But some times ago ,it can work successfully. 2.I find that the project of clang-cc doesn't exist in \cfe\tools when I use svn update.But I remember it existed in clang 2.6 .I have no idea. Could someone help me ,thanks a lot. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/cfe-commits/attachments/20100111/25a4d84c/attachment.html From dgregor at apple.com Mon Jan 11 12:40:56 2010 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 11 Jan 2010 18:40:56 -0000 Subject: [cfe-commits] r93162 - in /cfe/trunk: include/clang/AST/DeclarationName.h lib/AST/DeclarationName.cpp lib/AST/TypePrinter.cpp lib/Sema/Sema.h lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaLookup.cpp lib/Sema/SemaOverload.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateDeduction.cpp lib/Sema/SemaType.cpp Message-ID: <201001111840.o0BIevZh005770@zion.cs.uiuc.edu> Author: dgregor Date: Mon Jan 11 12:40:55 2010 New Revision: 93162 URL: http://llvm.org/viewvc/llvm-project?rev=93162&view=rev Log: Implement name lookup for conversion function template specializations (C++ [temp.mem]p5-6), which involves template argument deduction based on the type named, e.g., given struct X { template operator T*(); } x; when we call x.operator int*(); we perform template argument deduction to determine that T=int. This template argument deduction is needed for template specialization and explicit instantiation, e.g., template<> X::operator float*() { /* ... */ } and when calling or otherwise naming a conversion function (as in the first example). This fixes PR5742 and PR5762, although there's some remaining ugliness that's causing out-of-line definitions of conversion function templates to fail. I'll look into that separately. Modified: cfe/trunk/include/clang/AST/DeclarationName.h cfe/trunk/lib/AST/DeclarationName.cpp cfe/trunk/lib/AST/TypePrinter.cpp cfe/trunk/lib/Sema/Sema.h cfe/trunk/lib/Sema/SemaDeclCXX.cpp cfe/trunk/lib/Sema/SemaExpr.cpp cfe/trunk/lib/Sema/SemaLookup.cpp cfe/trunk/lib/Sema/SemaOverload.cpp cfe/trunk/lib/Sema/SemaTemplate.cpp cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp cfe/trunk/lib/Sema/SemaType.cpp Modified: cfe/trunk/include/clang/AST/DeclarationName.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclarationName.h?rev=93162&r1=93161&r2=93162&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/DeclarationName.h (original) +++ cfe/trunk/include/clang/AST/DeclarationName.h Mon Jan 11 12:40:55 2010 @@ -190,6 +190,14 @@ /// getNameKind - Determine what kind of name this is. NameKind getNameKind() const; + /// \brief Determines whether the name itself is dependent, e.g., because it + /// involves a C++ type that is itself dependent. + /// + /// Note that this does not capture all of the notions of "dependent name", + /// because an identifier can be a dependent name if it is used as the + /// callee in a call expression with dependent arguments. + bool isDependentName() const; + /// getName - Retrieve the human-readable string for this name. std::string getAsString() const; Modified: cfe/trunk/lib/AST/DeclarationName.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclarationName.cpp?rev=93162&r1=93161&r2=93162&view=diff ============================================================================== --- cfe/trunk/lib/AST/DeclarationName.cpp (original) +++ cfe/trunk/lib/AST/DeclarationName.cpp Mon Jan 11 12:40:55 2010 @@ -180,6 +180,11 @@ return Identifier; } +bool DeclarationName::isDependentName() const { + QualType T = getCXXNameType(); + return !T.isNull() && T->isDependentType(); +} + std::string DeclarationName::getAsString() const { switch (getNameKind()) { case Identifier: Modified: cfe/trunk/lib/AST/TypePrinter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=93162&r1=93161&r2=93162&view=diff ============================================================================== --- cfe/trunk/lib/AST/TypePrinter.cpp (original) +++ cfe/trunk/lib/AST/TypePrinter.cpp Mon Jan 11 12:40:55 2010 @@ -271,6 +271,10 @@ S += ")"; + if (T->getNoReturnAttr()) + S += " __attribute__((noreturn))"; + + if (T->hasExceptionSpec()) { S += " throw("; if (T->hasAnyExceptionSpec()) @@ -287,10 +291,9 @@ S += ")"; } - if (T->getNoReturnAttr()) - S += " __attribute__((noreturn))"; - Print(T->getResultType(), S); + AppendTypeQualList(S, T->getTypeQuals()); + Print(T->getResultType(), S); } void TypePrinter::PrintFunctionNoProto(const FunctionNoProtoType *T, Modified: cfe/trunk/lib/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=93162&r1=93161&r2=93162&view=diff ============================================================================== --- cfe/trunk/lib/Sema/Sema.h (original) +++ cfe/trunk/lib/Sema/Sema.h Mon Jan 11 12:40:55 2010 @@ -1178,8 +1178,14 @@ LookupObjCImplementationName }; + /// \brief Specifies whether (or how) name lookup is being performed for a + /// redeclaration (vs. a reference). enum RedeclarationKind { - NotForRedeclaration, + /// \brief The lookup is a reference to this name that is not for the + /// purpose of redeclaring the name. + NotForRedeclaration = 0, + /// \brief The lookup results will be used for redeclaration of a name, + /// if an entity by that name already exists. ForRedeclaration }; Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=93162&r1=93161&r2=93162&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Jan 11 12:40:55 2010 @@ -2743,7 +2743,9 @@ << ClassType << ConvType; } - if (Conversion->getPreviousDeclaration()) { + if (Conversion->getPrimaryTemplate()) { + // ignore specializations + } else if (Conversion->getPreviousDeclaration()) { const NamedDecl *ExpectedPrevDecl = Conversion->getPreviousDeclaration(); if (FunctionTemplateDecl *ConversionTemplate = Conversion->getDescribedFunctionTemplate()) @@ -2754,7 +2756,7 @@ } else if (FunctionTemplateDecl *ConversionTemplate = Conversion->getDescribedFunctionTemplate()) ClassDecl->addConversionFunction(ConversionTemplate); - else if (!Conversion->getPrimaryTemplate()) // ignore specializations + else ClassDecl->addConversionFunction(Conversion); return DeclPtrTy::make(Conversion); Modified: cfe/trunk/lib/Sema/SemaExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=93162&r1=93161&r2=93162&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) +++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Jan 11 12:40:55 2010 @@ -1010,11 +1010,18 @@ // C++ [temp.dep.expr]p3: // An id-expression is type-dependent if it contains: + // -- an identifier that was declared with a dependent type, + // (note: handled after lookup) + // -- a template-id that is dependent, + // (note: handled in BuildTemplateIdExpr) + // -- a conversion-function-id that specifies a dependent type, // -- a nested-name-specifier that contains a class-name that // names a dependent type. // Determine whether this is a member of an unknown specialization; // we need to handle these differently. - if (SS.isSet() && IsDependentIdExpression(*this, SS)) { + if ((Name.getNameKind() == DeclarationName::CXXConversionFunctionName && + Name.getCXXNameType()->isDependentType()) || + (SS.isSet() && IsDependentIdExpression(*this, SS))) { return ActOnDependentIdExpression(SS, Name, NameLoc, isAddressOfOperand, TemplateArgs); @@ -2281,7 +2288,7 @@ } } - assert(BaseType->isDependentType()); + assert(BaseType->isDependentType() || Name.isDependentName()); // Get the type being accessed in BaseType. If this is an arrow, the BaseExpr // must have pointer type, and the accessed type is the pointee. @@ -3170,7 +3177,7 @@ Expr *Base = BaseArg.takeAs(); OwningExprResult Result(*this); - if (Base->getType()->isDependentType()) { + if (Base->getType()->isDependentType() || Name.isDependentName()) { Result = ActOnDependentMemberExpr(ExprArg(*this, Base), Base->getType(), IsArrow, OpLoc, SS, FirstQualifierInScope, Modified: cfe/trunk/lib/Sema/SemaLookup.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=93162&r1=93161&r2=93162&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaLookup.cpp (original) +++ cfe/trunk/lib/Sema/SemaLookup.cpp Mon Jan 11 12:40:55 2010 @@ -444,10 +444,81 @@ bool Found = false; DeclContext::lookup_const_iterator I, E; - for (llvm::tie(I, E) = DC->lookup(R.getLookupName()); I != E; ++I) - if (R.isAcceptableDecl(*I)) - R.addDecl(*I), Found = true; + for (llvm::tie(I, E) = DC->lookup(R.getLookupName()); I != E; ++I) { + if (R.isAcceptableDecl(*I)) { + R.addDecl(*I); + Found = true; + } + } + if (R.getLookupName().getNameKind() + == DeclarationName::CXXConversionFunctionName && + !R.getLookupName().getCXXNameType()->isDependentType() && + isa(DC)) { + // C++ [temp.mem]p6: + // A specialization of a conversion function template is not found by + // name lookup. Instead, any conversion function templates visible in the + // context of the use are considered. [...] + const CXXRecordDecl *Record = cast(DC); + + const UnresolvedSet *Unresolved = Record->getConversionFunctions(); + for (UnresolvedSet::iterator U = Unresolved->begin(), + UEnd = Unresolved->end(); + U != UEnd; ++U) { + FunctionTemplateDecl *ConvTemplate = dyn_cast(*U); + if (!ConvTemplate) + continue; + + // When we're performing lookup for the purposes of redeclaration, just + // add the conversion function template. When we deduce template + // arguments for specializations, we'll end up unifying the return + // type of the new declaration with the type of the function template. + if (R.isForRedeclaration()) { + R.addDecl(ConvTemplate); + Found = true; + continue; + } + + // C++ [temp.mem]p6: + // [...] For each such operator, if argument deduction succeeds + // (14.9.2.3), the resulting specialization is used as if found by + // name lookup. + // + // When referencing a conversion function for any purpose other than + // a redeclaration (such that we'll be building an expression with the + // result), perform template argument deduction and place the + // specialization into the result set. We do this to avoid forcing all + // callers to perform special deduction for conversion functions. + Sema::TemplateDeductionInfo Info(R.getSema().Context); + FunctionDecl *Specialization = 0; + + const FunctionProtoType *ConvProto + = ConvTemplate->getTemplatedDecl()->getType() + ->getAs(); + assert(ConvProto && "Nonsensical conversion function template type"); + + // Compute the type of the function that we would expect the conversion + // function to have, if it were to match the name given. + // FIXME: Calling convention! + QualType ExpectedType + = R.getSema().Context.getFunctionType( + R.getLookupName().getCXXNameType(), + 0, 0, ConvProto->isVariadic(), + ConvProto->getTypeQuals(), + false, false, 0, 0, + ConvProto->getNoReturnAttr()); + + // Perform template argument deduction against the type that we would + // expect the function to have. + if (R.getSema().DeduceTemplateArguments(ConvTemplate, 0, ExpectedType, + Specialization, Info) + == Sema::TDK_Success) { + R.addDecl(Specialization); + Found = true; + } + } + } + return Found; } Modified: cfe/trunk/lib/Sema/SemaOverload.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=93162&r1=93161&r2=93162&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOverload.cpp (original) +++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Jan 11 12:40:55 2010 @@ -2307,8 +2307,6 @@ const FunctionProtoType* Proto = dyn_cast(Function->getType()->getAs()); assert(Proto && "Functions without a prototype cannot be overloaded"); - assert(!isa(Function) && - "Use AddConversionCandidate for conversion functions"); assert(!Function->getDescribedFunctionTemplate() && "Use AddTemplateOverloadCandidate for function templates"); @@ -2509,8 +2507,6 @@ const FunctionProtoType* Proto = dyn_cast(Method->getType()->getAs()); assert(Proto && "Methods without a prototype cannot be overloaded"); - assert(!isa(Method) && - "Use AddConversionCandidate for conversion functions"); assert(!isa(Method) && "Use AddOverloadCandidate for constructors"); Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=93162&r1=93161&r2=93162&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon Jan 11 12:40:55 2010 @@ -4540,8 +4540,10 @@ if (CXXMethodDecl *Method = dyn_cast(Prev)) { if (Context.hasSameUnqualifiedType(Method->getType(), R)) { Matches.clear(); + Matches.push_back(Method); - break; + if (Method->getTemplateSpecializationKind() == TSK_Undeclared) + break; } } } @@ -4553,7 +4555,7 @@ TemplateDeductionInfo Info(Context); FunctionDecl *Specialization = 0; if (TemplateDeductionResult TDK - = DeduceTemplateArguments(FunTmpl, + = DeduceTemplateArguments(FunTmpl, (HasExplicitTemplateArgs ? &TemplateArgs : 0), R, Specialization, Info)) { // FIXME: Keep track of almost-matches? Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=93162&r1=93161&r2=93162&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Mon Jan 11 12:40:55 2010 @@ -1312,20 +1312,18 @@ /// \param FunctionTemplate the function template for which we are performing /// template argument deduction. /// -/// \param HasExplicitTemplateArgs whether any template arguments were -/// explicitly specified. -/// -/// \param ExplicitTemplateArguments when @p HasExplicitTemplateArgs is true, -/// the explicitly-specified template arguments. -/// -/// \param NumExplicitTemplateArguments when @p HasExplicitTemplateArgs is true, -/// the number of explicitly-specified template arguments in -/// @p ExplicitTemplateArguments. This value may be zero. +/// \param ExplicitTemplateArguments the explicit template arguments provided +/// for this call. /// /// \param Args the function call arguments /// /// \param NumArgs the number of arguments in Args /// +/// \param Name the name of the function being called. This is only significant +/// when the function template is a conversion function template, in which +/// case this routine will also perform template argument deduction based on +/// the function to which +/// /// \param Specialization if template argument deduction was successful, /// this will be set to the function template specialization produced by /// template argument deduction. @@ -1336,7 +1334,7 @@ /// \returns the result of template argument deduction. Sema::TemplateDeductionResult Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, - const TemplateArgumentListInfo *ExplicitTemplateArgs, + const TemplateArgumentListInfo *ExplicitTemplateArgs, Expr **Args, unsigned NumArgs, FunctionDecl *&Specialization, TemplateDeductionInfo &Info) { Modified: cfe/trunk/lib/Sema/SemaType.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=93162&r1=93161&r2=93162&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaType.cpp (original) +++ cfe/trunk/lib/Sema/SemaType.cpp Mon Jan 11 12:40:55 2010 @@ -897,12 +897,16 @@ case UnqualifiedId::IK_ConstructorName: case UnqualifiedId::IK_DestructorName: - case UnqualifiedId::IK_ConversionFunctionId: // Constructors and destructors don't have return types. Use - // "void" instead. Conversion operators will check their return - // types separately. + // "void" instead. T = Context.VoidTy; break; + + case UnqualifiedId::IK_ConversionFunctionId: + // The result type of a conversion function is the type that it + // converts to. + T = GetTypeFromParser(D.getName().ConversionFunctionId); + break; } if (T.isNull()) @@ -1041,7 +1045,8 @@ const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun; // C99 6.7.5.3p1: The return type may not be a function or array type. - if (T->isArrayType() || T->isFunctionType()) { + if ((T->isArrayType() || T->isFunctionType()) && + (D.getName().getKind() != UnqualifiedId::IK_ConversionFunctionId)) { Diag(DeclType.Loc, diag::err_func_returning_array_function) << T; T = Context.IntTy; D.setInvalidType(true); From dgregor at apple.com Mon Jan 11 12:46:22 2010 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 11 Jan 2010 18:46:22 -0000 Subject: [cfe-commits] r93164 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaType.cpp test/Sema/declspec.c test/Sema/invalid-decl.c Message-ID: <201001111846.o0BIkNnF006060@zion.cs.uiuc.edu> Author: dgregor Date: Mon Jan 11 12:46:21 2010 New Revision: 93164 URL: http://llvm.org/viewvc/llvm-project?rev=93164&view=rev Log: Tighten up the "cannot return array or function type" diagnostic to say either "array type" or "function type", whichever it is. No reason to make the user guess. Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/SemaType.cpp cfe/trunk/test/Sema/declspec.c cfe/trunk/test/Sema/invalid-decl.c Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=93164&r1=93163&r2=93164&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Jan 11 12:46:21 2010 @@ -1484,7 +1484,7 @@ "jump bypasses setup of __block variable">; def err_func_returning_array_function : Error< - "function cannot return array or function type %0">; + "function cannot return %select{array|function}0 type %1">; def err_field_declared_as_function : Error<"field %0 declared as a function">; def err_field_incomplete : Error<"field has incomplete type %0">; def ext_variable_sized_type_in_struct : ExtWarn< Modified: cfe/trunk/lib/Sema/SemaType.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=93164&r1=93163&r2=93164&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaType.cpp (original) +++ cfe/trunk/lib/Sema/SemaType.cpp Mon Jan 11 12:46:21 2010 @@ -743,7 +743,8 @@ bool Variadic, unsigned Quals, SourceLocation Loc, DeclarationName Entity) { if (T->isArrayType() || T->isFunctionType()) { - Diag(Loc, diag::err_func_returning_array_function) << T; + Diag(Loc, diag::err_func_returning_array_function) + << T->isFunctionType() << T; return QualType(); } @@ -1045,9 +1046,11 @@ const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun; // C99 6.7.5.3p1: The return type may not be a function or array type. + // For conversion functions, we'll diagnose this particular error later. if ((T->isArrayType() || T->isFunctionType()) && (D.getName().getKind() != UnqualifiedId::IK_ConversionFunctionId)) { - Diag(DeclType.Loc, diag::err_func_returning_array_function) << T; + Diag(DeclType.Loc, diag::err_func_returning_array_function) + << T->isFunctionType() << T; T = Context.IntTy; D.setInvalidType(true); } Modified: cfe/trunk/test/Sema/declspec.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/declspec.c?rev=93164&r1=93163&r2=93164&view=diff ============================================================================== --- cfe/trunk/test/Sema/declspec.c (original) +++ cfe/trunk/test/Sema/declspec.c Mon Jan 11 12:46:21 2010 @@ -1,7 +1,7 @@ // RUN: %clang_cc1 %s -verify -fsyntax-only typedef char T[4]; -T foo(int n, int m) { } // expected-error {{cannot return array or function}} +T foo(int n, int m) { } // expected-error {{cannot return array type}} void foof(const char *, ...) __attribute__((__format__(__printf__, 1, 2))), barf (void); Modified: cfe/trunk/test/Sema/invalid-decl.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/invalid-decl.c?rev=93164&r1=93163&r2=93164&view=diff ============================================================================== --- cfe/trunk/test/Sema/invalid-decl.c (original) +++ cfe/trunk/test/Sema/invalid-decl.c Mon Jan 11 12:46:21 2010 @@ -6,7 +6,7 @@ // PR2400 -typedef xtype (*x)(void* handle); // expected-error {{function cannot return array or function type}} expected-warning {{type specifier missing, defaults to 'int'}} expected-warning {{type specifier missing, defaults to 'int'}} +typedef xtype (*x)(void* handle); // expected-error {{function cannot return function type}} expected-warning {{type specifier missing, defaults to 'int'}} expected-warning {{type specifier missing, defaults to 'int'}} typedef void ytype(); From dgregor at apple.com Mon Jan 11 12:53:27 2010 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 11 Jan 2010 18:53:27 -0000 Subject: [cfe-commits] r93166 - /cfe/trunk/lib/Sema/SemaDeclCXX.cpp Message-ID: <201001111853.o0BIrUFj006429@zion.cs.uiuc.edu> Author: dgregor Date: Mon Jan 11 12:53:25 2010 New Revision: 93166 URL: http://llvm.org/viewvc/llvm-project?rev=93166&view=rev Log: Add support for out-of-line definitions of conversion function templates. Previously, a little thinko in the code that replaced a conversion function template with its redeclaration was causing some very weird lookup behavior. Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=93166&r1=93165&r2=93166&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Jan 11 12:53:25 2010 @@ -2746,11 +2746,14 @@ if (Conversion->getPrimaryTemplate()) { // ignore specializations } else if (Conversion->getPreviousDeclaration()) { - const NamedDecl *ExpectedPrevDecl = Conversion->getPreviousDeclaration(); if (FunctionTemplateDecl *ConversionTemplate - = Conversion->getDescribedFunctionTemplate()) - ExpectedPrevDecl = ConversionTemplate->getPreviousDeclaration(); - if (ClassDecl->replaceConversion(ExpectedPrevDecl, Conversion)) + = Conversion->getDescribedFunctionTemplate()) { + if (ClassDecl->replaceConversion( + ConversionTemplate->getPreviousDeclaration(), + ConversionTemplate)) + return DeclPtrTy::make(ConversionTemplate); + } else if (ClassDecl->replaceConversion(Conversion->getPreviousDeclaration(), + Conversion)) return DeclPtrTy::make(Conversion); assert(Conversion->isInvalidDecl() && "Conversion should not get here."); } else if (FunctionTemplateDecl *ConversionTemplate From dgregor at apple.com Mon Jan 11 13:00:50 2010 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 11 Jan 2010 19:00:50 -0000 Subject: [cfe-commits] r93168 - /cfe/trunk/lib/Sema/SemaOverload.cpp Message-ID: <201001111900.o0BJ0ocd006763@zion.cs.uiuc.edu> Author: dgregor Date: Mon Jan 11 13:00:50 2010 New Revision: 93168 URL: http://llvm.org/viewvc/llvm-project?rev=93168&view=rev Log: Remove some pointless FIXMEs. No functionality change Modified: cfe/trunk/lib/Sema/SemaOverload.cpp Modified: cfe/trunk/lib/Sema/SemaOverload.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=93168&r1=93167&r2=93168&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOverload.cpp (original) +++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Jan 11 13:00:50 2010 @@ -639,7 +639,6 @@ } else if ((FromType->isIntegralType() || FromType->isEnumeralType()) && (ToType->isIntegralType() && !ToType->isEnumeralType())) { // Integral conversions (C++ 4.7). - // FIXME: isIntegralType shouldn't be true for enums in C++. SCS.Second = ICK_Integral_Conversion; FromType = ToType.getUnqualifiedType(); } else if (FromType->isFloatingType() && ToType->isFloatingType()) { @@ -656,7 +655,6 @@ ((FromType->isIntegralType() || FromType->isEnumeralType()) && ToType->isFloatingType())) { // Floating-integral conversions (C++ 4.9). - // FIXME: isIntegralType shouldn't be true for enums in C++. SCS.Second = ICK_Floating_Integral; FromType = ToType.getUnqualifiedType(); } else if ((FromType->isComplexType() && ToType->isArithmeticType()) || @@ -2468,8 +2466,6 @@ Expr **Args, unsigned NumArgs, OverloadCandidateSet& CandidateSet, bool SuppressUserConversions, bool ForceRValue) { - - // FIXME: use this CXXRecordDecl *ActingContext = cast(Decl->getDeclContext()); if (isa(Decl)) @@ -4789,7 +4785,6 @@ // resulting template argument list is used to generate a single // function template specialization, which is added to the set of // overloaded functions considered. - // FIXME: We don't really want to build the specialization here, do we? FunctionDecl *Specialization = 0; TemplateDeductionInfo Info(Context); if (TemplateDeductionResult Result From csdavec at swan.ac.uk Mon Jan 11 13:02:36 2010 From: csdavec at swan.ac.uk (David Chisnall) Date: Mon, 11 Jan 2010 19:02:36 -0000 Subject: [cfe-commits] r93169 - /cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Message-ID: <201001111902.o0BJ2aq5006853@zion.cs.uiuc.edu> Author: theraven Date: Mon Jan 11 13:02:35 2010 New Revision: 93169 URL: http://llvm.org/viewvc/llvm-project?rev=93169&view=rev Log: Fix type mismatch on 64-bit platforms (GNU ObjC). Modified: cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Modified: cfe/trunk/lib/CodeGen/CGObjCGNU.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCGNU.cpp?rev=93169&r1=93168&r2=93169&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGObjCGNU.cpp (original) +++ cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Mon Jan 11 13:02:35 2010 @@ -1934,7 +1934,7 @@ if (!IvarOffsetPointer) { uint64_t Offset = ComputeIvarBaseOffset(CGM, ID, Ivar); llvm::ConstantInt *OffsetGuess = - llvm::ConstantInt::get(LongTy, Offset, "ivar"); + llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Offset, "ivar"); // Don't emit the guess in non-PIC code because the linker will not be able // to replace it with the real version for a library. In non-PIC code you // must compile with the fragile ABI if you want to use ivars from a From ken.dyck at onsemi.com Mon Jan 11 13:19:57 2010 From: ken.dyck at onsemi.com (Ken Dyck) Date: Mon, 11 Jan 2010 19:19:57 -0000 Subject: [cfe-commits] r93171 - in /cfe/trunk: include/clang/AST/ASTContext.h lib/AST/ASTContext.cpp Message-ID: <201001111919.o0BJJvMg007521@zion.cs.uiuc.edu> Author: kjdyck Date: Mon Jan 11 13:19:56 2010 New Revision: 93171 URL: http://llvm.org/viewvc/llvm-project?rev=93171&view=rev Log: Change return type of getObjCEncodingTypeSize() to CharUnits as the units are in characters. Modified: cfe/trunk/include/clang/AST/ASTContext.h cfe/trunk/lib/AST/ASTContext.cpp Modified: cfe/trunk/include/clang/AST/ASTContext.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=93171&r1=93170&r2=93171&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/ASTContext.h (original) +++ cfe/trunk/include/clang/AST/ASTContext.h Mon Jan 11 13:19:56 2010 @@ -699,8 +699,8 @@ ObjCProtocolDecl *rProto); /// getObjCEncodingTypeSize returns size of type for objective-c encoding - /// purpose. - int getObjCEncodingTypeSize(QualType t); + /// purpose in characters. + CharUnits getObjCEncodingTypeSize(QualType t); /// This setter/getter represents the ObjC 'id' type. It is setup lazily, by /// Sema. id is always a (typedef for a) pointer type, a pointer to a struct. Modified: cfe/trunk/lib/AST/ASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=93171&r1=93170&r2=93171&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTContext.cpp (original) +++ cfe/trunk/lib/AST/ASTContext.cpp Mon Jan 11 13:19:56 2010 @@ -3137,7 +3137,7 @@ /// getObjCEncodingTypeSize returns size of type for objective-c encoding /// purpose. -int ASTContext::getObjCEncodingTypeSize(QualType type) { +CharUnits ASTContext::getObjCEncodingTypeSize(QualType type) { CharUnits sz = getTypeSizeInChars(type); // Make all integer and enum types at least as large as an int @@ -3146,7 +3146,7 @@ // Treat arrays as pointers, since that's how they're passed in. else if (type->isArrayType()) sz = getTypeSizeInChars(VoidPtrTy); - return sz.getQuantity(); + return sz; } static inline @@ -3172,7 +3172,7 @@ for (ObjCMethodDecl::param_iterator PI = Decl->param_begin(), E = Decl->param_end(); PI != E; ++PI) { QualType PType = (*PI)->getType(); - CharUnits sz = CharUnits::fromQuantity(getObjCEncodingTypeSize(PType)); + CharUnits sz = getObjCEncodingTypeSize(PType); assert (sz.isPositive() && "BlockExpr - Incomplete param type"); ParmOffset += sz; } @@ -3198,7 +3198,7 @@ PType = PVDecl->getType(); getObjCEncodingForType(PType, S); S += charUnitsToString(ParmOffset); - ParmOffset += CharUnits::fromQuantity(getObjCEncodingTypeSize(PType)); + ParmOffset += getObjCEncodingTypeSize(PType); } } @@ -3222,7 +3222,7 @@ for (ObjCMethodDecl::param_iterator PI = Decl->param_begin(), E = Decl->param_end(); PI != E; ++PI) { QualType PType = (*PI)->getType(); - CharUnits sz = CharUnits::fromQuantity(getObjCEncodingTypeSize(PType)); + CharUnits sz = getObjCEncodingTypeSize(PType); assert (sz.isPositive() && "getObjCEncodingForMethodDecl - Incomplete param type"); ParmOffset += sz; @@ -3250,7 +3250,7 @@ getObjCEncodingForTypeQualifier(PVDecl->getObjCDeclQualifier(), S); getObjCEncodingForType(PType, S); S += charUnitsToString(ParmOffset); - ParmOffset += CharUnits::fromQuantity(getObjCEncodingTypeSize(PType)); + ParmOffset += getObjCEncodingTypeSize(PType); } } From dgregor at apple.com Mon Jan 11 13:36:35 2010 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 11 Jan 2010 19:36:35 -0000 Subject: [cfe-commits] r93173 - in /cfe/trunk: lib/Sema/SemaOverload.cpp test/SemaCXX/overloaded-operator.cpp Message-ID: <201001111936.o0BJaamB008231@zion.cs.uiuc.edu> Author: dgregor Date: Mon Jan 11 13:36:35 2010 New Revision: 93173 URL: http://llvm.org/viewvc/llvm-project?rev=93173&view=rev Log: When computing surrogates for calls to a value of object type, look for all visible conversion functions. Modified: cfe/trunk/lib/Sema/SemaOverload.cpp cfe/trunk/test/SemaCXX/overloaded-operator.cpp Modified: cfe/trunk/lib/Sema/SemaOverload.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=93173&r1=93172&r2=93173&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOverload.cpp (original) +++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Jan 11 13:36:35 2010 @@ -5741,9 +5741,8 @@ // functions for each conversion function declared in an // accessible base class provided the function is not hidden // within T by another intervening declaration. - // FIXME: Look in base classes for more conversion operators! const UnresolvedSet *Conversions - = cast(Record->getDecl())->getConversionFunctions(); + = cast(Record->getDecl())->getVisibleConversionFunctions(); for (UnresolvedSet::iterator I = Conversions->begin(), E = Conversions->end(); I != E; ++I) { NamedDecl *D = *I; Modified: cfe/trunk/test/SemaCXX/overloaded-operator.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/overloaded-operator.cpp?rev=93173&r1=93172&r2=93173&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/overloaded-operator.cpp (original) +++ cfe/trunk/test/SemaCXX/overloaded-operator.cpp Mon Jan 11 13:36:35 2010 @@ -190,16 +190,23 @@ typedef float& Func2(int, double); struct ConvertToFunc { - operator Func1*(); // expected-note{{conversion candidate of type 'INTREF (*)(FLOAT, double)'}} - operator Func2&(); // expected-note{{conversion candidate of type 'float &(&)(int, double)'}} + operator Func1*(); // expected-note 2{{conversion candidate of type 'INTREF (*)(FLOAT, double)'}} + operator Func2&(); // expected-note 2{{conversion candidate of type 'float &(&)(int, double)'}} void operator()(); }; -void test_funcptr_call(ConvertToFunc ctf) { +struct ConvertToFuncDerived : ConvertToFunc { }; + +void test_funcptr_call(ConvertToFunc ctf, ConvertToFuncDerived ctfd) { int &i1 = ctf(1.0f, 2.0); - float &f2 = ctf((short int)1, 1.0f); + float &f1 = ctf((short int)1, 1.0f); ctf((long int)17, 2.0); // expected-error{{error: call to object of type 'struct ConvertToFunc' is ambiguous; candidates are:}} ctf(); + + int &i2 = ctfd(1.0f, 2.0); + float &f2 = ctfd((short int)1, 1.0f); + ctfd((long int)17, 2.0); // expected-error{{error: call to object of type 'struct ConvertToFuncDerived' is ambiguous; candidates are:}} + ctfd(); } struct HasMember { From benny.kra at googlemail.com Mon Jan 11 13:46:28 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Mon, 11 Jan 2010 19:46:28 -0000 Subject: [cfe-commits] r93175 - in /cfe/trunk: include/clang/Analysis/PathSensitive/BugReporter.h lib/Analysis/CFRefCount.cpp Message-ID: <201001111946.o0BJkS1Z008629@zion.cs.uiuc.edu> Author: d0k Date: Mon Jan 11 13:46:28 2010 New Revision: 93175 URL: http://llvm.org/viewvc/llvm-project?rev=93175&view=rev Log: Avoid use of deprecated functions (CStrInCStrNoCase and StringsEqualNoCase). Modified: cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h cfe/trunk/lib/Analysis/CFRefCount.cpp Modified: cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h?rev=93175&r1=93174&r2=93175&view=diff ============================================================================== --- cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h (original) +++ cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h Mon Jan 11 13:46:28 2010 @@ -23,7 +23,6 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/ImmutableSet.h" #include Modified: cfe/trunk/lib/Analysis/CFRefCount.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFRefCount.cpp?rev=93175&r1=93174&r2=93175&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/CFRefCount.cpp (original) +++ cfe/trunk/lib/Analysis/CFRefCount.cpp Mon Jan 11 13:46:28 2010 @@ -52,8 +52,8 @@ // not release it." // -using llvm::CStrInCStrNoCase; -using llvm::StringsEqualNoCase; +using llvm::StrInStrNoCase; +using llvm::StringRef; enum NamingConvention { NoConvention, CreateRule, InitRule }; @@ -122,20 +122,20 @@ break; case 3: // Methods starting with 'new' follow the create rule. - if (AtBeginning && StringsEqualNoCase("new", s, len)) + if (AtBeginning && StringRef(s, len).equals_lower("new")) C = CreateRule; break; case 4: // Methods starting with 'alloc' or contain 'copy' follow the // create rule - if (C == NoConvention && StringsEqualNoCase("copy", s, len)) + if (C == NoConvention && StringRef(s, len).equals_lower("copy")) C = CreateRule; else // Methods starting with 'init' follow the init rule. - if (AtBeginning && StringsEqualNoCase("init", s, len)) + if (AtBeginning && StringRef(s, len).equals_lower("init")) C = InitRule; break; case 5: - if (AtBeginning && StringsEqualNoCase("alloc", s, len)) + if (AtBeginning && StringRef(s, len).equals_lower("alloc")) C = CreateRule; break; } @@ -1372,11 +1372,11 @@ // "AppendValue", or "SetAttribute", then we assume that arguments may // "escape." This means that something else holds on to the object, // allowing it be used even after its local retain count drops to 0. - ArgEffect E = (CStrInCStrNoCase(FName, "InsertValue") || - CStrInCStrNoCase(FName, "AddValue") || - CStrInCStrNoCase(FName, "SetValue") || - CStrInCStrNoCase(FName, "AppendValue") || - CStrInCStrNoCase(FName, "SetAttribute")) + ArgEffect E = (StrInStrNoCase(FName, "InsertValue") != StringRef::npos|| + StrInStrNoCase(FName, "AddValue") != StringRef::npos || + StrInStrNoCase(FName, "SetValue") != StringRef::npos || + StrInStrNoCase(FName, "AppendValue") != StringRef::npos|| + StrInStrNoCase(FName, "SetAttribute")) != StringRef::npos ? MayEscape : DoNothing; S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, E); @@ -1555,7 +1555,8 @@ if (S.isKeywordSelector()) { const std::string &str = S.getAsString(); assert(!str.empty()); - if (CStrInCStrNoCase(&str[0], "delegate:")) ReceiverEff = StopTracking; + if (StrInStrNoCase(str, "delegate:") != StringRef::npos) + ReceiverEff = StopTracking; } // Look for methods that return an owned object. From dgregor at apple.com Mon Jan 11 13:52:23 2010 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 11 Jan 2010 19:52:23 -0000 Subject: [cfe-commits] r93177 - /cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p5.cpp Message-ID: <201001111952.o0BJqNQu008838@zion.cs.uiuc.edu> Author: dgregor Date: Mon Jan 11 13:52:23 2010 New Revision: 93177 URL: http://llvm.org/viewvc/llvm-project?rev=93177&view=rev Log: Test case for naming of conversion function template specializations Added: cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p5.cpp Added: cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p5.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p5.cpp?rev=93177&view=auto ============================================================================== --- cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p5.cpp (added) +++ cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p5.cpp Mon Jan 11 13:52:23 2010 @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +struct A { + template operator T*(); +}; + +template A::operator T*() { return 0; } +template <> A::operator char*(){ return 0; } // specialization +template A::operator void*(); // explicit instantiation + +int main() { + A a; + int *ip; + ip = a.operator int*(); +} + +// PR5742 +namespace PR5742 { + template struct A { }; + template struct B { }; + + struct S { + template operator T(); + } s; + + void f() { + s.operator A >(); + s.operator A >(); + s.operator A > >(); + } +} + +// PR5762 +class Foo { + public: + template operator T(); + + template + T As() { + return this->operator T(); + } + + template + T As2() { + return operator T(); + } + + int AsInt() { + return this->operator int(); + } +}; + +template float Foo::As(); +template double Foo::As2(); + +// Partial ordering with conversion function templates. +struct X0 { + template operator T*() { + T x; + x = 17; // expected-error{{read-only variable is not assignable}} + } + + template operator T*() const; // expected-note{{explicit instantiation refers here}} + + template operator const T*() const { + T x = T(); + return x; // expected-error{{cannot initialize return object of type 'char const *' with an lvalue of type 'char'}} + } +}; + +template X0::operator const char*() const; // expected-note{{'X0::operator char const *' requested here}} +template X0::operator const int*(); // expected-note{{'X0::operator int const *' requested here}} +template X0::operator float*() const; // expected-error{{explicit instantiation of undefined function template}} + +void test_X0(X0 x0, const X0 &x0c) { + x0.operator const int*(); + x0.operator float *(); + x0c.operator const char*(); +} From dgregor at apple.com Mon Jan 11 13:55:36 2010 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 11 Jan 2010 19:55:36 -0000 Subject: [cfe-commits] r93178 - in /cfe/trunk: lib/Sema/SemaTemplateDeduction.cpp test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp Message-ID: <201001111955.o0BJtauU008954@zion.cs.uiuc.edu> Author: dgregor Date: Mon Jan 11 13:55:36 2010 New Revision: 93178 URL: http://llvm.org/viewvc/llvm-project?rev=93178&view=rev Log: When resolving a single function template specialization to a function, be sure to adjust the resulting argument type to a pointer (if necessary). Fixes PR5910 and PR5949. Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp cfe/trunk/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=93178&r1=93177&r2=93178&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Mon Jan 11 13:55:36 2010 @@ -1473,8 +1473,11 @@ return TDK_FailedOverloadResolution; } - // Get the type of the resolved argument. + // Get the type of the resolved argument, and adjust it per + // C++0x [temp.deduct.call]p3. ArgType = ResolvedArg->getType(); + if (!ParamWasReference && ArgType->isFunctionType()) + ArgType = Context.getPointerType(ArgType); if (ArgType->isPointerType() || ArgType->isMemberPointerType()) TDF |= TDF_IgnoreQualifiers; Modified: cfe/trunk/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp?rev=93178&r1=93177&r2=93178&view=diff ============================================================================== --- cfe/trunk/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp (original) +++ cfe/trunk/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp Mon Jan 11 13:55:36 2010 @@ -9,3 +9,36 @@ // Z is deduced to be double f("aa",3.0); // expected-error{{no matching}} } + +// PR5910 +namespace PR5910 { + template + void Func() {} + + template + void Foo(R (*fp)()); + + void Test() { + Foo(Func); + } +} + +// PR5949 +namespace PR5949 { + struct Bar; + + template + void quuz(const Container &cont) { + } + + template + int Foo(Bar *b, void (*Baz)(const T &t), T * = 0) { + return 0; + } + + template + int Quux(Bar *b, T * = 0) + { + return Foo(b, quuz); + } +} From sabre at nondot.org Mon Jan 11 13:58:11 2010 From: sabre at nondot.org (Chris Lattner) Date: Mon, 11 Jan 2010 19:58:11 -0000 Subject: [cfe-commits] r93179 - /cfe/trunk/lib/CodeGen/CodeGenTypes.cpp Message-ID: <201001111958.o0BJwB1Z009061@zion.cs.uiuc.edu> Author: lattner Date: Mon Jan 11 13:58:10 2010 New Revision: 93179 URL: http://llvm.org/viewvc/llvm-project?rev=93179&view=rev Log: Use the new isInteger() method in a couple places, some random cleanup, and add a fixme. Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.cpp Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.cpp?rev=93179&r1=93178&r2=93179&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CodeGenTypes.cpp (original) +++ cfe/trunk/lib/CodeGen/CodeGenTypes.cpp Mon Jan 11 13:58:10 2010 @@ -38,12 +38,10 @@ I = CGRecordLayouts.begin(), E = CGRecordLayouts.end(); I != E; ++I) delete I->second; - { - llvm::FoldingSet::iterator - I = FunctionInfos.begin(), E = FunctionInfos.end(); - while (I != E) - delete &*I++; - } + + for (llvm::FoldingSet::iterator + I = FunctionInfos.begin(), E = FunctionInfos.end(); I != E; ) + delete &*I++; } /// ConvertType - Convert the specified type to its LLVM form. @@ -55,9 +53,8 @@ // circular types. Loop through all these defered pointees, if any, and // resolve them now. while (!PointersToResolve.empty()) { - std::pair P = - PointersToResolve.back(); - PointersToResolve.pop_back(); + std::pair P = PointersToResolve.pop_back_val(); + // We can handle bare pointers here because we know that the only pointers // to the Opaque type are P.second and from other types. Refining the // opqaue type away will invalidate P.second, but we don't mind :). @@ -87,9 +84,10 @@ const llvm::Type *CodeGenTypes::ConvertTypeForMemRecursive(QualType T) { const llvm::Type *ResultType = ConvertTypeRecursive(T); - if (ResultType == llvm::Type::getInt1Ty(getLLVMContext())) + if (ResultType->isInteger(1)) return llvm::IntegerType::get(getLLVMContext(), (unsigned)Context.getTypeSize(T)); + // FIXME: Should assert that the llvm type and AST type has the same size. return ResultType; } @@ -101,7 +99,7 @@ const llvm::Type *R = ConvertType(T); // If this is a non-bool type, don't map it. - if (R != llvm::Type::getInt1Ty(getLLVMContext())) + if (!R->isInteger(1)) return R; // Otherwise, return an integer of the target-specified size. @@ -383,11 +381,10 @@ QualType ETy = cast(Ty).getPointeeType(); const llvm::Type *PtrDiffTy = ConvertTypeRecursive(Context.getPointerDiffType()); - if (ETy->isFunctionType()) { + if (ETy->isFunctionType()) return llvm::StructType::get(TheModule.getContext(), PtrDiffTy, PtrDiffTy, NULL); - } else - return PtrDiffTy; + return PtrDiffTy; } case Type::TemplateSpecialization: @@ -435,10 +432,8 @@ // Okay, this is a definition of a type. Compile the implementation now. - if (TD->isEnum()) { - // Don't bother storing enums in TagDeclTypes. + if (TD->isEnum()) // Don't bother storing enums in TagDeclTypes. return ConvertTypeRecursive(cast(TD)->getIntegerType()); - } // This decl could well be recursive. In this case, insert an opaque // definition of this type, which the recursive uses will get. We will then @@ -449,15 +444,13 @@ llvm::PATypeHolder ResultHolder = llvm::OpaqueType::get(getLLVMContext()); TagDeclTypes.insert(std::make_pair(Key, ResultHolder)); - const llvm::Type *ResultType; const RecordDecl *RD = cast(TD); // Layout fields. - CGRecordLayout *Layout = - CGRecordLayoutBuilder::ComputeLayout(*this, RD); + CGRecordLayout *Layout = CGRecordLayoutBuilder::ComputeLayout(*this, RD); CGRecordLayouts[Key] = Layout; - ResultType = Layout->getLLVMType(); + const llvm::Type *ResultType = Layout->getLLVMType(); // Refine our Opaque type to ResultType. This can invalidate ResultType, so // make sure to read the result out of the holder. @@ -499,8 +492,7 @@ /// getCGRecordLayout - Return record layout info for the given llvm::Type. const CGRecordLayout & CodeGenTypes::getCGRecordLayout(const TagDecl *TD) const { - const Type *Key = - Context.getTagDeclType(TD).getTypePtr(); + const Type *Key = Context.getTagDeclType(TD).getTypePtr(); llvm::DenseMap::const_iterator I = CGRecordLayouts.find(Key); assert (I != CGRecordLayouts.end() From benny.kra at googlemail.com Mon Jan 11 14:15:06 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Mon, 11 Jan 2010 20:15:06 -0000 Subject: [cfe-commits] r93181 - /cfe/trunk/lib/Analysis/CFRefCount.cpp Message-ID: <201001112015.o0BKF7VA009774@zion.cs.uiuc.edu> Author: d0k Date: Mon Jan 11 14:15:06 2010 New Revision: 93181 URL: http://llvm.org/viewvc/llvm-project?rev=93181&view=rev Log: Fix pasto. Modified: cfe/trunk/lib/Analysis/CFRefCount.cpp Modified: cfe/trunk/lib/Analysis/CFRefCount.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFRefCount.cpp?rev=93181&r1=93180&r2=93181&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/CFRefCount.cpp (original) +++ cfe/trunk/lib/Analysis/CFRefCount.cpp Mon Jan 11 14:15:06 2010 @@ -1376,7 +1376,7 @@ StrInStrNoCase(FName, "AddValue") != StringRef::npos || StrInStrNoCase(FName, "SetValue") != StringRef::npos || StrInStrNoCase(FName, "AppendValue") != StringRef::npos|| - StrInStrNoCase(FName, "SetAttribute")) != StringRef::npos + StrInStrNoCase(FName, "SetAttribute") != StringRef::npos) ? MayEscape : DoNothing; S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, E); From gohman at apple.com Mon Jan 11 14:16:44 2010 From: gohman at apple.com (Dan Gohman) Date: Mon, 11 Jan 2010 12:16:44 -0800 Subject: [cfe-commits] r92987 - in /cfe/trunk: include/clang/Driver/CC1Options.td include/clang/Driver/ToolChain.h lib/Driver/ToolChains.cpp lib/Driver/ToolChains.h lib/Driver/Tools.cpp lib/Frontend/CompilerInvocation.cpp test/CodeGen/libcalls.c test/Driver/ana In-Reply-To: <46A43A72862D4C9FBB14AF2222B3617D@pc07654> References: <201001080220.o082KjWl017542@zion.cs.uiuc.edu> <9B426C2D6FAB4017A20E63A88FDAC729@pc07654> <5A6F598F-0807-4F2A-BF74-75DC837C2866@apple.com> <4CB7BAB5-4092-493E-A830-5C19CBB2C2A7@apple.com> <46A43A72862D4C9FBB14AF2222B3617D@pc07654> Message-ID: On Jan 10, 2010, at 2:07 PM, Nuno Lopes wrote: >> On Jan 8, 2010, at 3:51 PM, Dan Gohman wrote: >>> >>> On Jan 8, 2010, at 2:15 PM, Nuno Lopes wrote: >>> >>>>> Author: djg >>>>> Date: Thu Jan 7 20:20:44 2010 >>>>> New Revision: 92987 >>>>> >>>>> URL: http://llvm.org/viewvc/llvm-project?rev=92987&view=rev >>>>> Log: >>>>> Use -fno-math-errno by default, and remove the IsMathErrnoDefault >>>>> targethook, which is no longer being used. This fixes PR5971. >>>> >>>> wow.. does this means that if I don't read the compiler's manual >>>> carefully and if I don't add -fmath-errno to the CFLAGS, my code >>>> will start to be silently miscompiled?? >>>> I don't think that giving up on correctness here is the right >>>> way to go.. >>> >>> This change isn't "giving up on correctness" (unless there are bugs >>> with -fno-math-errno). Code that breaks was already not entirely >>> portable in this regard. >>> >>> It may be "giving up on compatibility" though. Clang is a new >>> compiler, and it's a good time to get things like this right, where >>> feasible. However, I'll leave it up to the clang developers to >>> decide what to do. >> >> We already have this behavior in llvm-gcc, so I think it is >> definitely the right thing for Clang. > > ok, reading the C99 standard 7.12.1p{2,4,5} it seems that you're > right. errno for math functions is implementation dependent. However > 'math_errhandling & MATH_ERRNO' must evaluate to 0 if it is not > defined. > However, glibc at this point will evaluate that expression to 1 (http://sourceware.org/ml/glibc-cvs/2009-q3/msg00162.html > ). I guess now it's the libc's headers that need to be patched to > test for __clang__. Offhand, I'd call that a library bug, in not providing a way for a compiler to have -fno-math-errno get a corresponding math_errhandling value. This is independent of which compiler is in use, and of whether -fno-math-errno is the default. But I won't object if the clang change must be reverted. Dan From kremenek at apple.com Mon Jan 11 14:52:10 2010 From: kremenek at apple.com (Ted Kremenek) Date: Mon, 11 Jan 2010 12:52:10 -0800 Subject: [cfe-commits] [Review] Rolling out ASTContext::getTypeSizeInChars() In-Reply-To: <8F2E4A8BCDA0B84DA6C9088EB5B27747D5EFEF@NAMAIL.ad.onsemi.com> References: <8F2E4A8BCDA0B84DA6C9088EB5B27747D5EFEF@NAMAIL.ad.onsemi.com> Message-ID: <48D53DB1-E4D7-4BA3-B178-F0D553AB4B24@apple.com> Hi Ken, Thanks for tackling this. I looked at the changes to libAnalysis, and noticed the following line: + amt = CharUnits::fromRaw(getContext().getTypeAlign(T) / 8); Does it make since to have a matching getTypeAlignInChars() as well? That would make the line: amt = getContext.getTypeAlignInChars(); I'm also concerned about the dimensionality here. Why did we choose 'Chars' instead of 'Bytes'? Ted On Jan 4, 2010, at 11:08 AM, Ken Dyck wrote: > > The attached patches replace occurrences of ASTContext::getTypeSize()/8 > with ASTContext::getTypeSizeInChars(), converting [u]int64_t variables > to CharUnits ones where it seems appropriate. No functional changes are > intended. The changes touch the AST, Analysis, Sema, and CodeGen > libraries and are split into patches accordingly. > > Comments appreciated. > > -Ken > > _______________________________________________ > cfe-commits mailing list > cfe-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits From fjahanian at apple.com Mon Jan 11 15:17:33 2010 From: fjahanian at apple.com (Fariborz Jahanian) Date: Mon, 11 Jan 2010 21:17:33 -0000 Subject: [cfe-commits] r93186 - in /cfe/trunk: lib/AST/StmtPrinter.cpp test/Rewriter/rewrite-anonymous-union.m Message-ID: <201001112117.o0BLHXRI012228@zion.cs.uiuc.edu> Author: fjahanian Date: Mon Jan 11 15:17:32 2010 New Revision: 93186 URL: http://llvm.org/viewvc/llvm-project?rev=93186&view=rev Log: Fix a problem related to rewrite of anonymous unions. (fixes radar 6948022) Added: cfe/trunk/test/Rewriter/rewrite-anonymous-union.m Modified: cfe/trunk/lib/AST/StmtPrinter.cpp Modified: cfe/trunk/lib/AST/StmtPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=93186&r1=93185&r2=93186&view=diff ============================================================================== --- cfe/trunk/lib/AST/StmtPrinter.cpp (original) +++ cfe/trunk/lib/AST/StmtPrinter.cpp Mon Jan 11 15:17:32 2010 @@ -739,9 +739,10 @@ void StmtPrinter::VisitMemberExpr(MemberExpr *Node) { // FIXME: Suppress printing implicit bases (like "this") PrintExpr(Node->getBase()); + if (FieldDecl *FD = dyn_cast(Node->getMemberDecl())) + if (FD->isAnonymousStructOrUnion()) + return; OS << (Node->isArrow() ? "->" : "."); - // FIXME: Suppress printing references to unnamed objects - // representing anonymous unions/structs if (NestedNameSpecifier *Qualifier = Node->getQualifier()) Qualifier->print(OS, Policy); Added: cfe/trunk/test/Rewriter/rewrite-anonymous-union.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Rewriter/rewrite-anonymous-union.m?rev=93186&view=auto ============================================================================== --- cfe/trunk/test/Rewriter/rewrite-anonymous-union.m (added) +++ cfe/trunk/test/Rewriter/rewrite-anonymous-union.m Mon Jan 11 15:17:32 2010 @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -rewrite-objc -o - %s +// rdar://6948022 + +typedef unsigned int uint32_t; + +typedef struct { + union { + uint32_t daysOfWeek; + uint32_t dayOfMonth; + }; + uint32_t nthOccurrence; +} OSPatternSpecificData; + + at interface NSNumber ++ (NSNumber *)numberWithLong:(long)value; + at end + + at interface OSRecurrence { + OSPatternSpecificData _pts; +} +- (void)_setTypeSpecificInfoOnRecord; + at end + + at implementation OSRecurrence +- (void)_setTypeSpecificInfoOnRecord +{ + [NSNumber numberWithLong:(_pts.dayOfMonth >= 31 ? -1 : _pts.dayOfMonth)]; +} + at end + From Ken.Dyck at onsemi.com Mon Jan 11 15:24:12 2010 From: Ken.Dyck at onsemi.com (Ken Dyck) Date: Mon, 11 Jan 2010 14:24:12 -0700 Subject: [cfe-commits] [Review] Rolling out ASTContext::getTypeSizeInChars() In-Reply-To: <48D53DB1-E4D7-4BA3-B178-F0D553AB4B24@apple.com> References: <8F2E4A8BCDA0B84DA6C9088EB5B27747D5EFEF@NAMAIL.ad.onsemi.com> <48D53DB1-E4D7-4BA3-B178-F0D553AB4B24@apple.com> Message-ID: <8F2E4A8BCDA0B84DA6C9088EB5B27747DF4706@NAMAIL.ad.onsemi.com> On Monday, January 11, 2010 3:52 PM, Ted Kremenek wrote > > Thanks for tackling this. I looked at the changes to > libAnalysis, and noticed the following line: > > + amt = CharUnits::fromRaw(getContext().getTypeAlign(T) / 8); > > Does it make since to have a matching getTypeAlignInChars() > as well? Yes. It's on my TODO list. > I'm also concerned about the dimensionality here. Why did we > choose 'Chars' instead of 'Bytes'? The short answer is that it reflects how getTypeSizeInChars() calculates its value. It divides the bit size of the type by the bit size of the char type, so calling them CharUnits seemed more accurate than ByteUnits. The aim is to eventually support character widths other than 8. What specifically are you concerned about? -Ken From kremenek at apple.com Mon Jan 11 15:49:45 2010 From: kremenek at apple.com (Ted Kremenek) Date: Mon, 11 Jan 2010 13:49:45 -0800 Subject: [cfe-commits] [Review] Rolling out ASTContext::getTypeSizeInChars() In-Reply-To: <8F2E4A8BCDA0B84DA6C9088EB5B27747DF4706@NAMAIL.ad.onsemi.com> References: <8F2E4A8BCDA0B84DA6C9088EB5B27747D5EFEF@NAMAIL.ad.onsemi.com> <48D53DB1-E4D7-4BA3-B178-F0D553AB4B24@apple.com> <8F2E4A8BCDA0B84DA6C9088EB5B27747DF4706@NAMAIL.ad.onsemi.com> Message-ID: On Jan 11, 2010, at 1:24 PM, Ken Dyck wrote: >> >> I'm also concerned about the dimensionality here. Why did we >> choose 'Chars' instead of 'Bytes'? > > The short answer is that it reflects how getTypeSizeInChars() calculates > its value. It divides the bit size of the type by the bit size of the > char type, so calling them CharUnits seemed more accurate than > ByteUnits. The aim is to eventually support character widths other than > 8. > > What specifically are you concerned about? Hi Ken, I'm concerned that the uses of getTypeSize() / 8 always want the size in bytes, not chars (if the size of chars differs from the size of bytes). Code that expects getTypeSizeInChars() to return the size in bytes (which is all the cases in libAnalysis) will get the wrong results. Ted From dgregor at apple.com Mon Jan 11 15:54:40 2010 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 11 Jan 2010 21:54:40 -0000 Subject: [cfe-commits] r93188 - in /cfe/trunk: lib/Sema/SemaDecl.cpp test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp Message-ID: <201001112154.o0BLseCt013656@zion.cs.uiuc.edu> Author: dgregor Date: Mon Jan 11 15:54:40 2010 New Revision: 93188 URL: http://llvm.org/viewvc/llvm-project?rev=93188&view=rev Log: Allow redefinitions of typedef-names within class scope when the type they redefine is a class-name but not a typedef-name, per C++0x [dcl.typedef]p4. The code in the test was valid C++98 and is valid C++0x, but an unintended consequence of DR56 made it ill-formed in C++03 (which we were luck enough to implement). Fixes PR5455. Modified: cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=93188&r1=93187&r2=93188&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Jan 11 15:54:40 2010 @@ -803,13 +803,38 @@ if (getLangOptions().Microsoft) return; - // C++ [dcl.typedef]p2: - // In a given non-class scope, a typedef specifier can be used to - // redefine the name of any type declared in that scope to refer - // to the type to which it already refers. if (getLangOptions().CPlusPlus) { + // C++ [dcl.typedef]p2: + // In a given non-class scope, a typedef specifier can be used to + // redefine the name of any type declared in that scope to refer + // to the type to which it already refers. if (!isa(CurContext)) return; + + // C++0x [dcl.typedef]p4: + // In a given class scope, a typedef specifier can be used to redefine + // any class-name declared in that scope that is not also a typedef-name + // to refer to the type to which it already refers. + // + // This wording came in via DR424, which was a correction to the + // wording in DR56, which accidentally banned code like: + // + // struct S { + // typedef struct A { } A; + // }; + // + // in the C++03 standard. We implement the C++0x semantics, which + // allow the above but disallow + // + // struct S { + // typedef int I; + // typedef int I; + // }; + // + // since that was the intent of DR56. + if (New->getUnderlyingType()->getAs()) + return; + Diag(New->getLocation(), diag::err_redefinition) << New->getDeclName(); Diag(Old->getLocation(), diag::note_previous_definition); Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp?rev=93188&r1=93187&r2=93188&view=diff ============================================================================== --- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp (original) +++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp Mon Jan 11 15:54:40 2010 @@ -1,5 +1,4 @@ // RUN: %clang_cc1 -verify %s -// XFAIL: * struct S { typedef struct A {} A; // expected-note {{previous definition is here}} From dgregor at apple.com Mon Jan 11 15:58:50 2010 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 11 Jan 2010 21:58:50 -0000 Subject: [cfe-commits] r93190 - /cfe/trunk/test/SemaCXX/composite-pointer-type.cpp Message-ID: <201001112158.o0BLwoEI013897@zion.cs.uiuc.edu> Author: dgregor Date: Mon Jan 11 15:58:49 2010 New Revision: 93190 URL: http://llvm.org/viewvc/llvm-project?rev=93190&view=rev Log: Add test case from PR5763 Modified: cfe/trunk/test/SemaCXX/composite-pointer-type.cpp Modified: cfe/trunk/test/SemaCXX/composite-pointer-type.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/composite-pointer-type.cpp?rev=93190&r1=93189&r2=93190&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/composite-pointer-type.cpp (original) +++ cfe/trunk/test/SemaCXX/composite-pointer-type.cpp Mon Jan 11 15:58:49 2010 @@ -43,3 +43,10 @@ IntPtrPtr j = 0; return i != j; } + +// PR5763 +typedef double Matrix4[4][4]; + +bool f(Matrix4 m1, const Matrix4 m2) { + return m1 != m2; +} From clattner at apple.com Mon Jan 11 15:59:47 2010 From: clattner at apple.com (Chris Lattner) Date: Mon, 11 Jan 2010 13:59:47 -0800 Subject: [cfe-commits] [Review] Rolling out ASTContext::getTypeSizeInChars() In-Reply-To: References: <8F2E4A8BCDA0B84DA6C9088EB5B27747D5EFEF@NAMAIL.ad.onsemi.com> <48D53DB1-E4D7-4BA3-B178-F0D553AB4B24@apple.com> <8F2E4A8BCDA0B84DA6C9088EB5B27747DF4706@NAMAIL.ad.onsemi.com> Message-ID: On Jan 11, 2010, at 1:49 PM, Ted Kremenek wrote: > On Jan 11, 2010, at 1:24 PM, Ken Dyck wrote: >>> I'm also concerned about the dimensionality here. Why did we >>> choose 'Chars' instead of 'Bytes'? >> >> The short answer is that it reflects how getTypeSizeInChars() >> calculates >> its value. It divides the bit size of the type by the bit size of the >> char type, so calling them CharUnits seemed more accurate than >> ByteUnits. The aim is to eventually support character widths other >> than >> 8. >> >> What specifically are you concerned about? > > Hi Ken, > > I'm concerned that the uses of getTypeSize() / 8 always want the > size in bytes, not chars (if the size of chars differs from the size > of bytes). Code that expects getTypeSizeInChars() to return the > size in bytes (which is all the cases in libAnalysis) will get the > wrong results. I'm pretty sure that Ken's approach is right. On target where a char is not one byte, sizeof(char) always returns 1, and size(foo) always returns size-in-bytes for example. -Chris From dgregor at apple.com Mon Jan 11 16:04:55 2010 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 11 Jan 2010 22:04:55 -0000 Subject: [cfe-commits] r93192 - in /cfe/trunk: lib/Sema/SemaDecl.cpp test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp Message-ID: <201001112204.o0BM4twG014186@zion.cs.uiuc.edu> Author: dgregor Date: Mon Jan 11 16:04:54 2010 New Revision: 93192 URL: http://llvm.org/viewvc/llvm-project?rev=93192&view=rev Log: Use isa rather than getAs, since the latter may (eventually) perform multiple levels of desugaring (thus breaking the newly-added tests) and the former is faster. Thanks, John! Modified: cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=93192&r1=93191&r2=93192&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Jan 11 16:04:54 2010 @@ -832,7 +832,7 @@ // }; // // since that was the intent of DR56. - if (New->getUnderlyingType()->getAs()) + if (isa(New->getUnderlyingType())) return; Diag(New->getLocation(), diag::err_redefinition) Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp?rev=93192&r1=93191&r2=93192&view=diff ============================================================================== --- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp (original) +++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp Mon Jan 11 16:04:54 2010 @@ -2,7 +2,11 @@ struct S { typedef struct A {} A; // expected-note {{previous definition is here}} - typedef struct B B; + typedef struct B {} B; typedef A A; // expected-error {{redefinition of 'A'}} + + struct C { }; // expected-note{{previous definition is here}} + typedef struct C OtherC; + typedef OtherC C; // expected-error{{redefinition of 'C'}} }; From dgregor at apple.com Mon Jan 11 16:30:10 2010 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 11 Jan 2010 22:30:10 -0000 Subject: [cfe-commits] r93196 - in /cfe/trunk: lib/Sema/SemaDecl.cpp test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp Message-ID: <201001112230.o0BMUAod015443@zion.cs.uiuc.edu> Author: dgregor Date: Mon Jan 11 16:30:10 2010 New Revision: 93196 URL: http://llvm.org/viewvc/llvm-project?rev=93196&view=rev Log: C++0x [dcl.typedef]p4, take 3, where we actually figure out what "that is not also a typedef-name" actually means. For anyone keeping score, that's John: 2, Doug: 0. Modified: cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=93196&r1=93195&r2=93196&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Jan 11 16:30:10 2010 @@ -832,7 +832,7 @@ // }; // // since that was the intent of DR56. - if (isa(New->getUnderlyingType())) + if (!isa(Old)) return; Diag(New->getLocation(), diag::err_redefinition) Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp?rev=93196&r1=93195&r2=93196&view=diff ============================================================================== --- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp (original) +++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p4.cpp Mon Jan 11 16:30:10 2010 @@ -2,11 +2,14 @@ struct S { typedef struct A {} A; // expected-note {{previous definition is here}} - typedef struct B {} B; + typedef struct B B; typedef A A; // expected-error {{redefinition of 'A'}} - struct C { }; // expected-note{{previous definition is here}} + struct C { }; typedef struct C OtherC; - typedef OtherC C; // expected-error{{redefinition of 'C'}} + typedef OtherC C; + + typedef struct D { } D2; + typedef D2 D; }; From csdavec at swan.ac.uk Mon Jan 11 16:33:19 2010 From: csdavec at swan.ac.uk (David Chisnall) Date: Mon, 11 Jan 2010 22:33:19 -0000 Subject: [cfe-commits] r93198 - /cfe/trunk/lib/Sema/SemaType.cpp Message-ID: <201001112233.o0BMXJ5f015621@zion.cs.uiuc.edu> Author: theraven Date: Mon Jan 11 16:33:19 2010 New Revision: 93198 URL: http://llvm.org/viewvc/llvm-project?rev=93198&view=rev Log: Allow VLAs in C++ if in GNU mode (GNU C++ permits them). Clang can now compile LanguageKit, although the resulting code crashes (although not in any of the functions that use VLAs). Modified: cfe/trunk/lib/Sema/SemaType.cpp Modified: cfe/trunk/lib/Sema/SemaType.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=93198&r1=93197&r2=93198&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaType.cpp (original) +++ cfe/trunk/lib/Sema/SemaType.cpp Mon Jan 11 16:33:19 2010 @@ -651,8 +651,10 @@ } T = Context.getConstantArrayType(T, ConstVal, ASM, Quals); } - // If this is not C99, extwarn about VLA's and C99 array size modifiers. - if (!getLangOptions().C99) { + // If this is not C99 or C++ with GNU extenisons, extwarn about VLA's and C99 + // array size modifiers. + if (!getLangOptions().C99 && + !(getLangOptions().CPlusPlus && getLangOptions().GNUMode)) { if (ArraySize && !ArraySize->isTypeDependent() && !ArraySize->isValueDependent() && !ArraySize->isIntegerConstantExpr(Context)) From dgregor at apple.com Mon Jan 11 16:40:46 2010 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 11 Jan 2010 22:40:46 -0000 Subject: [cfe-commits] r93199 - in /cfe/trunk: lib/Sema/SemaLookup.cpp test/SemaTemplate/function-template-specialization.cpp Message-ID: <201001112240.o0BMekBY015911@zion.cs.uiuc.edu> Author: dgregor Date: Mon Jan 11 16:40:45 2010 New Revision: 93199 URL: http://llvm.org/viewvc/llvm-project?rev=93199&view=rev Log: When performing name lookup into a scope, check that its entity is non-NULL before looking at the entity itself. Modified: cfe/trunk/lib/Sema/SemaLookup.cpp cfe/trunk/test/SemaTemplate/function-template-specialization.cpp Modified: cfe/trunk/lib/Sema/SemaLookup.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=93199&r1=93198&r2=93199&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaLookup.cpp (original) +++ cfe/trunk/lib/Sema/SemaLookup.cpp Mon Jan 11 16:40:45 2010 @@ -648,7 +648,7 @@ for (; S; S = S->getParent()) { DeclContext *Ctx = static_cast(S->getEntity()); - if (Ctx->isTransparentContext()) + if (!Ctx || Ctx->isTransparentContext()) continue; assert(Ctx && Ctx->isFileContext() && Modified: cfe/trunk/test/SemaTemplate/function-template-specialization.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/function-template-specialization.cpp?rev=93199&r1=93198&r2=93199&view=diff ============================================================================== --- cfe/trunk/test/SemaTemplate/function-template-specialization.cpp (original) +++ cfe/trunk/test/SemaTemplate/function-template-specialization.cpp Mon Jan 11 16:40:45 2010 @@ -33,3 +33,11 @@ template<> void f2<42>(double (&array)[42]); void f2<25>(double (&array)[25]); // expected-error{{specialization}} + +// PR5833 +namespace PR5833 { + template bool f0(T &t1); + template <> bool f0(float &t1); +} +template <> bool PR5833::f0(float &t1) {} + From kremenek at apple.com Mon Jan 11 16:42:59 2010 From: kremenek at apple.com (Ted Kremenek) Date: Mon, 11 Jan 2010 14:42:59 -0800 Subject: [cfe-commits] [Review] Rolling out ASTContext::getTypeSizeInChars() In-Reply-To: References: <8F2E4A8BCDA0B84DA6C9088EB5B27747D5EFEF@NAMAIL.ad.onsemi.com> <48D53DB1-E4D7-4BA3-B178-F0D553AB4B24@apple.com> <8F2E4A8BCDA0B84DA6C9088EB5B27747DF4706@NAMAIL.ad.onsemi.com> Message-ID: On Jan 11, 2010, at 1:59 PM, Chris Lattner wrote: > On Jan 11, 2010, at 1:49 PM, Ted Kremenek wrote: >> On Jan 11, 2010, at 1:24 PM, Ken Dyck wrote: >>>> I'm also concerned about the dimensionality here. Why did we >>>> choose 'Chars' instead of 'Bytes'? >>> >>> The short answer is that it reflects how getTypeSizeInChars() calculates >>> its value. It divides the bit size of the type by the bit size of the >>> char type, so calling them CharUnits seemed more accurate than >>> ByteUnits. The aim is to eventually support character widths other than >>> 8. >>> >>> What specifically are you concerned about? >> >> Hi Ken, >> >> I'm concerned that the uses of getTypeSize() / 8 always want the size in bytes, not chars (if the size of chars differs from the size of bytes). Code that expects getTypeSizeInChars() to return the size in bytes (which is all the cases in libAnalysis) will get the wrong results. > > I'm pretty sure that Ken's approach is right. On target where a char is not one byte, sizeof(char) always returns 1, and size(foo) always returns size-in-bytes for example. > > -Chris Sounds good. That's all I was concerned about! From fjahanian at apple.com Mon Jan 11 16:48:40 2010 From: fjahanian at apple.com (Fariborz Jahanian) Date: Mon, 11 Jan 2010 22:48:40 -0000 Subject: [cfe-commits] r93201 - in /cfe/trunk: lib/Frontend/RewriteObjC.cpp test/Rewriter/rewrite-forward-class.m Message-ID: <201001112248.o0BMmeYJ016267@zion.cs.uiuc.edu> Author: fjahanian Date: Mon Jan 11 16:48:40 2010 New Revision: 93201 URL: http://llvm.org/viewvc/llvm-project?rev=93201&view=rev Log: Fix rewriting for forward class declaration. (fixes radar 6969189). Added: cfe/trunk/test/Rewriter/rewrite-forward-class.m Modified: cfe/trunk/lib/Frontend/RewriteObjC.cpp Modified: cfe/trunk/lib/Frontend/RewriteObjC.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/RewriteObjC.cpp?rev=93201&r1=93200&r2=93201&view=diff ============================================================================== --- cfe/trunk/lib/Frontend/RewriteObjC.cpp (original) +++ cfe/trunk/lib/Frontend/RewriteObjC.cpp Mon Jan 11 16:48:40 2010 @@ -787,9 +787,17 @@ // as the class. As a convenience, we include the original declaration // as a comment. std::string typedefString; - typedefString += "// "; - typedefString.append(startBuf, semiPtr-startBuf+1); - typedefString += "\n"; + typedefString += "// @class "; + for (ObjCClassDecl::iterator I = ClassDecl->begin(), E = ClassDecl->end(); + I != E; ++I) { + ObjCInterfaceDecl *ForwardDecl = I->getInterface(); + typedefString += ForwardDecl->getNameAsString(); + if (I+1 != E) + typedefString += ", "; + else + typedefString += ";\n"; + } + for (ObjCClassDecl::iterator I = ClassDecl->begin(), E = ClassDecl->end(); I != E; ++I) { ObjCInterfaceDecl *ForwardDecl = I->getInterface(); Added: cfe/trunk/test/Rewriter/rewrite-forward-class.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Rewriter/rewrite-forward-class.m?rev=93201&view=auto ============================================================================== --- cfe/trunk/test/Rewriter/rewrite-forward-class.m (added) +++ cfe/trunk/test/Rewriter/rewrite-forward-class.m Mon Jan 11 16:48:40 2010 @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -rewrite-objc -o - %s +// rdar://6969189 + + at class XX; + at class YY, ZZ, QQ; + at class ISyncClient, SMSession, ISyncManager, ISyncSession, SMDataclassInfo, SMClientInfo, + DMCConfiguration, DMCStatusEntry; + From dgregor at apple.com Mon Jan 11 17:01:42 2010 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 11 Jan 2010 15:01:42 -0800 Subject: [cfe-commits] r93198 - /cfe/trunk/lib/Sema/SemaType.cpp In-Reply-To: <201001112233.o0BMXJ5f015621@zion.cs.uiuc.edu> References: <201001112233.o0BMXJ5f015621@zion.cs.uiuc.edu> Message-ID: <727F82CC-38BD-4A55-9B54-7E26F1C27DDE@apple.com> On Jan 11, 2010, at 2:33 PM, David Chisnall wrote: > Author: theraven > Date: Mon Jan 11 16:33:19 2010 > New Revision: 93198 > > URL: http://llvm.org/viewvc/llvm-project?rev=93198&view=rev > Log: > Allow VLAs in C++ if in GNU mode (GNU C++ permits them). Clang can > now compile LanguageKit, although the resulting code crashes > (although not in any of the functions that use VLAs). As noted in the PR about this http://llvm.org/bugs/show_bug.cgi?id=5678 there is CodeGen work that needs to be done to make VLAs work in C++, and that CodeGen work needs to happen before we enable VLAs in C++. Otherwise, people using VLAs (or accidentally using VLAs) will end up tracking down annoying miscompiles for a feature that we know doesn't work. Not good. Of course, there's also the problem that we're not even certain that we even *want* to ever support VLAs in C++. However, having a proper implementation that generates correct code goes a long way to answering "yes". In any case, please revert this change until you or someone else has some working CodeGen support for VLAs, so that we know they aren't totally broken. - Doug > Modified: > cfe/trunk/lib/Sema/SemaType.cpp > > Modified: cfe/trunk/lib/Sema/SemaType.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=93198&r1=93197&r2=93198&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- cfe/trunk/lib/Sema/SemaType.cpp (original) > +++ cfe/trunk/lib/Sema/SemaType.cpp Mon Jan 11 16:33:19 2010 > @@ -651,8 +651,10 @@ > } > T = Context.getConstantArrayType(T, ConstVal, ASM, Quals); > } > - // If this is not C99, extwarn about VLA's and C99 array size > modifiers. > - if (!getLangOptions().C99) { > + // If this is not C99 or C++ with GNU extenisons, extwarn about > VLA's and C99 > + // array size modifiers. > + if (!getLangOptions().C99 && > + !(getLangOptions().CPlusPlus && getLangOptions().GNUMode)) { > if (ArraySize && !ArraySize->isTypeDependent() && > !ArraySize->isValueDependent() && > !ArraySize->isIntegerConstantExpr(Context)) > > > _______________________________________________ > cfe-commits mailing list > cfe-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits From csdavec at swan.ac.uk Mon Jan 11 17:08:09 2010 From: csdavec at swan.ac.uk (David Chisnall) Date: Mon, 11 Jan 2010 23:08:09 -0000 Subject: [cfe-commits] r93205 - /cfe/trunk/lib/Sema/SemaType.cpp Message-ID: <201001112308.o0BN89sm017103@zion.cs.uiuc.edu> Author: theraven Date: Mon Jan 11 17:08:08 2010 New Revision: 93205 URL: http://llvm.org/viewvc/llvm-project?rev=93205&view=rev Log: Reverted r93198; done without reading relevant PR. Modified: cfe/trunk/lib/Sema/SemaType.cpp Modified: cfe/trunk/lib/Sema/SemaType.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=93205&r1=93204&r2=93205&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaType.cpp (original) +++ cfe/trunk/lib/Sema/SemaType.cpp Mon Jan 11 17:08:08 2010 @@ -651,10 +651,8 @@ } T = Context.getConstantArrayType(T, ConstVal, ASM, Quals); } - // If this is not C99 or C++ with GNU extenisons, extwarn about VLA's and C99 - // array size modifiers. - if (!getLangOptions().C99 && - !(getLangOptions().CPlusPlus && getLangOptions().GNUMode)) { + // If this is not C99, extwarn about VLA's and C99 array size modifiers. + if (!getLangOptions().C99) { if (ArraySize && !ArraySize->isTypeDependent() && !ArraySize->isValueDependent() && !ArraySize->isIntegerConstantExpr(Context)) From csdavec at swan.ac.uk Mon Jan 11 17:10:01 2010 From: csdavec at swan.ac.uk (David Chisnall) Date: Mon, 11 Jan 2010 23:10:01 +0000 Subject: [cfe-commits] r93198 - /cfe/trunk/lib/Sema/SemaType.cpp In-Reply-To: <727F82CC-38BD-4A55-9B54-7E26F1C27DDE@apple.com> References: <201001112233.o0BMXJ5f015621@zion.cs.uiuc.edu> <727F82CC-38BD-4A55-9B54-7E26F1C27DDE@apple.com> Message-ID: <16F50E72-5A33-4476-AA6B-20F8C9B8CF51@swan.ac.uk> On 11 Jan 2010, at 23:01, Douglas Gregor wrote: > In any case, please revert this change until you or someone else has > some working CodeGen support for VLAs, so that we know they aren't > totally broken. Ooops - I didn't look for a PR before looking at the problem, I just came across this problem with some C++ code that otherwise compiled with clang. I've reverted it now. David -- Send from my Jacquard Loom From dgregor at apple.com Mon Jan 11 17:10:22 2010 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 11 Jan 2010 15:10:22 -0800 Subject: [cfe-commits] r93198 - /cfe/trunk/lib/Sema/SemaType.cpp In-Reply-To: <16F50E72-5A33-4476-AA6B-20F8C9B8CF51@swan.ac.uk> References: <201001112233.o0BMXJ5f015621@zion.cs.uiuc.edu> <727F82CC-38BD-4A55-9B54-7E26F1C27DDE@apple.com> <16F50E72-5A33-4476-AA6B-20F8C9B8CF51@swan.ac.uk> Message-ID: On Jan 11, 2010, at 3:10 PM, David Chisnall wrote: > On 11 Jan 2010, at 23:01, Douglas Gregor wrote: > >> In any case, please revert this change until you or someone else >> has some working CodeGen support for VLAs, so that we know they >> aren't totally broken. > > Ooops - I didn't look for a PR before looking at the problem, I just > came across this problem with some C++ code that otherwise compiled > with clang. I've reverted it now. Thanks! - Doug From clattner at apple.com Mon Jan 11 17:22:15 2010 From: clattner at apple.com (Chris Lattner) Date: Mon, 11 Jan 2010 15:22:15 -0800 Subject: [cfe-commits] [Review] Rolling out ASTContext::getTypeSizeInChars() In-Reply-To: References: <8F2E4A8BCDA0B84DA6C9088EB5B27747D5EFEF@NAMAIL.ad.onsemi.com> <48D53DB1-E4D7-4BA3-B178-F0D553AB4B24@apple.com> <8F2E4A8BCDA0B84DA6C9088EB5B27747DF4706@NAMAIL.ad.onsemi.com> Message-ID: <8C144F17-42DD-4B62-AAB5-6BE47464EA13@apple.com> On Jan 11, 2010, at 2:42 PM, Ted Kremenek wrote: > > On Jan 11, 2010, at 1:59 PM, Chris Lattner wrote: > >> On Jan 11, 2010, at 1:49 PM, Ted Kremenek wrote: >>> On Jan 11, 2010, at 1:24 PM, Ken Dyck wrote: >>>>> I'm also concerned about the dimensionality here. Why did we >>>>> choose 'Chars' instead of 'Bytes'? >>>> >>>> The short answer is that it reflects how getTypeSizeInChars() >>>> calculates >>>> its value. It divides the bit size of the type by the bit size of >>>> the >>>> char type, so calling them CharUnits seemed more accurate than >>>> ByteUnits. The aim is to eventually support character widths >>>> other than >>>> 8. >>>> >>>> What specifically are you concerned about? >>> >>> Hi Ken, >>> >>> I'm concerned that the uses of getTypeSize() / 8 always want the >>> size in bytes, not chars (if the size of chars differs from the >>> size of bytes). Code that expects getTypeSizeInChars() to return >>> the size in bytes (which is all the cases in libAnalysis) will get >>> the wrong results. >> >> I'm pretty sure that Ken's approach is right. On target where a >> char is not one byte, sizeof(char) always returns 1, and size(foo) >> always returns size-in-bytes for example. Ugh, I meant "size-in-chars" :) -Chris >> >> -Chris > > Sounds good. That's all I was concerned about! From rideau3 at gmail.com Mon Jan 11 17:24:34 2010 From: rideau3 at gmail.com (Sean Hunt) Date: Mon, 11 Jan 2010 16:24:34 -0700 Subject: [cfe-commits] Fwd: r93198 - /cfe/trunk/lib/Sema/SemaType.cpp In-Reply-To: References: <201001112233.o0BMXJ5f015621@zion.cs.uiuc.edu> <727F82CC-38BD-4A55-9B54-7E26F1C27DDE@apple.com> Message-ID: ---------- Forwarded message ---------- From: Sean Hunt Date: Mon, Jan 11, 2010 at 4:11 PM Subject: Re: [cfe-commits] r93198 - /cfe/trunk/lib/Sema/SemaType.cpp To: Douglas Gregor On Mon, Jan 11, 2010 at 4:01 PM, Douglas Gregor wrote: > Of course, there's also the problem that we're not even certain that > we even *want* to ever support VLAs in C++. However, having a proper > implementation that generates correct code goes a long way to > answering "yes". I'm personally opposed to VLAs being in C++ if they do not warn by default; there should need to be a specific flag passed to enable them. Sean PS. I'm doing bad at this today. From dgregor at apple.com Mon Jan 11 17:29:11 2010 From: dgregor at apple.com (Douglas Gregor) Date: Mon, 11 Jan 2010 23:29:11 -0000 Subject: [cfe-commits] r93207 - in /cfe/trunk/lib: Parse/ParseExprCXX.cpp Sema/SemaDeclCXX.cpp Sema/SemaTemplate.cpp Message-ID: <201001112329.o0BNTBmN017985@zion.cs.uiuc.edu> Author: dgregor Date: Mon Jan 11 17:29:10 2010 New Revision: 93207 URL: http://llvm.org/viewvc/llvm-project?rev=93207&view=rev Log: Eliminate an embarrassing performance regression in C/ObjC, where we were performing name lookup for template names in C/ObjC and always finding nothing. Turn off such lookup unless we're in C++ mode, along with the check that determines whether the given identifier is a "current class name", and assert that we don't make this mistake again. Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp cfe/trunk/lib/Sema/SemaDeclCXX.cpp cfe/trunk/lib/Sema/SemaTemplate.cpp Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=93207&r1=93206&r2=93207&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original) +++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Mon Jan 11 17:29:10 2010 @@ -1153,6 +1153,13 @@ IdentifierInfo *Id = Tok.getIdentifierInfo(); SourceLocation IdLoc = ConsumeToken(); + if (!getLang().CPlusPlus) { + // If we're not in C++, only identifiers matter. Record the + // identifier and return. + Result.setIdentifier(Id, IdLoc); + return false; + } + if (AllowConstructorName && Actions.isCurrentClassName(*Id, CurScope, &SS)) { // We have parsed a constructor name. @@ -1207,7 +1214,8 @@ return false; } - if ((AllowDestructorName || SS.isSet()) && Tok.is(tok::tilde)) { + if (getLang().CPlusPlus && + (AllowDestructorName || SS.isSet()) && Tok.is(tok::tilde)) { // C++ [expr.unary.op]p10: // There is an ambiguity in the unary-expression ~X(), where X is a // class-name. The ambiguity is resolved in favor of treating ~ as a Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=93207&r1=93206&r2=93207&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Jan 11 17:29:10 2010 @@ -424,6 +424,8 @@ /// the innermost class. bool Sema::isCurrentClassName(const IdentifierInfo &II, Scope *, const CXXScopeSpec *SS) { + assert(getLangOptions().CPlusPlus && "No class names in C!"); + CXXRecordDecl *CurDecl; if (SS && SS->isSet() && !SS->isInvalid()) { DeclContext *DC = computeDeclContext(*SS, true); Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=93207&r1=93206&r2=93207&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon Jan 11 17:29:10 2010 @@ -80,6 +80,8 @@ TypeTy *ObjectTypePtr, bool EnteringContext, TemplateTy &TemplateResult) { + assert(getLangOptions().CPlusPlus && "No template names in C!"); + DeclarationName TName; switch (Name.getKind()) { From kremenek at apple.com Mon Jan 11 17:56:39 2010 From: kremenek at apple.com (Ted Kremenek) Date: Mon, 11 Jan 2010 23:56:39 -0000 Subject: [cfe-commits] r93209 - in /cfe/trunk: include/clang-c/Index.h tools/CIndex/CIndex.cpp tools/CIndex/CIndex.exports tools/CIndex/CIndexUSRs.cpp Message-ID: <201001112356.o0BNueDp019018@zion.cs.uiuc.edu> Author: kremenek Date: Mon Jan 11 17:56:39 2010 New Revision: 93209 URL: http://llvm.org/viewvc/llvm-project?rev=93209&view=rev Log: CIndex: - Remove unused (and unimplemented) clang_getDeclarationName(). - Remove unused (and unimplemented) clang_getEntity(). - Add clang_getEntityFromDecl(): maps from a CXDecl to a CXEntity) - Add clang_getDeclaration(): maps from a (CXEntity, CXTranslationUnit) to a CXDecl). Modified: cfe/trunk/include/clang-c/Index.h cfe/trunk/tools/CIndex/CIndex.cpp cfe/trunk/tools/CIndex/CIndex.exports cfe/trunk/tools/CIndex/CIndexUSRs.cpp Modified: cfe/trunk/include/clang-c/Index.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=93209&r1=93208&r2=93209&view=diff ============================================================================== --- cfe/trunk/include/clang-c/Index.h (original) +++ cfe/trunk/include/clang-c/Index.h Mon Jan 11 17:56:39 2010 @@ -142,7 +142,10 @@ } CXCursor; /* A unique token for looking up "visible" CXDecls from a CXTranslationUnit. */ -typedef void *CXEntity; +typedef struct { + CXIndex index; + void *data; +} CXEntity; /** * For functions returning a string that might or might not need @@ -321,14 +324,17 @@ /* * CXEntity Operations. */ -CINDEX_LINKAGE const char *clang_getDeclarationName(CXEntity); + +/* clang_getDeclaration() maps from a CXEntity to the matching CXDecl (if any) + * in a specified translation unit. */ +CINDEX_LINKAGE CXDecl clang_getDeclaration(CXEntity, CXTranslationUnit); + CINDEX_LINKAGE const char *clang_getUSR(CXEntity); -CINDEX_LINKAGE CXEntity clang_getEntity(const char *USR); /* * CXDecl Operations. */ CINDEX_LINKAGE CXCursor clang_getCursorFromDecl(CXDecl); -CINDEX_LINKAGE CXEntity clang_getEntityFromDecl(CXDecl); +CINDEX_LINKAGE CXEntity clang_getEntityFromDecl(CXIndex, CXDecl); CINDEX_LINKAGE CXString clang_getDeclSpelling(CXDecl); CINDEX_LINKAGE unsigned clang_getDeclLine(CXDecl); CINDEX_LINKAGE unsigned clang_getDeclColumn(CXDecl); Modified: cfe/trunk/tools/CIndex/CIndex.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndex.cpp?rev=93209&r1=93208&r2=93209&view=diff ============================================================================== --- cfe/trunk/tools/CIndex/CIndex.cpp (original) +++ cfe/trunk/tools/CIndex/CIndex.cpp Mon Jan 11 17:56:39 2010 @@ -628,10 +628,6 @@ // CXDecl Operations. // -CXEntity clang_getEntityFromDecl(CXDecl) { - return 0; -} - CXString clang_getDeclSpelling(CXDecl AnonDecl) { assert(AnonDecl && "Passed null CXDecl"); NamedDecl *ND = static_cast(AnonDecl); Modified: cfe/trunk/tools/CIndex/CIndex.exports URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndex.exports?rev=93209&r1=93208&r2=93209&view=diff ============================================================================== --- cfe/trunk/tools/CIndex/CIndex.exports (original) +++ cfe/trunk/tools/CIndex/CIndex.exports Mon Jan 11 17:56:39 2010 @@ -28,9 +28,8 @@ _clang_getDeclSource _clang_getDeclSourceFile _clang_getDeclSpelling -_clang_getDeclarationName +_clang_getDeclaration _clang_getDefinitionSpellingAndExtent -_clang_getEntity _clang_getEntityFromDecl _clang_getFileName _clang_getFileTime Modified: cfe/trunk/tools/CIndex/CIndexUSRs.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndexUSRs.cpp?rev=93209&r1=93208&r2=93209&view=diff ============================================================================== --- cfe/trunk/tools/CIndex/CIndexUSRs.cpp (original) +++ cfe/trunk/tools/CIndex/CIndexUSRs.cpp Mon Jan 11 17:56:39 2010 @@ -30,17 +30,52 @@ // // module.m: static void Foo() { } // + +static inline Entity GetEntity(const CXEntity &E) { + return Entity::getFromOpaquePtr(E.data); +} + +static inline ASTUnit *GetTranslationUnit(CXTranslationUnit TU) { + return (ASTUnit*) TU; +} -const char *clang_getDeclarationName(CXEntity) { - return ""; +static inline ASTContext &GetASTContext(CXTranslationUnit TU) { + return GetTranslationUnit(TU)->getASTContext(); } -const char *clang_getUSR(CXEntity) { - return ""; +static inline CXEntity NullCXEntity() { + CXEntity CE; + CE.index = NULL; + CE.data = NULL; + return CE; +} + +static inline CXEntity MakeEntity(CXIndex CIdx, const Entity &E) { + CXEntity CE; + CE.index = CIdx; + CE.data = E.getAsOpaquePtr(); + return CE; } -CXEntity clang_getEntity(const char *URI) { - return 0; +static inline Program &GetProgram(CXIndex CIdx) { + return ((CIndexer*) CIdx)->getProgram(); +} + +/// clang_getDeclaration() maps from a CXEntity to the matching CXDecl (if any) +/// in a specified translation unit. +CXDecl clang_getDeclaration(CXEntity CE, CXTranslationUnit TU) { + return (CXDecl) GetEntity(CE).getDecl(GetASTContext(TU)); +} + + +CXEntity clang_getEntityFromDecl(CXIndex CIdx, CXDecl CE) { + if (Decl *D = (Decl *) CE) + return MakeEntity(CIdx, Entity::get(D, GetProgram(CIdx))); + return NullCXEntity(); +} + +const char *clang_getUSR(CXEntity) { + return ""; } } // end extern "C" From mrs at apple.com Mon Jan 11 18:28:59 2010 From: mrs at apple.com (Mike Stump) Date: Tue, 12 Jan 2010 00:28:59 -0000 Subject: [cfe-commits] r93211 - /cfe/trunk/utils/VtableTest/gen.cc Message-ID: <201001120029.o0C0T0kb020355@zion.cs.uiuc.edu> Author: mrs Date: Mon Jan 11 18:28:59 2010 New Revision: 93211 URL: http://llvm.org/viewvc/llvm-project?rev=93211&view=rev Log: Allow N_FIELDS to be 0. Modified: cfe/trunk/utils/VtableTest/gen.cc Modified: cfe/trunk/utils/VtableTest/gen.cc URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/VtableTest/gen.cc?rev=93211&r1=93210&r2=93211&view=diff ============================================================================== --- cfe/trunk/utils/VtableTest/gen.cc (original) +++ cfe/trunk/utils/VtableTest/gen.cc Mon Jan 11 18:28:59 2010 @@ -110,7 +110,7 @@ gl(" {"); /* Fields */ - int n_fields = random() % (N_FIELDS*4); + int n_fields = N_FIELDS == 0 ? 0 : random() % (N_FIELDS*4); // PARAM: 3/4 of all structs should have no members if (n_fields >= N_FIELDS) n_fields = 0; From kremenek at apple.com Mon Jan 11 18:36:38 2010 From: kremenek at apple.com (Ted Kremenek) Date: Tue, 12 Jan 2010 00:36:38 -0000 Subject: [cfe-commits] r93212 - in /cfe/trunk/tools/CIndex: CIndex.cpp CIndexer.h Message-ID: <201001120036.o0C0acvF020606@zion.cs.uiuc.edu> Author: kremenek Date: Mon Jan 11 18:36:38 2010 New Revision: 93212 URL: http://llvm.org/viewvc/llvm-project?rev=93212&view=rev Log: Make createCXString() a static member function of class CIndex. Modified: cfe/trunk/tools/CIndex/CIndex.cpp cfe/trunk/tools/CIndex/CIndexer.h Modified: cfe/trunk/tools/CIndex/CIndex.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndex.cpp?rev=93212&r1=93211&r2=93212&view=diff ============================================================================== --- cfe/trunk/tools/CIndex/CIndex.cpp (original) +++ cfe/trunk/tools/CIndex/CIndex.cpp Mon Jan 11 18:36:38 2010 @@ -416,7 +416,7 @@ } } -static CXString createCXString(const char *String, bool DupString = false) { +CXString CIndexer::CIndexer::createCXString(const char *String, bool DupString){ CXString Str; if (DupString) { Str.Spelling = strdup(String); @@ -579,7 +579,8 @@ CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) { assert(CTUnit && "Passed null CXTranslationUnit"); ASTUnit *CXXUnit = static_cast(CTUnit); - return createCXString(CXXUnit->getOriginalSourceFileName().c_str(), true); + return CIndexer::createCXString(CXXUnit->getOriginalSourceFileName().c_str(), + true); } void clang_loadTranslationUnit(CXTranslationUnit CTUnit, @@ -633,18 +634,19 @@ NamedDecl *ND = static_cast(AnonDecl); if (ObjCMethodDecl *OMD = dyn_cast(ND)) - return createCXString(OMD->getSelector().getAsString().c_str(), true); + return CIndexer::createCXString(OMD->getSelector().getAsString().c_str(), + true); if (ObjCCategoryImplDecl *CIMP = dyn_cast(ND)) // No, this isn't the same as the code below. getIdentifier() is non-virtual // and returns different names. NamedDecl returns the class name and // ObjCCategoryImplDecl returns the category name. - return createCXString(CIMP->getIdentifier()->getNameStart()); + return CIndexer::createCXString(CIMP->getIdentifier()->getNameStart()); if (ND->getIdentifier()) - return createCXString(ND->getIdentifier()->getNameStart()); + return CIndexer::createCXString(ND->getIdentifier()->getNameStart()); - return createCXString(""); + return CIndexer::createCXString(""); } unsigned clang_getDeclLine(CXDecl AnonDecl) { @@ -759,28 +761,29 @@ case CXCursor_ObjCSuperClassRef: { ObjCInterfaceDecl *OID = dyn_cast(ND); assert(OID && "clang_getCursorLine(): Missing interface decl"); - return createCXString(OID->getSuperClass()->getIdentifier() - ->getNameStart()); + return CIndexer::createCXString(OID->getSuperClass()->getIdentifier() + ->getNameStart()); } case CXCursor_ObjCClassRef: { if (ObjCInterfaceDecl *OID = dyn_cast(ND)) - return createCXString(OID->getIdentifier()->getNameStart()); + return CIndexer::createCXString(OID->getIdentifier()->getNameStart()); ObjCCategoryDecl *OCD = dyn_cast(ND); assert(OCD && "clang_getCursorLine(): Missing category decl"); - return createCXString(OCD->getClassInterface()->getIdentifier() + return CIndexer::createCXString(OCD->getClassInterface()->getIdentifier() ->getNameStart()); } case CXCursor_ObjCProtocolRef: { ObjCProtocolDecl *OID = dyn_cast(ND); assert(OID && "clang_getCursorLine(): Missing protocol decl"); - return createCXString(OID->getIdentifier()->getNameStart()); + return CIndexer::createCXString(OID->getIdentifier()->getNameStart()); } case CXCursor_ObjCSelectorRef: { ObjCMessageExpr *OME = dyn_cast( static_cast(C.stmt)); assert(OME && "clang_getCursorLine(): Missing message expr"); - return createCXString(OME->getSelector().getAsString().c_str(), true); + return CIndexer::createCXString(OME->getSelector().getAsString().c_str(), + true); } case CXCursor_VarRef: case CXCursor_FunctionRef: @@ -788,10 +791,11 @@ DeclRefExpr *DRE = dyn_cast( static_cast(C.stmt)); assert(DRE && "clang_getCursorLine(): Missing decl ref expr"); - return createCXString(DRE->getDecl()->getIdentifier()->getNameStart()); + return CIndexer::createCXString(DRE->getDecl()->getIdentifier() + ->getNameStart()); } default: - return createCXString(""); + return CIndexer::createCXString(""); } } return clang_getDeclSpelling(C.decl); @@ -1049,8 +1053,9 @@ NamedDecl *ND = static_cast(C.decl); SourceManager &SourceMgr = ND->getASTContext().getSourceManager(); - return (void *)getFileEntryFromSourceLocation(SourceMgr, - getLocationFromCursor(C,SourceMgr, ND)); + return (void *) + getFileEntryFromSourceLocation(SourceMgr, getLocationFromCursor(C,SourceMgr, + ND)); } void clang_getDefinitionSpellingAndExtent(CXCursor C, Modified: cfe/trunk/tools/CIndex/CIndexer.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndexer.h?rev=93212&r1=93211&r2=93212&view=diff ============================================================================== --- cfe/trunk/tools/CIndex/CIndexer.h (original) +++ cfe/trunk/tools/CIndex/CIndexer.h Mon Jan 11 18:36:38 2010 @@ -81,6 +81,8 @@ /// \brief Get the path of the clang resource files. std::string getClangResourcesPath(); + + static CXString createCXString(const char *String, bool DupString = false); }; #endif From kremenek at apple.com Mon Jan 11 18:38:53 2010 From: kremenek at apple.com (Ted Kremenek) Date: Tue, 12 Jan 2010 00:38:53 -0000 Subject: [cfe-commits] r93213 - in /cfe/trunk: include/clang-c/Index.h tools/CIndex/CIndexUSRs.cpp Message-ID: <201001120038.o0C0cr2r020679@zion.cs.uiuc.edu> Author: kremenek Date: Mon Jan 11 18:38:53 2010 New Revision: 93213 URL: http://llvm.org/viewvc/llvm-project?rev=93213&view=rev Log: Change clang_getUSR() to return a CXString instead of a 'const char *'. Modified: cfe/trunk/include/clang-c/Index.h cfe/trunk/tools/CIndex/CIndexUSRs.cpp Modified: cfe/trunk/include/clang-c/Index.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=93213&r1=93212&r2=93213&view=diff ============================================================================== --- cfe/trunk/include/clang-c/Index.h (original) +++ cfe/trunk/include/clang-c/Index.h Mon Jan 11 18:38:53 2010 @@ -329,7 +329,7 @@ * in a specified translation unit. */ CINDEX_LINKAGE CXDecl clang_getDeclaration(CXEntity, CXTranslationUnit); -CINDEX_LINKAGE const char *clang_getUSR(CXEntity); +CINDEX_LINKAGE CXString clang_getUSR(CXEntity); /* * CXDecl Operations. */ Modified: cfe/trunk/tools/CIndex/CIndexUSRs.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndexUSRs.cpp?rev=93213&r1=93212&r2=93213&view=diff ============================================================================== --- cfe/trunk/tools/CIndex/CIndexUSRs.cpp (original) +++ cfe/trunk/tools/CIndex/CIndexUSRs.cpp Mon Jan 11 18:38:53 2010 @@ -74,8 +74,8 @@ return NullCXEntity(); } -const char *clang_getUSR(CXEntity) { - return ""; +CXString clang_getUSR(CXEntity) { + return CIndexer::createCXString(""); } } // end extern "C" From rjmccall at apple.com Mon Jan 11 18:44:58 2010 From: rjmccall at apple.com (John McCall) Date: Tue, 12 Jan 2010 00:44:58 -0000 Subject: [cfe-commits] r93214 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaCXXCast.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaInit.cpp lib/Sema/SemaOverload.cpp lib/Sema/SemaOverload.h test/SemaCXX/ambig-user-defined-conversions.cpp test/SemaCXX/builtin-ptrtomember-overload-1.cpp test/SemaCXX/conditional-expr.cpp Message-ID: <201001120044.o0C0ixp6020907@zion.cs.uiuc.edu> Author: rjmccall Date: Mon Jan 11 18:44:57 2010 New Revision: 93214 URL: http://llvm.org/viewvc/llvm-project?rev=93214&view=rev Log: Introduce a specific representation for the ambiguous implicit conversion sequence. Lots of small relevant changes. Fixes some serious problems with ambiguous conversions; also possibly improves associated diagnostics. Modified: cfe/trunk/lib/Sema/Sema.h cfe/trunk/lib/Sema/SemaCXXCast.cpp cfe/trunk/lib/Sema/SemaDeclCXX.cpp cfe/trunk/lib/Sema/SemaExprCXX.cpp cfe/trunk/lib/Sema/SemaInit.cpp cfe/trunk/lib/Sema/SemaOverload.cpp cfe/trunk/lib/Sema/SemaOverload.h cfe/trunk/test/SemaCXX/ambig-user-defined-conversions.cpp cfe/trunk/test/SemaCXX/builtin-ptrtomember-overload-1.cpp cfe/trunk/test/SemaCXX/conditional-expr.cpp Modified: cfe/trunk/lib/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=93214&r1=93213&r2=93214&view=diff ============================================================================== --- cfe/trunk/lib/Sema/Sema.h (original) +++ cfe/trunk/lib/Sema/Sema.h Mon Jan 11 18:44:57 2010 @@ -1044,6 +1044,9 @@ SourceLocation Loc = SourceLocation()); void NoteOverloadCandidate(FunctionDecl *Fn); + void DiagnoseAmbiguousConversion(const ImplicitConversionSequence &ICS, + SourceLocation CaretLoc, + const PartialDiagnostic &PDiag); FunctionDecl *ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, bool Complain); Modified: cfe/trunk/lib/Sema/SemaCXXCast.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXCast.cpp?rev=93214&r1=93213&r2=93214&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaCXXCast.cpp (original) +++ cfe/trunk/lib/Sema/SemaCXXCast.cpp Mon Jan 11 18:44:57 2010 @@ -893,7 +893,7 @@ /*InOverloadResolution=*/false, /*one of user provided casts*/true); - if (ICS.ConversionKind == ImplicitConversionSequence::BadConversion) + if (ICS.isBad()) return TC_NotApplicable; // The conversion is possible, so commit to it. Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=93214&r1=93213&r2=93214&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Jan 11 18:44:57 2010 @@ -4389,8 +4389,7 @@ = CompareReferenceRelationship(DeclLoc, T1, T2, DerivedToBase); // Most paths end in a failed conversion. - if (ICS) - ICS->ConversionKind = ImplicitConversionSequence::BadConversion; + if (ICS) ICS->setBad(); // C++ [dcl.init.ref]p5: // A reference to type "cv1 T1" is initialized by an expression @@ -4428,7 +4427,7 @@ // has a type that is a derived class of the parameter type, // in which case the implicit conversion sequence is a // derived-to-base Conversion (13.3.3.1). - ICS->ConversionKind = ImplicitConversionSequence::StandardConversion; + ICS->setStandard(); ICS->Standard.First = ICK_Identity; ICS->Standard.Second = DerivedToBase? ICK_Derived_To_Base : ICK_Identity; ICS->Standard.Third = ICK_Identity; @@ -4513,7 +4512,7 @@ // conversion or, if the conversion function returns an // entity of a type that is a derived class of the parameter // type, a derived-to-base Conversion. - ICS->ConversionKind = ImplicitConversionSequence::UserDefinedConversion; + ICS->setUserDefined(); ICS->UserDefined.Before = Best->Conversions[0].Standard; ICS->UserDefined.After = Best->FinalConversion; ICS->UserDefined.ConversionFunction = Best->Function; @@ -4539,10 +4538,11 @@ case OR_Ambiguous: if (ICS) { + ICS->setAmbiguous(); for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(); Cand != CandidateSet.end(); ++Cand) if (Cand->Viable) - ICS->ConversionFunctionSet.push_back(Cand->Function); + ICS->Ambiguous.addConversion(Cand->Function); break; } Diag(DeclLoc, diag::err_ref_init_ambiguous) << DeclType << Init->getType() @@ -4616,7 +4616,7 @@ if (InitLvalue != Expr::LV_Valid && T2->isRecordType() && RefRelationship >= Ref_Compatible_With_Added_Qualification) { if (ICS) { - ICS->ConversionKind = ImplicitConversionSequence::StandardConversion; + ICS->setStandard(); ICS->Standard.First = ICK_Identity; ICS->Standard.Second = DerivedToBase? ICK_Derived_To_Base : ICK_Identity; ICS->Standard.Third = ICK_Identity; @@ -4688,29 +4688,26 @@ /*InOverloadResolution=*/false); // Of course, that's still a reference binding. - if (ICS->ConversionKind == ImplicitConversionSequence::StandardConversion) { + if (ICS->isStandard()) { ICS->Standard.ReferenceBinding = true; ICS->Standard.RRefBinding = isRValRef; - } else if (ICS->ConversionKind == - ImplicitConversionSequence::UserDefinedConversion) { + } else if (ICS->isUserDefined()) { ICS->UserDefined.After.ReferenceBinding = true; ICS->UserDefined.After.RRefBinding = isRValRef; } - return ICS->ConversionKind == ImplicitConversionSequence::BadConversion; + return ICS->isBad(); } else { ImplicitConversionSequence Conversions; bool badConversion = PerformImplicitConversion(Init, T1, AA_Initializing, false, false, Conversions); if (badConversion) { - if ((Conversions.ConversionKind == - ImplicitConversionSequence::BadConversion) - && !Conversions.ConversionFunctionSet.empty()) { + if (Conversions.isAmbiguous()) { Diag(DeclLoc, diag::err_lvalue_to_rvalue_ambig_ref) << Init->getSourceRange(); - for (int j = Conversions.ConversionFunctionSet.size()-1; + for (int j = Conversions.Ambiguous.conversions().size()-1; j >= 0; j--) { - FunctionDecl *Func = Conversions.ConversionFunctionSet[j]; + FunctionDecl *Func = Conversions.Ambiguous.conversions()[j]; NoteOverloadCandidate(Func); } } Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=93214&r1=93213&r2=93214&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon Jan 11 18:44:57 2010 @@ -1075,7 +1075,7 @@ AssignmentAction Action, bool AllowExplicit, bool Elidable, ImplicitConversionSequence& ICS) { - ICS.ConversionKind = ImplicitConversionSequence::BadConversion; + ICS.setBad(); if (Elidable && getLangOptions().CPlusPlus0x) { ICS = TryImplicitConversion(From, ToType, /*SuppressUserConversions=*/false, @@ -1083,7 +1083,7 @@ /*ForceRValue=*/true, /*InOverloadResolution=*/false); } - if (ICS.ConversionKind == ImplicitConversionSequence::BadConversion) { + if (ICS.isBad()) { ICS = TryImplicitConversion(From, ToType, /*SuppressUserConversions=*/false, AllowExplicit, @@ -1103,7 +1103,7 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType, const ImplicitConversionSequence &ICS, AssignmentAction Action, bool IgnoreBaseAccess) { - switch (ICS.ConversionKind) { + switch (ICS.getKind()) { case ImplicitConversionSequence::StandardConversion: if (PerformImplicitConversion(From, ToType, ICS.Standard, Action, IgnoreBaseAccess)) @@ -1157,6 +1157,12 @@ return PerformImplicitConversion(From, ToType, ICS.UserDefined.After, AA_Converting, IgnoreBaseAccess); } + + case ImplicitConversionSequence::AmbiguousConversion: + DiagnoseAmbiguousConversion(ICS, From->getExprLoc(), + PDiag(diag::err_typecheck_ambiguous_condition) + << From->getSourceRange()); + return true; case ImplicitConversionSequence::EllipsisConversion: assert(false && "Cannot perform an ellipsis conversion"); @@ -1474,14 +1480,18 @@ /// \brief Get the target type of a standard or user-defined conversion. static QualType TargetType(const ImplicitConversionSequence &ICS) { - assert((ICS.ConversionKind == - ImplicitConversionSequence::StandardConversion || - ICS.ConversionKind == - ImplicitConversionSequence::UserDefinedConversion) && - "function only valid for standard or user-defined conversions"); - if (ICS.ConversionKind == ImplicitConversionSequence::StandardConversion) - return QualType::getFromOpaquePtr(ICS.Standard.ToTypePtr); - return QualType::getFromOpaquePtr(ICS.UserDefined.After.ToTypePtr); + switch (ICS.getKind()) { + case ImplicitConversionSequence::StandardConversion: + return ICS.Standard.getToType(); + case ImplicitConversionSequence::UserDefinedConversion: + return ICS.UserDefined.After.getToType(); + case ImplicitConversionSequence::AmbiguousConversion: + return ICS.Ambiguous.getToType(); + case ImplicitConversionSequence::EllipsisConversion: + case ImplicitConversionSequence::BadConversion: + llvm_unreachable("function not valid for ellipsis or bad conversions"); + } + return QualType(); // silence warnings } /// \brief Try to convert a type to another according to C++0x 5.16p3. @@ -1511,19 +1521,16 @@ /*ForceRValue=*/false, &ICS)) { - assert((ICS.ConversionKind == - ImplicitConversionSequence::StandardConversion || - ICS.ConversionKind == - ImplicitConversionSequence::UserDefinedConversion) && + assert((ICS.isStandard() || ICS.isUserDefined()) && "expected a definite conversion"); bool DirectBinding = - ICS.ConversionKind == ImplicitConversionSequence::StandardConversion ? - ICS.Standard.DirectBinding : ICS.UserDefined.After.DirectBinding; + ICS.isStandard() ? ICS.Standard.DirectBinding + : ICS.UserDefined.After.DirectBinding; if (DirectBinding) return false; } } - ICS.ConversionKind = ImplicitConversionSequence::BadConversion; + ICS.setBad(); // -- If E2 is an rvalue, or if the conversion above cannot be done: // -- if E1 and E2 have class type, and the underlying class types are // the same or one is a base class of the other: @@ -1619,8 +1626,7 @@ /// handles the reference binding specially. static bool ConvertForConditional(Sema &Self, Expr *&E, const ImplicitConversionSequence &ICS) { - if (ICS.ConversionKind == ImplicitConversionSequence::StandardConversion && - ICS.Standard.ReferenceBinding) { + if (ICS.isStandard() && ICS.Standard.ReferenceBinding) { assert(ICS.Standard.DirectBinding && "TryClassUnification should never generate indirect ref bindings"); // FIXME: CheckReferenceInit should be able to reuse the ICS instead of @@ -1632,8 +1638,7 @@ /*AllowExplicit=*/false, /*ForceRValue=*/false); } - if (ICS.ConversionKind == ImplicitConversionSequence::UserDefinedConversion && - ICS.UserDefined.After.ReferenceBinding) { + if (ICS.isUserDefined() && ICS.UserDefined.After.ReferenceBinding) { assert(ICS.UserDefined.After.DirectBinding && "TryClassUnification should never generate indirect ref bindings"); return Self.CheckReferenceInit(E, Self.Context.getLValueReferenceType( @@ -1721,10 +1726,8 @@ if (TryClassUnification(*this, RHS, LHS, QuestionLoc, ICSRightToLeft)) return QualType(); - bool HaveL2R = ICSLeftToRight.ConversionKind != - ImplicitConversionSequence::BadConversion; - bool HaveR2L = ICSRightToLeft.ConversionKind != - ImplicitConversionSequence::BadConversion; + bool HaveL2R = !ICSLeftToRight.isBad(); + bool HaveR2L = !ICSRightToLeft.isBad(); // If both can be converted, [...] the program is ill-formed. if (HaveL2R && HaveR2L) { Diag(QuestionLoc, diag::err_conditional_ambiguous) @@ -1938,8 +1941,8 @@ /*InOverloadResolution=*/false); ImplicitConversionSequence E1ToC2, E2ToC2; - E1ToC2.ConversionKind = ImplicitConversionSequence::BadConversion; - E2ToC2.ConversionKind = ImplicitConversionSequence::BadConversion; + E1ToC2.setBad(); + E2ToC2.setBad(); if (Context.getCanonicalType(Composite1) != Context.getCanonicalType(Composite2)) { E1ToC2 = TryImplicitConversion(E1, Composite2, @@ -1954,14 +1957,8 @@ /*InOverloadResolution=*/false); } - bool ToC1Viable = E1ToC1.ConversionKind != - ImplicitConversionSequence::BadConversion - && E2ToC1.ConversionKind != - ImplicitConversionSequence::BadConversion; - bool ToC2Viable = E1ToC2.ConversionKind != - ImplicitConversionSequence::BadConversion - && E2ToC2.ConversionKind != - ImplicitConversionSequence::BadConversion; + bool ToC1Viable = !E1ToC1.isBad() && !E2ToC1.isBad(); + bool ToC2Viable = !E1ToC2.isBad() && !E2ToC2.isBad(); if (ToC1Viable && !ToC2Viable) { if (!PerformImplicitConversion(E1, Composite1, E1ToC1, Sema::AA_Converting) && !PerformImplicitConversion(E2, Composite1, E2ToC1, Sema::AA_Converting)) Modified: cfe/trunk/lib/Sema/SemaInit.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=93214&r1=93213&r2=93214&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaInit.cpp (original) +++ cfe/trunk/lib/Sema/SemaInit.cpp Mon Jan 11 18:44:57 2010 @@ -670,7 +670,7 @@ /*ForceRValue=*/false, /*InOverloadResolution=*/false); - if (ICS.ConversionKind != ImplicitConversionSequence::BadConversion) { + if (!ICS.isBad()) { if (SemaRef.PerformImplicitConversion(expr, ElemType, ICS, Sema::AA_Initializing)) hadError = true; @@ -2300,6 +2300,11 @@ Sequence); if (ConvOvlResult == OR_Success) return; + if (ConvOvlResult != OR_No_Viable_Function) { + Sequence.SetOverloadFailure( + InitializationSequence::FK_ReferenceInitOverloadFailed, + ConvOvlResult); + } } } @@ -2384,7 +2389,7 @@ /*FIXME:InOverloadResolution=*/false, /*UserCast=*/Kind.isExplicitCast()); - if (ICS.ConversionKind == ImplicitConversionSequence::BadConversion) { + if (ICS.isBad()) { // FIXME: Use the conversion function set stored in ICS to turn // this into an overloading ambiguity diagnostic. However, we need // to keep that set as an OverloadCandidateSet rather than as some @@ -2685,14 +2690,14 @@ // Perform overload resolution. If it fails, return the failed result. OverloadCandidateSet::iterator Best; - if (OverloadingResult Result + if (OverloadingResult Result = S.BestViableFunction(CandidateSet, DeclLoc, Best)) { Sequence.SetOverloadFailure( InitializationSequence::FK_UserConversionOverloadFailed, Result); return; } - + FunctionDecl *Function = Best->Function; if (isa(Function)) { @@ -2711,7 +2716,7 @@ if (Best->FinalConversion.First || Best->FinalConversion.Second || Best->FinalConversion.Third) { ImplicitConversionSequence ICS; - ICS.ConversionKind = ImplicitConversionSequence::StandardConversion; + ICS.setStandard(); ICS.Standard = Best->FinalConversion; Sequence.AddConversionSequenceStep(ICS, DestType); } @@ -2732,7 +2737,7 @@ /*FIXME:InOverloadResolution=*/false, /*UserCast=*/Kind.isExplicitCast()); - if (ICS.ConversionKind == ImplicitConversionSequence::BadConversion) { + if (ICS.isBad()) { Sequence.SetFailed(InitializationSequence::FK_ConversionFailed); return; } Modified: cfe/trunk/lib/Sema/SemaOverload.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=93214&r1=93213&r2=93214&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOverload.cpp (original) +++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Jan 11 18:44:57 2010 @@ -145,15 +145,12 @@ /// used as part of the ranking of standard conversion sequences /// (C++ 13.3.3.2p4). bool StandardConversionSequence::isPointerConversionToBool() const { - QualType FromType = QualType::getFromOpaquePtr(FromTypePtr); - QualType ToType = QualType::getFromOpaquePtr(ToTypePtr); - // Note that FromType has not necessarily been transformed by the // array-to-pointer or function-to-pointer implicit conversions, so // check for their presence as well as checking whether FromType is // a pointer. - if (ToType->isBooleanType() && - (FromType->isPointerType() || FromType->isBlockPointerType() || + if (getToType()->isBooleanType() && + (getFromType()->isPointerType() || getFromType()->isBlockPointerType() || First == ICK_Array_To_Pointer || First == ICK_Function_To_Pointer)) return true; @@ -167,8 +164,8 @@ bool StandardConversionSequence:: isPointerConversionToVoidPointer(ASTContext& Context) const { - QualType FromType = QualType::getFromOpaquePtr(FromTypePtr); - QualType ToType = QualType::getFromOpaquePtr(ToTypePtr); + QualType FromType = getFromType(); + QualType ToType = getToType(); // Note that FromType has not necessarily been transformed by the // array-to-pointer implicit conversion, so check for its presence @@ -250,6 +247,9 @@ case EllipsisConversion: fprintf(stderr, "Ellipsis conversion"); break; + case AmbiguousConversion: + fprintf(stderr, "Ambiguous conversion"); + break; case BadConversion: fprintf(stderr, "Bad conversion"); break; @@ -258,6 +258,22 @@ fprintf(stderr, "\n"); } +void AmbiguousConversionSequence::construct() { + new (&conversions()) ConversionSet(); +} + +void AmbiguousConversionSequence::destruct() { + conversions().~ConversionSet(); +} + +void +AmbiguousConversionSequence::copyFrom(const AmbiguousConversionSequence &O) { + FromTypePtr = O.FromTypePtr; + ToTypePtr = O.ToTypePtr; + new (&conversions()) ConversionSet(O.conversions()); +} + + // IsOverload - Determine whether the given New declaration is an // overload of the declarations in Old. This routine returns false if // New and Old cannot be overloaded, e.g., if New has the same @@ -432,14 +448,14 @@ OverloadCandidateSet Conversions; OverloadingResult UserDefResult = OR_Success; if (IsStandardConversion(From, ToType, InOverloadResolution, ICS.Standard)) - ICS.ConversionKind = ImplicitConversionSequence::StandardConversion; + ICS.setStandard(); else if (getLangOptions().CPlusPlus && (UserDefResult = IsUserDefinedConversion(From, ToType, ICS.UserDefined, Conversions, !SuppressUserConversions, AllowExplicit, ForceRValue, UserCast)) == OR_Success) { - ICS.ConversionKind = ImplicitConversionSequence::UserDefinedConversion; + ICS.setUserDefined(); // C++ [over.ics.user]p4: // A conversion of an expression of class type to the same class // type is given Exact Match rank, and a conversion of an @@ -456,10 +472,10 @@ (FromCanon == ToCanon || IsDerivedFrom(FromCanon, ToCanon))) { // Turn this into a "standard" conversion sequence, so that it // gets ranked with standard conversion sequences. - ICS.ConversionKind = ImplicitConversionSequence::StandardConversion; + ICS.setStandard(); ICS.Standard.setAsIdentityConversion(); - ICS.Standard.FromTypePtr = From->getType().getAsOpaquePtr(); - ICS.Standard.ToTypePtr = ToType.getAsOpaquePtr(); + ICS.Standard.setFromType(From->getType()); + ICS.Standard.setToType(ToType); ICS.Standard.CopyConstructor = Constructor; if (ToCanon != FromCanon) ICS.Standard.Second = ICK_Derived_To_Base; @@ -473,17 +489,18 @@ // of a class copy-initialization, or by 13.3.1.4, 13.3.1.5, or // 13.3.1.6 in all cases, only standard conversion sequences and // ellipsis conversion sequences are allowed. - if (SuppressUserConversions && - ICS.ConversionKind == ImplicitConversionSequence::UserDefinedConversion) - ICS.ConversionKind = ImplicitConversionSequence::BadConversion; + if (SuppressUserConversions && ICS.isUserDefined()) + ICS.setBad(); + } else if (UserDefResult == OR_Ambiguous) { + ICS.setAmbiguous(); + ICS.Ambiguous.setFromType(From->getType()); + ICS.Ambiguous.setToType(ToType); + for (OverloadCandidateSet::iterator Cand = Conversions.begin(); + Cand != Conversions.end(); ++Cand) + if (Cand->Viable) + ICS.Ambiguous.addConversion(Cand->Function); } else { - ICS.ConversionKind = ImplicitConversionSequence::BadConversion; - if (UserDefResult == OR_Ambiguous) { - for (OverloadCandidateSet::iterator Cand = Conversions.begin(); - Cand != Conversions.end(); ++Cand) - if (Cand->Viable) - ICS.ConversionFunctionSet.push_back(Cand->Function); - } + ICS.setBad(); } return ICS; @@ -524,7 +541,7 @@ SCS.setAsIdentityConversion(); SCS.Deprecated = false; SCS.IncompatibleObjC = false; - SCS.FromTypePtr = FromType.getAsOpaquePtr(); + SCS.setFromType(FromType); SCS.CopyConstructor = 0; // There are no standard conversions for class types in C++, so @@ -573,7 +590,7 @@ // conversion (4.4). (C++ 4.2p2) SCS.Second = ICK_Identity; SCS.Third = ICK_Qualification; - SCS.ToTypePtr = ToType.getAsOpaquePtr(); + SCS.setToType(ToType); return true; } } else if (FromType->isFunctionType() && argIsLvalue == Expr::LV_Valid) { @@ -724,7 +741,7 @@ if (CanonFrom != CanonTo) return false; - SCS.ToTypePtr = FromType.getAsOpaquePtr(); + SCS.setToType(FromType); return true; } @@ -1544,8 +1561,7 @@ // the argument of the constructor. // QualType ThisType = Constructor->getThisType(Context); - if (Best->Conversions[0].ConversionKind == - ImplicitConversionSequence::EllipsisConversion) + if (Best->Conversions[0].isEllipsis()) User.EllipsisConversion = true; else { User.Before = Best->Conversions[0].Standard; @@ -1553,9 +1569,9 @@ } User.ConversionFunction = Constructor; User.After.setAsIdentityConversion(); - User.After.FromTypePtr - = ThisType->getAs()->getPointeeType().getAsOpaquePtr(); - User.After.ToTypePtr = ToType.getAsOpaquePtr(); + User.After.setFromType( + ThisType->getAs()->getPointeeType()); + User.After.setToType(ToType); return OR_Success; } else if (CXXConversionDecl *Conversion = dyn_cast(Best->Function)) { @@ -1635,18 +1651,28 @@ // conversion sequence than an ellipsis conversion sequence // (13.3.3.1.3). // - if (ICS1.ConversionKind < ICS2.ConversionKind) - return ImplicitConversionSequence::Better; - else if (ICS2.ConversionKind < ICS1.ConversionKind) - return ImplicitConversionSequence::Worse; + // C++0x [over.best.ics]p10: + // For the purpose of ranking implicit conversion sequences as + // described in 13.3.3.2, the ambiguous conversion sequence is + // treated as a user-defined sequence that is indistinguishable + // from any other user-defined conversion sequence. + if (ICS1.getKind() < ICS2.getKind()) { + if (!(ICS1.isUserDefined() && ICS2.isAmbiguous())) + return ImplicitConversionSequence::Better; + } else if (ICS2.getKind() < ICS1.getKind()) { + if (!(ICS2.isUserDefined() && ICS1.isAmbiguous())) + return ImplicitConversionSequence::Worse; + } + + if (ICS1.isAmbiguous() || ICS2.isAmbiguous()) + return ImplicitConversionSequence::Indistinguishable; // Two implicit conversion sequences of the same form are // indistinguishable conversion sequences unless one of the // following rules apply: (C++ 13.3.3.2p3): - if (ICS1.ConversionKind == ImplicitConversionSequence::StandardConversion) + if (ICS1.isStandard()) return CompareStandardConversionSequences(ICS1.Standard, ICS2.Standard); - else if (ICS1.ConversionKind == - ImplicitConversionSequence::UserDefinedConversion) { + else if (ICS1.isUserDefined()) { // User-defined conversion sequence U1 is a better conversion // sequence than another user-defined conversion sequence U2 if // they contain the same user-defined conversion function or @@ -1739,8 +1765,8 @@ // Both conversion sequences are conversions to void // pointers. Compare the source types to determine if there's an // inheritance relationship in their sources. - QualType FromType1 = QualType::getFromOpaquePtr(SCS1.FromTypePtr); - QualType FromType2 = QualType::getFromOpaquePtr(SCS2.FromTypePtr); + QualType FromType1 = SCS1.getFromType(); + QualType FromType2 = SCS2.getFromType(); // Adjust the types we're converting from via the array-to-pointer // conversion, if we need to. @@ -1796,8 +1822,8 @@ // top-level cv-qualifiers, and the type to which the reference // initialized by S2 refers is more cv-qualified than the type // to which the reference initialized by S1 refers. - QualType T1 = QualType::getFromOpaquePtr(SCS1.ToTypePtr); - QualType T2 = QualType::getFromOpaquePtr(SCS2.ToTypePtr); + QualType T1 = SCS1.getToType(); + QualType T2 = SCS2.getToType(); T1 = Context.getCanonicalType(T1); T2 = Context.getCanonicalType(T2); Qualifiers T1Quals, T2Quals; @@ -1927,10 +1953,10 @@ ImplicitConversionSequence::CompareKind Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1, const StandardConversionSequence& SCS2) { - QualType FromType1 = QualType::getFromOpaquePtr(SCS1.FromTypePtr); - QualType ToType1 = QualType::getFromOpaquePtr(SCS1.ToTypePtr); - QualType FromType2 = QualType::getFromOpaquePtr(SCS2.FromTypePtr); - QualType ToType2 = QualType::getFromOpaquePtr(SCS2.ToTypePtr); + QualType FromType1 = SCS1.getFromType(); + QualType ToType1 = SCS1.getToType(); + QualType FromType2 = SCS2.getFromType(); + QualType ToType2 = SCS2.getToType(); // Adjust the types we're converting from via the array-to-pointer // conversion, if we need to. @@ -2175,7 +2201,7 @@ // to exit early. ImplicitConversionSequence ICS; ICS.Standard.setAsIdentityConversion(); - ICS.ConversionKind = ImplicitConversionSequence::BadConversion; + ICS.setBad(); // We need to have an object of class type. if (const PointerType *PT = FromType->getAs()) @@ -2211,9 +2237,9 @@ return ICS; // Success. Mark this as a reference binding. - ICS.ConversionKind = ImplicitConversionSequence::StandardConversion; - ICS.Standard.FromTypePtr = FromType.getAsOpaquePtr(); - ICS.Standard.ToTypePtr = ImplicitParamType.getAsOpaquePtr(); + ICS.setStandard(); + ICS.Standard.setFromType(FromType); + ICS.Standard.setToType(ImplicitParamType); ICS.Standard.ReferenceBinding = true; ICS.Standard.DirectBinding = true; ICS.Standard.RRefBinding = false; @@ -2242,7 +2268,7 @@ ImplicitConversionSequence ICS = TryObjectArgumentInitialization(From->getType(), Method, Method->getParent()); - if (ICS.ConversionKind == ImplicitConversionSequence::BadConversion) + if (ICS.isBad()) return Diag(From->getSourceRange().getBegin(), diag::err_implicit_object_parameter_init) << ImplicitParamRecordType << FromRecordType << From->getSourceRange(); @@ -2274,8 +2300,8 @@ /// of the expression From to bool (C++0x [conv]p3). bool Sema::PerformContextuallyConvertToBool(Expr *&From) { ImplicitConversionSequence ICS = TryContextuallyConvertToBool(From); - if (!PerformImplicitConversion(From, Context.BoolTy, ICS, AA_Converting)) - return false; + if (!ICS.isBad()) + return PerformImplicitConversion(From, Context.BoolTy, ICS, AA_Converting); if (!DiagnoseMultipleUserDefinedConversion(From, Context.BoolTy)) return Diag(From->getSourceRange().getBegin(), @@ -2388,35 +2414,15 @@ = TryCopyInitialization(Args[ArgIdx], ParamType, SuppressUserConversions, ForceRValue, /*InOverloadResolution=*/true); - if (Candidate.Conversions[ArgIdx].ConversionKind - == ImplicitConversionSequence::BadConversion) { - // 13.3.3.1-p10 If several different sequences of conversions exist that - // each convert the argument to the parameter type, the implicit conversion - // sequence associated with the parameter is defined to be the unique conversion - // sequence designated the ambiguous conversion sequence. For the purpose of - // ranking implicit conversion sequences as described in 13.3.3.2, the ambiguous - // conversion sequence is treated as a user-defined sequence that is - // indistinguishable from any other user-defined conversion sequence - if (!Candidate.Conversions[ArgIdx].ConversionFunctionSet.empty()) { - Candidate.Conversions[ArgIdx].ConversionKind = - ImplicitConversionSequence::UserDefinedConversion; - // Set the conversion function to one of them. As due to ambiguity, - // they carry the same weight and is needed for overload resolution - // later. - Candidate.Conversions[ArgIdx].UserDefined.ConversionFunction = - Candidate.Conversions[ArgIdx].ConversionFunctionSet[0]; - } - else { - Candidate.Viable = false; - break; - } + if (Candidate.Conversions[ArgIdx].isBad()) { + Candidate.Viable = false; + break; } } else { // (C++ 13.3.2p2): For the purposes of overload resolution, any // argument for which there is no corresponding parameter is // considered to ""match the ellipsis" (C+ 13.3.3.1.3). - Candidate.Conversions[ArgIdx].ConversionKind - = ImplicitConversionSequence::EllipsisConversion; + Candidate.Conversions[ArgIdx].setEllipsis(); } } } @@ -2552,8 +2558,7 @@ // parameter. Candidate.Conversions[0] = TryObjectArgumentInitialization(ObjectType, Method, ActingContext); - if (Candidate.Conversions[0].ConversionKind - == ImplicitConversionSequence::BadConversion) { + if (Candidate.Conversions[0].isBad()) { Candidate.Viable = false; return; } @@ -2572,8 +2577,7 @@ = TryCopyInitialization(Args[ArgIdx], ParamType, SuppressUserConversions, ForceRValue, /*InOverloadResolution=*/true); - if (Candidate.Conversions[ArgIdx + 1].ConversionKind - == ImplicitConversionSequence::BadConversion) { + if (Candidate.Conversions[ArgIdx + 1].isBad()) { Candidate.Viable = false; break; } @@ -2581,8 +2585,7 @@ // (C++ 13.3.2p2): For the purposes of overload resolution, any // argument for which there is no corresponding parameter is // considered to ""match the ellipsis" (C+ 13.3.3.1.3). - Candidate.Conversions[ArgIdx + 1].ConversionKind - = ImplicitConversionSequence::EllipsisConversion; + Candidate.Conversions[ArgIdx + 1].setEllipsis(); } } } @@ -2706,9 +2709,8 @@ Candidate.IsSurrogate = false; Candidate.IgnoreObjectArgument = false; Candidate.FinalConversion.setAsIdentityConversion(); - Candidate.FinalConversion.FromTypePtr - = Conversion->getConversionType().getAsOpaquePtr(); - Candidate.FinalConversion.ToTypePtr = ToType.getAsOpaquePtr(); + Candidate.FinalConversion.setFromType(Conversion->getConversionType()); + Candidate.FinalConversion.setToType(ToType); // Determine the implicit conversion sequence for the implicit // object parameter. @@ -2722,8 +2724,7 @@ // in overload resolution. if (Candidate.Conversions[0].Standard.Second == ICK_Derived_To_Base) Candidate.Conversions[0].Standard.Second = ICK_Identity; - if (Candidate.Conversions[0].ConversionKind - == ImplicitConversionSequence::BadConversion) { + if (Candidate.Conversions[0].isBad()) { Candidate.Viable = false; return; } @@ -2766,7 +2767,7 @@ /*ForceRValue=*/false, /*InOverloadResolution=*/false); - switch (ICS.ConversionKind) { + switch (ICS.getKind()) { case ImplicitConversionSequence::StandardConversion: Candidate.FinalConversion = ICS.Standard; break; @@ -2844,7 +2845,7 @@ // object parameter. ImplicitConversionSequence ObjectInit = TryObjectArgumentInitialization(ObjectType, Conversion, ActingContext); - if (ObjectInit.ConversionKind == ImplicitConversionSequence::BadConversion) { + if (ObjectInit.isBad()) { Candidate.Viable = false; return; } @@ -2852,8 +2853,7 @@ // The first conversion is actually a user-defined conversion whose // first conversion is ObjectInit's standard conversion (which is // effectively a reference binding). Record it as such. - Candidate.Conversions[0].ConversionKind - = ImplicitConversionSequence::UserDefinedConversion; + Candidate.Conversions[0].setUserDefined(); Candidate.Conversions[0].UserDefined.Before = ObjectInit.Standard; Candidate.Conversions[0].UserDefined.EllipsisConversion = false; Candidate.Conversions[0].UserDefined.ConversionFunction = Conversion; @@ -2894,8 +2894,7 @@ /*SuppressUserConversions=*/false, /*ForceRValue=*/false, /*InOverloadResolution=*/false); - if (Candidate.Conversions[ArgIdx + 1].ConversionKind - == ImplicitConversionSequence::BadConversion) { + if (Candidate.Conversions[ArgIdx + 1].isBad()) { Candidate.Viable = false; break; } @@ -2903,8 +2902,7 @@ // (C++ 13.3.2p2): For the purposes of overload resolution, any // argument for which there is no corresponding parameter is // considered to ""match the ellipsis" (C+ 13.3.3.1.3). - Candidate.Conversions[ArgIdx + 1].ConversionKind - = ImplicitConversionSequence::EllipsisConversion; + Candidate.Conversions[ArgIdx + 1].setEllipsis(); } } } @@ -3038,8 +3036,7 @@ /*ForceRValue=*/false, /*InOverloadResolution=*/false); } - if (Candidate.Conversions[ArgIdx].ConversionKind - == ImplicitConversionSequence::BadConversion) { + if (Candidate.Conversions[ArgIdx].isBad()) { Candidate.Viable = false; break; } @@ -4304,11 +4301,22 @@ Diag(Fn->getLocation(), diag::note_ovl_candidate); } -namespace { - -void NoteDeletedCandidate(Sema &S, OverloadCandidate *Cand) { +/// Diagnoses an ambiguous conversion. The partial diagnostic is the +/// "lead" diagnostic; it will be given two arguments, the source and +/// target types of the conversion. +void Sema::DiagnoseAmbiguousConversion(const ImplicitConversionSequence &ICS, + SourceLocation CaretLoc, + const PartialDiagnostic &PDiag) { + Diag(CaretLoc, PDiag) + << ICS.Ambiguous.getFromType() << ICS.Ambiguous.getToType(); + for (AmbiguousConversionSequence::const_iterator + I = ICS.Ambiguous.begin(), E = ICS.Ambiguous.end(); I != E; ++I) { + NoteOverloadCandidate(*I); + } } +namespace { + void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand) { // Note deleted candidates, but only if they're viable. if (Cand->Viable && @@ -4335,18 +4343,13 @@ for (int i = Cand->Conversions.size()-1; i >= 0; i--) { const ImplicitConversionSequence &Conversion = Cand->Conversions[i]; - if ((Conversion.ConversionKind != - ImplicitConversionSequence::BadConversion) || - Conversion.ConversionFunctionSet.size() == 0) + + if (!Conversion.isAmbiguous()) continue; - S.Diag(Cand->Function->getLocation(), - diag::note_ovl_candidate_not_viable) << (i+1); + + S.DiagnoseAmbiguousConversion(Conversion, Cand->Function->getLocation(), + PDiag(diag::note_ovl_candidate_not_viable) << (i+1)); errReported = true; - for (int j = Conversion.ConversionFunctionSet.size()-1; - j >= 0; j--) { - FunctionDecl *Func = Conversion.ConversionFunctionSet[j]; - S.NoteOverloadCandidate(Func); - } } } @@ -4411,21 +4414,11 @@ unsigned NoOperands = Cand->Conversions.size(); for (unsigned ArgIdx = 0; ArgIdx < NoOperands; ++ArgIdx) { const ImplicitConversionSequence &ICS = Cand->Conversions[ArgIdx]; - if (ICS.ConversionKind != ImplicitConversionSequence::BadConversion || - ICS.ConversionFunctionSet.empty()) - continue; - if (CXXConversionDecl *Func = dyn_cast( - Cand->Conversions[ArgIdx].ConversionFunctionSet[0])) { - QualType FromTy = - QualType(static_cast(ICS.UserDefined.Before.FromTypePtr),0); - S.Diag(OpLoc, diag::note_ambiguous_type_conversion) - << FromTy << Func->getConversionType(); - } - for (unsigned j = 0; j < ICS.ConversionFunctionSet.size(); j++) { - FunctionDecl *Func = - Cand->Conversions[ArgIdx].ConversionFunctionSet[j]; - S.NoteOverloadCandidate(Func); - } + if (ICS.isBad()) break; // all meaningless after first invalid + if (!ICS.isAmbiguous()) continue; + + S.DiagnoseAmbiguousConversion(ICS, OpLoc, + PDiag(diag::note_ambiguous_type_conversion)); } } @@ -4479,7 +4472,7 @@ Cands.push_back(Cand); std::sort(Cands.begin(), Cands.end(), CompareOverloadCandidates(SourceMgr)); - bool ReportedNonViableOperator = false; + bool ReportedAmbiguousConversions = false; llvm::SmallVectorImpl::iterator I, E; for (I = Cands.begin(), E = Cands.end(); I != E; ++I) { @@ -4492,16 +4485,20 @@ // This a builtin candidate. We do not, in general, want to list // every possible builtin candidate. + else if (Cand->Viable) { + // Generally we only see ambiguities including viable builtin + // operators if overload resolution got screwed up by an + // ambiguous user-defined conversion. + // + // FIXME: It's quite possible for different conversions to see + // different ambiguities, though. + if (!ReportedAmbiguousConversions) { + NoteAmbiguousUserConversions(*this, OpLoc, Cand); + ReportedAmbiguousConversions = true; + } - // If this is a viable builtin, print it. - else if (Cand->Viable) + // If this is a viable builtin, print it. NoteBuiltinOperatorCandidate(*this, Opc, OpLoc, Cand); - - // Otherwise, non-viability might be due to ambiguous user-defined - // conversions. Report them exactly once. - else if (!ReportedNonViableOperator) { - NoteAmbiguousUserConversions(*this, OpLoc, Cand); - ReportedNonViableOperator = true; } } } @@ -5414,7 +5411,7 @@ << Args[0]->getSourceRange() << Args[1]->getSourceRange(); PrintOverloadCandidates(CandidateSet, OCD_AllCandidates); return ExprError(); - } + } // We matched a built-in operator; build it. return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]); Modified: cfe/trunk/lib/Sema/SemaOverload.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.h?rev=93214&r1=93213&r2=93214&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOverload.h (original) +++ cfe/trunk/lib/Sema/SemaOverload.h Mon Jan 11 18:44:57 2010 @@ -149,6 +149,15 @@ /// conversions. CXXConstructorDecl *CopyConstructor; + void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); } + void setToType(QualType T) { ToTypePtr = T.getAsOpaquePtr(); } + QualType getFromType() const { + return QualType::getFromOpaquePtr(FromTypePtr); + } + QualType getToType() const { + return QualType::getFromOpaquePtr(ToTypePtr); + } + void setAsIdentityConversion(); ImplicitConversionRank getRank() const; bool isPointerConversionToBool() const; @@ -190,6 +199,48 @@ void DebugPrint() const; }; + /// Represents an ambiguous user-defined conversion sequence. + struct AmbiguousConversionSequence { + typedef llvm::SmallVector ConversionSet; + + void *FromTypePtr; + void *ToTypePtr; + char Buffer[sizeof(ConversionSet)]; + + QualType getFromType() const { + return QualType::getFromOpaquePtr(FromTypePtr); + } + QualType getToType() const { + return QualType::getFromOpaquePtr(ToTypePtr); + } + void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); } + void setToType(QualType T) { ToTypePtr = T.getAsOpaquePtr(); } + + ConversionSet &conversions() { + return *reinterpret_cast(Buffer); + } + + const ConversionSet &conversions() const { + return *reinterpret_cast(Buffer); + } + + void addConversion(FunctionDecl *D) { + conversions().push_back(D); + } + + typedef ConversionSet::iterator iterator; + iterator begin() { return conversions().begin(); } + iterator end() { return conversions().end(); } + + typedef ConversionSet::const_iterator const_iterator; + const_iterator begin() const { return conversions().begin(); } + const_iterator end() const { return conversions().end(); } + + void construct(); + void destruct(); + void copyFrom(const AmbiguousConversionSequence &); + }; + /// ImplicitConversionSequence - Represents an implicit conversion /// sequence, which may be a standard conversion sequence /// (C++ 13.3.3.1.1), user-defined conversion sequence (C++ 13.3.3.1.2), @@ -197,18 +248,26 @@ struct ImplicitConversionSequence { /// Kind - The kind of implicit conversion sequence. BadConversion /// specifies that there is no conversion from the source type to - /// the target type. The enumerator values are ordered such that - /// better implicit conversions have smaller values. + /// the target type. AmbiguousConversion represents the unique + /// ambiguous conversion (C++0x [over.best.ics]p10). enum Kind { StandardConversion = 0, UserDefinedConversion, + AmbiguousConversion, EllipsisConversion, BadConversion }; + private: /// ConversionKind - The kind of implicit conversion sequence. Kind ConversionKind; + void setKind(Kind K) { + if (isAmbiguous()) Ambiguous.destruct(); + ConversionKind = K; + } + + public: union { /// When ConversionKind == StandardConversion, provides the /// details of the standard conversion sequence. @@ -217,12 +276,54 @@ /// When ConversionKind == UserDefinedConversion, provides the /// details of the user-defined conversion sequence. UserDefinedConversionSequence UserDefined; + + /// When ConversionKind == AmbiguousConversion, provides the + /// details of the ambiguous conversion. + AmbiguousConversionSequence Ambiguous; }; + + ImplicitConversionSequence() : ConversionKind(BadConversion) {} + ~ImplicitConversionSequence() { + if (isAmbiguous()) Ambiguous.destruct(); + } + ImplicitConversionSequence(const ImplicitConversionSequence &Other) + : ConversionKind(Other.ConversionKind) + { + switch (ConversionKind) { + case StandardConversion: Standard = Other.Standard; break; + case UserDefinedConversion: UserDefined = Other.UserDefined; break; + case AmbiguousConversion: Ambiguous.copyFrom(Other.Ambiguous); break; + case EllipsisConversion: break; + case BadConversion: break; + } + } + + ImplicitConversionSequence & + operator=(const ImplicitConversionSequence &Other) { + if (isAmbiguous()) Ambiguous.destruct(); + new (this) ImplicitConversionSequence(Other); + return *this; + } - /// When ConversionKind == BadConversion due to multiple conversion - /// functions, this will list those functions. - llvm::SmallVector ConversionFunctionSet; - + Kind getKind() const { return ConversionKind; } + bool isBad() const { return ConversionKind == BadConversion; } + bool isStandard() const { return ConversionKind == StandardConversion; } + bool isEllipsis() const { return ConversionKind == EllipsisConversion; } + bool isAmbiguous() const { return ConversionKind == AmbiguousConversion; } + bool isUserDefined() const { + return ConversionKind == UserDefinedConversion; + } + + void setBad() { setKind(BadConversion); } + void setStandard() { setKind(StandardConversion); } + void setEllipsis() { setKind(EllipsisConversion); } + void setUserDefined() { setKind(UserDefinedConversion); } + void setAmbiguous() { + if (isAmbiguous()) return; + ConversionKind = AmbiguousConversion; + Ambiguous.construct(); + } + // The result of a comparison between implicit conversion // sequences. Use Sema::CompareImplicitConversionSequences to // actually perform the comparison. @@ -280,6 +381,16 @@ /// after the call to the overload candidate to convert the result /// of calling the conversion function to the required type. StandardConversionSequence FinalConversion; + + /// hasAmbiguousConversion - Returns whether this overload + /// candidate requires an ambiguous conversion or not. + bool hasAmbiguousConversion() const { + for (llvm::SmallVectorImpl::const_iterator + I = Conversions.begin(), E = Conversions.end(); I != E; ++I) { + if (I->isAmbiguous()) return true; + } + return false; + } }; /// OverloadCandidateSet - A set of overload candidates, used in C++ Modified: cfe/trunk/test/SemaCXX/ambig-user-defined-conversions.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/ambig-user-defined-conversions.cpp?rev=93214&r1=93213&r2=93214&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/ambig-user-defined-conversions.cpp (original) +++ cfe/trunk/test/SemaCXX/ambig-user-defined-conversions.cpp Mon Jan 11 18:44:57 2010 @@ -21,6 +21,13 @@ func(b1, f()); // expected-error {{call to 'func' is ambiguous}} return f(); // expected-error {{conversion from 'struct test0::B' to 'int const' is ambiguous}} } + + // This used to crash when comparing the two operands. + void func2(const char cc); // expected-note {{candidate function}} + void func2(const int ci); // expected-note {{candidate function}} + void Test2() { + func2(b1); // expected-error {{call to 'func2' is ambiguous}} + } } namespace test1 { Modified: cfe/trunk/test/SemaCXX/builtin-ptrtomember-overload-1.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/builtin-ptrtomember-overload-1.cpp?rev=93214&r1=93213&r2=93214&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/builtin-ptrtomember-overload-1.cpp (original) +++ cfe/trunk/test/SemaCXX/builtin-ptrtomember-overload-1.cpp Mon Jan 11 18:44:57 2010 @@ -40,7 +40,7 @@ } void foo1(C1 c1, int E::* pmf) { - // FIXME. Error reporting needs much improvement here. - int i = c1->*pmf; // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'struct C1'}} \ - // expected-note {{because of ambiguity in conversion of 'struct C1' to 'struct E *'}} + int i = c1->*pmf; // expected-error {{use of overloaded operator '->*' is ambiguous}} \ + // expected-note {{because of ambiguity in conversion of 'struct C1' to 'struct E *'}} \ + // expected-note 4 {{built-in candidate operator}} } Modified: cfe/trunk/test/SemaCXX/conditional-expr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/conditional-expr.cpp?rev=93214&r1=93213&r2=93214&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/conditional-expr.cpp (original) +++ cfe/trunk/test/SemaCXX/conditional-expr.cpp Mon Jan 11 18:44:57 2010 @@ -7,8 +7,8 @@ struct ToBool { explicit operator bool(); }; struct B; -struct A { A(); A(const B&); }; -struct B { operator A() const; }; +struct A { A(); A(const B&); }; // expected-note 2 {{candidate constructor}} +struct B { operator A() const; }; // expected-note 2 {{candidate function}} struct I { operator int(); }; struct J { operator I(); }; struct K { operator double(); }; @@ -50,8 +50,8 @@ enum Enum { EVal }; struct Ambig { - operator short(); - operator signed char(); + operator short(); // expected-note 2 {{candidate function}} + operator signed char(); // expected-note 2 {{candidate function}} }; void test() @@ -129,10 +129,10 @@ vfn pfn = i1 ? F() : test; pfn = i1 ? test : F(); // these are ambiguous - better messages would be nice - (void)(i1 ? A() : B()); // expected-error {{incompatible operand types}} - (void)(i1 ? B() : A()); // expected-error {{incompatible operand types}} - (void)(i1 ? 1 : Ambig()); // expected-error {{incompatible operand types}} - (void)(i1 ? Ambig() : 1); // expected-error {{incompatible operand types}} + (void)(i1 ? A() : B()); // expected-error {{conversion from 'struct B' to 'struct A' is ambiguous}} + (void)(i1 ? B() : A()); // expected-error {{conversion from 'struct B' to 'struct A' is ambiguous}} + (void)(i1 ? 1 : Ambig()); // expected-error {{conversion from 'struct Ambig' to 'int' is ambiguous}} + (void)(i1 ? Ambig() : 1); // expected-error {{conversion from 'struct Ambig' to 'int' is ambiguous}} // By the way, this isn't an lvalue: &(i1 ? i1 : i2); // expected-error {{address expression must be an lvalue or a function designator}} From rjmccall at apple.com Mon Jan 11 18:48:53 2010 From: rjmccall at apple.com (John McCall) Date: Tue, 12 Jan 2010 00:48:53 -0000 Subject: [cfe-commits] r93215 - /cfe/trunk/lib/Sema/SemaOverload.cpp Message-ID: <201001120048.o0C0mrI3021037@zion.cs.uiuc.edu> Author: rjmccall Date: Mon Jan 11 18:48:53 2010 New Revision: 93215 URL: http://llvm.org/viewvc/llvm-project?rev=93215&view=rev Log: Sort overload results by viability. Modified: cfe/trunk/lib/Sema/SemaOverload.cpp Modified: cfe/trunk/lib/Sema/SemaOverload.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=93215&r1=93214&r2=93215&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOverload.cpp (original) +++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Jan 11 18:48:53 2010 @@ -4422,28 +4422,36 @@ } } -struct CompareOverloadCandidates { - SourceManager &SM; - CompareOverloadCandidates(SourceManager &SM) : SM(SM) {} +struct CompareOverloadCandidatesForDisplay { + Sema &S; + CompareOverloadCandidatesForDisplay(Sema &S) : S(S) {} bool operator()(const OverloadCandidate *L, const OverloadCandidate *R) { // Order first by viability. - if (L->Viable != R->Viable) - return L->Viable; + if (L->Viable) { + if (!R->Viable) return true; + + // TODO: introduce a tri-valued comparison for overload + // candidates. Would be more worthwhile if we had a sort + // that could exploit it. + if (S.isBetterOverloadCandidate(*L, *R)) return true; + if (S.isBetterOverloadCandidate(*R, *L)) return false; + } else if (R->Viable) + return false; // Put declared functions first. if (L->Function) { if (!R->Function) return true; - return SM.isBeforeInTranslationUnit(L->Function->getLocation(), - R->Function->getLocation()); + return S.SourceMgr.isBeforeInTranslationUnit(L->Function->getLocation(), + R->Function->getLocation()); } else if (R->Function) return false; // Then surrogates. if (L->IsSurrogate) { if (!R->IsSurrogate) return true; - return SM.isBeforeInTranslationUnit(L->Surrogate->getLocation(), - R->Surrogate->getLocation()); + return S.SourceMgr.isBeforeInTranslationUnit(L->Surrogate->getLocation(), + R->Surrogate->getLocation()); } else if (R->IsSurrogate) return false; // And builtins just come in a jumble. @@ -4470,7 +4478,8 @@ Cand != LastCand; ++Cand) if (Cand->Viable || OCD == OCD_AllCandidates) Cands.push_back(Cand); - std::sort(Cands.begin(), Cands.end(), CompareOverloadCandidates(SourceMgr)); + std::sort(Cands.begin(), Cands.end(), + CompareOverloadCandidatesForDisplay(*this)); bool ReportedAmbiguousConversions = false; From rjmccall at apple.com Mon Jan 11 19:09:12 2010 From: rjmccall at apple.com (John McCall) Date: Tue, 12 Jan 2010 01:09:12 -0000 Subject: [cfe-commits] r93216 - /cfe/trunk/test/SemaCXX/conditional-expr.cpp Message-ID: <201001120109.o0C19DjT021861@zion.cs.uiuc.edu> Author: rjmccall Date: Mon Jan 11 19:09:12 2010 New Revision: 93216 URL: http://llvm.org/viewvc/llvm-project?rev=93216&view=rev Log: Chris thinks these diagnostics are better now. :) Modified: cfe/trunk/test/SemaCXX/conditional-expr.cpp Modified: cfe/trunk/test/SemaCXX/conditional-expr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/conditional-expr.cpp?rev=93216&r1=93215&r2=93216&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/conditional-expr.cpp (original) +++ cfe/trunk/test/SemaCXX/conditional-expr.cpp Mon Jan 11 19:09:12 2010 @@ -128,7 +128,6 @@ // "the type [it] woud have if E2 were converted to an rvalue" vfn pfn = i1 ? F() : test; pfn = i1 ? test : F(); - // these are ambiguous - better messages would be nice (void)(i1 ? A() : B()); // expected-error {{conversion from 'struct B' to 'struct A' is ambiguous}} (void)(i1 ? B() : A()); // expected-error {{conversion from 'struct B' to 'struct A' is ambiguous}} (void)(i1 ? 1 : Ambig()); // expected-error {{conversion from 'struct Ambig' to 'int' is ambiguous}} From dgregor at apple.com Mon Jan 11 19:17:50 2010 From: dgregor at apple.com (Douglas Gregor) Date: Tue, 12 Jan 2010 01:17:50 -0000 Subject: [cfe-commits] r93217 - /cfe/trunk/lib/Sema/SemaLookup.cpp Message-ID: <201001120117.o0C1Hokd022151@zion.cs.uiuc.edu> Author: dgregor Date: Mon Jan 11 19:17:50 2010 New Revision: 93217 URL: http://llvm.org/viewvc/llvm-project?rev=93217&view=rev Log: Name lookup should know better than to look into a class before it's defined Modified: cfe/trunk/lib/Sema/SemaLookup.cpp Modified: cfe/trunk/lib/Sema/SemaLookup.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=93217&r1=93216&r2=93217&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaLookup.cpp (original) +++ cfe/trunk/lib/Sema/SemaLookup.cpp Mon Jan 11 19:17:50 2010 @@ -460,7 +460,9 @@ // name lookup. Instead, any conversion function templates visible in the // context of the use are considered. [...] const CXXRecordDecl *Record = cast(DC); - + if (!Record->isDefinition()) + return Found; + const UnresolvedSet *Unresolved = Record->getConversionFunctions(); for (UnresolvedSet::iterator U = Unresolved->begin(), UEnd = Unresolved->end(); From fjahanian at apple.com Mon Jan 11 19:22:23 2010 From: fjahanian at apple.com (Fariborz Jahanian) Date: Tue, 12 Jan 2010 01:22:23 -0000 Subject: [cfe-commits] r93219 - in /cfe/trunk: lib/Frontend/RewriteObjC.cpp test/Rewriter/rewrite-eh.m Message-ID: <201001120122.o0C1MOvM022330@zion.cs.uiuc.edu> Author: fjahanian Date: Mon Jan 11 19:22:23 2010 New Revision: 93219 URL: http://llvm.org/viewvc/llvm-project?rev=93219&view=rev Log: Fix rewriting of MacOS sjlj based eh. Fixes radar 7522880. Added: cfe/trunk/test/Rewriter/rewrite-eh.m Modified: cfe/trunk/lib/Frontend/RewriteObjC.cpp Modified: cfe/trunk/lib/Frontend/RewriteObjC.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/RewriteObjC.cpp?rev=93219&r1=93218&r2=93219&view=diff ============================================================================== --- cfe/trunk/lib/Frontend/RewriteObjC.cpp (original) +++ cfe/trunk/lib/Frontend/RewriteObjC.cpp Mon Jan 11 19:22:23 2010 @@ -1757,10 +1757,10 @@ buf += "1) { "; ReplaceText(startLoc, lParenLoc-startBuf+1, buf.c_str(), buf.size()); sawIdTypedCatch = true; - } else if (const PointerType *pType = t->getAs()) { - ObjCInterfaceType *cls; // Should be a pointer to a class. - - cls = dyn_cast(pType->getPointeeType().getTypePtr()); + } else if (t->isObjCObjectPointerType()) { + QualType InterfaceTy = t->getPointeeType(); + const ObjCInterfaceType *cls = // Should be a pointer to a class. + InterfaceTy->getAs(); if (cls) { buf += "objc_exception_match((struct objc_class *)objc_getClass(\""; buf += cls->getDecl()->getNameAsString(); Added: cfe/trunk/test/Rewriter/rewrite-eh.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Rewriter/rewrite-eh.m?rev=93219&view=auto ============================================================================== --- cfe/trunk/test/Rewriter/rewrite-eh.m (added) +++ cfe/trunk/test/Rewriter/rewrite-eh.m Mon Jan 11 19:22:23 2010 @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -rewrite-objc -o - %s +// rdar://7522880 + + at interface NSException + at end + + at interface Foo + at end + + at implementation Foo +- (void)bar { + @try { + } @catch (NSException *e) { + } + @catch (Foo *f) { + } + @catch (...) { + } +} + at end From kremenek at apple.com Mon Jan 11 20:07:59 2010 From: kremenek at apple.com (Ted Kremenek) Date: Tue, 12 Jan 2010 02:07:59 -0000 Subject: [cfe-commits] r93223 - /cfe/trunk/tools/CIndex/CIndexUSRs.cpp Message-ID: <201001120207.o0C27x8F024065@zion.cs.uiuc.edu> Author: kremenek Date: Mon Jan 11 20:07:58 2010 New Revision: 93223 URL: http://llvm.org/viewvc/llvm-project?rev=93223&view=rev Log: Add a boilerplate implementation for clang_getUSR(). WIP. Modified: cfe/trunk/tools/CIndex/CIndexUSRs.cpp Modified: cfe/trunk/tools/CIndex/CIndexUSRs.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndexUSRs.cpp?rev=93223&r1=93222&r2=93223&view=diff ============================================================================== --- cfe/trunk/tools/CIndex/CIndexUSRs.cpp (original) +++ cfe/trunk/tools/CIndex/CIndexUSRs.cpp Mon Jan 11 20:07:58 2010 @@ -12,6 +12,9 @@ //===----------------------------------------------------------------------===// #include "CIndexer.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/raw_ostream.h"; +#include "clang/AST/DeclVisitor.h"; extern "C" { @@ -74,8 +77,83 @@ return NullCXEntity(); } -CXString clang_getUSR(CXEntity) { - return CIndexer::createCXString(""); +//===----------------------------------------------------------------------===// +// USR generation. +//===----------------------------------------------------------------------===// + +namespace { +class USRGenerator : public DeclVisitor { + llvm::raw_ostream &Out; +public: + USRGenerator(llvm::raw_ostream &out) : Out(out) {} + + void VisitObjCContainerDecl(ObjCContainerDecl *CD); + void VisitObjCMethodDecl(ObjCMethodDecl *MD); + void VisitObjCPropertyDecl(ObjCPropertyDecl *D); +}; +} // end anonymous namespace + +void USRGenerator::VisitObjCMethodDecl(ObjCMethodDecl *D) { + Visit(cast(D->getDeclContext())); + Out << (D->isInstanceMethod() ? "_IM_" : "_CM_"); + Out << DeclarationName(D->getSelector()); +} + +void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) { + switch (D->getKind()) { + default: + assert(false && "Invalid ObjC container."); + case Decl::ObjCInterface: + case Decl::ObjCImplementation: + Out << "objc_class_" << D->getName(); + break; + case Decl::ObjCCategory: { + ObjCCategoryDecl *CD = cast(D); + Out << "objc_cat_" << CD->getClassInterface()->getName() + << '_' << CD->getName(); + break; + } + case Decl::ObjCCategoryImpl: { + ObjCCategoryImplDecl *CD = cast(D); + Out << "objc_cat_" << CD->getClassInterface()->getName() + << '_' << CD->getName(); + break; + } + case Decl::ObjCProtocol: + Out << "objc_prot_" << cast(D)->getName(); + break; + } +} + +void USRGenerator::VisitObjCPropertyDecl(ObjCPropertyDecl *D) { + Visit(cast(D->getDeclContext())); + Out << "_prop_" << D->getName(); +} + +// FIXME: This is a skeleton implementation. It will be overhauled. +CXString clang_getUSR(CXEntity CE) { + const Entity &E = GetEntity(CE); + + // FIXME: Support cross-translation unit CXEntities. + if (!E.isInternalToTU()) + return CIndexer::createCXString(NULL); + + Decl *D = E.getInternalDecl(); + if (!D) + return CIndexer::createCXString(NULL); + + llvm::SmallString<1024> StrBuf; + { + llvm::raw_svector_ostream Out(StrBuf); + USRGenerator UG(Out); + UG.Visit(D); + } + + if (StrBuf.empty()) + return CIndexer::createCXString(NULL); + + // Return a copy of the string that must be disposed by the caller. + return CIndexer::createCXString(StrBuf.c_str(), true); } } // end extern "C" From rjmccall at apple.com Mon Jan 11 20:15:36 2010 From: rjmccall at apple.com (John McCall) Date: Tue, 12 Jan 2010 02:15:36 -0000 Subject: [cfe-commits] r93224 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaOverload.cpp test/SemaCXX/overload-call.cpp Message-ID: <201001120215.o0C2Fa6k024414@zion.cs.uiuc.edu> Author: rjmccall Date: Mon Jan 11 20:15:36 2010 New Revision: 93224 URL: http://llvm.org/viewvc/llvm-project?rev=93224&view=rev Log: Reorganize some of the code to note overload candidates. Improves the fidelity with which we note them as functions/constructors and templates thereof. Also will be helpful when reporting bad conversions (next). Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/SemaOverload.cpp cfe/trunk/test/SemaCXX/overload-call.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=93224&r1=93223&r2=93224&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Jan 11 20:15:36 2010 @@ -895,23 +895,23 @@ "call to member function %0 is ambiguous">; def err_ovl_deleted_member_call : Error< "call to %select{unavailable|deleted}0 member function %1">; -def note_ovl_candidate : Note<"candidate function">; +def note_ovl_candidate : Note<"candidate " + "%select{function|function|constructor|" + "is the implicit default constructor|" + "is the implicit copy constructor|" + "is the implicit copy assignment operator}0">; +def note_ovl_template_candidate : Note< + "candidate function template specialization %0">; +def note_ovl_candidate_deleted : Note< + "candidate %select{function|function|constructor}0 has been explicitly " + "%select{made unavailable|deleted}1">; +def note_ovl_template_candidate_deleted : Note< + "candidate function template specialization %0 has been explicit " + "&select{made unavailable|deleted}1">; def note_ovl_candidate_not_viable : Note<"function not viable because" " of ambiguity in conversion of argument %0">; -def note_ovl_candidate_ctor : Note<"candidate constructor">; -def note_ovl_candidate_implicit_copy_ctor : Note< - "candidate is the implicit copy constructor">; -def note_ovl_candidate_implicit_default_ctor : Note< - "candidate is the implicit default constructor">; -def note_ovl_candidate_meth : Note<"candidate function">; -def note_ovl_candidate_implicit_copy_assign : Note< - "candidate is the implicit copy assignment operator">; def note_ambiguous_type_conversion: Note< "because of ambiguity in conversion of %0 to %1">; -def note_ovl_template_candidate : Note< - "candidate function template specialization %0">; -def note_ovl_candidate_deleted : Note< - "candidate function has been explicitly %select{made unavailable|deleted}0">; def note_ovl_builtin_binary_candidate : Note< "built-in candidate %0">; def note_ovl_builtin_unary_candidate : Note< Modified: cfe/trunk/lib/Sema/SemaOverload.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=93224&r1=93223&r2=93224&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOverload.cpp (original) +++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Jan 11 20:15:36 2010 @@ -4263,42 +4263,62 @@ return OR_Success; } -/// Notes the location of an overload candidate. -void Sema::NoteOverloadCandidate(FunctionDecl *Fn) { +namespace { - if (CXXConstructorDecl *Ctor = dyn_cast(Fn)) { - // At least call it a 'constructor'. - if (!Ctor->isImplicit()) { - Diag(Ctor->getLocation(), diag::note_ovl_candidate_ctor); - return; - } +enum OverloadCandidateKind { + oc_function, + oc_method, + oc_constructor, + oc_implicit_default_constructor, + oc_implicit_copy_constructor, + oc_implicit_copy_assignment, + oc_template_specialization // function, constructor, or conversion template +}; - CXXRecordDecl *Record = Ctor->getParent(); - if (Ctor->isCopyConstructor()) { - Diag(Record->getLocation(), diag::note_ovl_candidate_implicit_copy_ctor); - return; - } +OverloadCandidateKind ClassifyOverloadCandidate(FunctionDecl *Fn) { + if (Fn->getPrimaryTemplate()) + return oc_template_specialization; - Diag(Record->getLocation(), diag::note_ovl_candidate_implicit_default_ctor); - return; + if (CXXConstructorDecl *Ctor = dyn_cast(Fn)) { + if (!Ctor->isImplicit()) + return oc_constructor; + + return Ctor->isCopyConstructor() ? oc_implicit_copy_constructor + : oc_implicit_default_constructor; } if (CXXMethodDecl *Meth = dyn_cast(Fn)) { // This actually gets spelled 'candidate function' for now, but // it doesn't hurt to split it out. - if (!Meth->isImplicit()) { - Diag(Meth->getLocation(), diag::note_ovl_candidate_meth); - return; - } + if (!Meth->isImplicit()) + return oc_method; assert(Meth->isCopyAssignment() && "implicit method is not copy assignment operator?"); - Diag(Meth->getParent()->getLocation(), - diag::note_ovl_candidate_implicit_copy_assign); + return oc_implicit_copy_assignment; + } + + return oc_function; +} + +std::string DescribeFunctionTemplate(Sema &S, FunctionDecl *Fn) { + FunctionTemplateDecl *FunTmpl = Fn->getPrimaryTemplate(); + return S.getTemplateArgumentBindingsText(FunTmpl->getTemplateParameters(), + *Fn->getTemplateSpecializationArgs()); +} + +} // end anonymous namespace + +// Notes the location of an overload candidate. +void Sema::NoteOverloadCandidate(FunctionDecl *Fn) { + OverloadCandidateKind K = ClassifyOverloadCandidate(Fn); + if (K == oc_template_specialization) { + Diag(Fn->getLocation(), diag::note_ovl_template_candidate) + << DescribeFunctionTemplate(*this, Fn); return; } - Diag(Fn->getLocation(), diag::note_ovl_candidate); + Diag(Fn->getLocation(), diag::note_ovl_candidate) << (unsigned) K; } /// Diagnoses an ambiguous conversion. The partial diagnostic is the @@ -4318,26 +4338,23 @@ namespace { void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand) { + FunctionDecl *Fn = Cand->Function; + // Note deleted candidates, but only if they're viable. - if (Cand->Viable && - (Cand->Function->isDeleted() || - Cand->Function->hasAttr())) { - S.Diag(Cand->Function->getLocation(), diag::note_ovl_candidate_deleted) - << Cand->Function->isDeleted(); - return; - } + if (Cand->Viable && (Fn->isDeleted() || Fn->hasAttr())) { + OverloadCandidateKind FnKind = ClassifyOverloadCandidate(Fn); + + if (FnKind == oc_template_specialization) { + S.Diag(Fn->getLocation(), diag::note_ovl_template_candidate_deleted) + << DescribeFunctionTemplate(S, Fn) << Fn->isDeleted(); + return; + } - if (FunctionTemplateDecl *FunTmpl - = Cand->Function->getPrimaryTemplate()) { - // Function template specialization - // FIXME: Give a better reason! - S.Diag(Cand->Function->getLocation(), diag::note_ovl_template_candidate) - << S.getTemplateArgumentBindingsText(FunTmpl->getTemplateParameters(), - *Cand->Function->getTemplateSpecializationArgs()); + S.Diag(Fn->getLocation(), diag::note_ovl_candidate_deleted) + << FnKind << Fn->isDeleted(); return; } - // Normal function bool errReported = false; if (!Cand->Viable && Cand->Conversions.size() > 0) { for (int i = Cand->Conversions.size()-1; i >= 0; i--) { @@ -4347,14 +4364,14 @@ if (!Conversion.isAmbiguous()) continue; - S.DiagnoseAmbiguousConversion(Conversion, Cand->Function->getLocation(), + S.DiagnoseAmbiguousConversion(Conversion, Fn->getLocation(), PDiag(diag::note_ovl_candidate_not_viable) << (i+1)); errReported = true; } } if (!errReported) - S.NoteOverloadCandidate(Cand->Function); + S.NoteOverloadCandidate(Fn); } void NoteSurrogateCandidate(Sema &S, OverloadCandidate *Cand) { Modified: cfe/trunk/test/SemaCXX/overload-call.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/overload-call.cpp?rev=93224&r1=93223&r2=93224&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/overload-call.cpp (original) +++ cfe/trunk/test/SemaCXX/overload-call.cpp Mon Jan 11 20:15:36 2010 @@ -301,3 +301,13 @@ (void)ir; } } + +// Tests the exact text used to note the candidates +namespace test1 { + template void foo(T t, unsigned N); // expected-note {{candidate function template specialization [with T = int]}} + void foo(int n, char N); // expected-note {{candidate function}} + + void test() { + foo(4, "hello"); //expected-error {{no matching function for call to 'foo'}} + } +} From daniel at zuster.org Mon Jan 11 20:34:08 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 12 Jan 2010 02:34:08 -0000 Subject: [cfe-commits] r93225 - /cfe/trunk/tools/CIndex/CIndex.cpp Message-ID: <201001120234.o0C2Y8Sj025016@zion.cs.uiuc.edu> Author: ddunbar Date: Mon Jan 11 20:34:07 2010 New Revision: 93225 URL: http://llvm.org/viewvc/llvm-project?rev=93225&view=rev Log: Remove duplicate class name, MSVC doesn't like this. Modified: cfe/trunk/tools/CIndex/CIndex.cpp Modified: cfe/trunk/tools/CIndex/CIndex.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndex.cpp?rev=93225&r1=93224&r2=93225&view=diff ============================================================================== --- cfe/trunk/tools/CIndex/CIndex.cpp (original) +++ cfe/trunk/tools/CIndex/CIndex.cpp Mon Jan 11 20:34:07 2010 @@ -416,7 +416,7 @@ } } -CXString CIndexer::CIndexer::createCXString(const char *String, bool DupString){ +CXString CIndexer::createCXString(const char *String, bool DupString){ CXString Str; if (DupString) { Str.Spelling = strdup(String); From mrs at apple.com Mon Jan 11 21:01:18 2010 From: mrs at apple.com (Mike Stump) Date: Tue, 12 Jan 2010 03:01:18 -0000 Subject: [cfe-commits] r93226 - /cfe/trunk/utils/VtableTest/gen.cc Message-ID: <201001120301.o0C31I7r026054@zion.cs.uiuc.edu> Author: mrs Date: Mon Jan 11 21:01:18 2010 New Revision: 93226 URL: http://llvm.org/viewvc/llvm-project?rev=93226&view=rev Log: Add covariance tester. Modified: cfe/trunk/utils/VtableTest/gen.cc Modified: cfe/trunk/utils/VtableTest/gen.cc URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/VtableTest/gen.cc?rev=93226&r1=93225&r2=93226&view=diff ============================================================================== --- cfe/trunk/utils/VtableTest/gen.cc (original) +++ cfe/trunk/utils/VtableTest/gen.cc Mon Jan 11 21:01:18 2010 @@ -3,9 +3,10 @@ #define N_FIELDS 7 #define N_FUNCS 128 -#define FUNCSPACING 10 -#define N_STRUCTS 300 /* 1280 */ -#define N_BASES 30 +#define FUNCSPACING 20 +#define N_STRUCTS 180 /* 1280 */ +#define N_BASES 6 +#define COVARIANT 0 const char *simple_types[] = { "bool", "char", "short", "int", "float", "double", "long double", "wchar_t", "void *", @@ -84,15 +85,19 @@ // polymorphic = true; base_type = 3; } - switch (random()%8) { + // PARAM: 1/4 are public, 1/8 are privare, 1/8 are protected, the reset, default + int base_protection = 0; + if (!COVARIANT) + base_protection = random()%8; + switch (base_protection) { case 0: case 1: + g("public "); break; case 2: case 3: - break; case 4: case 5: - g("public "); break; + break; case 6: g("private "); break; case 7: @@ -129,7 +134,18 @@ for (int i = 0; i < n_funcs; ++i) { int fn = old_func + random() % FUNCSPACING + 1; funcs[i] = fn; - g(" virtual void fun"); g(fn); g("(char *t) { mix(\"vfn this offset\", (char *)this - t); mix(\"vfn uuid\", "); g(++uuid); gl("); }"); + int rettype = 0; + if (COVARIANT) + rettype = s; + if (rettype) { + g(" virtual s"); g(rettype); g("* fun"); + } else + g(" virtual void fun"); + g(fn); g("(char *t) { mix(\"vfn this offset\", (char *)this - t); mix(\"vfn uuid\", "); g(++uuid); + if (rettype) + gl("); return 0; }"); + else + gl("); }"); funcs_present[s][fn] = 1; final_override[s][fn] = s; old_func = fn; @@ -183,7 +199,18 @@ funcs[n_funcs++] = fn; if (n_funcs == (N_FUNCS*FUNCSPACING-1)) abort(); - g(" virtual void fun"); g(fn); g("(char *t) { mix(\"vfn this offset\", (char *)this - t); mix(\"vfn uuid\", "); g(++uuid); gl("); }"); + int rettype = 0; + if (COVARIANT) + rettype = s; + if (rettype) { + g(" virtual s"); g(rettype); g("* fun"); + } else + g(" virtual void fun"); + g(fn); g("(char *t) { mix(\"vfn this offset\", (char *)this - t); mix(\"vfn uuid\", "); g(++uuid); + if (rettype) + gl("); return 0; }"); + else + gl("); }"); funcs_present[s][fn] = 1; final_override[s][fn] = s; } From daniel at zuster.org Mon Jan 11 21:18:56 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Mon, 11 Jan 2010 19:18:56 -0800 Subject: [cfe-commits] r93118 - in /cfe/trunk: include/clang/AST/Attr.h lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h lib/CodeGen/CodeGenTypes.cpp lib/CodeGen/CodeGenTypes.h lib/CodeGen/TargetInfo.cpp lib/CodeGen/TargetInfo.h lib/Frontend/PCHR Message-ID: <6a8523d61001111918o40a6c4day3d83085c73bd6a76@mail.gmail.com> Hi Anton, On Sun, Jan 10, 2010 at 4:58 AM, Anton Korobeynikov wrote: > Author: asl > Date: Sun Jan 10 06:58:08 2010 > New Revision: 93118 > > URL: http://llvm.org/viewvc/llvm-project?rev=93118&view=rev > Log: > Generalize target weirdness handling having proper layering in mind: > ?1. Add helper class for sema checks for target attributes > ?2. Add helper class for codegen of target attributes > > As a proof-of-concept - implement msp430's 'interrupt' attribute. > > Added: > ? ?cfe/trunk/lib/CodeGen/TargetInfo.h > ? ?cfe/trunk/lib/Sema/TargetAttributesSema.cpp > ? ?cfe/trunk/lib/Sema/TargetAttributesSema.h > Modified: > ? ?cfe/trunk/include/clang/AST/Attr.h > ? ?cfe/trunk/lib/CodeGen/CodeGenModule.cpp > ? ?cfe/trunk/lib/CodeGen/CodeGenModule.h > ? ?cfe/trunk/lib/CodeGen/CodeGenTypes.cpp > ? ?cfe/trunk/lib/CodeGen/CodeGenTypes.h > ? ?cfe/trunk/lib/CodeGen/TargetInfo.cpp > ? ?cfe/trunk/lib/Frontend/PCHReaderDecl.cpp > ? ?cfe/trunk/lib/Frontend/PCHWriter.cpp > ? ?cfe/trunk/lib/Sema/Sema.cpp > ? ?cfe/trunk/lib/Sema/Sema.h > ? ?cfe/trunk/lib/Sema/SemaDeclAttr.cpp > > Modified: cfe/trunk/include/clang/AST/Attr.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Attr.h?rev=93118&r1=93117&r2=93118&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/AST/Attr.h (original) > +++ cfe/trunk/include/clang/AST/Attr.h Sun Jan 10 06:58:08 2010 > @@ -55,8 +55,6 @@ > ? ? Cleanup, > ? ? Const, > ? ? Constructor, > - ? ?DLLExport, > - ? ?DLLImport, > ? ? Deprecated, > ? ? Destructor, > ? ? FastCall, > @@ -93,7 +91,12 @@ > ? ? Visibility, > ? ? WarnUnusedResult, > ? ? Weak, > - ? ?WeakImport > + ? ?WeakImport, > + > + ? ?FIRST_TARGET_ATTRIBUTE, > + ? ?DLLExport, > + ? ?DLLImport, > + ? ?MSP430Interrupt > ? }; This should be FIRST_TARGET_ATTRIBUTE=DLLExport, if the name is to be believed. > > ?private: > @@ -456,8 +459,6 @@ > ? static bool classof(const VisibilityAttr *A) { return true; } > ?}; > > -DEF_SIMPLE_ATTR(DLLImport); > -DEF_SIMPLE_ATTR(DLLExport); > ?DEF_SIMPLE_ATTR(FastCall); > ?DEF_SIMPLE_ATTR(StdCall); > ?DEF_SIMPLE_ATTR(CDecl); > @@ -566,6 +567,27 @@ > ?DEF_SIMPLE_ATTR(Hiding); > ?DEF_SIMPLE_ATTR(Override); > > +// Target-specific attributes > +DEF_SIMPLE_ATTR(DLLImport); > +DEF_SIMPLE_ATTR(DLLExport); > + > +class MSP430InterruptAttr : public Attr { > + ?unsigned Number; > + > +public: > + ?MSP430InterruptAttr(unsigned n) : Attr(MSP430Interrupt), Number(n) {} > + > + ?unsigned getNumber() const { return Number; } > + > + ?virtual Attr *clone(ASTContext &C) const { > + ? ?return ::new (C) MSP430InterruptAttr(Number); > + ?} > + > + ?// Implement isa/cast/dyncast/etc. > + ?static bool classof(const Attr *A) { return A->getKind() == MSP430Interrupt; } > + ?static bool classof(const MSP430InterruptAttr *A) { return true; } > +}; > + > ?#undef DEF_SIMPLE_ATTR > > ?} ?// end namespace clang > > Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=93118&r1=93117&r2=93118&view=diff > > ============================================================================== > --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original) > +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Sun Jan 10 06:58:08 2010 > @@ -17,6 +17,7 @@ > ?#include "CGCall.h" > ?#include "CGObjCRuntime.h" > ?#include "Mangle.h" > +#include "TargetInfo.h" > ?#include "clang/CodeGen/CodeGenOptions.h" > ?#include "clang/AST/ASTContext.h" > ?#include "clang/AST/DeclObjC.h" > @@ -42,8 +43,9 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Diagnostic &diags) > ? : BlockModule(C, M, TD, Types, *this), Context(C), > ? ? Features(C.getLangOptions()), CodeGenOpts(CGO), TheModule(M), > - ? ?TheTargetData(TD), Diags(diags), Types(C, M, TD), MangleCtx(C), > - ? ?VtableInfo(*this), Runtime(0), > + ? ?TheTargetData(TD), TheTargetCodeGenInfo(0), Diags(diags), > + ? ?Types(C, M, TD, getTargetCodeGenInfo().getABIInfo()), > + ? ?MangleCtx(C), VtableInfo(*this), Runtime(0), > ? ? MemCpyFn(0), MemMoveFn(0), MemSetFn(0), CFConstantStringClassRef(0), > ? ? VMContext(M.getContext()) { > > @@ -376,6 +378,8 @@ > > ? if (const SectionAttr *SA = D->getAttr()) > ? ? GV->setSection(SA->getName()); > + > + ?getTargetCodeGenInfo().SetTargetAttributes(D, GV, *this); > ?} > > ?void CodeGenModule::SetInternalFunctionAttributes(const Decl *D, > > Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=93118&r1=93117&r2=93118&view=diff > > ============================================================================== > --- cfe/trunk/lib/CodeGen/CodeGenModule.h (original) > +++ cfe/trunk/lib/CodeGen/CodeGenModule.h Sun Jan 10 06:58:08 2010 > @@ -43,6 +43,7 @@ > ?} > > ?namespace clang { > + ?class TargetCodeGenInfo; > ? class ASTContext; > ? class FunctionDecl; > ? class IdentifierInfo; > @@ -85,6 +86,7 @@ > ? const CodeGenOptions &CodeGenOpts; > ? llvm::Module &TheModule; > ? const llvm::TargetData &TheTargetData; > + ?mutable const TargetCodeGenInfo *TheTargetCodeGenInfo; > ? Diagnostic &Diags; > ? CodeGenTypes Types; > ? MangleContext MangleCtx; > @@ -191,6 +193,7 @@ > ? Diagnostic &getDiags() const { return Diags; } > ? const llvm::TargetData &getTargetData() const { return TheTargetData; } > ? llvm::LLVMContext &getLLVMContext() { return VMContext; } > + ?const TargetCodeGenInfo &getTargetCodeGenInfo() const; > > ? /// getDeclVisibilityMode - Compute the visibility of the decl \arg D. > ? LangOptions::VisibilityMode getDeclVisibilityMode(const Decl *D) const; > > Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.cpp?rev=93118&r1=93117&r2=93118&view=diff > > ============================================================================== > --- cfe/trunk/lib/CodeGen/CodeGenTypes.cpp (original) > +++ cfe/trunk/lib/CodeGen/CodeGenTypes.cpp Sun Jan 10 06:58:08 2010 > @@ -28,9 +28,9 @@ > ?using namespace CodeGen; > > ?CodeGenTypes::CodeGenTypes(ASTContext &Ctx, llvm::Module& M, > - ? ? ? ? ? ? ? ? ? ? ? ? ? const llvm::TargetData &TD) > + ? ? ? ? ? ? ? ? ? ? ? ? ? const llvm::TargetData &TD, const ABIInfo &Info) > ? : Context(Ctx), Target(Ctx.Target), TheModule(M), TheTargetData(TD), > - ? ?TheABIInfo(0) { > + ? ?TheABIInfo(Info) { > ?} > > ?CodeGenTypes::~CodeGenTypes() { > @@ -44,7 +44,6 @@ > ? ? while (I != E) > ? ? ? delete &*I++; > ? } > - ?delete TheABIInfo; > ?} > > ?/// ConvertType - Convert the specified type to its LLVM form. > > Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.h?rev=93118&r1=93117&r2=93118&view=diff > > ============================================================================== > --- cfe/trunk/lib/CodeGen/CodeGenTypes.h (original) > +++ cfe/trunk/lib/CodeGen/CodeGenTypes.h Sun Jan 10 06:58:08 2010 > @@ -85,7 +85,7 @@ > ? const TargetInfo &Target; > ? llvm::Module& TheModule; > ? const llvm::TargetData& TheTargetData; > - ?mutable const ABIInfo* TheABIInfo; > + ?const ABIInfo& TheABIInfo; > > ? llvm::SmallVector ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? llvm::OpaqueType *>, 8> ?PointersToResolve; > @@ -140,13 +140,14 @@ > ? /// interface to convert type T into a llvm::Type. > ? const llvm::Type *ConvertNewType(QualType T); > ?public: > - ?CodeGenTypes(ASTContext &Ctx, llvm::Module &M, const llvm::TargetData &TD); > + ?CodeGenTypes(ASTContext &Ctx, llvm::Module &M, const llvm::TargetData &TD, > + ? ? ? ? ? ? ? const ABIInfo &Info); > ? ~CodeGenTypes(); > > ? const llvm::TargetData &getTargetData() const { return TheTargetData; } > ? const TargetInfo &getTarget() const { return Target; } > ? ASTContext &getContext() const { return Context; } > - ?const ABIInfo &getABIInfo() const; > + ?const ABIInfo &getABIInfo() const { return TheABIInfo; } > ? llvm::LLVMContext &getLLVMContext() { return TheModule.getContext(); } > > ? /// ConvertType - Convert type T into a llvm::Type. > > Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=93118&r1=93117&r2=93118&view=diff > > ============================================================================== > --- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original) > +++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Sun Jan 10 06:58:08 2010 > @@ -1,4 +1,4 @@ > -//===---- TargetABIInfo.cpp - Encapsulate target ABI details ----*- C++ -*-===// > +//===---- TargetInfo.cpp - Encapsulate target details -----------*- C++ -*-===// > ?// > ?// ? ? ? ? ? ? ? ? ? ? The LLVM Compiler Infrastructure > ?// > @@ -12,10 +12,12 @@ > ?// > ?//===----------------------------------------------------------------------===// > > +#include "TargetInfo.h" > ?#include "ABIInfo.h" > ?#include "CodeGenFunction.h" > ?#include "clang/AST/RecordLayout.h" > ?#include "llvm/Type.h" > +#include "llvm/ADT/StringExtras.h" See comment below. > ?#include "llvm/ADT/Triple.h" > ?#include "llvm/Support/raw_ostream.h" > ?using namespace clang; > @@ -50,6 +52,8 @@ > ? OS << ")\n"; > ?} > > +TargetCodeGenInfo::~TargetCodeGenInfo() { delete Info; } > + > ?static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays); > > ?/// isEmptyField - Return true iff a the field is "empty", that is it > @@ -251,6 +255,27 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?CodeGenFunction &CGF) const; > ?}; > > +class DefaultTargetCodeGenInfo : public TargetCodeGenInfo { > +public: > + ?DefaultTargetCodeGenInfo():TargetCodeGenInfo(new DefaultABIInfo()) {}; > +}; > + > +llvm::Value *DefaultABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? CodeGenFunction &CGF) const { > + ?return 0; > +} > + > +ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ASTContext &Context, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?llvm::LLVMContext &VMContext) const { > + ?if (CodeGenFunction::hasAggregateLLVMType(Ty)) { > + ? ?return ABIArgInfo::getIndirect(0); > + ?} else { > + ? ?return (Ty->isPromotableIntegerType() ? > + ? ? ? ? ? ?ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); > + ?} > +} > + > ?/// X86_32ABIInfo - The X86-32 ABI information. > ?class X86_32ABIInfo : public ABIInfo { > ? ASTContext &Context; > @@ -291,8 +316,14 @@ > ? ? : ABIInfo(), Context(Context), IsDarwinVectorABI(d), > ? ? ? IsSmallStructInRegABI(p) {} > ?}; > -} > > +class X86_32TargetCodeGenInfo : public TargetCodeGenInfo { > +public: > + ?X86_32TargetCodeGenInfo(ASTContext &Context, bool d, bool p) > + ? ?:TargetCodeGenInfo(new X86_32ABIInfo(Context, d, p)) {}; > +}; > + > +} > > ?/// shouldReturnTypeInRegister - Determine if the given type should be > ?/// passed in a register (for the Darwin ABI). > @@ -585,6 +616,12 @@ > ? virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?CodeGenFunction &CGF) const; > ?}; > + > +class X86_64TargetCodeGenInfo : public TargetCodeGenInfo { > +public: > + ?X86_64TargetCodeGenInfo():TargetCodeGenInfo(new X86_64ABIInfo()) {}; > +}; > + > ?} > > ?X86_64ABIInfo::Class X86_64ABIInfo::merge(Class Accum, > @@ -1389,6 +1426,11 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?CodeGenFunction &CGF) const; > ?}; > > +class PIC16TargetCodeGenInfo : public TargetCodeGenInfo { > +public: > + ?PIC16TargetCodeGenInfo():TargetCodeGenInfo(new PIC16ABIInfo()) {}; > +}; > + > ?} > > ?ABIArgInfo PIC16ABIInfo::classifyReturnType(QualType RetTy, > @@ -1448,6 +1490,12 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?CodeGenFunction &CGF) const; > ?}; > > +class ARMTargetCodeGenInfo : public TargetCodeGenInfo { > +public: > + ?ARMTargetCodeGenInfo(ARMABIInfo::ABIKind K) > + ? ?:TargetCodeGenInfo(new ARMABIInfo(K)) {}; > +}; > + > ?} > > ?void ARMABIInfo::computeInfo(CGFunctionInfo &FI, ASTContext &Context, > @@ -1704,6 +1752,11 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?CodeGenFunction &CGF) const; > ?}; > > +class SystemZTargetCodeGenInfo : public TargetCodeGenInfo { > +public: > + ?SystemZTargetCodeGenInfo():TargetCodeGenInfo(new SystemZABIInfo()) {}; > +}; > + > ?} > > ?bool SystemZABIInfo::isPromotableIntegerType(QualType Ty) const { > @@ -1757,51 +1810,79 @@ > ? } > ?} > > -ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ASTContext &Context, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?llvm::LLVMContext &VMContext) const { > - ?if (CodeGenFunction::hasAggregateLLVMType(Ty)) { > - ? ?return ABIArgInfo::getIndirect(0); > - ?} else { > - ? ?return (Ty->isPromotableIntegerType() ? > - ? ? ? ? ? ?ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); > - ?} > +// MSP430 ABI Implementation > + > +namespace { > + > +class MSP430TargetCodeGenInfo : public TargetCodeGenInfo { > +public: > + ?MSP430TargetCodeGenInfo():TargetCodeGenInfo(new DefaultABIInfo()) {}; > + ?void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, > + ? ? ? ? ? ? ? ? ? ? ? ? ? CodeGen::CodeGenModule &M) const; > +}; > + > ?} > > -llvm::Value *DefaultABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? CodeGenFunction &CGF) const { > - ?return 0; > +void MSP430TargetCodeGenInfo::SetTargetAttributes(const Decl *D, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?llvm::GlobalValue *GV, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? CodeGen::CodeGenModule &M) const { > + ?if (const FunctionDecl *FD = dyn_cast(D)) { > + ? ?if (const MSP430InterruptAttr *attr = FD->getAttr()) { > + ? ? ?// Handle 'interrupt' attribute: > + ? ? ?llvm::Function *F = cast(GV); > + > + ? ? ?// Step 1: Set ISR calling convention. > + ? ? ?F->setCallingConv(llvm::CallingConv::MSP430_INTR); > + > + ? ? ?// Step 2: Add attributes goodness. > + ? ? ?F->addFnAttr(llvm::Attribute::NoInline); > + > + ? ? ?// Step 3: Emit ISR vector alias. > + ? ? ?unsigned Num = attr->getNumber() + 0xffe0; > + ? ? ?new llvm::GlobalAlias(GV->getType(), llvm::Function::ExternalLinkage, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ?"vector_" + > + ? ? ? ? ? ? ? ? ? ? ? ? ? ?llvm::LowercaseString(llvm::utohexstr(Num)), Please use a raw_ostream & SmallString instead of adding a dependency on StringExtras. > + ? ? ? ? ? ? ? ? ? ? ? ? ? ?GV, &M.getModule()); > + ? ?} > + ?} > ?} > > -const ABIInfo &CodeGenTypes::getABIInfo() const { > - ?if (TheABIInfo) > - ? ?return *TheABIInfo; > +const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() const { > + ?if (TheTargetCodeGenInfo) > + ? ?return *TheTargetCodeGenInfo; > > - ?// For now we just cache the ABIInfo in CodeGenTypes and don't free it. > + ?// For now we just cache the TargetCodeGenInfo in CodeGenModule and don't > + ?// free it. > > ? const llvm::Triple &Triple(getContext().Target.getTriple()); > ? switch (Triple.getArch()) { > ? default: > - ? ?return *(TheABIInfo = new DefaultABIInfo); > + ? ?return *(TheTargetCodeGenInfo = new DefaultTargetCodeGenInfo); > > ? case llvm::Triple::arm: > ? case llvm::Triple::thumb: > ? ? // FIXME: We want to know the float calling convention as well. > ? ? if (strcmp(getContext().Target.getABI(), "apcs-gnu") == 0) > - ? ? ?return *(TheABIInfo = new ARMABIInfo(ARMABIInfo::APCS)); > + ? ? ?return *(TheTargetCodeGenInfo = > + ? ? ? ? ? ? ? new ARMTargetCodeGenInfo(ARMABIInfo::APCS)); > > - ? ?return *(TheABIInfo = new ARMABIInfo(ARMABIInfo::AAPCS)); > + ? ?return *(TheTargetCodeGenInfo = > + ? ? ? ? ? ? new ARMTargetCodeGenInfo(ARMABIInfo::AAPCS)); > > ? case llvm::Triple::pic16: > - ? ?return *(TheABIInfo = new PIC16ABIInfo()); > + ? ?return *(TheTargetCodeGenInfo = new PIC16TargetCodeGenInfo()); > > ? case llvm::Triple::systemz: > - ? ?return *(TheABIInfo = new SystemZABIInfo()); > + ? ?return *(TheTargetCodeGenInfo = new SystemZTargetCodeGenInfo()); > + > + ?case llvm::Triple::msp430: > + ? ?return *(TheTargetCodeGenInfo = new MSP430TargetCodeGenInfo()); > > ? case llvm::Triple::x86: > ? ? switch (Triple.getOS()) { > ? ? case llvm::Triple::Darwin: > - ? ? ?return *(TheABIInfo = new X86_32ABIInfo(Context, true, true)); > + ? ? ?return *(TheTargetCodeGenInfo = > + ? ? ? ? ? ? ? new X86_32TargetCodeGenInfo(Context, true, true)); > ? ? case llvm::Triple::Cygwin: > ? ? case llvm::Triple::MinGW32: > ? ? case llvm::Triple::MinGW64: > @@ -1809,13 +1890,15 @@ > ? ? case llvm::Triple::DragonFly: > ? ? case llvm::Triple::FreeBSD: > ? ? case llvm::Triple::OpenBSD: > - ? ? ?return *(TheABIInfo = new X86_32ABIInfo(Context, false, true)); > + ? ? ?return *(TheTargetCodeGenInfo = > + ? ? ? ? ? ? ? new X86_32TargetCodeGenInfo(Context, false, true)); > > ? ? default: > - ? ? ?return *(TheABIInfo = new X86_32ABIInfo(Context, false, false)); > + ? ? ?return *(TheTargetCodeGenInfo = > + ? ? ? ? ? ? ? new X86_32TargetCodeGenInfo(Context, false, false)); > ? ? } > > ? case llvm::Triple::x86_64: > - ? ?return *(TheABIInfo = new X86_64ABIInfo()); > + ? ?return *(TheTargetCodeGenInfo = new X86_64TargetCodeGenInfo()); > ? } > ?} > > Added: cfe/trunk/lib/CodeGen/TargetInfo.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.h?rev=93118&view=auto > > ============================================================================== > --- cfe/trunk/lib/CodeGen/TargetInfo.h (added) > +++ cfe/trunk/lib/CodeGen/TargetInfo.h Sun Jan 10 06:58:08 2010 > @@ -0,0 +1,50 @@ > +//===---- TargetInfo.h - Encapsulate target details -------------*- C++ -*-===// > +// > +// ? ? ? ? ? ? ? ? ? ? The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > +// > +// These classes wrap the information about a call or function > +// definition used to handle ABI compliancy. > +// > +//===----------------------------------------------------------------------===// > + > +#ifndef CLANG_CODEGEN_TARGETINFO_H > +#define CLANG_CODEGEN_TARGETINFO_H > + > +namespace llvm { > + ?class GlobalValue; > +} > + > +namespace clang { > + ?class ABIInfo; > + ?class Decl; > + > + ?namespace CodeGen { > + ? ?class CodeGenModule; > + ?} > + > + ?/// TargetCodeGenInfo - This class organizes various target-specific > + ?/// codegeneration issues, like target-specific attributes, builtins and so > + ?/// on. > + ?class TargetCodeGenInfo { > + ? ?ABIInfo *Info; > + ?public: > + ? ?// WARNING: Acquires the ownership of ABIInfo. > + ? ?TargetCodeGenInfo(ABIInfo *info = 0):Info(info) { }; > + ? ?virtual ~TargetCodeGenInfo(); > + > + ? ?/// getABIInfo() - Returns ABI info helper for the target. > + ? ?const ABIInfo& getABIInfo() const { return *Info; } > + > + ? ?/// SetTargetAttributes - Provides a convenient hook to handle extra > + ? ?/// target-specific attributes for the given global. > + ? ?virtual void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? CodeGen::CodeGenModule &M) const { }; > + ?}; > +} > + > +#endif // CLANG_CODEGEN_TARGETINFO_H > > Modified: cfe/trunk/lib/Frontend/PCHReaderDecl.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderDecl.cpp?rev=93118&r1=93117&r2=93118&view=diff > > ============================================================================== > --- cfe/trunk/lib/Frontend/PCHReaderDecl.cpp (original) > +++ cfe/trunk/lib/Frontend/PCHReaderDecl.cpp Sun Jan 10 06:58:08 2010 > @@ -438,6 +438,9 @@ > ? ? bool IsInherited = Record[Idx++]; > > ? ? switch (Kind) { > + ? ?default: > + ? ? ?assert(0 && "Unknown attribute!"); > + ? ? ?break; This is bad, this will make it easy for us to miss missing PCH support when adding attributes in the future. Please remove the default and just add the individual enums which would be warned about. > ? ? STRING_ATTR(Alias); > ? ? UNSIGNED_ATTR(Aligned); > ? ? SIMPLE_ATTR(AlwaysInline); > > Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=93118&r1=93117&r2=93118&view=diff > > ============================================================================== > --- cfe/trunk/lib/Frontend/PCHWriter.cpp (original) > +++ cfe/trunk/lib/Frontend/PCHWriter.cpp Sun Jan 10 06:58:08 2010 > @@ -1739,9 +1739,12 @@ > ?void PCHWriter::WriteAttributeRecord(const Attr *Attr) { > ? RecordData Record; > ? for (; Attr; Attr = Attr->getNext()) { > - ? ?Record.push_back(Attr->getKind()); // FIXME: stable encoding > + ? ?Record.push_back(Attr->getKind()); // FIXME: stable encoding, target attrs > ? ? Record.push_back(Attr->isInherited()); > ? ? switch (Attr->getKind()) { > + ? ?default: > + ? ? ?assert(0 && "Does not support PCH writing for this attribute yet!"); > + ? ? ?break; Are you planning on adding target attribute PCH support? - Daniel > ? ? case Attr::Alias: > ? ? ? AddString(cast(Attr)->getAliasee(), Record); > ? ? ? break; > > Modified: cfe/trunk/lib/Sema/Sema.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=93118&r1=93117&r2=93118&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/Sema.cpp (original) > +++ cfe/trunk/lib/Sema/Sema.cpp Sun Jan 10 06:58:08 2010 > @@ -13,6 +13,7 @@ > ?//===----------------------------------------------------------------------===// > > ?#include "Sema.h" > +#include "TargetAttributesSema.h" > ?#include "llvm/ADT/DenseMap.h" > ?#include "llvm/ADT/APFloat.h" > ?#include "clang/AST/ASTConsumer.h" > @@ -347,7 +348,8 @@ > ?Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, > ? ? ? ? ? ?bool CompleteTranslationUnit, > ? ? ? ? ? ?CodeCompleteConsumer *CodeCompleter) > - ?: LangOpts(pp.getLangOptions()), PP(pp), Context(ctxt), Consumer(consumer), > + ?: TheTargetAttributesSema(0), > + ? ?LangOpts(pp.getLangOptions()), PP(pp), Context(ctxt), Consumer(consumer), > ? ? Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()), > ? ? ExternalSource(0), CodeCompleter(CodeCompleter), CurContext(0), > ? ? CurBlock(0), PackContext(0), ParsingDeclDepth(0), > @@ -368,6 +370,11 @@ > ? ? ? ? ? ? ? ? ? ExpressionEvaluationContextRecord(PotentiallyEvaluated, 0)); > ?} > > +Sema::~Sema() { > + ?if (PackContext) FreePackedContext(); > + ?delete TheTargetAttributesSema; > +} > + > ?/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast. > ?/// If there is already an implicit cast, merge into the existing one. > ?/// If isLvalue, the result of the cast is an lvalue. > > Modified: cfe/trunk/lib/Sema/Sema.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=93118&r1=93117&r2=93118&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/Sema.h (original) > +++ cfe/trunk/lib/Sema/Sema.h Sun Jan 10 06:58:08 2010 > @@ -101,6 +101,7 @@ > ? class InitializationKind; > ? class InitializationSequence; > ? class VisibleDeclConsumer; > + ?class TargetAttributesSema; > > ?/// BlockSemaInfo - When a block is being parsed, this contains information > ?/// about the block. ?It is pointed to from Sema::CurBlock. > @@ -176,6 +177,7 @@ > ?class Sema : public Action { > ? Sema(const Sema&); ? ? ? ? ? // DO NOT IMPLEMENT > ? void operator=(const Sema&); // DO NOT IMPLEMENT > + ?mutable const TargetAttributesSema* TheTargetAttributesSema; > ?public: > ? const LangOptions &LangOpts; > ? Preprocessor &PP; > @@ -426,13 +428,12 @@ > ? Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, > ? ? ? ?bool CompleteTranslationUnit = true, > ? ? ? ?CodeCompleteConsumer *CompletionConsumer = 0); > - ?~Sema() { > - ? ?if (PackContext) FreePackedContext(); > - ?} > + ?~Sema(); > > ? const LangOptions &getLangOptions() const { return LangOpts; } > ? Diagnostic &getDiagnostics() const { return Diags; } > ? SourceManager &getSourceManager() const { return SourceMgr; } > + ?const TargetAttributesSema &getTargetAttributesSema() const; > > ? /// \brief Helper class that creates diagnostics with optional > ? /// template instantiation stacks. > > Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=93118&r1=93117&r2=93118&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Sun Jan 10 06:58:08 2010 > @@ -12,6 +12,7 @@ > ?//===----------------------------------------------------------------------===// > > ?#include "Sema.h" > +#include "TargetAttributesSema.h" > ?#include "clang/AST/ASTContext.h" > ?#include "clang/AST/DeclObjC.h" > ?#include "clang/AST/Expr.h" > @@ -1959,7 +1960,10 @@ > ? ? // Just ignore > ? ? break; > ? default: > - ? ?S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); > + ? ?// Ask target about the attribute. > + ? ?const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); > + ? ?if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) > + ? ? ?S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); > ? ? break; > ? } > ?} > > Added: cfe/trunk/lib/Sema/TargetAttributesSema.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TargetAttributesSema.cpp?rev=93118&view=auto > > ============================================================================== > --- cfe/trunk/lib/Sema/TargetAttributesSema.cpp (added) > +++ cfe/trunk/lib/Sema/TargetAttributesSema.cpp Sun Jan 10 06:58:08 2010 > @@ -0,0 +1,86 @@ > +//===-- TargetAttributesSema.cpp - Encapsulate target attributes-*- C++ -*-===// > +// > +// ? ? ? ? ? ? ? ? ? ? The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > +// > +// This file contains semantic analysis implementation for target-specific > +// attributes. > +// > +//===----------------------------------------------------------------------===// > + > +#include "Sema.h" > +#include "TargetAttributesSema.h" > +#include "clang/Basic/TargetInfo.h" > +#include "llvm/ADT/Triple.h" > + > +using namespace clang; > + > +TargetAttributesSema::~TargetAttributesSema() {} > +bool TargetAttributesSema::ProcessDeclAttribute(Scope *scope, Decl *D, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const AttributeList &Attr, Sema &S) const { > + ?return false; > +} > + > +static void HandleMSP430InterruptAttr(Decl *d, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const AttributeList &Attr, Sema &S) { > + ? ?// Check the attribute arguments. > + ? ?if (Attr.getNumArgs() != 1) { > + ? ? ?S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; > + ? ? ?return; > + ? ?} > + > + ? ?// FIXME: Check for decl - it should be void ()(void). > + > + ? ?Expr *NumParamsExpr = static_cast(Attr.getArg(0)); > + ? ?llvm::APSInt NumParams(32); > + ? ?if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { > + ? ? ?S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) > + ? ? ? ?<< "interrupt" << NumParamsExpr->getSourceRange(); > + ? ? ?return; > + ? ?} > + > + ? ?unsigned Num = NumParams.getLimitedValue(255); > + ? ?if ((Num & 1) || Num > 30) { > + ? ? ?S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) > + ? ? ? ?<< "interrupt" << (int)NumParams.getSExtValue() > + ? ? ? ?<< NumParamsExpr->getSourceRange(); > + ? ? ?return; > + ? ?} > + > + ? ?d->addAttr(::new (S.Context) MSP430InterruptAttr(Num)); > + ? ?d->addAttr(::new (S.Context) UsedAttr()); > + ?} Please add a test case for the attribute checking. > +namespace { > + ?class MSP430AttributesSema : public TargetAttributesSema { > + ?public: > + ? ?MSP430AttributesSema() { } > + ? ?bool ProcessDeclAttribute(Scope *scope, Decl *D, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const AttributeList &Attr, Sema &S) const { > + ? ? ?if (Attr.getName()->getName() == "interrupt") { > + ? ? ? ?HandleMSP430InterruptAttr(D, Attr, S); > + ? ? ? ?return true; > + ? ? ?} > + ? ? ?return false; > + ? ?} > + ?}; > +} > + > +const TargetAttributesSema &Sema::getTargetAttributesSema() const { > + ?if (TheTargetAttributesSema) > + ? ?return *TheTargetAttributesSema; > + > + ?const llvm::Triple &Triple(Context.Target.getTriple()); > + ?switch (Triple.getArch()) { > + ?default: > + ? ?return *(TheTargetAttributesSema = new TargetAttributesSema); > + > + ?case llvm::Triple::msp430: > + ? ?return *(TheTargetAttributesSema = new MSP430AttributesSema); > + ?} > +} > + > > Added: cfe/trunk/lib/Sema/TargetAttributesSema.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TargetAttributesSema.h?rev=93118&view=auto > > ============================================================================== > --- cfe/trunk/lib/Sema/TargetAttributesSema.h (added) > +++ cfe/trunk/lib/Sema/TargetAttributesSema.h Sun Jan 10 06:58:08 2010 > @@ -0,0 +1,27 @@ > +//===--- TargetAttributesSema.h - Semantic Analysis For Target Attributes -===// > +// > +// ? ? ? ? ? ? ? ? ? ? The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > + > +#ifndef CLANG_SEMA_TARGETSEMA_H > +#define CLANG_SEMA_TARGETSEMA_H > + > +namespace clang { > + ?class Scope; > + ?class Decl; > + ?class Attr; > + ?class Sema; > + > + ?class TargetAttributesSema { > + ?public: > + ? ?virtual ~TargetAttributesSema(); > + ? ?virtual bool ProcessDeclAttribute(Scope *scope, Decl *D, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const AttributeList &Attr, Sema &S) const; > + ?}; > +} > + > +#endif > > > _______________________________________________ > cfe-commits mailing list > cfe-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits > From dgregor at apple.com Tue Jan 12 00:38:30 2010 From: dgregor at apple.com (Douglas Gregor) Date: Tue, 12 Jan 2010 06:38:30 -0000 Subject: [cfe-commits] r93231 - in /cfe/trunk: lib/Sema/SemaCodeComplete.cpp test/Index/complete-at-directives.m test/Index/complete-at-exprstmt.m test/Index/complete-objc-message.m Message-ID: <201001120638.o0C6cU8u000546@zion.cs.uiuc.edu> Author: dgregor Date: Tue Jan 12 00:38:28 2010 New Revision: 93231 URL: http://llvm.org/viewvc/llvm-project?rev=93231&view=rev Log: Use horizontal-space markers in code-completion results rather than embedding single space characters. Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp cfe/trunk/test/Index/complete-at-directives.m cfe/trunk/test/Index/complete-at-exprstmt.m cfe/trunk/test/Index/complete-objc-message.m Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=93231&r1=93230&r2=93231&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original) +++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Tue Jan 12 00:38:28 2010 @@ -1677,7 +1677,7 @@ if (Idx > 0) { std::string Keyword; if (Idx > StartParameter) - Keyword = " "; + Result->AddChunk(CodeCompletionString::CK_HorizontalSpace); if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx)) Keyword += II->getName().str(); Keyword += ":"; @@ -2462,14 +2462,14 @@ // @dynamic Pattern = new CodeCompletionString; Pattern->AddTypedTextChunk("dynamic"); - Pattern->AddTextChunk(" "); + Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace); Pattern->AddPlaceholderChunk("property"); Results.MaybeAddResult(Result(Pattern, 0)); // @synthesize Pattern = new CodeCompletionString; Pattern->AddTypedTextChunk("synthesize"); - Pattern->AddTextChunk(" "); + Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace); Pattern->AddPlaceholderChunk("property"); Results.MaybeAddResult(Result(Pattern, 0)); } @@ -2493,9 +2493,9 @@ // @class name ; Pattern = new CodeCompletionString; Pattern->AddTypedTextChunk("class"); - Pattern->AddTextChunk(" "); + Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace); Pattern->AddPlaceholderChunk("identifier"); - Pattern->AddTextChunk(";"); // add ';' chunk + Pattern->AddChunk(CodeCompletionString::CK_SemiColon); Results.MaybeAddResult(Result(Pattern, 0)); // @interface name @@ -2503,30 +2503,35 @@ // such. Pattern = new CodeCompletionString; Pattern->AddTypedTextChunk("interface"); - Pattern->AddTextChunk(" "); + Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace); + Pattern->AddPlaceholderChunk("class"); Results.MaybeAddResult(Result(Pattern, 0)); // @protocol name Pattern = new CodeCompletionString; Pattern->AddTypedTextChunk("protocol"); - Pattern->AddTextChunk(" "); + Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace); + Pattern->AddPlaceholderChunk("protocol"); Results.MaybeAddResult(Result(Pattern, 0)); // @implementation name Pattern = new CodeCompletionString; Pattern->AddTypedTextChunk("implementation"); - Pattern->AddTextChunk(" "); + Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace); + Pattern->AddPlaceholderChunk("class"); Results.MaybeAddResult(Result(Pattern, 0)); // @compatibility_alias name Pattern = new CodeCompletionString; Pattern->AddTypedTextChunk("compatibility_alias"); - Pattern->AddTextChunk(" "); + Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace); + Pattern->AddPlaceholderChunk("alias"); - Pattern->AddTextChunk(" "); + Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace); + Pattern->AddPlaceholderChunk("class"); Results.MaybeAddResult(Result(Pattern, 0)); } @@ -2593,15 +2598,17 @@ // @throw Pattern = new CodeCompletionString; Pattern->AddTypedTextChunk("throw"); - Pattern->AddTextChunk(" "); + Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace); + Pattern->AddPlaceholderChunk("expression"); - Pattern->AddTextChunk(";"); - Results.MaybeAddResult(Result(Pattern, 0)); // FIXME: add ';' chunk + Pattern->AddChunk(CodeCompletionString::CK_SemiColon); + Results.MaybeAddResult(Result(Pattern, 0)); // @synchronized ( expression ) { statements } Pattern = new CodeCompletionString; Pattern->AddTypedTextChunk("synchronized"); - Pattern->AddTextChunk(" "); + Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace); + Pattern->AddChunk(CodeCompletionString::CK_LeftParen); Pattern->AddPlaceholderChunk("expression"); Pattern->AddChunk(CodeCompletionString::CK_RightParen); Modified: cfe/trunk/test/Index/complete-at-directives.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-at-directives.m?rev=93231&r1=93230&r2=93231&view=diff ============================================================================== --- cfe/trunk/test/Index/complete-at-directives.m (original) +++ cfe/trunk/test/Index/complete-at-directives.m Tue Jan 12 00:38:28 2010 @@ -6,11 +6,11 @@ @end // RUN: c-index-test -code-completion-at=%s:2:2 %s | FileCheck -check-prefix=CHECK-CC1 %s -// CHECK-CC1: {TypedText class}{Text }{Placeholder identifier}{Text ;} -// CHECK-CC1: {TypedText compatibility_alias}{Text }{Placeholder alias}{Text }{Placeholder class} -// CHECK-CC1: {TypedText implementation}{Text }{Placeholder class} -// CHECK-CC1: {TypedText interface}{Text }{Placeholder class} -// CHECK-CC1: {TypedText protocol}{Text }{Placeholder protocol} +// CHECK-CC1: {TypedText class}{HorizontalSpace }{Placeholder identifier}{Text ;} +// CHECK-CC1: {TypedText compatibility_alias}{HorizontalSpace }{Placeholder alias}{HorizontalSpace }{Placeholder class} +// CHECK-CC1: {TypedText implementation}{HorizontalSpace }{Placeholder class} +// CHECK-CC1: {TypedText interface}{HorizontalSpace }{Placeholder class} +// CHECK-CC1: {TypedText protocol}{HorizontalSpace }{Placeholder protocol} // RUN: c-index-test -code-completion-at=%s:3:2 %s | FileCheck -check-prefix=CHECK-CC2 %s // CHECK-CC2: {TypedText end} @@ -19,6 +19,6 @@ // CHECK-CC2: {TypedText required} // RUN: c-index-test -code-completion-at=%s:6:2 %s | FileCheck -check-prefix=CHECK-CC3 %s -// CHECK-CC3: {TypedText dynamic}{Text }{Placeholder property} +// CHECK-CC3: {TypedText dynamic}{HorizontalSpace }{Placeholder property} // CHECK-CC3: {TypedText end} -// CHECK-CC3: {TypedText synthesize}{Text }{Placeholder property} +// CHECK-CC3: {TypedText synthesize}{HorizontalSpace }{Placeholder property} Modified: cfe/trunk/test/Index/complete-at-exprstmt.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-at-exprstmt.m?rev=93231&r1=93230&r2=93231&view=diff ============================================================================== --- cfe/trunk/test/Index/complete-at-exprstmt.m (original) +++ cfe/trunk/test/Index/complete-at-exprstmt.m Tue Jan 12 00:38:28 2010 @@ -13,8 +13,8 @@ // CHECK-CC1: {TypedText encode}{LeftParen (}{Placeholder type-name}{RightParen )} // CHECK-CC1: {TypedText protocol}{LeftParen (}{Placeholder protocol-name}{RightParen )} // CHECK-CC1: {TypedText selector}{LeftParen (}{Placeholder selector}{RightParen )} -// CHECK-CC1: {TypedText synchronized}{Text }{LeftParen (}{Placeholder expression}{RightParen )}{LeftBrace {}{Placeholder statements}{RightBrace }} -// CHECK-CC1: {TypedText throw}{Text }{Placeholder expression}{Text ;} +// CHECK-CC1: {TypedText synchronized}{HorizontalSpace }{LeftParen (}{Placeholder expression}{RightParen )}{LeftBrace {}{Placeholder statements}{RightBrace }} +// CHECK-CC1: {TypedText throw}{HorizontalSpace }{Placeholder expression}{Text ;} // CHECK-CC1: {TypedText try}{LeftBrace {}{Placeholder statements}{RightBrace }}{Text @catch}{LeftParen (}{Placeholder parameter}{RightParen )}{LeftBrace {}{Placeholder statements}{RightBrace }}{Text @finally}{LeftBrace {}{Placeholder statements}{RightBrace }} // RUN: c-index-test -code-completion-at=%s:9:19 %s | FileCheck -check-prefix=CHECK-CC2 %s // CHECK-CC2: {TypedText encode}{LeftParen (}{Placeholder type-name}{RightParen )} Modified: cfe/trunk/test/Index/complete-objc-message.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-objc-message.m?rev=93231&r1=93230&r2=93231&view=diff ============================================================================== --- cfe/trunk/test/Index/complete-objc-message.m (original) +++ cfe/trunk/test/Index/complete-objc-message.m Tue Jan 12 00:38:28 2010 @@ -105,7 +105,7 @@ // RUN: c-index-test -code-completion-at=%s:23:19 %s | FileCheck -check-prefix=CHECK-CC1 %s // CHECK-CC1: {TypedText categoryClassMethod} -// CHECK-CC1: {TypedText classMethod1:}{Placeholder (id)a}{Text withKeyword:}{Placeholder (int)b} +// CHECK-CC1: {TypedText classMethod1:}{Placeholder (id)a}{HorizontalSpace }{Text withKeyword:}{Placeholder (int)b} // CHECK-CC1: {TypedText classMethod2} // CHECK-CC1: {TypedText new} // CHECK-CC1: {TypedText protocolClassMethod} @@ -117,10 +117,10 @@ // CHECK-CC3: ObjCClassMethodDecl:{ResultType int}{TypedText MyClassMethod:}{Placeholder (id)obj} // CHECK-CC3: ObjCClassMethodDecl:{ResultType int}{TypedText MyPrivateMethod} // RUN: c-index-test -code-completion-at=%s:65:16 %s | FileCheck -check-prefix=CHECK-CC4 %s -// CHECK-CC4: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyInstMethod:}{Placeholder (id)x}{Text second:}{Placeholder (id)y} +// CHECK-CC4: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyInstMethod:}{Placeholder (id)x}{HorizontalSpace }{Text second:}{Placeholder (id)y} // CHECK-CC4: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyPrivateInstMethod} // RUN: c-index-test -code-completion-at=%s:74:9 %s | FileCheck -check-prefix=CHECK-CC5 %s -// CHECK-CC5: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyInstMethod:}{Placeholder (id)x}{Text second:}{Placeholder (id)y} +// CHECK-CC5: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyInstMethod:}{Placeholder (id)x}{HorizontalSpace }{Text second:}{Placeholder (id)y} // CHECK-CC5: ObjCInstanceMethodDecl:{ResultType int}{TypedText MySubInstMethod} // RUN: c-index-test -code-completion-at=%s:82:8 %s | FileCheck -check-prefix=CHECK-CC6 %s // CHECK-CC6: ObjCInstanceMethodDecl:{ResultType id}{TypedText protocolInstanceMethod:}{Placeholder (int)value} @@ -128,15 +128,15 @@ // RUN: c-index-test -code-completion-at=%s:95:8 %s | FileCheck -check-prefix=CHECK-CC7 %s // CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method} // CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (int)i} -// CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{Text Arg1:}{Placeholder (int)i1}{Text Arg2:}{Placeholder (int)i2} -// CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{Text Arg1:}{Placeholder (int)i1}{Text OtherArg:}{Placeholder (id)obj} -// CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{Text SomeArg:}{Placeholder (int)i1}{Text OtherArg:}{Placeholder (id)obj} -// CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText OtherMethod:}{Placeholder (float)f}{Text Arg1:}{Placeholder (int)i1}{Text Arg2:}{Placeholder (int)i2} +// CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace }{Text Arg2:}{Placeholder (int)i2} +// CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace }{Text OtherArg:}{Placeholder (id)obj} +// CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace }{Text SomeArg:}{Placeholder (int)i1}{HorizontalSpace }{Text OtherArg:}{Placeholder (id)obj} +// CHECK-CC7: ObjCInstanceMethodDecl:{ResultType int}{TypedText OtherMethod:}{Placeholder (float)f}{HorizontalSpace }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace }{Text Arg2:}{Placeholder (int)i2} // RUN: c-index-test -code-completion-at=%s:95:17 %s | FileCheck -check-prefix=CHECK-CC8 %s // CHECK-CC8: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{TypedText } -// CHECK-CC8: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{TypedText Arg1:}{Placeholder (int)i1}{Text Arg2:}{Placeholder (int)i2} -// CHECK-CC8: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{TypedText Arg1:}{Placeholder (int)i1}{Text OtherArg:}{Placeholder (id)obj} -// CHECK-CC8: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{TypedText SomeArg:}{Placeholder (int)i1}{Text OtherArg:}{Placeholder (id)obj} +// CHECK-CC8: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{TypedText Arg1:}{Placeholder (int)i1}{HorizontalSpace }{Text Arg2:}{Placeholder (int)i2} +// CHECK-CC8: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{TypedText Arg1:}{Placeholder (int)i1}{HorizontalSpace }{Text OtherArg:}{Placeholder (id)obj} +// CHECK-CC8: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{TypedText SomeArg:}{Placeholder (int)i1}{HorizontalSpace }{Text OtherArg:}{Placeholder (id)obj} // RUN: c-index-test -code-completion-at=%s:95:24 %s | FileCheck -check-prefix=CHECK-CC9 %s // CHECK-CC9: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{Informative Arg1:}{TypedText Arg2:}{Placeholder (int)i2} // CHECK-CC9: ObjCInstanceMethodDecl:{ResultType int}{Informative Method:}{Informative Arg1:}{TypedText OtherArg:}{Placeholder (id)obj} From rjmccall at apple.com Tue Jan 12 01:18:20 2010 From: rjmccall at apple.com (John McCall) Date: Tue, 12 Jan 2010 07:18:20 -0000 Subject: [cfe-commits] r93233 - in /cfe/trunk/lib/Sema: Sema.h SemaDeclCXX.cpp SemaExprCXX.cpp SemaInit.cpp SemaOverload.cpp Message-ID: <201001120718.o0C7IKBV001957@zion.cs.uiuc.edu> Author: rjmccall Date: Tue Jan 12 01:18:19 2010 New Revision: 93233 URL: http://llvm.org/viewvc/llvm-project?rev=93233&view=rev Log: So I was sitting around, trying vainly to think of something to commit, and then I said to myself, self, why don't you go add a couple of parameters to a method and then fail to use them, and I thought that sounded like a pretty good idea, so I did it. Modified: cfe/trunk/lib/Sema/Sema.h cfe/trunk/lib/Sema/SemaDeclCXX.cpp cfe/trunk/lib/Sema/SemaExprCXX.cpp cfe/trunk/lib/Sema/SemaInit.cpp cfe/trunk/lib/Sema/SemaOverload.cpp Modified: cfe/trunk/lib/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=93233&r1=93232&r2=93233&view=diff ============================================================================== --- cfe/trunk/lib/Sema/Sema.h (original) +++ cfe/trunk/lib/Sema/Sema.h Tue Jan 12 01:18:19 2010 @@ -1040,6 +1040,7 @@ }; void PrintOverloadCandidates(OverloadCandidateSet& CandidateSet, OverloadCandidateDisplayKind OCD, + Expr **Args, unsigned NumArgs, const char *Opc = 0, SourceLocation Loc = SourceLocation()); Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=93233&r1=93232&r2=93233&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Jan 12 01:18:19 2010 @@ -4200,7 +4200,7 @@ else Diag(Loc, diag::err_ovl_no_viable_function_in_init) << ClassType << Range; - PrintOverloadCandidates(CandidateSet, OCD_AllCandidates); + PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs); return 0; case OR_Ambiguous: @@ -4208,7 +4208,7 @@ Diag(Loc, diag::err_ovl_ambiguous_init) << InitEntity << Range; else Diag(Loc, diag::err_ovl_ambiguous_init) << ClassType << Range; - PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates); + PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, Args, NumArgs); return 0; case OR_Deleted: @@ -4223,7 +4223,7 @@ << Best->Function->isDeleted() << RD->getDeclName() << Range; } - PrintOverloadCandidates(CandidateSet, OCD_AllCandidates); + PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs); return 0; } @@ -4547,7 +4547,7 @@ } Diag(DeclLoc, diag::err_ref_init_ambiguous) << DeclType << Init->getType() << Init->getSourceRange(); - PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates); + PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, &Init, 1); return true; case OR_No_Viable_Function: Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=93233&r1=93232&r2=93233&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue Jan 12 01:18:19 2010 @@ -673,20 +673,20 @@ case OR_No_Viable_Function: Diag(StartLoc, diag::err_ovl_no_viable_function_in_call) << Name << Range; - PrintOverloadCandidates(Candidates, OCD_AllCandidates); + PrintOverloadCandidates(Candidates, OCD_AllCandidates, Args, NumArgs); return true; case OR_Ambiguous: Diag(StartLoc, diag::err_ovl_ambiguous_call) << Name << Range; - PrintOverloadCandidates(Candidates, OCD_ViableCandidates); + PrintOverloadCandidates(Candidates, OCD_ViableCandidates, Args, NumArgs); return true; case OR_Deleted: Diag(StartLoc, diag::err_ovl_deleted_call) << Best->Function->isDeleted() << Name << Range; - PrintOverloadCandidates(Candidates, OCD_AllCandidates); + PrintOverloadCandidates(Candidates, OCD_AllCandidates, Args, NumArgs); return true; } assert(false && "Unreachable, bad result from BestViableFunction"); Modified: cfe/trunk/lib/Sema/SemaInit.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=93233&r1=93232&r2=93233&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaInit.cpp (original) +++ cfe/trunk/lib/Sema/SemaInit.cpp Tue Jan 12 01:18:19 2010 @@ -88,7 +88,7 @@ S.Diag(Init->getSourceRange().getBegin(), diag::err_typecheck_convert_ambiguous) << DeclType << Init->getType() << Init->getSourceRange(); - S.PrintOverloadCandidates(CandidateSet, Sema::OCD_AllCandidates); + S.PrintOverloadCandidates(CandidateSet, Sema::OCD_AllCandidates, &Init, 1); return true; } return false; @@ -3015,14 +3015,16 @@ S.Diag(Loc, diag::err_temp_copy_no_viable) << (int)Entity.getKind() << CurInitExpr->getType() << CurInitExpr->getSourceRange(); - S.PrintOverloadCandidates(CandidateSet, Sema::OCD_AllCandidates); + S.PrintOverloadCandidates(CandidateSet, Sema::OCD_AllCandidates, + &CurInitExpr, 1); return S.ExprError(); case OR_Ambiguous: S.Diag(Loc, diag::err_temp_copy_ambiguous) << (int)Entity.getKind() << CurInitExpr->getType() << CurInitExpr->getSourceRange(); - S.PrintOverloadCandidates(CandidateSet, Sema::OCD_ViableCandidates); + S.PrintOverloadCandidates(CandidateSet, Sema::OCD_ViableCandidates, + &CurInitExpr, 1); return S.ExprError(); case OR_Deleted: @@ -3437,14 +3439,16 @@ << DestType << Args[0]->getType() << Args[0]->getSourceRange(); - S.PrintOverloadCandidates(FailedCandidateSet, Sema::OCD_ViableCandidates); + S.PrintOverloadCandidates(FailedCandidateSet, Sema::OCD_ViableCandidates, + Args, NumArgs); break; case OR_No_Viable_Function: S.Diag(Kind.getLocation(), diag::err_typecheck_nonviable_condition) << Args[0]->getType() << DestType.getNonReferenceType() << Args[0]->getSourceRange(); - S.PrintOverloadCandidates(FailedCandidateSet, Sema::OCD_AllCandidates); + S.PrintOverloadCandidates(FailedCandidateSet, Sema::OCD_AllCandidates, + Args, NumArgs); break; case OR_Deleted: { @@ -3547,13 +3551,14 @@ S.Diag(Kind.getLocation(), diag::err_ovl_ambiguous_init) << DestType << ArgsRange; S.PrintOverloadCandidates(FailedCandidateSet, - Sema::OCD_ViableCandidates); + Sema::OCD_ViableCandidates, Args, NumArgs); break; case OR_No_Viable_Function: S.Diag(Kind.getLocation(), diag::err_ovl_no_viable_function_in_init) << DestType << ArgsRange; - S.PrintOverloadCandidates(FailedCandidateSet, Sema::OCD_AllCandidates); + S.PrintOverloadCandidates(FailedCandidateSet, Sema::OCD_AllCandidates, + Args, NumArgs); break; case OR_Deleted: { Modified: cfe/trunk/lib/Sema/SemaOverload.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=93233&r1=93232&r2=93233&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOverload.cpp (original) +++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Jan 12 01:18:19 2010 @@ -1631,7 +1631,7 @@ << From->getType() << ToType << From->getSourceRange(); else return false; - PrintOverloadCandidates(CandidateSet, OCD_AllCandidates); + PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, &From, 1); return true; } @@ -4484,6 +4484,7 @@ void Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet, OverloadCandidateDisplayKind OCD, + Expr **Args, unsigned NumArgs, const char *Opc, SourceLocation OpLoc) { // Sort the candidates by viability and position. Sorting directly would @@ -5032,13 +5033,13 @@ Diag(Fn->getSourceRange().getBegin(), diag::err_ovl_no_viable_function_in_call) << ULE->getName() << Fn->getSourceRange(); - PrintOverloadCandidates(CandidateSet, OCD_AllCandidates); + PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs); break; case OR_Ambiguous: Diag(Fn->getSourceRange().getBegin(), diag::err_ovl_ambiguous_call) << ULE->getName() << Fn->getSourceRange(); - PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates); + PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, Args, NumArgs); break; case OR_Deleted: @@ -5046,7 +5047,7 @@ << Best->Function->isDeleted() << ULE->getName() << Fn->getSourceRange(); - PrintOverloadCandidates(CandidateSet, OCD_AllCandidates); + PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs); break; } @@ -5201,7 +5202,7 @@ Diag(OpLoc, diag::err_ovl_ambiguous_oper) << UnaryOperator::getOpcodeStr(Opc) << Input->getSourceRange(); - PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, + PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, Args, NumArgs, UnaryOperator::getOpcodeStr(Opc), OpLoc); return ExprError(); @@ -5210,7 +5211,7 @@ << Best->Function->isDeleted() << UnaryOperator::getOpcodeStr(Opc) << Input->getSourceRange(); - PrintOverloadCandidates(CandidateSet, OCD_AllCandidates); + PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs); return ExprError(); } @@ -5417,7 +5418,7 @@ assert(Result.isInvalid() && "C++ binary operator overloading is missing candidates!"); if (Result.isInvalid()) - PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, + PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, 2, BinaryOperator::getOpcodeStr(Opc), OpLoc); return move(Result); } @@ -5426,7 +5427,7 @@ Diag(OpLoc, diag::err_ovl_ambiguous_oper) << BinaryOperator::getOpcodeStr(Opc) << Args[0]->getSourceRange() << Args[1]->getSourceRange(); - PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, + PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, Args, 2, BinaryOperator::getOpcodeStr(Opc), OpLoc); return ExprError(); @@ -5435,7 +5436,7 @@ << Best->Function->isDeleted() << BinaryOperator::getOpcodeStr(Opc) << Args[0]->getSourceRange() << Args[1]->getSourceRange(); - PrintOverloadCandidates(CandidateSet, OCD_AllCandidates); + PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, 2); return ExprError(); } @@ -5545,7 +5546,7 @@ Diag(LLoc, diag::err_ovl_no_viable_subscript) << Args[0]->getType() << Args[0]->getSourceRange() << Args[1]->getSourceRange(); - PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, + PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, 2, "[]", LLoc); return ExprError(); } @@ -5553,7 +5554,7 @@ case OR_Ambiguous: Diag(LLoc, diag::err_ovl_ambiguous_oper) << "[]" << Args[0]->getSourceRange() << Args[1]->getSourceRange(); - PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, + PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, Args, 2, "[]", LLoc); return ExprError(); @@ -5561,7 +5562,7 @@ Diag(LLoc, diag::err_ovl_deleted_oper) << Best->Function->isDeleted() << "[]" << Args[0]->getSourceRange() << Args[1]->getSourceRange(); - PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, + PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, 2, "[]", LLoc); return ExprError(); } @@ -5646,14 +5647,14 @@ Diag(UnresExpr->getMemberLoc(), diag::err_ovl_no_viable_member_function_in_call) << DeclName << MemExprE->getSourceRange(); - PrintOverloadCandidates(CandidateSet, OCD_AllCandidates); + PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs); // FIXME: Leaking incoming expressions! return ExprError(); case OR_Ambiguous: Diag(UnresExpr->getMemberLoc(), diag::err_ovl_ambiguous_member_call) << DeclName << MemExprE->getSourceRange(); - PrintOverloadCandidates(CandidateSet, OCD_AllCandidates); + PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs); // FIXME: Leaking incoming expressions! return ExprError(); @@ -5661,7 +5662,7 @@ Diag(UnresExpr->getMemberLoc(), diag::err_ovl_deleted_member_call) << Best->Function->isDeleted() << DeclName << MemExprE->getSourceRange(); - PrintOverloadCandidates(CandidateSet, OCD_AllCandidates); + PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs); // FIXME: Leaking incoming expressions! return ExprError(); } @@ -5809,14 +5810,14 @@ Diag(Object->getSourceRange().getBegin(), diag::err_ovl_no_viable_object_call) << Object->getType() << Object->getSourceRange(); - PrintOverloadCandidates(CandidateSet, OCD_AllCandidates); + PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs); break; case OR_Ambiguous: Diag(Object->getSourceRange().getBegin(), diag::err_ovl_ambiguous_object_call) << Object->getType() << Object->getSourceRange(); - PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates); + PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, Args, NumArgs); break; case OR_Deleted: @@ -5824,7 +5825,7 @@ diag::err_ovl_deleted_object_call) << Best->Function->isDeleted() << Object->getType() << Object->getSourceRange(); - PrintOverloadCandidates(CandidateSet, OCD_AllCandidates); + PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs); break; } @@ -6005,20 +6006,20 @@ else Diag(OpLoc, diag::err_ovl_no_viable_oper) << "operator->" << Base->getSourceRange(); - PrintOverloadCandidates(CandidateSet, OCD_AllCandidates); + PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, &Base, 1); return ExprError(); case OR_Ambiguous: Diag(OpLoc, diag::err_ovl_ambiguous_oper) << "->" << Base->getSourceRange(); - PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates); + PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, &Base, 1); return ExprError(); case OR_Deleted: Diag(OpLoc, diag::err_ovl_deleted_oper) << Best->Function->isDeleted() << "->" << Base->getSourceRange(); - PrintOverloadCandidates(CandidateSet, OCD_AllCandidates); + PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, &Base, 1); return ExprError(); } From benny.kra at googlemail.com Tue Jan 12 05:32:40 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Tue, 12 Jan 2010 11:32:40 -0000 Subject: [cfe-commits] r93237 - /cfe/trunk/tools/CIndex/CIndexUSRs.cpp Message-ID: <201001121132.o0CBWf97025708@zion.cs.uiuc.edu> Author: d0k Date: Tue Jan 12 05:32:40 2010 New Revision: 93237 URL: http://llvm.org/viewvc/llvm-project?rev=93237&view=rev Log: Remove trailing semicolons and silence MSVC warning about C linkage. warning C4190: 'GetEntity' has C-linkage specified, but returns UDT 'clang::idx::Entity' which is incompatible with C Modified: cfe/trunk/tools/CIndex/CIndexUSRs.cpp Modified: cfe/trunk/tools/CIndex/CIndexUSRs.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndexUSRs.cpp?rev=93237&r1=93236&r2=93237&view=diff ============================================================================== --- cfe/trunk/tools/CIndex/CIndexUSRs.cpp (original) +++ cfe/trunk/tools/CIndex/CIndexUSRs.cpp Tue Jan 12 05:32:40 2010 @@ -12,11 +12,9 @@ //===----------------------------------------------------------------------===// #include "CIndexer.h" +#include "clang/AST/DeclVisitor.h" #include "llvm/ADT/SmallString.h" -#include "llvm/Support/raw_ostream.h"; -#include "clang/AST/DeclVisitor.h"; - -extern "C" { +#include "llvm/Support/raw_ostream.h" // Some notes on CXEntity: // @@ -63,7 +61,9 @@ static inline Program &GetProgram(CXIndex CIdx) { return ((CIndexer*) CIdx)->getProgram(); } - + +extern "C" { + /// clang_getDeclaration() maps from a CXEntity to the matching CXDecl (if any) /// in a specified translation unit. CXDecl clang_getDeclaration(CXEntity CE, CXTranslationUnit TU) { From benny.kra at googlemail.com Tue Jan 12 05:52:21 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Tue, 12 Jan 2010 11:52:21 -0000 Subject: [cfe-commits] r93238 - in /cfe/trunk/test/Index: complete-at-directives.m complete-at-exprstmt.m Message-ID: <201001121152.o0CBqLjN026466@zion.cs.uiuc.edu> Author: d0k Date: Tue Jan 12 05:52:20 2010 New Revision: 93238 URL: http://llvm.org/viewvc/llvm-project?rev=93238&view=rev Log: Fix tests for r93231. Modified: cfe/trunk/test/Index/complete-at-directives.m cfe/trunk/test/Index/complete-at-exprstmt.m Modified: cfe/trunk/test/Index/complete-at-directives.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-at-directives.m?rev=93238&r1=93237&r2=93238&view=diff ============================================================================== --- cfe/trunk/test/Index/complete-at-directives.m (original) +++ cfe/trunk/test/Index/complete-at-directives.m Tue Jan 12 05:52:20 2010 @@ -6,7 +6,7 @@ @end // RUN: c-index-test -code-completion-at=%s:2:2 %s | FileCheck -check-prefix=CHECK-CC1 %s -// CHECK-CC1: {TypedText class}{HorizontalSpace }{Placeholder identifier}{Text ;} +// CHECK-CC1: {TypedText class}{HorizontalSpace }{Placeholder identifier}{SemiColon ;} // CHECK-CC1: {TypedText compatibility_alias}{HorizontalSpace }{Placeholder alias}{HorizontalSpace }{Placeholder class} // CHECK-CC1: {TypedText implementation}{HorizontalSpace }{Placeholder class} // CHECK-CC1: {TypedText interface}{HorizontalSpace }{Placeholder class} Modified: cfe/trunk/test/Index/complete-at-exprstmt.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-at-exprstmt.m?rev=93238&r1=93237&r2=93238&view=diff ============================================================================== --- cfe/trunk/test/Index/complete-at-exprstmt.m (original) +++ cfe/trunk/test/Index/complete-at-exprstmt.m Tue Jan 12 05:52:20 2010 @@ -14,7 +14,7 @@ // CHECK-CC1: {TypedText protocol}{LeftParen (}{Placeholder protocol-name}{RightParen )} // CHECK-CC1: {TypedText selector}{LeftParen (}{Placeholder selector}{RightParen )} // CHECK-CC1: {TypedText synchronized}{HorizontalSpace }{LeftParen (}{Placeholder expression}{RightParen )}{LeftBrace {}{Placeholder statements}{RightBrace }} -// CHECK-CC1: {TypedText throw}{HorizontalSpace }{Placeholder expression}{Text ;} +// CHECK-CC1: {TypedText throw}{HorizontalSpace }{Placeholder expression}{SemiColon ;} // CHECK-CC1: {TypedText try}{LeftBrace {}{Placeholder statements}{RightBrace }}{Text @catch}{LeftParen (}{Placeholder parameter}{RightParen )}{LeftBrace {}{Placeholder statements}{RightBrace }}{Text @finally}{LeftBrace {}{Placeholder statements}{RightBrace }} // RUN: c-index-test -code-completion-at=%s:9:19 %s | FileCheck -check-prefix=CHECK-CC2 %s // CHECK-CC2: {TypedText encode}{LeftParen (}{Placeholder type-name}{RightParen )} From Ken.Dyck at onsemi.com Tue Jan 12 07:02:56 2010 From: Ken.Dyck at onsemi.com (Ken Dyck) Date: Tue, 12 Jan 2010 06:02:56 -0700 Subject: [cfe-commits] [Review] Rolling out ASTContext::getTypeSizeInChars() In-Reply-To: References: <8F2E4A8BCDA0B84DA6C9088EB5B27747D5EFEF@NAMAIL.ad.onsemi.com> <48D53DB1-E4D7-4BA3-B178-F0D553AB4B24@apple.com> <8F2E4A8BCDA0B84DA6C9088EB5B27747DF4706@NAMAIL.ad.onsemi.com> Message-ID: <8F2E4A8BCDA0B84DA6C9088EB5B27747DF489B@NAMAIL.ad.onsemi.com> On Monday, January 11, 2010 4:50 PM, Ted Kremenek wrote: > > On Jan 11, 2010, at 1:24 PM, Ken Dyck wrote: > > >> > >> I'm also concerned about the dimensionality here. Why did > we choose > >> 'Chars' instead of 'Bytes'? > > > > The short answer is that it reflects how getTypeSizeInChars() > > calculates its value. It divides the bit size of the type > by the bit > > size of the char type, so calling them CharUnits seemed > more accurate > > than ByteUnits. The aim is to eventually support character widths > > other than 8. > > > > What specifically are you concerned about? > > I'm concerned that the uses of getTypeSize() / 8 always want > the size in bytes, not chars (if the size of chars differs > from the size of bytes). Code that expects > getTypeSizeInChars() to return the size in bytes (which is > all the cases in libAnalysis) will get the wrong results. Just to get the terminology straight here, when we are talking about bytes do we mean: A. an 8-bit value, B. the smallest addressable unit of memory on a machine, or C. an addressable unit of data storage large enough to hold any member of the basic character set of the execution environment (C99), or D. something else? However we define byte it seems that it is at least theoretically possible for the character type to have a different width, and so I think Ted makes a valid point. If there is code that expects a size in bytes (however defined), perhaps we need to add another API. As a clang newbie, it is difficult to determine whether a literal 8 means the width of a byte or that of a character, so I'm relying on you guys for reviews. So far, I have been approaching the problem with definition C above and the simpifying assumption that clang enforces byte width == char width, even if neither are 8. This allows characters and bytes to be used interchangably. -Ken From dgregor at apple.com Tue Jan 12 09:04:32 2010 From: dgregor at apple.com (Douglas Gregor) Date: Tue, 12 Jan 2010 07:04:32 -0800 Subject: [cfe-commits] r93238 - in /cfe/trunk/test/Index: complete-at-directives.m complete-at-exprstmt.m In-Reply-To: <201001121152.o0CBqLjN026466@zion.cs.uiuc.edu> References: <201001121152.o0CBqLjN026466@zion.cs.uiuc.edu> Message-ID: On Jan 12, 2010, at 3:52 AM, Benjamin Kramer wrote: > Author: d0k > Date: Tue Jan 12 05:52:20 2010 > New Revision: 93238 > > URL: http://llvm.org/viewvc/llvm-project?rev=93238&view=rev > Log: > Fix tests for r93231. > > Modified: > cfe/trunk/test/Index/complete-at-directives.m > cfe/trunk/test/Index/complete-at-exprstmt.m Thank you! - Doug From kremenek at apple.com Tue Jan 12 10:34:10 2010 From: kremenek at apple.com (Ted Kremenek) Date: Tue, 12 Jan 2010 08:34:10 -0800 Subject: [cfe-commits] [Review] Rolling out ASTContext::getTypeSizeInChars() In-Reply-To: <8F2E4A8BCDA0B84DA6C9088EB5B27747DF489B@NAMAIL.ad.onsemi.com> References: <8F2E4A8BCDA0B84DA6C9088EB5B27747D5EFEF@NAMAIL.ad.onsemi.com> <48D53DB1-E4D7-4BA3-B178-F0D553AB4B24@apple.com> <8F2E4A8BCDA0B84DA6C9088EB5B27747DF4706@NAMAIL.ad.onsemi.com> <8F2E4A8BCDA0B84DA6C9088EB5B27747DF489B@NAMAIL.ad.onsemi.com> Message-ID: <949EBA13-E69F-438F-B3BE-8913E2E86EBC@apple.com> On Jan 12, 2010, at 5:02 AM, Ken Dyck wrote: > Just to get the terminology straight here, when we are talking about > bytes do we mean: > > A. an 8-bit value, > B. the smallest addressable unit of memory on a machine, or > C. an addressable unit of data storage large enough to hold any member > of the basic character set of the execution environment (C99), or > D. something else? > > However we define byte it seems that it is at least theoretically > possible for the character type to have a different width, and so I > think Ted makes a valid point. If there is code that expects a size in > bytes (however defined), perhaps we need to add another API. > > As a clang newbie, it is difficult to determine whether a literal 8 > means the width of a byte or that of a character, so I'm relying on you > guys for reviews. So far, I have been approaching the problem with > definition C above and the simpifying assumption that clang enforces > byte width == char width, even if neither are 8. This allows characters > and bytes to be used interchangably. I'm thinking of B, but I'm also thinking of the unit reported by the 'sizeof()' operator. From dgregor at apple.com Tue Jan 12 11:06:21 2010 From: dgregor at apple.com (Douglas Gregor) Date: Tue, 12 Jan 2010 17:06:21 -0000 Subject: [cfe-commits] r93240 - in /cfe/trunk: lib/Sema/SemaTemplate.cpp test/SemaTemplate/typo-dependent-name.cpp Message-ID: <201001121706.o0CH6L9A006805@zion.cs.uiuc.edu> Author: dgregor Date: Tue Jan 12 11:06:20 2010 New Revision: 93240 URL: http://llvm.org/viewvc/llvm-project?rev=93240&view=rev Log: When determining whether a given name is a template in a dependent context, do not attempt typo correction. This harms performance (as Abramo noted) and can cause some amusing errors, as in this new testcase. Added: cfe/trunk/test/SemaTemplate/typo-dependent-name.cpp (with props) Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=93240&r1=93239&r2=93240&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue Jan 12 11:06:20 2010 @@ -194,7 +194,8 @@ ObjectTypeSearchedInScope = true; } } else if (isDependent) { - // We cannot look into a dependent object type or + // We cannot look into a dependent object type or nested nme + // specifier. return; } else { // Perform unqualified name lookup in the current scope. @@ -205,7 +206,7 @@ assert(!Found.isAmbiguous() && "Cannot handle template name-lookup ambiguities"); - if (Found.empty()) { + if (Found.empty() && !isDependent) { // If we did not find any names, attempt to correct any typos. DeclarationName Name = Found.getLookupName(); if (CorrectTypo(Found, S, &SS, LookupCtx)) { Added: cfe/trunk/test/SemaTemplate/typo-dependent-name.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/typo-dependent-name.cpp?rev=93240&view=auto ============================================================================== --- cfe/trunk/test/SemaTemplate/typo-dependent-name.cpp (added) +++ cfe/trunk/test/SemaTemplate/typo-dependent-name.cpp Tue Jan 12 11:06:20 2010 @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template +struct Base { + T inner; +}; + +template +struct X { + template + struct Inner { + }; + + bool f(T other) { + return this->inner < other; + } +}; Propchange: cfe/trunk/test/SemaTemplate/typo-dependent-name.cpp ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cfe/trunk/test/SemaTemplate/typo-dependent-name.cpp ------------------------------------------------------------------------------ svn:keywords = Id Propchange: cfe/trunk/test/SemaTemplate/typo-dependent-name.cpp ------------------------------------------------------------------------------ svn:mime-type = text/plain From fjahanian at apple.com Tue Jan 12 11:31:23 2010 From: fjahanian at apple.com (Fariborz Jahanian) Date: Tue, 12 Jan 2010 17:31:23 -0000 Subject: [cfe-commits] r93241 - /cfe/trunk/lib/Frontend/RewriteObjC.cpp Message-ID: <201001121731.o0CHVNeK007927@zion.cs.uiuc.edu> Author: fjahanian Date: Tue Jan 12 11:31:23 2010 New Revision: 93241 URL: http://llvm.org/viewvc/llvm-project?rev=93241&view=rev Log: Improve on objective-c pointer recognition during rewrite. No functionality chang. Modified: cfe/trunk/lib/Frontend/RewriteObjC.cpp Modified: cfe/trunk/lib/Frontend/RewriteObjC.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/RewriteObjC.cpp?rev=93241&r1=93240&r2=93241&view=diff ============================================================================== --- cfe/trunk/lib/Frontend/RewriteObjC.cpp (original) +++ cfe/trunk/lib/Frontend/RewriteObjC.cpp Tue Jan 12 11:31:23 2010 @@ -1195,7 +1195,8 @@ ObjCIvarDecl *D = IV->getDecl(); const Expr *BaseExpr = IV->getBase(); if (CurMethodDef) { - if (IV->isArrow() && isa(BaseExpr)) { + if (BaseExpr->getType()->isObjCObjectPointerType() && + isa(BaseExpr)) { ObjCInterfaceType *iFaceDecl = dyn_cast(BaseExpr->getType()->getPointeeType()); // lookup which class implements the instance variable. @@ -1243,7 +1244,7 @@ // Explicit ivar refs need to have a cast inserted. // FIXME: consider sharing some of this code with the code above. - if (IV->isArrow()) { + if (BaseExpr->getType()->isObjCObjectPointerType()) { ObjCInterfaceType *iFaceDecl = dyn_cast(BaseExpr->getType()->getPointeeType()); // lookup which class implements the instance variable. From dgregor at apple.com Tue Jan 12 11:52:59 2010 From: dgregor at apple.com (Douglas Gregor) Date: Tue, 12 Jan 2010 17:52:59 -0000 Subject: [cfe-commits] r93243 - in /cfe/trunk: lib/Parse/ParseDeclCXX.cpp test/SemaTemplate/dependent-base-classes.cpp Message-ID: <201001121752.o0CHqx4r008670@zion.cs.uiuc.edu> Author: dgregor Date: Tue Jan 12 11:52:59 2010 New Revision: 93243 URL: http://llvm.org/viewvc/llvm-project?rev=93243&view=rev Log: Parse dependent template-ids in base clauses and member initializers. This isn't actually in the C++ grammar (in any version), but that's clearly an oversight: both GCC and EDG support this syntax, and it's used within Boost code. I'll file a core issue proposing precisely the change made here. Fixes PR6008. Added: cfe/trunk/test/SemaTemplate/dependent-base-classes.cpp (with props) Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=93243&r1=93242&r2=93243&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original) +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Tue Jan 12 11:52:59 2010 @@ -468,7 +468,8 @@ if (Tok.is(tok::annot_template_id)) { TemplateIdAnnotation *TemplateId = static_cast(Tok.getAnnotationValue()); - if (TemplateId->Kind == TNK_Type_template) { + if (TemplateId->Kind == TNK_Type_template || + TemplateId->Kind == TNK_Dependent_template_name) { AnnotateTemplateIdTokenAsType(SS); assert(Tok.is(tok::annot_typename) && "template-id -> type failed"); @@ -1527,12 +1528,12 @@ if (Tok.is(tok::annot_template_id)) { TemplateIdAnnotation *TemplateId = static_cast(Tok.getAnnotationValue()); - if (TemplateId->Kind == TNK_Type_template) { + if (TemplateId->Kind == TNK_Type_template || + TemplateId->Kind == TNK_Dependent_template_name) { AnnotateTemplateIdTokenAsType(&SS); assert(Tok.is(tok::annot_typename) && "template-id -> type failed"); TemplateTypeTy = Tok.getAnnotationValue(); } - // FIXME. May need to check for TNK_Dependent_template as well. } if (!TemplateTypeTy && Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_member_or_base_name); Added: cfe/trunk/test/SemaTemplate/dependent-base-classes.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/dependent-base-classes.cpp?rev=93243&view=auto ============================================================================== --- cfe/trunk/test/SemaTemplate/dependent-base-classes.cpp (added) +++ cfe/trunk/test/SemaTemplate/dependent-base-classes.cpp Tue Jan 12 11:52:59 2010 @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template +struct X0 : T::template apply { + X0(U u) : T::template apply(u) { } +}; Propchange: cfe/trunk/test/SemaTemplate/dependent-base-classes.cpp ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cfe/trunk/test/SemaTemplate/dependent-base-classes.cpp ------------------------------------------------------------------------------ svn:keywords = Id Propchange: cfe/trunk/test/SemaTemplate/dependent-base-classes.cpp ------------------------------------------------------------------------------ svn:mime-type = text/plain From clattner at apple.com Tue Jan 12 12:17:41 2010 From: clattner at apple.com (Chris Lattner) Date: Tue, 12 Jan 2010 10:17:41 -0800 Subject: [cfe-commits] [Review] Rolling out ASTContext::getTypeSizeInChars() In-Reply-To: <8F2E4A8BCDA0B84DA6C9088EB5B27747DF489B@NAMAIL.ad.onsemi.com> References: <8F2E4A8BCDA0B84DA6C9088EB5B27747D5EFEF@NAMAIL.ad.onsemi.com> <48D53DB1-E4D7-4BA3-B178-F0D553AB4B24@apple.com> <8F2E4A8BCDA0B84DA6C9088EB5B27747DF4706@NAMAIL.ad.onsemi.com> <8F2E4A8BCDA0B84DA6C9088EB5B27747DF489B@NAMAIL.ad.onsemi.com> Message-ID: On Jan 12, 2010, at 5:02 AM, Ken Dyck wrote: > On Monday, January 11, 2010 4:50 PM, Ted Kremenek wrote: >> >> On Jan 11, 2010, at 1:24 PM, Ken Dyck wrote: >> >>>> >>>> I'm also concerned about the dimensionality here. Why did >> we choose >>>> 'Chars' instead of 'Bytes'? >>> >>> The short answer is that it reflects how getTypeSizeInChars() >>> calculates its value. It divides the bit size of the type >> by the bit >>> size of the char type, so calling them CharUnits seemed >> more accurate >>> than ByteUnits. The aim is to eventually support character widths >>> other than 8. >>> >>> What specifically are you concerned about? >> >> I'm concerned that the uses of getTypeSize() / 8 always want >> the size in bytes, not chars (if the size of chars differs >> from the size of bytes). Code that expects >> getTypeSizeInChars() to return the size in bytes (which is >> all the cases in libAnalysis) will get the wrong results. > > Just to get the terminology straight here, when we are talking about > bytes do we mean: > > A. an 8-bit value, > B. the smallest addressable unit of memory on a machine, or > C. an addressable unit of data storage large enough to hold any > member > of the basic character set of the execution environment (C99), or > D. something else? > > However we define byte it seems that it is at least theoretically > possible for the character type to have a different width, and so I > think Ted makes a valid point. If there is code that expects a size in > bytes (however defined), perhaps we need to add another API. In clang, I prefer to avoid the term 'byte'. CharUnits is great because it specifically says it is in units of char. :) > As a clang newbie, it is difficult to determine whether a literal 8 > means the width of a byte or that of a character, so I'm relying on > you > guys for reviews. So far, I have been approaching the problem with > definition C above and the simpifying assumption that clang enforces > byte width == char width, even if neither are 8. This allows > characters > and bytes to be used interchangably. To date, LLVM only supports 8-bit byte targets whose char's are 8 bits. -Chris From fjahanian at apple.com Tue Jan 12 12:33:58 2010 From: fjahanian at apple.com (Fariborz Jahanian) Date: Tue, 12 Jan 2010 18:33:58 -0000 Subject: [cfe-commits] r93246 - in /cfe/trunk: lib/Basic/Targets.cpp test/Rewriter/rewrite-weak-attr.m Message-ID: <201001121833.o0CIXwIY010438@zion.cs.uiuc.edu> Author: fjahanian Date: Tue Jan 12 12:33:57 2010 New Revision: 93246 URL: http://llvm.org/viewvc/llvm-project?rev=93246&view=rev Log: Define __weak attribute for objective-c pointers in win32 targets. Fixes radar 7530235. Daniel please review. Added: cfe/trunk/test/Rewriter/rewrite-weak-attr.m Modified: cfe/trunk/lib/Basic/Targets.cpp Modified: cfe/trunk/lib/Basic/Targets.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets.cpp?rev=93246&r1=93245&r2=93246&view=diff ============================================================================== --- cfe/trunk/lib/Basic/Targets.cpp (original) +++ cfe/trunk/lib/Basic/Targets.cpp Tue Jan 12 12:33:57 2010 @@ -994,6 +994,10 @@ DefineStd(Builder, "WIN32", Opts); DefineStd(Builder, "WINNT", Opts); Builder.defineMacro("_X86_"); + if (Opts.ObjC1) + // __weak is always defined, for use in blocks and with objc pointers, + // even for i686-pc-win32 targets. + Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))"); } }; } // end anonymous namespace Added: cfe/trunk/test/Rewriter/rewrite-weak-attr.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Rewriter/rewrite-weak-attr.m?rev=93246&view=auto ============================================================================== --- cfe/trunk/test/Rewriter/rewrite-weak-attr.m (added) +++ cfe/trunk/test/Rewriter/rewrite-weak-attr.m Tue Jan 12 12:33:57 2010 @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -fblocks -Dnil=0 -rewrite-objc -o - %s +int main() { + __weak __block id foo = nil; + __block id foo2 = nil; + id foo3 = nil; + + void (^myblock)() = ^{ + foo = nil; + foo2 = nil; + [foo3 bar]; + id foo4 = foo3; + }; +} From kremenek at apple.com Tue Jan 12 12:53:15 2010 From: kremenek at apple.com (Ted Kremenek) Date: Tue, 12 Jan 2010 18:53:15 -0000 Subject: [cfe-commits] r93248 - /cfe/trunk/tools/c-index-test/c-index-test.c Message-ID: <201001121853.o0CIrFer011263@zion.cs.uiuc.edu> Author: kremenek Date: Tue Jan 12 12:53:15 2010 New Revision: 93248 URL: http://llvm.org/viewvc/llvm-project?rev=93248&view=rev Log: Make 'CXTranslationUnitIterator' an argument to perform_test_load(), perform_test_load_tu(), and perform_test_load_source(). Modified: cfe/trunk/tools/c-index-test/c-index-test.c Modified: cfe/trunk/tools/c-index-test/c-index-test.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=93248&r1=93247&r2=93248&view=diff ============================================================================== --- cfe/trunk/tools/c-index-test/c-index-test.c (original) +++ cfe/trunk/tools/c-index-test/c-index-test.c Tue Jan 12 12:53:15 2010 @@ -160,9 +160,9 @@ } static int perform_test_load(CXIndex Idx, CXTranslationUnit TU, - const char *filter, const char *prefix) { + const char *filter, const char *prefix, + CXTranslationUnitIterator Visitor) { enum CXCursorKind K = CXCursor_NotImplemented; - CXTranslationUnitIterator Visitor = TranslationUnitVisitor; enum CXCursorKind *ck = &K; if (prefix) @@ -187,7 +187,8 @@ } int perform_test_load_tu(const char *file, const char *filter, - const char *prefix) { + const char *prefix, + CXTranslationUnitIterator Visitor) { CXIndex Idx; CXTranslationUnit TU; Idx = clang_createIndex(/* excludeDeclsFromPCH */ @@ -197,10 +198,11 @@ if (!CreateTranslationUnit(Idx, file, &TU)) return 1; - return perform_test_load(Idx, TU, filter, prefix); + return perform_test_load(Idx, TU, filter, prefix, Visitor); } -int perform_test_load_source(int argc, const char **argv, const char *filter) { +int perform_test_load_source(int argc, const char **argv, const char *filter, + CXTranslationUnitIterator Visitor) { const char *UseExternalASTs = getenv("CINDEXTEST_USE_EXTERNAL_AST_GENERATION"); CXIndex Idx; @@ -218,7 +220,7 @@ return 1; } - return perform_test_load(Idx, TU, filter, NULL); + return perform_test_load(Idx, TU, filter, NULL, Visitor); } /******************************************************************************/ @@ -582,9 +584,11 @@ return perform_code_completion(argc, argv); if (argc >= 4 && strcmp(argv[1], "-test-load-tu") == 0) return perform_test_load_tu(argv[2], argv[3], - argc >= 5 ? argv[4] : 0); + argc >= 5 ? argv[4] : 0, + TranslationUnitVisitor); if (argc >= 4 && strcmp(argv[1], "-test-load-source") == 0) - return perform_test_load_source(argc - 3, argv + 3, argv[2]); + return perform_test_load_source(argc - 3, argv + 3, argv[2], + TranslationUnitVisitor); if (argc >= 4 && strcmp(argv[1], "-test-file-scan") == 0) return perform_file_scan(argv[2], argv[3], argc >= 5 ? argv[4] : 0); From kremenek at apple.com Tue Jan 12 13:35:54 2010 From: kremenek at apple.com (Ted Kremenek) Date: Tue, 12 Jan 2010 19:35:54 -0000 Subject: [cfe-commits] r93250 - /cfe/trunk/tools/CIndex/CIndexUSRs.cpp Message-ID: <201001121935.o0CJZsY6012986@zion.cs.uiuc.edu> Author: kremenek Date: Tue Jan 12 13:35:53 2010 New Revision: 93250 URL: http://llvm.org/viewvc/llvm-project?rev=93250&view=rev Log: Further tweaking of USR generation. WIP. Modified: cfe/trunk/tools/CIndex/CIndexUSRs.cpp Modified: cfe/trunk/tools/CIndex/CIndexUSRs.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndexUSRs.cpp?rev=93250&r1=93249&r2=93250&view=diff ============================================================================== --- cfe/trunk/tools/CIndex/CIndexUSRs.cpp (original) +++ cfe/trunk/tools/CIndex/CIndexUSRs.cpp Tue Jan 12 13:35:53 2010 @@ -87,15 +87,29 @@ public: USRGenerator(llvm::raw_ostream &out) : Out(out) {} + void VisitNamedDecl(NamedDecl *D); void VisitObjCContainerDecl(ObjCContainerDecl *CD); void VisitObjCMethodDecl(ObjCMethodDecl *MD); void VisitObjCPropertyDecl(ObjCPropertyDecl *D); }; } // end anonymous namespace + +void USRGenerator::VisitNamedDecl(NamedDecl *D) { + DeclContext *DC = D->getDeclContext(); + if (NamedDecl *DCN = dyn_cast(DC)) { + Visit(DCN); + Out << '_'; + } + else { + Out << '_'; + } + Out << D->getName(); +} + void USRGenerator::VisitObjCMethodDecl(ObjCMethodDecl *D) { Visit(cast(D->getDeclContext())); - Out << (D->isInstanceMethod() ? "_IM_" : "_CM_"); + Out << (D->isInstanceMethod() ? "(im)" : "(cm)"); Out << DeclarationName(D->getSelector()); } @@ -105,29 +119,29 @@ assert(false && "Invalid ObjC container."); case Decl::ObjCInterface: case Decl::ObjCImplementation: - Out << "objc_class_" << D->getName(); + Out << "objc(cs)" << D->getName(); break; case Decl::ObjCCategory: { ObjCCategoryDecl *CD = cast(D); - Out << "objc_cat_" << CD->getClassInterface()->getName() + Out << "objc(cy)" << CD->getClassInterface()->getName() << '_' << CD->getName(); break; } case Decl::ObjCCategoryImpl: { ObjCCategoryImplDecl *CD = cast(D); - Out << "objc_cat_" << CD->getClassInterface()->getName() + Out << "objc(cy)" << CD->getClassInterface()->getName() << '_' << CD->getName(); break; } case Decl::ObjCProtocol: - Out << "objc_prot_" << cast(D)->getName(); + Out << "objc(pl)" << cast(D)->getName(); break; } } void USRGenerator::VisitObjCPropertyDecl(ObjCPropertyDecl *D) { Visit(cast(D->getDeclContext())); - Out << "_prop_" << D->getName(); + Out << "(py)" << D->getName(); } // FIXME: This is a skeleton implementation. It will be overhauled. From daniel at zuster.org Tue Jan 12 13:44:01 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 12 Jan 2010 11:44:01 -0800 Subject: [cfe-commits] r93246 - in /cfe/trunk: lib/Basic/Targets.cpp test/Rewriter/rewrite-weak-attr.m In-Reply-To: <201001121833.o0CIXwIY010438@zion.cs.uiuc.edu> References: <201001121833.o0CIXwIY010438@zion.cs.uiuc.edu> Message-ID: <6a8523d61001121144r6ed24709l8a9a4baed2f9fe5a@mail.gmail.com> Hi Fariborz, On Tue, Jan 12, 2010 at 10:33 AM, Fariborz Jahanian wrote: > Author: fjahanian > Date: Tue Jan 12 12:33:57 2010 > New Revision: 93246 > > URL: http://llvm.org/viewvc/llvm-project?rev=93246&view=rev > Log: > Define __weak attribute for objective-c pointers in > win32 targets. Fixes radar 7530235. Daniel please review. This isn't the right fix, this defines __weak for all win32 targets which isn't valid. Similarly, it doesn't fix the bug on other platforms, like linux. What we want is that the rewriter action specifically enables blocks supports for *all* targets, since the rewriter is capable of rewriting away the blocks. We may need to shuffle some of the code in driver/cc1_main.cpp to make this easier, but the idea should be to give specific FrontendAction objects the opportunity to override values in the CompilerInvocation. - Daniel > Added: > ? ?cfe/trunk/test/Rewriter/rewrite-weak-attr.m > Modified: > ? ?cfe/trunk/lib/Basic/Targets.cpp > > Modified: cfe/trunk/lib/Basic/Targets.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets.cpp?rev=93246&r1=93245&r2=93246&view=diff > > ============================================================================== > --- cfe/trunk/lib/Basic/Targets.cpp (original) > +++ cfe/trunk/lib/Basic/Targets.cpp Tue Jan 12 12:33:57 2010 > @@ -994,6 +994,10 @@ > ? ? DefineStd(Builder, "WIN32", Opts); > ? ? DefineStd(Builder, "WINNT", Opts); > ? ? Builder.defineMacro("_X86_"); > + ? ?if (Opts.ObjC1) > + ? ? ?// __weak is always defined, for use in blocks and with objc pointers, > + ? ? ?// even for i686-pc-win32 targets. > + ? ? ?Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))"); > ? } > ?}; > ?} // end anonymous namespace > > Added: cfe/trunk/test/Rewriter/rewrite-weak-attr.m > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Rewriter/rewrite-weak-attr.m?rev=93246&view=auto > > ============================================================================== > --- cfe/trunk/test/Rewriter/rewrite-weak-attr.m (added) > +++ cfe/trunk/test/Rewriter/rewrite-weak-attr.m Tue Jan 12 12:33:57 2010 > @@ -0,0 +1,13 @@ > +// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -fblocks -Dnil=0 -rewrite-objc ?-o - %s > +int main() { > + ? ? ? ?__weak __block id foo = nil; > + ? ? ? ?__block id foo2 = nil; > + ? ? ? ?id foo3 = nil; > + > + ? ? ? ?void (^myblock)() = ^{ > + ? ? ? ? ? ? ? ?foo = nil; > + ? ? ? ? ? ? ? ?foo2 = nil; > + ? ? ? ? ? ? ? ?[foo3 bar]; > + ? ? ? ? ? ? ? ?id foo4 = foo3; > + ? ? ? ?}; > +} > > > _______________________________________________ > cfe-commits mailing list > cfe-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits > From chandlerc at gmail.com Tue Jan 12 14:32:25 2010 From: chandlerc at gmail.com (Chandler Carruth) Date: Tue, 12 Jan 2010 20:32:25 -0000 Subject: [cfe-commits] r93252 - in /cfe/trunk: include/clang/AST/ASTContext.h lib/AST/ASTContext.cpp lib/Sema/SemaInit.cpp test/CodeGenCXX/reference-init.cpp Message-ID: <201001122032.o0CKWPlm015240@zion.cs.uiuc.edu> Author: chandlerc Date: Tue Jan 12 14:32:25 2010 New Revision: 93252 URL: http://llvm.org/viewvc/llvm-project?rev=93252&view=rev Log: Fix the CodeGen half of PR5911 by changing reference initialization to correctly look through arrays to see cv-qualifiers. Also enhances the routine for doing this to preserve more type sugaring for diagnostics. Modified: cfe/trunk/include/clang/AST/ASTContext.h cfe/trunk/lib/AST/ASTContext.cpp cfe/trunk/lib/Sema/SemaInit.cpp cfe/trunk/test/CodeGenCXX/reference-init.cpp Modified: cfe/trunk/include/clang/AST/ASTContext.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=93252&r1=93251&r2=93252&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/ASTContext.h (original) +++ cfe/trunk/include/clang/AST/ASTContext.h Tue Jan 12 14:32:25 2010 @@ -898,17 +898,18 @@ return getCanonicalType(T1) == getCanonicalType(T2); } - /// \brief Returns this type as a completely-unqualified array type, capturing - /// the qualifiers in Quals. This only operates on canonical types in order - /// to ensure the ArrayType doesn't itself have qualifiers. + /// \brief Returns this type as a completely-unqualified array type, + /// capturing the qualifiers in Quals. This will remove the minimal amount of + /// sugaring from the types, similar to the behavior of + /// QualType::getUnqualifiedType(). /// - /// \param T is the canonicalized QualType, which may be an ArrayType + /// \param T is the qualified type, which may be an ArrayType /// /// \param Quals will receive the full set of qualifiers that were - /// applied to the element type of the array. + /// applied to the array. /// /// \returns if this is an array type, the completely unqualified array type - /// that corresponds to it. Otherwise, returns this->getUnqualifiedType(). + /// that corresponds to it. Otherwise, returns T.getUnqualifiedType(). QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals); /// \brief Determine whether the given types are equivalent after Modified: cfe/trunk/lib/AST/ASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=93252&r1=93251&r2=93252&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTContext.cpp (original) +++ cfe/trunk/lib/AST/ASTContext.cpp Tue Jan 12 14:32:25 2010 @@ -2374,13 +2374,11 @@ QualType ASTContext::getUnqualifiedArrayType(QualType T, Qualifiers &Quals) { - assert(T.isCanonical() && "Only operates on canonical types"); + Quals = T.getQualifiers(); if (!isa(T)) { - Quals = T.getLocalQualifiers(); - return T.getLocalUnqualifiedType(); + return T.getUnqualifiedType(); } - assert(!T.hasQualifiers() && "canonical array type has qualifiers!"); const ArrayType *AT = cast(T); QualType Elt = AT->getElementType(); QualType UnqualElt = getUnqualifiedArrayType(Elt, Quals); Modified: cfe/trunk/lib/Sema/SemaInit.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=93252&r1=93251&r2=93252&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaInit.cpp (original) +++ cfe/trunk/lib/Sema/SemaInit.cpp Tue Jan 12 14:32:25 2010 @@ -2227,9 +2227,11 @@ QualType DestType = Entity.getType(); QualType cv1T1 = DestType->getAs()->getPointeeType(); - QualType T1 = cv1T1.getUnqualifiedType(); + Qualifiers T1Quals; + QualType T1 = S.Context.getUnqualifiedArrayType(cv1T1, T1Quals); QualType cv2T2 = Initializer->getType(); - QualType T2 = cv2T2.getUnqualifiedType(); + Qualifiers T2Quals; + QualType T2 = S.Context.getUnqualifiedArrayType(cv2T2, T2Quals); SourceLocation DeclLoc = Initializer->getLocStart(); // If the initializer is the address of an overloaded function, try @@ -2279,9 +2281,9 @@ // can occur. This property will be checked by PerformInitialization. if (DerivedToBase) Sequence.AddDerivedToBaseCastStep( - S.Context.getQualifiedType(T1, cv2T2.getQualifiers()), + S.Context.getQualifiedType(T1, T2Quals), /*isLValue=*/true); - if (cv1T1.getQualifiers() != cv2T2.getQualifiers()) + if (T1Quals != T2Quals) Sequence.AddQualificationConversionStep(cv1T1, /*IsLValue=*/true); Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/false); return; @@ -2312,7 +2314,7 @@ // non-volatile const type (i.e., cv1 shall be const), or the reference // shall be an rvalue reference and the initializer expression shall // be an rvalue. - if (!((isLValueRef && cv1T1.getCVRQualifiers() == Qualifiers::Const) || + if (!((isLValueRef && T1Quals.hasConst()) || (isRValueRef && InitLvalue != Expr::LV_Valid))) { if (ConvOvlResult && !Sequence.getFailedCandidateSet().empty()) Sequence.SetOverloadFailure( @@ -2339,9 +2341,9 @@ RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) { if (DerivedToBase) Sequence.AddDerivedToBaseCastStep( - S.Context.getQualifiedType(T1, cv2T2.getQualifiers()), + S.Context.getQualifiedType(T1, T2Quals), /*isLValue=*/false); - if (cv1T1.getQualifiers() != cv2T2.getQualifiers()) + if (T1Quals != T2Quals) Sequence.AddQualificationConversionStep(cv1T1, /*IsLValue=*/false); Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/true); return; @@ -2406,8 +2408,10 @@ // [...] If T1 is reference-related to T2, cv1 must be the // same cv-qualification as, or greater cv-qualification // than, cv2; otherwise, the program is ill-formed. + unsigned T1CVRQuals = T1Quals.getCVRQualifiers(); + unsigned T2CVRQuals = T2Quals.getCVRQualifiers(); if (RefRelationship == Sema::Ref_Related && - !cv1T1.isAtLeastAsQualifiedAs(cv2T2)) { + (T1CVRQuals | T2CVRQuals) != T1CVRQuals) { Sequence.SetFailed(InitializationSequence::FK_ReferenceInitDropsQualifiers); return; } Modified: cfe/trunk/test/CodeGenCXX/reference-init.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/reference-init.cpp?rev=93252&r1=93251&r2=93252&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/reference-init.cpp (original) +++ cfe/trunk/test/CodeGenCXX/reference-init.cpp Tue Jan 12 14:32:25 2010 @@ -7,3 +7,10 @@ void a(XPTParamDescriptor *params) { const nsXPTParamInfo& paramInfo = params[0]; } + +// CodeGen of reference initialized const arrays. +namespace PR5911 { + template int f(const T (&a)[N]) { return N; } + int iarr[] = { 1 }; + int test() { return f(iarr); } +} From dgregor at apple.com Tue Jan 12 14:42:11 2010 From: dgregor at apple.com (Douglas Gregor) Date: Tue, 12 Jan 2010 12:42:11 -0800 Subject: [cfe-commits] r93252 - in /cfe/trunk: include/clang/AST/ASTContext.h lib/AST/ASTContext.cpp lib/Sema/SemaInit.cpp test/CodeGenCXX/reference-init.cpp In-Reply-To: <201001122032.o0CKWPlm015240@zion.cs.uiuc.edu> References: <201001122032.o0CKWPlm015240@zion.cs.uiuc.edu> Message-ID: <1F8EE0B9-C9C1-4C96-9838-A0FDE6F25939@apple.com> On Jan 12, 2010, at 12:32 PM, Chandler Carruth wrote: > Author: chandlerc > Date: Tue Jan 12 14:32:25 2010 > New Revision: 93252 > > URL: http://llvm.org/viewvc/llvm-project?rev=93252&view=rev > Log: > Fix the CodeGen half of PR5911 by changing reference initialization to > correctly look through arrays to see cv-qualifiers. Also enhances > the routine > for doing this to preserve more type sugaring for diagnostics. Thanks! > Modified: > cfe/trunk/include/clang/AST/ASTContext.h > cfe/trunk/lib/AST/ASTContext.cpp > cfe/trunk/lib/Sema/SemaInit.cpp > cfe/trunk/test/CodeGenCXX/reference-init.cpp > > Modified: cfe/trunk/include/clang/AST/ASTContext.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=93252&r1=93251&r2=93252&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- cfe/trunk/include/clang/AST/ASTContext.h (original) > +++ cfe/trunk/include/clang/AST/ASTContext.h Tue Jan 12 14:32:25 2010 > @@ -898,17 +898,18 @@ > return getCanonicalType(T1) == getCanonicalType(T2); > } > > - /// \brief Returns this type as a completely-unqualified array > type, capturing > - /// the qualifiers in Quals. This only operates on canonical > types in order > - /// to ensure the ArrayType doesn't itself have qualifiers. > + /// \brief Returns this type as a completely-unqualified array > type, > + /// capturing the qualifiers in Quals. This will remove the > minimal amount of > + /// sugaring from the types, similar to the behavior of > + /// QualType::getUnqualifiedType(). > /// > - /// \param T is the canonicalized QualType, which may be an > ArrayType > + /// \param T is the qualified type, which may be an ArrayType > /// > /// \param Quals will receive the full set of qualifiers that were > - /// applied to the element type of the array. > + /// applied to the array. > /// > /// \returns if this is an array type, the completely unqualified > array type > - /// that corresponds to it. Otherwise, returns this- > >getUnqualifiedType(). > + /// that corresponds to it. Otherwise, returns > T.getUnqualifiedType(). > QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals); > > /// \brief Determine whether the given types are equivalent after > > Modified: cfe/trunk/lib/AST/ASTContext.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=93252&r1=93251&r2=93252&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- cfe/trunk/lib/AST/ASTContext.cpp (original) > +++ cfe/trunk/lib/AST/ASTContext.cpp Tue Jan 12 14:32:25 2010 > @@ -2374,13 +2374,11 @@ > > QualType ASTContext::getUnqualifiedArrayType(QualType T, > Qualifiers &Quals) { > - assert(T.isCanonical() && "Only operates on canonical types"); > + Quals = T.getQualifiers(); > if (!isa(T)) { > - Quals = T.getLocalQualifiers(); > - return T.getLocalUnqualifiedType(); > + return T.getUnqualifiedType(); > } > > - assert(!T.hasQualifiers() && "canonical array type has > qualifiers!"); > const ArrayType *AT = cast(T); > QualType Elt = AT->getElementType(); > QualType UnqualElt = getUnqualifiedArrayType(Elt, Quals); > > Modified: cfe/trunk/lib/Sema/SemaInit.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=93252&r1=93251&r2=93252&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- cfe/trunk/lib/Sema/SemaInit.cpp (original) > +++ cfe/trunk/lib/Sema/SemaInit.cpp Tue Jan 12 14:32:25 2010 > @@ -2227,9 +2227,11 @@ > > QualType DestType = Entity.getType(); > QualType cv1T1 = DestType->getAs()->getPointeeType(); > - QualType T1 = cv1T1.getUnqualifiedType(); > + Qualifiers T1Quals; > + QualType T1 = S.Context.getUnqualifiedArrayType(cv1T1, T1Quals); > QualType cv2T2 = Initializer->getType(); > - QualType T2 = cv2T2.getUnqualifiedType(); > + Qualifiers T2Quals; > + QualType T2 = S.Context.getUnqualifiedArrayType(cv2T2, T2Quals); > SourceLocation DeclLoc = Initializer->getLocStart(); > > // If the initializer is the address of an overloaded function, try > @@ -2279,9 +2281,9 @@ > // can occur. This property will be checked by > PerformInitialization. > if (DerivedToBase) > Sequence.AddDerivedToBaseCastStep( > - S.Context.getQualifiedType(T1, > cv2T2.getQualifiers()), > + S.Context.getQualifiedType(T1, T2Quals), > /*isLValue=*/true); > - if (cv1T1.getQualifiers() != cv2T2.getQualifiers()) > + if (T1Quals != T2Quals) > Sequence.AddQualificationConversionStep(cv1T1, /*IsLValue=*/ > true); > Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/ > false); > return; > @@ -2312,7 +2314,7 @@ > // non-volatile const type (i.e., cv1 shall be const), or > the reference > // shall be an rvalue reference and the initializer > expression shall > // be an rvalue. > - if (!((isLValueRef && cv1T1.getCVRQualifiers() == > Qualifiers::Const) || > + if (!((isLValueRef && T1Quals.hasConst()) || > (isRValueRef && InitLvalue != Expr::LV_Valid))) { > if (ConvOvlResult && !Sequence.getFailedCandidateSet().empty()) > Sequence.SetOverloadFailure( > @@ -2339,9 +2341,9 @@ > RefRelationship >= > Sema::Ref_Compatible_With_Added_Qualification) { > if (DerivedToBase) > Sequence.AddDerivedToBaseCastStep( > - S.Context.getQualifiedType(T1, > cv2T2.getQualifiers()), > + S.Context.getQualifiedType(T1, T2Quals), > /*isLValue=*/false); > - if (cv1T1.getQualifiers() != cv2T2.getQualifiers()) > + if (T1Quals != T2Quals) > Sequence.AddQualificationConversionStep(cv1T1, /*IsLValue=*/ > false); > Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/ > true); > return; > @@ -2406,8 +2408,10 @@ > // [...] If T1 is reference-related to T2, cv1 must be the > // same cv-qualification as, or greater cv-qualification > // than, cv2; otherwise, the program is ill-formed. > + unsigned T1CVRQuals = T1Quals.getCVRQualifiers(); > + unsigned T2CVRQuals = T2Quals.getCVRQualifiers(); > if (RefRelationship == Sema::Ref_Related && > - !cv1T1.isAtLeastAsQualifiedAs(cv2T2)) { > + (T1CVRQuals | T2CVRQuals) != T1CVRQuals) { > Sequence.SetFailed > (InitializationSequence::FK_ReferenceInitDropsQualifiers); > return; > } > > Modified: cfe/trunk/test/CodeGenCXX/reference-init.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/reference-init.cpp?rev=93252&r1=93251&r2=93252&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- cfe/trunk/test/CodeGenCXX/reference-init.cpp (original) > +++ cfe/trunk/test/CodeGenCXX/reference-init.cpp Tue Jan 12 14:32:25 > 2010 > @@ -7,3 +7,10 @@ > void a(XPTParamDescriptor *params) { > const nsXPTParamInfo& paramInfo = params[0]; > } > + > +// CodeGen of reference initialized const arrays. > +namespace PR5911 { > + template int f(const T (&a)[N]) { return N; } > + int iarr[] = { 1 }; > + int test() { return f(iarr); } > +} > > > _______________________________________________ > cfe-commits mailing list > cfe-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits From mrs at apple.com Tue Jan 12 14:55:39 2010 From: mrs at apple.com (Mike Stump) Date: Tue, 12 Jan 2010 20:55:39 -0000 Subject: [cfe-commits] r93254 - /cfe/trunk/utils/VtableTest/gen.cc Message-ID: <201001122055.o0CKteCI016014@zion.cs.uiuc.edu> Author: mrs Date: Tue Jan 12 14:55:39 2010 New Revision: 93254 URL: http://llvm.org/viewvc/llvm-project?rev=93254&view=rev Log: Improve covariance tester to randomize the return value more. Modified: cfe/trunk/utils/VtableTest/gen.cc Modified: cfe/trunk/utils/VtableTest/gen.cc URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/VtableTest/gen.cc?rev=93254&r1=93253&r2=93254&view=diff ============================================================================== --- cfe/trunk/utils/VtableTest/gen.cc (original) +++ cfe/trunk/utils/VtableTest/gen.cc Tue Jan 12 14:55:39 2010 @@ -29,6 +29,9 @@ char base_present[N_STRUCTS][N_STRUCTS]; char funcs_present[N_STRUCTS][N_FUNCS*FUNCSPACING]; +// The return type for each function when doing covariant testcase generation. +short ret_types[N_STRUCTS][N_FUNCS*FUNCSPACING]; + bool is_ambiguous(int s, int base) { for (int i = 0; i < N_STRUCTS; ++i) { if ((base_present[base][i] & base_present[s][i]) == 1) @@ -40,6 +43,24 @@ void add_bases(int s, int base) { for (int i = 0; i < N_STRUCTS; ++i) base_present[s][i] |= base_present[base][i]; + if (!COVARIANT) + return; + for (int i = 0; i < N_FUNCS*FUNCSPACING; ++i) { + if (!ret_types[base][i]) + continue; + if (!ret_types[s][i]) { + ret_types[s][i] = ret_types[base][i]; + continue; + } + if (base_present[ret_types[base][i]][ret_types[s][i]]) + // If the return type of the function from this base dominates + ret_types[s][i] = ret_types[base][i]; + if (base_present[ret_types[s][i]][ret_types[base][i]]) + // If a previous base dominates + continue; + // If neither dominates, we'll use this class. + ret_types[s][i] = s; + } } // This contains the class that has the final override for @@ -134,15 +155,27 @@ for (int i = 0; i < n_funcs; ++i) { int fn = old_func + random() % FUNCSPACING + 1; funcs[i] = fn; - int rettype = 0; - if (COVARIANT) - rettype = s; - if (rettype) { - g(" virtual s"); g(rettype); g("* fun"); + int ret_type = 0; + if (COVARIANT) { + ret_type = random() % s + 1; + if (!base_present[s][ret_type] + || !base_present[ret_type][ret_types[s][fn]]) + if (ret_types[s][fn]) { + printf(" // Found one for s%d for s%d* fun%d.\n", s, + ret_types[s][fn], fn); + ret_type = ret_types[s][fn]; + } else + ret_type = s; + else + printf(" // Wow found one for s%d for fun%d.\n", s, fn); + ret_types[s][fn] = ret_type; + } + if (ret_type) { + g(" virtual s"); g(ret_type); g("* fun"); } else g(" virtual void fun"); g(fn); g("(char *t) { mix(\"vfn this offset\", (char *)this - t); mix(\"vfn uuid\", "); g(++uuid); - if (rettype) + if (ret_type) gl("); return 0; }"); else gl("); }"); @@ -179,15 +212,15 @@ if (base_present[prev_base][new_base]) { // The previous base dominates the new base, no update necessary - fprintf(stderr, "// No override for fun%d in s%d as s%d dominates s%d.\n", - fn, s, prev_base, new_base); + printf(" // No override for fun%d in s%d as s%d dominates s%d.\n", + fn, s, prev_base, new_base); continue; } if (base_present[new_base][prev_base]) { // The new base dominates the old base, no override necessary - fprintf(stderr, "// No override for fun%d in s%d as s%d dominates s%d.\n", - fn, s, new_base, prev_base); + printf(" // No override for fun%d in s%d as s%d dominates s%d.\n", + fn, s, new_base, prev_base); // record the final override final_override[s][fn] = new_base; continue; @@ -199,15 +232,23 @@ funcs[n_funcs++] = fn; if (n_funcs == (N_FUNCS*FUNCSPACING-1)) abort(); - int rettype = 0; - if (COVARIANT) - rettype = s; - if (rettype) { - g(" virtual s"); g(rettype); g("* fun"); + int ret_type = 0; + if (COVARIANT) { + if (!ret_types[s][fn]) { + ret_types[s][fn] = ret_type = s; + } else { + ret_type = ret_types[s][fn]; + if (ret_type != s) + printf(" // Calculated return type in s%d as s%d* fun%d.\n", + s, ret_type, fn); + } + } + if (ret_type) { + g(" virtual s"); g(ret_type); g("* fun"); } else g(" virtual void fun"); g(fn); g("(char *t) { mix(\"vfn this offset\", (char *)this - t); mix(\"vfn uuid\", "); g(++uuid); - if (rettype) + if (ret_type) gl("); return 0; }"); else gl("); }"); From sabre at nondot.org Tue Jan 12 14:58:53 2010 From: sabre at nondot.org (Chris Lattner) Date: Tue, 12 Jan 2010 20:58:53 -0000 Subject: [cfe-commits] r93255 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDeclAttr.cpp test/Sema/attr-section.c Message-ID: <201001122058.o0CKwrD0016148@zion.cs.uiuc.edu> Author: lattner Date: Tue Jan 12 14:58:53 2010 New Revision: 93255 URL: http://llvm.org/viewvc/llvm-project?rev=93255&view=rev Log: implement PR6007, diagnosing invalid attribute((section)) Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/SemaDeclAttr.cpp cfe/trunk/test/Sema/attr-section.c Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=93255&r1=93254&r2=93255&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Jan 12 14:58:53 2010 @@ -683,6 +683,8 @@ "argument to %0 attribute was not a string literal">; def err_attribute_section_invalid_for_target : Error< "argument to 'section' attribute is not valid for this target: %0">; +def err_attribute_section_local_variable : Error< + "'section' attribute is not valid on local variables">; def err_attribute_aligned_not_power_of_two : Error< "requested alignment is not a power of 2">; def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning< Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=93255&r1=93254&r2=93255&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Tue Jan 12 14:58:53 2010 @@ -926,14 +926,19 @@ // If the target wants to validate the section specifier, make it happen. std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString()); - if (Error.empty()) { - D->addAttr(::new (S.Context) SectionAttr(SE->getString())); + if (!Error.empty()) { + S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) + << Error; return; } - S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) - << Error; - + // This attribute cannot be applied to local variables. + if (isa(D) && cast(D)->hasLocalStorage()) { + S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable); + return; + } + + D->addAttr(::new (S.Context) SectionAttr(SE->getString())); } static void HandleCDeclAttr(Decl *d, const AttributeList &Attr, Sema &S) { Modified: cfe/trunk/test/Sema/attr-section.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-section.c?rev=93255&r1=93254&r2=93255&view=diff ============================================================================== --- cfe/trunk/test/Sema/attr-section.c (original) +++ cfe/trunk/test/Sema/attr-section.c Tue Jan 12 14:58:53 2010 @@ -8,3 +8,8 @@ int y __attribute__((section( "sadf"))); // expected-error {{mach-o section specifier requires a segment and section separated by a comma}} +// PR6007 +void test() { + __attribute__((section("NEAR,x"))) int n1; // expected-error {{'section' attribute is not valid on local variables}} + __attribute__((section("NEAR,x"))) static int n2; // ok. +} \ No newline at end of file From sabre at nondot.org Tue Jan 12 15:23:57 2010 From: sabre at nondot.org (Chris Lattner) Date: Tue, 12 Jan 2010 21:23:57 -0000 Subject: [cfe-commits] r93256 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/Sema.h lib/Sema/SemaExpr.cpp test/Analysis/misc-ps.m test/Sema/exprs.c test/Sema/i-c-e.c test/SemaTemplate/instantiate-expr-1.cpp test/SemaTemplate/instantiate-static-var.cpp Message-ID: <201001122123.o0CLNwg1017112@zion.cs.uiuc.edu> Author: lattner Date: Tue Jan 12 15:23:57 2010 New Revision: 93256 URL: http://llvm.org/viewvc/llvm-project?rev=93256&view=rev Log: implement PR6004, warning about divide and remainder by zero. Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/Sema.h cfe/trunk/lib/Sema/SemaExpr.cpp cfe/trunk/test/Analysis/misc-ps.m cfe/trunk/test/Sema/exprs.c cfe/trunk/test/Sema/i-c-e.c cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp cfe/trunk/test/SemaTemplate/instantiate-static-var.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=93256&r1=93255&r2=93256&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Jan 12 15:23:57 2010 @@ -1557,10 +1557,10 @@ "comparing floating point with == or != is unsafe">, InGroup>, DefaultIgnore; -def warn_shift_negative : Warning< - "shift count is negative">; -def warn_shift_gt_typewidth : Warning< - "shift count >= width of type">; +def warn_division_by_zero : Warning<"division by zero is undefined">; +def warn_remainder_by_zero : Warning<"remainder by zero is undefined">; +def warn_shift_negative : Warning<"shift count is negative">; +def warn_shift_gt_typewidth : Warning<"shift count >= width of type">; def warn_precedence_bitwise_rel : Warning< "%0 has lower precedence than %1; %1 will be evaluated first">, Modified: cfe/trunk/lib/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=93256&r1=93255&r2=93256&view=diff ============================================================================== --- cfe/trunk/lib/Sema/Sema.h (original) +++ cfe/trunk/lib/Sema/Sema.h Tue Jan 12 15:23:57 2010 @@ -3644,7 +3644,8 @@ QualType CheckPointerToMemberOperands( // C++ 5.5 Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isIndirect); QualType CheckMultiplyDivideOperands( // C99 6.5.5 - Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false); + Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign, + bool isDivide); QualType CheckRemainderOperands( // C99 6.5.5 Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false); QualType CheckAdditionOperands( // C99 6.5.6 Modified: cfe/trunk/lib/Sema/SemaExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=93256&r1=93255&r2=93256&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) +++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Jan 12 15:23:57 2010 @@ -4793,8 +4793,7 @@ return QualType(); } -inline QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex, - Expr *&rex) { +QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex, Expr *&rex) { // For conversion purposes, we ignore any qualifiers. // For example, "const float" and "float" are equivalent. QualType lhsType = @@ -4855,19 +4854,26 @@ return QualType(); } -inline QualType Sema::CheckMultiplyDivideOperands( - Expr *&lex, Expr *&rex, SourceLocation Loc, bool isCompAssign) { +QualType Sema::CheckMultiplyDivideOperands( + Expr *&lex, Expr *&rex, SourceLocation Loc, bool isCompAssign, bool isDiv) { if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) return CheckVectorOperands(Loc, lex, rex); QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign); - if (lex->getType()->isArithmeticType() && rex->getType()->isArithmeticType()) - return compType; - return InvalidOperands(Loc, lex, rex); + if (!lex->getType()->isArithmeticType() || + !rex->getType()->isArithmeticType()) + return InvalidOperands(Loc, lex, rex); + + // Check for division by zero. + if (isDiv && + rex->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull)) + Diag(Loc, diag::warn_division_by_zero) << rex->getSourceRange(); + + return compType; } -inline QualType Sema::CheckRemainderOperands( +QualType Sema::CheckRemainderOperands( Expr *&lex, Expr *&rex, SourceLocation Loc, bool isCompAssign) { if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) { if (lex->getType()->isIntegerType() && rex->getType()->isIntegerType()) @@ -4877,12 +4883,17 @@ QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign); - if (lex->getType()->isIntegerType() && rex->getType()->isIntegerType()) - return compType; - return InvalidOperands(Loc, lex, rex); + if (!lex->getType()->isIntegerType() || !rex->getType()->isIntegerType()) + return InvalidOperands(Loc, lex, rex); + + // Check for remainder by zero. + if (rex->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull)) + Diag(Loc, diag::warn_remainder_by_zero) << rex->getSourceRange(); + + return compType; } -inline QualType Sema::CheckAdditionOperands( // C99 6.5.6 +QualType Sema::CheckAdditionOperands( // C99 6.5.6 Expr *&lex, Expr *&rex, SourceLocation Loc, QualType* CompLHSTy) { if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) { QualType compType = CheckVectorOperands(Loc, lex, rex); @@ -6082,7 +6093,8 @@ break; case BinaryOperator::Mul: case BinaryOperator::Div: - ResultTy = CheckMultiplyDivideOperands(lhs, rhs, OpLoc); + ResultTy = CheckMultiplyDivideOperands(lhs, rhs, OpLoc, false, + Opc == BinaryOperator::Div); break; case BinaryOperator::Rem: ResultTy = CheckRemainderOperands(lhs, rhs, OpLoc); @@ -6118,7 +6130,8 @@ break; case BinaryOperator::MulAssign: case BinaryOperator::DivAssign: - CompResultTy = CheckMultiplyDivideOperands(lhs, rhs, OpLoc, true); + CompResultTy = CheckMultiplyDivideOperands(lhs, rhs, OpLoc, true, + Opc == BinaryOperator::DivAssign); CompLHSTy = CompResultTy; if (!CompResultTy.isNull()) ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy); Modified: cfe/trunk/test/Analysis/misc-ps.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/misc-ps.m?rev=93256&r1=93255&r2=93256&view=diff ============================================================================== --- cfe/trunk/test/Analysis/misc-ps.m (original) +++ cfe/trunk/test/Analysis/misc-ps.m Tue Jan 12 15:23:57 2010 @@ -91,16 +91,16 @@ void divzeroassume(unsigned x, unsigned j) { x /= j; - if (j == 0) x /= 0; // no-warning - if (j == 0) x /= j; // no-warning - if (j == 0) x = x / 0; // no-warning + if (j == 0) x /= 0; // no static-analyzer warning expected-warning {{division by zero is undefined}} + if (j == 0) x /= j; // no static-analyzer warning + if (j == 0) x = x / 0; // no static-analyzer warning expected-warning {{division by zero is undefined}} } void divzeroassumeB(unsigned x, unsigned j) { x = x / j; - if (j == 0) x /= 0; // no-warning - if (j == 0) x /= j; // no-warning - if (j == 0) x = x / 0; // no-warning + if (j == 0) x /= 0; // no static-analyzer warning expected-warning {{division by zero is undefined}} + if (j == 0) x /= j; // no static-analyzer warning + if (j == 0) x = x / 0; // no static-analyzer warning expected-warning {{division by zero is undefined}} } // InitListExpr processing Modified: cfe/trunk/test/Sema/exprs.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/exprs.c?rev=93256&r1=93255&r2=93256&view=diff ============================================================================== --- cfe/trunk/test/Sema/exprs.c (original) +++ cfe/trunk/test/Sema/exprs.c Tue Jan 12 15:23:57 2010 @@ -114,3 +114,11 @@ // rdar://7446395 void test16(float x) { x == ((void*) 0); } // expected-error {{invalid operands to binary expression}} +// PR6004 +void test17(int x) { + x = x / 0; // expected-warning {{division by zero is undefined}} + x = x % 0; // expected-warning {{remainder by zero is undefined}} + x /= 0; // expected-warning {{division by zero is undefined}} + x %= 0; // expected-warning {{remainder by zero is undefined}} +} + Modified: cfe/trunk/test/Sema/i-c-e.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/i-c-e.c?rev=93256&r1=93255&r2=93256&view=diff ============================================================================== --- cfe/trunk/test/Sema/i-c-e.c (original) +++ cfe/trunk/test/Sema/i-c-e.c Tue Jan 12 15:23:57 2010 @@ -57,8 +57,9 @@ // Pointer + __builtin_constant_p char pbcp[__builtin_constant_p(4) ? (intptr_t)&expr : 0]; // expected-error {{variable length array declaration not allowed at file scope}} -int illegaldiv1[1 || 1/0]; -int illegaldiv2[1/0]; // expected-error {{variable length array declaration not allowed at file scope}} +int illegaldiv1[1 || 1/0]; // expected-warning {{division by zero is undefined}} +int illegaldiv2[1/0]; // expected-error {{variable length array declaration not allowed at file scope}} \ + // expected-warning {{division by zero is undefined}} int illegaldiv3[INT_MIN / -1]; // expected-error {{variable length array declaration not allowed at file scope}} int chooseexpr[__builtin_choose_expr(1, 1, expr)]; Modified: cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp?rev=93256&r1=93255&r2=93256&view=diff ============================================================================== --- cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp (original) +++ cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp Tue Jan 12 15:23:57 2010 @@ -35,7 +35,8 @@ template struct BitfieldDivide { int bitfield : I / J; // expected-error{{expression is not an integer constant expression}} \ - // expected-note{{division by zero}} + // expected-note{{division by zero}} \ + // expected-warning {{division by zero is undefined}} }; void test_BitfieldDivide() { Modified: cfe/trunk/test/SemaTemplate/instantiate-static-var.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-static-var.cpp?rev=93256&r1=93255&r2=93256&view=diff ============================================================================== --- cfe/trunk/test/SemaTemplate/instantiate-static-var.cpp (original) +++ cfe/trunk/test/SemaTemplate/instantiate-static-var.cpp Tue Jan 12 15:23:57 2010 @@ -2,7 +2,7 @@ template class X { public: - static const T value = 10 / Divisor; // expected-error{{in-class initializer is not an integral constant expression}} + static const T value = 10 / Divisor; // expected-error{{in-class initializer is not an integral constant expression}} expected-warning {{division by zero is undefined}} }; int array1[X::value == 5? 1 : -1]; From dgregor at apple.com Tue Jan 12 15:28:44 2010 From: dgregor at apple.com (Douglas Gregor) Date: Tue, 12 Jan 2010 21:28:44 -0000 Subject: [cfe-commits] r93257 - in /cfe/trunk: include/clang/Basic/DiagnosticParseKinds.td include/clang/Basic/DiagnosticSemaKinds.td include/clang/Parse/Action.h lib/Parse/ParseDeclCXX.cpp lib/Sema/Sema.h lib/Sema/SemaTemplate.cpp test/SemaTemplate/dependent-base-classes.cpp Message-ID: <201001122128.o0CLSja1017288@zion.cs.uiuc.edu> Author: dgregor Date: Tue Jan 12 15:28:44 2010 New Revision: 93257 URL: http://llvm.org/viewvc/llvm-project?rev=93257&view=rev Log: Improve recovery for template-ids whose template-name doesn't actually name a template, when they occur in a base-specifier. This is one of the (few) places where we know for sure that an identifier followed by a '<' must be a template name, so we can diagnose and recover well: test/SemaTemplate/dependent-base-classes.cpp:9:16: error: missing 'template' keyword prior to dependent template name 'T::apply' struct X1 : T::apply { }; // expected-error{{missing 'template' ... ^ template test/SemaTemplate/dependent-base-classes.cpp:12:13: error: unknown template name 'vector' struct X2 : vector { }; // expected-error{{unknown template name 'vector'}} ^ 2 diagnostics generated. Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/include/clang/Parse/Action.h cfe/trunk/lib/Parse/ParseDeclCXX.cpp cfe/trunk/lib/Sema/Sema.h cfe/trunk/lib/Sema/SemaTemplate.cpp cfe/trunk/test/SemaTemplate/dependent-base-classes.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=93257&r1=93256&r2=93257&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Tue Jan 12 15:28:44 2010 @@ -261,6 +261,8 @@ /// C++ Templates def err_expected_template : Error<"expected template">; +def err_unknown_template_name : Error< + "unknown template name %0">; def err_expected_comma_greater : Error< "expected ',' or '>' in template-parameter-list">; def err_expected_type_id_after : Error<"expected type-id after '%0'">; Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=93257&r1=93256&r2=93257&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Jan 12 15:28:44 2010 @@ -1309,6 +1309,8 @@ "'%0%1' instantiated to a class template, not a function template">; def note_referenced_class_template : Error< "class template declared here">; +def err_template_kw_missing : Error< + "missing 'template' keyword prior to dependent template name '%0%1'">; // C++0x Variadic Templates def err_template_param_pack_default_arg : Error< Modified: cfe/trunk/include/clang/Parse/Action.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=93257&r1=93256&r2=93257&view=diff ============================================================================== --- cfe/trunk/include/clang/Parse/Action.h (original) +++ cfe/trunk/include/clang/Parse/Action.h Tue Jan 12 15:28:44 2010 @@ -291,6 +291,42 @@ bool EnteringContext, TemplateTy &Template) = 0; + /// \brief Action called as part of error recovery when the parser has + /// determined that the given name must refer to a template, but + /// \c isTemplateName() did not return a result. + /// + /// This callback permits the action to give a detailed diagnostic when an + /// unknown template name is encountered and, potentially, to try to recover + /// by producing a new template in \p SuggestedTemplate. + /// + /// \param II the name that should be a template. + /// + /// \param IILoc the location of the name in the source. + /// + /// \param S the scope in which name lookup was performed. + /// + /// \param SS the C++ scope specifier that preceded the name. + /// + /// \param SuggestedTemplate if the action sets this template to a non-NULL, + /// template, the parser will recover by consuming the template name token + /// and the template argument list that follows. + /// + /// \param SuggestedTemplateKind as input, the kind of template that we + /// expect (e.g., \c TNK_Type_template or \c TNK_Function_template). If the + /// action provides a suggested template, this should be set to the kind of + /// template. + /// + /// \returns true if a diagnostic was emitted, false otherwise. When false, + /// the parser itself will emit a generic "unknown template name" diagnostic. + virtual bool DiagnoseUnknownTemplateName(const IdentifierInfo &II, + SourceLocation IILoc, + Scope *S, + const CXXScopeSpec *SS, + TemplateTy &SuggestedTemplate, + TemplateNameKind &SuggestedKind) { + return false; + } + /// ActOnCXXGlobalScopeSpecifier - Return the object that represents the /// global scope ('::'). virtual CXXScopeTy *ActOnCXXGlobalScopeSpecifier(Scope *S, Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=93257&r1=93256&r2=93257&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original) +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Tue Jan 12 15:28:44 2010 @@ -490,18 +490,57 @@ return true; } + IdentifierInfo *Id = Tok.getIdentifierInfo(); + SourceLocation IdLoc = ConsumeToken(); + + if (Tok.is(tok::less)) { + // It looks the user intended to write a template-id here, but the + // template-name was wrong. Try to fix that. + TemplateNameKind TNK = TNK_Type_template; + TemplateTy Template; + if (!Actions.DiagnoseUnknownTemplateName(*Id, IdLoc, CurScope, + SS, Template, TNK)) { + Diag(IdLoc, diag::err_unknown_template_name) + << Id; + } + + if (!Template) + return true; + + // Form the template name + UnqualifiedId TemplateName; + TemplateName.setIdentifier(Id, IdLoc); + + // Parse the full template-id, then turn it into a type. + if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateName, + SourceLocation(), true)) + return true; + if (TNK == TNK_Dependent_template_name) + AnnotateTemplateIdTokenAsType(SS); + + // If we didn't end up with a typename token, there's nothing more we + // can do. + if (Tok.isNot(tok::annot_typename)) + return true; + + // Retrieve the type from the annotation token, consume that token, and + // return. + EndLocation = Tok.getAnnotationEndLoc(); + TypeTy *Type = Tok.getAnnotationValue(); + ConsumeToken(); + return Type; + } + // We have an identifier; check whether it is actually a type. - TypeTy *Type = Actions.getTypeName(*Tok.getIdentifierInfo(), - Tok.getLocation(), CurScope, SS, - true); - if (!Type) { - Diag(Tok, DestrExpected ? diag::err_destructor_class_name + TypeTy *Type = Actions.getTypeName(*Id, IdLoc, CurScope, SS, true); + if (!Type) { + Diag(IdLoc, DestrExpected ? diag::err_destructor_class_name : diag::err_expected_class_name); return true; } // Consume the identifier. - EndLocation = ConsumeToken(); + EndLocation = IdLoc; return Type; } Modified: cfe/trunk/lib/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=93257&r1=93256&r2=93257&view=diff ============================================================================== --- cfe/trunk/lib/Sema/Sema.h (original) +++ cfe/trunk/lib/Sema/Sema.h Tue Jan 12 15:28:44 2010 @@ -2367,6 +2367,14 @@ TypeTy *ObjectType, bool EnteringContext, TemplateTy &Template); + + virtual bool DiagnoseUnknownTemplateName(const IdentifierInfo &II, + SourceLocation IILoc, + Scope *S, + const CXXScopeSpec *SS, + TemplateTy &SuggestedTemplate, + TemplateNameKind &SuggestedKind); + bool DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl); TemplateDecl *AdjustDeclIfTemplate(DeclPtrTy &Decl); Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=93257&r1=93256&r2=93257&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue Jan 12 15:28:44 2010 @@ -143,6 +143,30 @@ return TemplateKind; } +bool Sema::DiagnoseUnknownTemplateName(const IdentifierInfo &II, + SourceLocation IILoc, + Scope *S, + const CXXScopeSpec *SS, + TemplateTy &SuggestedTemplate, + TemplateNameKind &SuggestedKind) { + // We can't recover unless there's a dependent scope specifier preceding the + // template name. + if (!SS || !SS->isSet() || !isDependentScopeSpecifier(*SS) || + computeDeclContext(*SS)) + return false; + + // The code is missing a 'template' keyword prior to the dependent template + // name. + NestedNameSpecifier *Qualifier = (NestedNameSpecifier*)SS->getScopeRep(); + Diag(IILoc, diag::err_template_kw_missing) + << Qualifier << II.getName() + << CodeModificationHint::CreateInsertion(IILoc, "template "); + SuggestedTemplate + = TemplateTy::make(Context.getDependentTemplateName(Qualifier, &II)); + SuggestedKind = TNK_Dependent_template_name; + return true; +} + void Sema::LookupTemplateName(LookupResult &Found, Scope *S, const CXXScopeSpec &SS, QualType ObjectType, Modified: cfe/trunk/test/SemaTemplate/dependent-base-classes.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/dependent-base-classes.cpp?rev=93257&r1=93256&r2=93257&view=diff ============================================================================== --- cfe/trunk/test/SemaTemplate/dependent-base-classes.cpp (original) +++ cfe/trunk/test/SemaTemplate/dependent-base-classes.cpp Tue Jan 12 15:28:44 2010 @@ -4,3 +4,9 @@ struct X0 : T::template apply { X0(U u) : T::template apply(u) { } }; + +template +struct X1 : T::apply { }; // expected-error{{missing 'template' keyword prior to dependent template name 'T::apply'}} + +template +struct X2 : vector { }; // expected-error{{unknown template name 'vector'}} From sabre at nondot.org Tue Jan 12 15:30:55 2010 From: sabre at nondot.org (Chris Lattner) Date: Tue, 12 Jan 2010 21:30:55 -0000 Subject: [cfe-commits] r93258 - in /cfe/trunk: lib/Sema/SemaExpr.cpp test/Sema/exprs.c test/SemaTemplate/instantiate-expr-1.cpp test/SemaTemplate/instantiate-static-var.cpp Message-ID: <201001122130.o0CLUuLH017363@zion.cs.uiuc.edu> Author: lattner Date: Tue Jan 12 15:30:55 2010 New Revision: 93258 URL: http://llvm.org/viewvc/llvm-project?rev=93258&view=rev Log: use DiagRuntimeBehavior to silence the div/rem by zero warning when not in an evaluated context. This removes some bogus warnings. Modified: cfe/trunk/lib/Sema/SemaExpr.cpp cfe/trunk/test/Sema/exprs.c cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp cfe/trunk/test/SemaTemplate/instantiate-static-var.cpp Modified: cfe/trunk/lib/Sema/SemaExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=93258&r1=93257&r2=93258&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) +++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Jan 12 15:30:55 2010 @@ -4868,7 +4868,8 @@ // Check for division by zero. if (isDiv && rex->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull)) - Diag(Loc, diag::warn_division_by_zero) << rex->getSourceRange(); + DiagRuntimeBehavior(Loc, PDiag(diag::warn_division_by_zero) + << rex->getSourceRange()); return compType; } @@ -4888,7 +4889,8 @@ // Check for remainder by zero. if (rex->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull)) - Diag(Loc, diag::warn_remainder_by_zero) << rex->getSourceRange(); + DiagRuntimeBehavior(Loc, PDiag(diag::warn_remainder_by_zero) + << rex->getSourceRange()); return compType; } Modified: cfe/trunk/test/Sema/exprs.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/exprs.c?rev=93258&r1=93257&r2=93258&view=diff ============================================================================== --- cfe/trunk/test/Sema/exprs.c (original) +++ cfe/trunk/test/Sema/exprs.c Tue Jan 12 15:30:55 2010 @@ -120,5 +120,7 @@ x = x % 0; // expected-warning {{remainder by zero is undefined}} x /= 0; // expected-warning {{division by zero is undefined}} x %= 0; // expected-warning {{remainder by zero is undefined}} + + x = sizeof(x/0); // no warning. } Modified: cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp?rev=93258&r1=93257&r2=93258&view=diff ============================================================================== --- cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp (original) +++ cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp Tue Jan 12 15:30:55 2010 @@ -35,8 +35,7 @@ template struct BitfieldDivide { int bitfield : I / J; // expected-error{{expression is not an integer constant expression}} \ - // expected-note{{division by zero}} \ - // expected-warning {{division by zero is undefined}} + // expected-note{{division by zero}} }; void test_BitfieldDivide() { Modified: cfe/trunk/test/SemaTemplate/instantiate-static-var.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-static-var.cpp?rev=93258&r1=93257&r2=93258&view=diff ============================================================================== --- cfe/trunk/test/SemaTemplate/instantiate-static-var.cpp (original) +++ cfe/trunk/test/SemaTemplate/instantiate-static-var.cpp Tue Jan 12 15:30:55 2010 @@ -2,7 +2,7 @@ template class X { public: - static const T value = 10 / Divisor; // expected-error{{in-class initializer is not an integral constant expression}} expected-warning {{division by zero is undefined}} + static const T value = 10 / Divisor; // expected-error{{in-class initializer is not an integral constant expression}} }; int array1[X::value == 5? 1 : -1]; From sabre at nondot.org Tue Jan 12 16:06:58 2010 From: sabre at nondot.org (Chris Lattner) Date: Tue, 12 Jan 2010 22:06:58 -0000 Subject: [cfe-commits] r93260 - /cfe/trunk/test/Misc/tabstop.c Message-ID: <201001122206.o0CM6xaa018669@zion.cs.uiuc.edu> Author: lattner Date: Tue Jan 12 16:06:58 2010 New Revision: 93260 URL: http://llvm.org/viewvc/llvm-project?rev=93260&view=rev Log: testcase for -ftabstop, patch by Christian Adaker! Added: cfe/trunk/test/Misc/tabstop.c Added: cfe/trunk/test/Misc/tabstop.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/tabstop.c?rev=93260&view=auto ============================================================================== --- cfe/trunk/test/Misc/tabstop.c (added) +++ cfe/trunk/test/Misc/tabstop.c Tue Jan 12 16:06:58 2010 @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -ftabstop 3 -fsyntax-only %s 2>&1 | FileCheck -check-prefix=3 -strict-whitespace %s +// RUN: %clang_cc1 -ftabstop 4 -fsyntax-only %s 2>&1 | FileCheck -check-prefix=4 -strict-whitespace %s +// RUN: %clang_cc1 -ftabstop 5 -fsyntax-only %s 2>&1 | FileCheck -check-prefix=5 -strict-whitespace %s + +// tab + void* a = 1; + +// tab tab + void* b = 1; + +// 3x space tab + void* c = 1; + +// tab at column 10 +void* d = 1; + +//CHECK-3: {{^ void\* a = 1;}} +//CHECK-3: {{^ void\* b = 1;}} +//CHECK-3: {{^ void\* c = 1;}} +//CHECK-3: {{^void\* d = 1;}} + +//CHECK-4: {{^ void\* a = 1;}} +//CHECK-4: {{^ void\* b = 1;}} +//CHECK-4: {{^ void\* c = 1;}} +//CHECK-4: {{^void\* d = 1;}} + +//CHECK-5: {{^ void\* a = 1;}} +//CHECK-5: {{^ void\* b = 1;}} +//CHECK-5: {{^ void\* c = 1;}} +//CHECK-5: {{^void\* d = 1;}} From clattner at apple.com Tue Jan 12 16:07:37 2010 From: clattner at apple.com (Chris Lattner) Date: Tue, 12 Jan 2010 14:07:37 -0800 Subject: [cfe-commits] [PATCH] -ftabstop In-Reply-To: <199d10ce1001101223w2849c906h974b545a0e9ec642@mail.gmail.com> References: <199d10ce1001051444q7788750dw2b63291ab9c6d7ff@mail.gmail.com> <35C064DB-70A1-4190-8A6D-E350C2067CAE@apple.com> <199d10ce1001101223w2849c906h974b545a0e9ec642@mail.gmail.com> Message-ID: <3D9C1A3C-1DB8-478E-959E-FB4B357509FE@apple.com> On Jan 10, 2010, at 12:23 PM, Christian Ad?ker wrote: > On Sat, Jan 9, 2010 at 10:54 PM, Chris Lattner > wrote: >> Please improve it in two ways: 1) write a testcase, 2) reject - >> ftabstop=0, which will cause a division by zero error. Thanks! >> >> -Chris > > Here is a test case, and a patch for checking that the TabStop value > is in a reasonable range (having an upper limit stops -ftabstop=-1 > from consuming all available memory). > > //Christian > Thanks! I applied the testcase in r93260. I think the driver should produce a warning on -ftabstop=0 or - ftabstop=10231231, not just silently ignore the error. What do you think? -Chris From mrs at apple.com Tue Jan 12 16:20:01 2010 From: mrs at apple.com (Mike Stump) Date: Tue, 12 Jan 2010 22:20:01 -0000 Subject: [cfe-commits] r93262 - /cfe/trunk/utils/VtableTest/gen.cc Message-ID: <201001122220.o0CMK1Wb019088@zion.cs.uiuc.edu> Author: mrs Date: Tue Jan 12 16:20:00 2010 New Revision: 93262 URL: http://llvm.org/viewvc/llvm-project?rev=93262&view=rev Log: Remove unused code. Modified: cfe/trunk/utils/VtableTest/gen.cc Modified: cfe/trunk/utils/VtableTest/gen.cc URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/VtableTest/gen.cc?rev=93262&r1=93261&r2=93262&view=diff ============================================================================== --- cfe/trunk/utils/VtableTest/gen.cc (original) +++ cfe/trunk/utils/VtableTest/gen.cc Tue Jan 12 16:20:00 2010 @@ -27,7 +27,6 @@ int uuid = 0; char base_present[N_STRUCTS][N_STRUCTS]; -char funcs_present[N_STRUCTS][N_FUNCS*FUNCSPACING]; // The return type for each function when doing covariant testcase generation. short ret_types[N_STRUCTS][N_FUNCS*FUNCSPACING]; @@ -179,7 +178,6 @@ gl("); return 0; }"); else gl("); }"); - funcs_present[s][fn] = 1; final_override[s][fn] = s; old_func = fn; } @@ -252,7 +250,6 @@ gl("); return 0; }"); else gl("); }"); - funcs_present[s][fn] = 1; final_override[s][fn] = s; } } From dgregor at apple.com Tue Jan 12 17:18:54 2010 From: dgregor at apple.com (Douglas Gregor) Date: Tue, 12 Jan 2010 23:18:54 -0000 Subject: [cfe-commits] r93266 - in /cfe/trunk: include/clang/Basic/PartialDiagnostic.h lib/Sema/SemaExpr.cpp test/Sema/exprs.c test/Sema/self-comparison.c Message-ID: <201001122318.o0CNItrV021411@zion.cs.uiuc.edu> Author: dgregor Date: Tue Jan 12 17:18:54 2010 New Revision: 93266 URL: http://llvm.org/viewvc/llvm-project?rev=93266&view=rev Log: Don't emit string-comparison or self-comparison warnings in unevaluated contexts, because they only matter for code that will actually be evaluated at runtime. As part of this, I had to extend PartialDiagnostic to support fix-it hints. Modified: cfe/trunk/include/clang/Basic/PartialDiagnostic.h cfe/trunk/lib/Sema/SemaExpr.cpp cfe/trunk/test/Sema/exprs.c cfe/trunk/test/Sema/self-comparison.c Modified: cfe/trunk/include/clang/Basic/PartialDiagnostic.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/PartialDiagnostic.h?rev=93266&r1=93265&r2=93266&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/PartialDiagnostic.h (original) +++ cfe/trunk/include/clang/Basic/PartialDiagnostic.h Tue Jan 12 17:18:54 2010 @@ -26,7 +26,8 @@ class PartialDiagnostic { struct Storage { - Storage() : NumDiagArgs(0), NumDiagRanges(0) { } + Storage() : NumDiagArgs(0), NumDiagRanges(0), NumCodeModificationHints(0) { + } enum { /// MaxArguments - The maximum number of arguments we can hold. We @@ -42,6 +43,10 @@ /// NumDiagRanges - This is the number of ranges in the DiagRanges array. unsigned char NumDiagRanges; + /// \brief The number of code modifications hints in the + /// CodeModificationHints array. + unsigned char NumCodeModificationHints; + /// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum /// values, with one for each argument. This specifies whether the argument /// is in DiagArgumentsStr or in DiagArguments. @@ -56,6 +61,12 @@ /// DiagRanges - The list of ranges added to this diagnostic. It currently /// only support 10 ranges, could easily be extended if needed. SourceRange DiagRanges[10]; + + enum { MaxCodeModificationHints = 3 }; + + /// CodeModificationHints - If valid, provides a hint with some code + /// to insert, remove, or modify at a particular position. + CodeModificationHint CodeModificationHints[MaxCodeModificationHints]; }; /// DiagID - The diagnostic ID. @@ -84,6 +95,20 @@ DiagStorage->DiagRanges[DiagStorage->NumDiagRanges++] = R; } + void AddCodeModificationHint(const CodeModificationHint &Hint) const { + if (Hint.isNull()) + return; + + if (!DiagStorage) + DiagStorage = new Storage; + + assert(DiagStorage->NumCodeModificationHints < + Storage::MaxCodeModificationHints && + "Too many code modification hints!"); + DiagStorage->CodeModificationHints[DiagStorage->NumCodeModificationHints++] + = Hint; + } + public: PartialDiagnostic(unsigned DiagID) : DiagID(DiagID), DiagStorage(0) { } @@ -130,6 +155,10 @@ // Add all ranges. for (unsigned i = 0, e = DiagStorage->NumDiagRanges; i != e; ++i) DB.AddSourceRange(DiagStorage->DiagRanges[i]); + + // Add all code modification hints + for (unsigned i = 0, e = DiagStorage->NumCodeModificationHints; i != e; ++i) + DB.AddCodeModificationHint(DiagStorage->CodeModificationHints[i]); } friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, @@ -165,6 +194,13 @@ friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, DeclarationName N); + + friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, + const CodeModificationHint &Hint) { + PD.AddCodeModificationHint(Hint); + return PD; + } + }; inline PartialDiagnostic PDiag(unsigned DiagID = 0) { Modified: cfe/trunk/lib/Sema/SemaExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=93266&r1=93265&r2=93266&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) +++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Jan 12 17:18:54 2010 @@ -5196,7 +5196,7 @@ if (DeclRefExpr* DRR = dyn_cast(RHSStripped)) if (DRL->getDecl() == DRR->getDecl() && !isa(DRL->getDecl())) - Diag(Loc, diag::warn_selfcomparison); + DiagRuntimeBehavior(Loc, PDiag(diag::warn_selfcomparison)); if (isa(LHSStripped)) LHSStripped = LHSStripped->IgnoreParenCasts(); @@ -5231,15 +5231,17 @@ case BinaryOperator::NE: resultComparison = ") != 0"; break; default: assert(false && "Invalid comparison operator"); } - Diag(Loc, diag::warn_stringcompare) - << isa(literalStringStripped) - << literalString->getSourceRange() - << CodeModificationHint::CreateReplacement(SourceRange(Loc), ", ") - << CodeModificationHint::CreateInsertion(lex->getLocStart(), - "strcmp(") - << CodeModificationHint::CreateInsertion( - PP.getLocForEndOfToken(rex->getLocEnd()), - resultComparison); + + DiagRuntimeBehavior(Loc, + PDiag(diag::warn_stringcompare) + << isa(literalStringStripped) + << literalString->getSourceRange() + << CodeModificationHint::CreateReplacement(SourceRange(Loc), ", ") + << CodeModificationHint::CreateInsertion(lex->getLocStart(), + "strcmp(") + << CodeModificationHint::CreateInsertion( + PP.getLocForEndOfToken(rex->getLocEnd()), + resultComparison)); } } @@ -5503,7 +5505,7 @@ if (DeclRefExpr* DRL = dyn_cast(lex->IgnoreParens())) if (DeclRefExpr* DRR = dyn_cast(rex->IgnoreParens())) if (DRL->getDecl() == DRR->getDecl()) - Diag(Loc, diag::warn_selfcomparison); + DiagRuntimeBehavior(Loc, PDiag(diag::warn_selfcomparison)); } // Check for comparisons of floating point operands using != and ==. Modified: cfe/trunk/test/Sema/exprs.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/exprs.c?rev=93266&r1=93265&r2=93266&view=diff ============================================================================== --- cfe/trunk/test/Sema/exprs.c (original) +++ cfe/trunk/test/Sema/exprs.c Tue Jan 12 17:18:54 2010 @@ -87,6 +87,10 @@ return X == "foo"; // expected-warning {{comparison against a string literal is unspecified}} } +int test12b(const char *X) { + return sizeof(X == "foo"); // no-warning +} + // rdar://6719156 void test13( void (^P)()) { // expected-error {{blocks support disabled - compile with -fblocks}} Modified: cfe/trunk/test/Sema/self-comparison.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/self-comparison.c?rev=93266&r1=93265&r2=93266&view=diff ============================================================================== --- cfe/trunk/test/Sema/self-comparison.c (original) +++ cfe/trunk/test/Sema/self-comparison.c Tue Jan 12 17:18:54 2010 @@ -31,3 +31,8 @@ enum { A }; return A == A; // no-warning } + +// Don't complain in unevaluated contexts. +int compare_sizeof(int x) { + return sizeof(x == x); // no-warning +} From adaker at nada.kth.se Tue Jan 12 17:30:33 2010 From: adaker at nada.kth.se (=?ISO-8859-1?Q?Christian_Ad=E5ker?=) Date: Wed, 13 Jan 2010 00:30:33 +0100 Subject: [cfe-commits] [PATCH] -ftabstop In-Reply-To: <3D9C1A3C-1DB8-478E-959E-FB4B357509FE@apple.com> References: <199d10ce1001051444q7788750dw2b63291ab9c6d7ff@mail.gmail.com> <35C064DB-70A1-4190-8A6D-E350C2067CAE@apple.com> <199d10ce1001101223w2849c906h974b545a0e9ec642@mail.gmail.com> <3D9C1A3C-1DB8-478E-959E-FB4B357509FE@apple.com> Message-ID: <199d10ce1001121530t1f7a9760p13d4c5bd2dc06278@mail.gmail.com> On Tue, Jan 12, 2010 at 11:07 PM, Chris Lattner wrote: > I think the driver should produce a warning on -ftabstop=0 or > -ftabstop=10231231, not just silently ignore the error. ?What do you think? Of course it should. Especially now when I noticed a Diagnostic object was so readily available. :) Fixed. I also noticed that code modification hints are not printed properly around tabs. I'll fix those as well. //Christian -------------- next part -------------- diff --git include/clang/Basic/DiagnosticDriverKinds.td include/clang/Basic/DiagnosticDriverKinds.td index efbc787..dfb6f8d 100644 --- include/clang/Basic/DiagnosticDriverKinds.td +++ include/clang/Basic/DiagnosticDriverKinds.td @@ -81,5 +81,7 @@ def warn_drv_clang_unsupported : Warning< "the clang compiler does not support '%0'">; def warn_drv_assuming_mfloat_abi_is : Warning< "unknown platform, assuming -mfloat-abi=%0">; +def warn_ignoring_ftabstop_value : Warning< + "ignoring invalid -ftabstop value '%0', using default value %1">; } diff --git include/clang/Frontend/DiagnosticOptions.h include/clang/Frontend/DiagnosticOptions.h index 0220e64..13039bb 100644 --- include/clang/Frontend/DiagnosticOptions.h +++ include/clang/Frontend/DiagnosticOptions.h @@ -37,6 +37,7 @@ public: /// The distance between tab stops. unsigned TabStop; + enum { DefaultTabStop = 8, MaxTabStop = 100 }; /// Column limit for formatting message diagnostics, or 0 if unused. unsigned MessageLength; @@ -52,7 +53,7 @@ public: public: DiagnosticOptions() { IgnoreWarnings = 0; - TabStop = 8; + TabStop = DefaultTabStop; MessageLength = 0; NoRewriteMacros = 0; Pedantic = 0; diff --git lib/Frontend/CompilerInvocation.cpp lib/Frontend/CompilerInvocation.cpp index 375c75c..0bca475 100644 --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -222,7 +222,7 @@ static void DiagnosticOptsToArgs(const DiagnosticOptions &Opts, Res.push_back("-verify"); if (Opts.ShowOptionNames) Res.push_back("-fdiagnostics-show-option"); - if (Opts.TabStop != 8) { + if (Opts.TabStop != DiagnosticOptions::DefaultTabStop) { Res.push_back("-ftabstop"); Res.push_back(llvm::utostr(Opts.TabStop)); } @@ -808,7 +808,13 @@ static void ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, Opts.ShowOptionNames = Args.hasArg(OPT_fdiagnostics_show_option); Opts.ShowSourceRanges = Args.hasArg(OPT_fdiagnostics_print_source_range_info); Opts.VerifyDiagnostics = Args.hasArg(OPT_verify); - Opts.TabStop = getLastArgIntValue(Args, OPT_ftabstop, 8, Diags); + Opts.TabStop = getLastArgIntValue(Args, OPT_ftabstop, + DiagnosticOptions::DefaultTabStop, Diags); + if (Opts.TabStop == 0 || Opts.TabStop > DiagnosticOptions::MaxTabStop) { + Diags.Report(diag::warn_ignoring_ftabstop_value) + << Opts.TabStop << DiagnosticOptions::DefaultTabStop; + Opts.TabStop = DiagnosticOptions::DefaultTabStop; + } Opts.MessageLength = getLastArgIntValue(Args, OPT_fmessage_length, 0, Diags); Opts.DumpBuildInformation = getLastArgValue(Args, OPT_dump_build_information); Opts.Warnings = getAllArgValues(Args, OPT_W); diff --git lib/Frontend/TextDiagnosticPrinter.cpp lib/Frontend/TextDiagnosticPrinter.cpp index c27d112..fcefd4e 100644 --- lib/Frontend/TextDiagnosticPrinter.cpp +++ lib/Frontend/TextDiagnosticPrinter.cpp @@ -371,15 +371,17 @@ void TextDiagnosticPrinter::EmitCaretDiagnostic(SourceLocation Loc, CaretLine.push_back('^'); // Scan the source line, looking for tabs. If we find any, manually expand - // them to 8 characters and update the CaretLine to match. + // them to spaces and update the CaretLine to match. for (unsigned i = 0; i != SourceLine.size(); ++i) { if (SourceLine[i] != '\t') continue; // Replace this tab with at least one space. SourceLine[i] = ' '; - unsigned TabStop = DiagOpts->TabStop > 0 ? DiagOpts->TabStop : 8; // Compute the number of spaces we need to insert. + unsigned TabStop = DiagOpts->TabStop; + assert(0 < TabStop && TabStop <= DiagnosticOptions::MaxTabStop && + "Invalid -ftabstop value"); unsigned NumSpaces = ((i+TabStop)/TabStop * TabStop) - (i+1); assert(NumSpaces < TabStop && "Invalid computation of space amt"); From kremenek at apple.com Tue Jan 12 17:33:42 2010 From: kremenek at apple.com (Ted Kremenek) Date: Tue, 12 Jan 2010 23:33:42 -0000 Subject: [cfe-commits] r93267 - in /cfe/trunk: include/clang-c/Index.h tools/CIndex/CIndexUSRs.cpp Message-ID: <201001122333.o0CNXgKf021959@zion.cs.uiuc.edu> Author: kremenek Date: Tue Jan 12 17:33:42 2010 New Revision: 93267 URL: http://llvm.org/viewvc/llvm-project?rev=93267&view=rev Log: Rename clang_getUSR() -> clang_getDeclUSR(). For now we take a CXDecl instead of a CXEntity. Enhance USR generation a bit with support for records. Modified: cfe/trunk/include/clang-c/Index.h cfe/trunk/tools/CIndex/CIndexUSRs.cpp Modified: cfe/trunk/include/clang-c/Index.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=93267&r1=93266&r2=93267&view=diff ============================================================================== --- cfe/trunk/include/clang-c/Index.h (original) +++ cfe/trunk/include/clang-c/Index.h Tue Jan 12 17:33:42 2010 @@ -329,7 +329,6 @@ * in a specified translation unit. */ CINDEX_LINKAGE CXDecl clang_getDeclaration(CXEntity, CXTranslationUnit); -CINDEX_LINKAGE CXString clang_getUSR(CXEntity); /* * CXDecl Operations. */ @@ -338,6 +337,7 @@ CINDEX_LINKAGE CXString clang_getDeclSpelling(CXDecl); CINDEX_LINKAGE unsigned clang_getDeclLine(CXDecl); CINDEX_LINKAGE unsigned clang_getDeclColumn(CXDecl); +CINDEX_LINKAGE CXString clang_getDeclUSR(CXDecl); CINDEX_LINKAGE const char *clang_getDeclSource(CXDecl); /* deprecate */ CINDEX_LINKAGE CXFile clang_getDeclSourceFile(CXDecl); Modified: cfe/trunk/tools/CIndex/CIndexUSRs.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndexUSRs.cpp?rev=93267&r1=93266&r2=93267&view=diff ============================================================================== --- cfe/trunk/tools/CIndex/CIndexUSRs.cpp (original) +++ cfe/trunk/tools/CIndex/CIndexUSRs.cpp Tue Jan 12 17:33:42 2010 @@ -62,57 +62,55 @@ return ((CIndexer*) CIdx)->getProgram(); } -extern "C" { - -/// clang_getDeclaration() maps from a CXEntity to the matching CXDecl (if any) -/// in a specified translation unit. -CXDecl clang_getDeclaration(CXEntity CE, CXTranslationUnit TU) { - return (CXDecl) GetEntity(CE).getDecl(GetASTContext(TU)); -} - - -CXEntity clang_getEntityFromDecl(CXIndex CIdx, CXDecl CE) { - if (Decl *D = (Decl *) CE) - return MakeEntity(CIdx, Entity::get(D, GetProgram(CIdx))); - return NullCXEntity(); -} - //===----------------------------------------------------------------------===// // USR generation. //===----------------------------------------------------------------------===// namespace { -class USRGenerator : public DeclVisitor { - llvm::raw_ostream &Out; -public: - USRGenerator(llvm::raw_ostream &out) : Out(out) {} - - void VisitNamedDecl(NamedDecl *D); - void VisitObjCContainerDecl(ObjCContainerDecl *CD); - void VisitObjCMethodDecl(ObjCMethodDecl *MD); - void VisitObjCPropertyDecl(ObjCPropertyDecl *D); -}; + class USRGenerator : public DeclVisitor { + llvm::raw_ostream &Out; + public: + USRGenerator(llvm::raw_ostream &out) : Out(out) {} + + void VisitNamedDecl(NamedDecl *D); + void VisitObjCContainerDecl(ObjCContainerDecl *CD); + void VisitObjCMethodDecl(ObjCMethodDecl *MD); + void VisitObjCPropertyDecl(ObjCPropertyDecl *D); + void VisitRecordDecl(RecordDecl *D); + void VisitTypedefDecl(TypedefDecl *D); + }; } // end anonymous namespace void USRGenerator::VisitNamedDecl(NamedDecl *D) { DeclContext *DC = D->getDeclContext(); - if (NamedDecl *DCN = dyn_cast(DC)) { + if (NamedDecl *DCN = dyn_cast(DC)) Visit(DCN); - Out << '_'; - } - else { - Out << '_'; - } - Out << D->getName(); + + const std::string &s = D->getNameAsString(); + assert(!s.empty()); + Out << '@' << s; } + +void USRGenerator::VisitRecordDecl(RecordDecl *D) { + DeclContext *DC = D->getDeclContext(); + if (NamedDecl *DCN = dyn_cast(DC)) + Visit(DCN); + Out << "@struct^"; + const std::string &s = D->getNameAsString(); + if (s.empty()) + Out << "^anon"; + else + Out << s; +} + void USRGenerator::VisitObjCMethodDecl(ObjCMethodDecl *D) { Visit(cast(D->getDeclContext())); Out << (D->isInstanceMethod() ? "(im)" : "(cm)"); - Out << DeclarationName(D->getSelector()); + Out << DeclarationName(D->getSelector()).getAsString(); } - + void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) { switch (D->getKind()) { default: @@ -124,13 +122,13 @@ case Decl::ObjCCategory: { ObjCCategoryDecl *CD = cast(D); Out << "objc(cy)" << CD->getClassInterface()->getName() - << '_' << CD->getName(); + << '_' << CD->getName(); break; } case Decl::ObjCCategoryImpl: { ObjCCategoryImplDecl *CD = cast(D); Out << "objc(cy)" << CD->getClassInterface()->getName() - << '_' << CD->getName(); + << '_' << CD->getName(); break; } case Decl::ObjCProtocol: @@ -138,29 +136,42 @@ break; } } - + void USRGenerator::VisitObjCPropertyDecl(ObjCPropertyDecl *D) { Visit(cast(D->getDeclContext())); Out << "(py)" << D->getName(); } + +void USRGenerator::VisitTypedefDecl(TypedefDecl *D) { + DeclContext *DC = D->getDeclContext(); + if (NamedDecl *DCN = dyn_cast(DC)) + Visit(DCN); + Out << "typedef@" << D->getName(); +} + +extern "C" { + +/// clang_getDeclaration() maps from a CXEntity to the matching CXDecl (if any) +/// in a specified translation unit. +CXDecl clang_getDeclaration(CXEntity CE, CXTranslationUnit TU) { + return (CXDecl) GetEntity(CE).getDecl(GetASTContext(TU)); +} + +CXEntity clang_getEntityFromDecl(CXIndex CIdx, CXDecl CE) { + if (Decl *D = (Decl *) CE) + return MakeEntity(CIdx, Entity::get(D, GetProgram(CIdx))); + return NullCXEntity(); +} + // FIXME: This is a skeleton implementation. It will be overhauled. -CXString clang_getUSR(CXEntity CE) { - const Entity &E = GetEntity(CE); - - // FIXME: Support cross-translation unit CXEntities. - if (!E.isInternalToTU()) - return CIndexer::createCXString(NULL); - - Decl *D = E.getInternalDecl(); - if (!D) - return CIndexer::createCXString(NULL); - +CXString clang_getDeclUSR(CXDecl D) { + assert(D && "Null CXDecl passed to clang_getDeclUSR()"); llvm::SmallString<1024> StrBuf; { llvm::raw_svector_ostream Out(StrBuf); USRGenerator UG(Out); - UG.Visit(D); + UG.Visit(static_cast(D)); } if (StrBuf.empty()) @@ -168,6 +179,6 @@ // Return a copy of the string that must be disposed by the caller. return CIndexer::createCXString(StrBuf.c_str(), true); -} +} } // end extern "C" From kremenek at apple.com Tue Jan 12 17:34:05 2010 From: kremenek at apple.com (Ted Kremenek) Date: Tue, 12 Jan 2010 23:34:05 -0000 Subject: [cfe-commits] r93268 - /cfe/trunk/tools/CIndex/CIndex.exports Message-ID: <201001122334.o0CNY5Fg021979@zion.cs.uiuc.edu> Author: kremenek Date: Tue Jan 12 17:34:05 2010 New Revision: 93268 URL: http://llvm.org/viewvc/llvm-project?rev=93268&view=rev Log: Make clang_getDeclUSR() visible. Modified: cfe/trunk/tools/CIndex/CIndex.exports Modified: cfe/trunk/tools/CIndex/CIndex.exports URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndex.exports?rev=93268&r1=93267&r2=93268&view=diff ============================================================================== --- cfe/trunk/tools/CIndex/CIndex.exports (original) +++ cfe/trunk/tools/CIndex/CIndex.exports Tue Jan 12 17:34:05 2010 @@ -28,6 +28,7 @@ _clang_getDeclSource _clang_getDeclSourceFile _clang_getDeclSpelling +_clang_getDeclUSR _clang_getDeclaration _clang_getDefinitionSpellingAndExtent _clang_getEntityFromDecl @@ -36,7 +37,6 @@ _clang_getNullCursor _clang_getNumCompletionChunks _clang_getTranslationUnitSpelling -_clang_getUSR _clang_isDeclaration _clang_isDefinition _clang_isInvalid From kremenek at apple.com Tue Jan 12 17:34:26 2010 From: kremenek at apple.com (Ted Kremenek) Date: Tue, 12 Jan 2010 23:34:26 -0000 Subject: [cfe-commits] r93269 - /cfe/trunk/tools/c-index-test/c-index-test.c Message-ID: <201001122334.o0CNYQPo022000@zion.cs.uiuc.edu> Author: kremenek Date: Tue Jan 12 17:34:26 2010 New Revision: 93269 URL: http://llvm.org/viewvc/llvm-project?rev=93269&view=rev Log: Add USR printing modes to c-index-test. Modified: cfe/trunk/tools/c-index-test/c-index-test.c Modified: cfe/trunk/tools/c-index-test/c-index-test.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=93269&r1=93268&r2=93269&view=diff ============================================================================== --- cfe/trunk/tools/c-index-test/c-index-test.c (original) +++ cfe/trunk/tools/c-index-test/c-index-test.c Tue Jan 12 17:34:26 2010 @@ -159,6 +159,36 @@ } } +/******************************************************************************/ +/* USR testing. */ +/******************************************************************************/ + +static void USRDeclVisitor(CXDecl D, CXCursor C, CXClientData Filter) { + if (!Filter || (C.kind == *(enum CXCursorKind *)Filter)) { + CXString USR = clang_getDeclUSR(C.decl); + if (!USR.Spelling) { + clang_disposeString(USR); + return; + } + printf("// %s: %s %s", FileCheckPrefix, GetCursorSource(C), USR.Spelling); + PrintDeclExtent(C.decl); + printf("\n"); + clang_disposeString(USR); + } +} + +static void USRVisitor(CXTranslationUnit Unit, CXCursor Cursor, + CXClientData Filter) { + if (Cursor.decl) { + /* USRDeclVisitor(Unit, Cursor.decl, Cursor, Filter);*/ + clang_loadDeclaration(Cursor.decl, USRDeclVisitor, 0); + } +} + +/******************************************************************************/ +/* Loading ASTs/source. */ +/******************************************************************************/ + static int perform_test_load(CXIndex Idx, CXTranslationUnit TU, const char *filter, const char *prefix, CXTranslationUnitIterator Visitor) { @@ -560,6 +590,14 @@ /* Command line processing. */ /******************************************************************************/ +static CXTranslationUnitIterator GetVisitor(const char *s) { + if (s[0] == '\0') + return TranslationUnitVisitor; + if (strcmp(s, "-usrs") == 0) + return USRVisitor; + return NULL; +} + static void print_usage(void) { fprintf(stderr, "usage: c-index-test -code-completion-at= \n" @@ -567,8 +605,11 @@ "[FileCheck prefix]\n" " c-index-test -test-load-tu " "[FileCheck prefix]\n" - " c-index-test -test-load-source {}*\n\n" - " options for -test-load-tu and -test-load-source:\n%s", + " c-index-test -test-load-tu-usrs " + "[FileCheck prefix]\n" + " c-index-test -test-load-source {}*\n" + " c-index-test -test-load-source-usrs {}*\n\n" + " values:\n%s", " all - load all symbols, including those from PCH\n" " local - load all symbols except those in PCH\n" " category - only load ObjC categories (non-PCH)\n" @@ -582,14 +623,17 @@ int main(int argc, const char **argv) { if (argc > 2 && strstr(argv[1], "-code-completion-at=") == argv[1]) return perform_code_completion(argc, argv); - if (argc >= 4 && strcmp(argv[1], "-test-load-tu") == 0) - return perform_test_load_tu(argv[2], argv[3], - argc >= 5 ? argv[4] : 0, - TranslationUnitVisitor); - if (argc >= 4 && strcmp(argv[1], "-test-load-source") == 0) - return perform_test_load_source(argc - 3, argv + 3, argv[2], - TranslationUnitVisitor); - if (argc >= 4 && strcmp(argv[1], "-test-file-scan") == 0) + else if (argc >= 4 && strncmp(argv[1], "-test-load-tu", 13) == 0) { + CXTranslationUnitIterator I = GetVisitor(argv[1] + 13); + if (I) + return perform_test_load_tu(argv[2], argv[3], argc >= 5 ? argv[4] : 0, I); + } + else if (argc >= 4 && strncmp(argv[1], "-test-load-source", 17) == 0) { + CXTranslationUnitIterator I = GetVisitor(argv[1] + 17); + if (I) + return perform_test_load_source(argc - 3, argv + 3, argv[2], I); + } + else if (argc >= 4 && strcmp(argv[1], "-test-file-scan") == 0) return perform_file_scan(argv[2], argv[3], argc >= 5 ? argv[4] : 0); From fjahanian at apple.com Tue Jan 12 17:58:59 2010 From: fjahanian at apple.com (Fariborz Jahanian) Date: Tue, 12 Jan 2010 23:58:59 -0000 Subject: [cfe-commits] r93271 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaExpr.cpp test/SemaObjC/ivar-lookup-resolution-builtin.m Message-ID: <201001122358.o0CNwxBS023020@zion.cs.uiuc.edu> Author: fjahanian Date: Tue Jan 12 17:58:59 2010 New Revision: 93271 URL: http://llvm.org/viewvc/llvm-project?rev=93271&view=rev Log: When in objective-c methods, do the built-in name lookup after ivar name lookup. Fixes pr5986. Added: cfe/trunk/test/SemaObjC/ivar-lookup-resolution-builtin.m Modified: cfe/trunk/lib/Sema/Sema.h cfe/trunk/lib/Sema/SemaExpr.cpp Modified: cfe/trunk/lib/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=93271&r1=93270&r2=93271&view=diff ============================================================================== --- cfe/trunk/lib/Sema/Sema.h (original) +++ cfe/trunk/lib/Sema/Sema.h Tue Jan 12 17:58:59 2010 @@ -1481,7 +1481,8 @@ OwningExprResult LookupInObjCMethod(LookupResult &R, Scope *S, - IdentifierInfo *II); + IdentifierInfo *II, + bool AllowBuiltinCreation=false); OwningExprResult ActOnDependentIdExpression(const CXXScopeSpec &SS, DeclarationName Name, Modified: cfe/trunk/lib/Sema/SemaExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=93271&r1=93270&r2=93271&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) +++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Jan 12 17:58:59 2010 @@ -1033,12 +1033,13 @@ // Just re-use the lookup done by isTemplateName. DecomposeTemplateName(R, Id); } else { - LookupParsedName(R, S, &SS, true); + bool IvarLookupFollowUp = (!SS.isSet() && II && getCurMethodDecl()); + LookupParsedName(R, S, &SS, !IvarLookupFollowUp); // If this reference is in an Objective-C method, then we need to do // some special Objective-C lookup, too. - if (!SS.isSet() && II && getCurMethodDecl()) { - OwningExprResult E(LookupInObjCMethod(R, S, II)); + if (IvarLookupFollowUp) { + OwningExprResult E(LookupInObjCMethod(R, S, II, true)); if (E.isInvalid()) return ExprError(); @@ -1218,7 +1219,8 @@ /// Returns a null sentinel to indicate trivial success. Sema::OwningExprResult Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, - IdentifierInfo *II) { + IdentifierInfo *II, + bool AllowBuiltinCreation) { SourceLocation Loc = Lookup.getNameLoc(); // There are two cases to handle here. 1) scoped lookup could have failed, @@ -1299,7 +1301,18 @@ T = Context.getObjCClassType(); return Owned(new (Context) ObjCSuperExpr(Loc, T)); } - + if (Lookup.empty() && II && AllowBuiltinCreation) { + // FIXME. Consolidate this with similar code in LookupName. + if (unsigned BuiltinID = II->getBuiltinID()) { + if (!(getLangOptions().CPlusPlus && + Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))) { + NamedDecl *D = LazilyCreateBuiltin((IdentifierInfo *)II, BuiltinID, + S, Lookup.isForRedeclaration(), + Lookup.getNameLoc()); + if (D) Lookup.addDecl(D); + } + } + } // Sentinel value saying that we didn't do anything special. return Owned((Expr*) 0); } Added: cfe/trunk/test/SemaObjC/ivar-lookup-resolution-builtin.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/ivar-lookup-resolution-builtin.m?rev=93271&view=auto ============================================================================== --- cfe/trunk/test/SemaObjC/ivar-lookup-resolution-builtin.m (added) +++ cfe/trunk/test/SemaObjC/ivar-lookup-resolution-builtin.m Tue Jan 12 17:58:59 2010 @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// pr5986 + + at interface Test { + int index; +} +- (int) index; ++ (int) ClassMethod; + at end + + at implementation Test +- (int) index +{ + return index; +} ++ (int) ClassMethod +{ + return index; // expected-error {{instance variable 'index' accessed in class method}} +} + at end + + at interface Test1 { +} +- (int) InstMethod; ++ (int) ClassMethod; + at end + + at implementation Test1 +- (int) InstMethod +{ + return index; // expected-warning {{implicitly declaring C library function 'index'}} \ + // expected-note {{please include the header or explicitly provide a declaration for 'index'}} \ + // expected-warning {{incompatible pointer to integer conversion returning}} +} ++ (int) ClassMethod +{ + return index; // expected-warning {{incompatible pointer to integer conversion returning}} +} + at end + From dgregor at apple.com Tue Jan 12 18:12:49 2010 From: dgregor at apple.com (Douglas Gregor) Date: Wed, 13 Jan 2010 00:12:49 -0000 Subject: [cfe-commits] r93274 - /cfe/trunk/lib/Sema/SemaDeclCXX.cpp Message-ID: <201001130012.o0D0Cn64023560@zion.cs.uiuc.edu> Author: dgregor Date: Tue Jan 12 18:12:48 2010 New Revision: 93274 URL: http://llvm.org/viewvc/llvm-project?rev=93274&view=rev Log: Remove broken fix-it when a default function argument has been redefined. There's a FIXME with an apology about why we don't try to do better here. Fixes . Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=93274&r1=93273&r2=93274&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Jan 12 18:12:48 2010 @@ -270,18 +270,18 @@ ParmVarDecl *NewParam = New->getParamDecl(p); if (OldParam->hasDefaultArg() && NewParam->hasDefaultArg()) { - // FIXME: If the parameter doesn't have an identifier then the location - // points to the '=' which means that the fixit hint won't remove any - // extra spaces between the type and the '='. - SourceLocation Begin = NewParam->getLocation(); - if (NewParam->getIdentifier()) - Begin = PP.getLocForEndOfToken(Begin); - + // FIXME: If we knew where the '=' was, we could easily provide a fix-it + // hint here. Alternatively, we could walk the type-source information + // for NewParam to find the last source location in the type... but it + // isn't worth the effort right now. This is the kind of test case that + // is hard to get right: + + // int f(int); + // void g(int (*fp)(int) = f); + // void g(int (*fp)(int) = &f); Diag(NewParam->getLocation(), diag::err_param_default_argument_redefinition) - << NewParam->getDefaultArgRange() - << CodeModificationHint::CreateRemoval(SourceRange(Begin, - NewParam->getLocEnd())); + << NewParam->getDefaultArgRange(); // Look for the function declaration where the default argument was // actually written, which may be a declaration prior to Old. From kremenek at apple.com Tue Jan 12 18:13:47 2010 From: kremenek at apple.com (Ted Kremenek) Date: Wed, 13 Jan 2010 00:13:47 -0000 Subject: [cfe-commits] r93275 - /cfe/trunk/tools/CIndex/CIndex.cpp Message-ID: <201001130013.o0D0DlcN023611@zion.cs.uiuc.edu> Author: kremenek Date: Tue Jan 12 18:13:47 2010 New Revision: 93275 URL: http://llvm.org/viewvc/llvm-project?rev=93275&view=rev Log: Make method definitions in TUVisitor out-of-line, making it easy to tell what visitor methods are defined. Generalize TUVisitor to take a general "root" and "iterator" callback; this is prep. work to merging TUVisitor and CDeclVisitor. Modified: cfe/trunk/tools/CIndex/CIndex.cpp Modified: cfe/trunk/tools/CIndex/CIndex.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndex.cpp?rev=93275&r1=93274&r2=93275&view=diff ============================================================================== --- cfe/trunk/tools/CIndex/CIndex.cpp (original) +++ cfe/trunk/tools/CIndex/CIndex.cpp Tue Jan 12 18:13:47 2010 @@ -165,9 +165,13 @@ #endif // Translation Unit Visitor. + class TUVisitor : public DeclVisitor { - CXTranslationUnit TUnit; - CXTranslationUnitIterator Callback; +public: + typedef void (*Iterator)(void *, CXCursor, CXClientData); +private: + void *Root; // CXDecl or CXTranslationUnit + Iterator Callback; // CXTranslationUnitIterator or CXDeclIterator. CXClientData CData; // MaxPCHLevel - the maximum PCH level of declarations that we will pass on @@ -185,44 +189,59 @@ return; CXCursor C = { CK, ND, 0 }; - Callback(TUnit, C, CData); + Callback(Root, C, CData); } + public: - TUVisitor(CXTranslationUnit CTU, - CXTranslationUnitIterator cback, CXClientData D, - unsigned MaxPCHLevel) : - TUnit(CTU), Callback(cback), CData(D), MaxPCHLevel(MaxPCHLevel) {} + TUVisitor(void *root, Iterator cback, CXClientData D, unsigned MaxPCHLevel) : + Root(root), Callback(cback), CData(D), MaxPCHLevel(MaxPCHLevel) {} - void VisitTranslationUnitDecl(TranslationUnitDecl *D) { - VisitDeclContext(dyn_cast(D)); - } - void VisitDeclContext(DeclContext *DC) { - for (DeclContext::decl_iterator - I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) - Visit(*I); - } + void VisitDeclContext(DeclContext *DC); + void VisitFunctionDecl(FunctionDecl *ND); + void VisitObjCCategoryDecl(ObjCCategoryDecl *ND); + void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *ND); + void VisitObjCImplementationDecl(ObjCImplementationDecl *ND); + void VisitObjCInterfaceDecl(ObjCInterfaceDecl *ND); + void VisitObjCProtocolDecl(ObjCProtocolDecl *ND); + void VisitTagDecl(TagDecl *ND); + void VisitTranslationUnitDecl(TranslationUnitDecl *D); + void VisitTypedefDecl(TypedefDecl *ND); + void VisitVarDecl(VarDecl *ND); +}; - void VisitFunctionDecl(FunctionDecl *ND) { - Call(ND->isThisDeclarationADefinition() ? CXCursor_FunctionDefn - : CXCursor_FunctionDecl, ND); - } - void VisitObjCCategoryDecl(ObjCCategoryDecl *ND) { - Call(CXCursor_ObjCCategoryDecl, ND); - } - void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *ND) { - Call(CXCursor_ObjCCategoryDefn, ND); - } - void VisitObjCImplementationDecl(ObjCImplementationDecl *ND) { - Call(CXCursor_ObjCClassDefn, ND); - } - void VisitObjCInterfaceDecl(ObjCInterfaceDecl *ND) { - Call(CXCursor_ObjCInterfaceDecl, ND); - } - void VisitObjCProtocolDecl(ObjCProtocolDecl *ND) { - Call(CXCursor_ObjCProtocolDecl, ND); - } - void VisitTagDecl(TagDecl *ND) { - switch (ND->getTagKind()) { +void TUVisitor::VisitDeclContext(DeclContext *DC) { + for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end(); + I != E; ++I) + Visit(*I); +} + +void TUVisitor::VisitFunctionDecl(FunctionDecl *ND) { + Call(ND->isThisDeclarationADefinition() ? CXCursor_FunctionDefn + : CXCursor_FunctionDecl, ND); +} + +void TUVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) { + Call(CXCursor_ObjCCategoryDecl, ND); +} + +void TUVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *ND) { + Call(CXCursor_ObjCCategoryDefn, ND); +} + +void TUVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *ND) { + Call(CXCursor_ObjCClassDefn, ND); +} + +void TUVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ND) { + Call(CXCursor_ObjCInterfaceDecl, ND); +} + +void TUVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *ND) { + Call(CXCursor_ObjCProtocolDecl, ND); +} + +void TUVisitor::VisitTagDecl(TagDecl *ND) { + switch (ND->getTagKind()) { case TagDecl::TK_struct: Call(CXCursor_StructDecl, ND); break; @@ -235,16 +254,20 @@ case TagDecl::TK_enum: Call(CXCursor_EnumDecl, ND); break; - } } - void VisitTypedefDecl(TypedefDecl *ND) { - Call(CXCursor_TypedefDecl, ND); - } - void VisitVarDecl(VarDecl *ND) { - Call(CXCursor_VarDecl, ND); - } -}; +} + +void TUVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) { + VisitDeclContext(dyn_cast(D)); +} + +void TUVisitor::VisitTypedefDecl(TypedefDecl *ND) { + Call(CXCursor_TypedefDecl, ND); +} +void TUVisitor::VisitVarDecl(VarDecl *ND) { + Call(CXCursor_VarDecl, ND); +} // Declaration visitor. class CDeclVisitor : public DeclVisitor { From kremenek at apple.com Tue Jan 12 18:22:50 2010 From: kremenek at apple.com (Ted Kremenek) Date: Wed, 13 Jan 2010 00:22:50 -0000 Subject: [cfe-commits] r93276 - /cfe/trunk/tools/CIndex/CIndex.cpp Message-ID: <201001130022.o0D0MohS023945@zion.cs.uiuc.edu> Author: kremenek Date: Tue Jan 12 18:22:49 2010 New Revision: 93276 URL: http://llvm.org/viewvc/llvm-project?rev=93276&view=rev Log: Move definitions for visitor methods in CDeclVisitor out-of-line. Modified: cfe/trunk/tools/CIndex/CIndex.cpp Modified: cfe/trunk/tools/CIndex/CIndex.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndex.cpp?rev=93276&r1=93275&r2=93276&view=diff ============================================================================== --- cfe/trunk/tools/CIndex/CIndex.cpp (original) +++ cfe/trunk/tools/CIndex/CIndex.cpp Tue Jan 12 18:22:49 2010 @@ -297,83 +297,113 @@ unsigned MaxPCHLevel) : CDecl(C), Callback(cback), CData(D), MaxPCHLevel(MaxPCHLevel) {} - void VisitObjCCategoryDecl(ObjCCategoryDecl *ND) { - // Issue callbacks for the containing class. - Call(CXCursor_ObjCClassRef, ND); - // FIXME: Issue callbacks for protocol refs. - VisitDeclContext(dyn_cast(ND)); - } - void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) { - // Issue callbacks for super class. - if (D->getSuperClass()) - Call(CXCursor_ObjCSuperClassRef, D); + void VisitDeclContext(DeclContext *DC); + void VisitEnumConstantDecl(EnumConstantDecl *ND); + void VisitFieldDecl(FieldDecl *ND); + void VisitFunctionDecl(FunctionDecl *ND); + void VisitObjCCategoryDecl(ObjCCategoryDecl *ND); + void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D); + void VisitObjCImplementationDecl(ObjCImplementationDecl *D); + void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); + void VisitObjCIvarDecl(ObjCIvarDecl *ND); + void VisitObjCMethodDecl(ObjCMethodDecl *ND); + void VisitObjCPropertyDecl(ObjCPropertyDecl *ND); + void VisitObjCProtocolDecl(ObjCProtocolDecl *PID); + void VisitParmVarDecl(ParmVarDecl *ND); + void VisitTagDecl(TagDecl *D); + void VisitVarDecl(VarDecl *ND); +}; +} // end anonymous namespace - for (ObjCProtocolDecl::protocol_iterator I = D->protocol_begin(), - E = D->protocol_end(); I != E; ++I) - Call(CXCursor_ObjCProtocolRef, *I); - VisitDeclContext(dyn_cast(D)); - } - void VisitObjCProtocolDecl(ObjCProtocolDecl *PID) { - for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(), - E = PID->protocol_end(); I != E; ++I) - Call(CXCursor_ObjCProtocolRef, *I); +void CDeclVisitor::VisitDeclContext(DeclContext *DC) { + for (DeclContext::decl_iterator + I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) + Visit(*I); +} - VisitDeclContext(dyn_cast(PID)); - } - void VisitTagDecl(TagDecl *D) { - VisitDeclContext(dyn_cast(D)); - } - void VisitObjCImplementationDecl(ObjCImplementationDecl *D) { - VisitDeclContext(dyn_cast(D)); - } - void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { - VisitDeclContext(dyn_cast(D)); - } - void VisitDeclContext(DeclContext *DC) { - for (DeclContext::decl_iterator - I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) - Visit(*I); - } - void VisitEnumConstantDecl(EnumConstantDecl *ND) { - Call(CXCursor_EnumConstantDecl, ND); - } - void VisitFieldDecl(FieldDecl *ND) { - Call(CXCursor_FieldDecl, ND); - } - void VisitVarDecl(VarDecl *ND) { - Call(CXCursor_VarDecl, ND); - } - void VisitParmVarDecl(ParmVarDecl *ND) { - Call(CXCursor_ParmDecl, ND); - } - void VisitObjCPropertyDecl(ObjCPropertyDecl *ND) { - Call(CXCursor_ObjCPropertyDecl, ND); - } - void VisitObjCIvarDecl(ObjCIvarDecl *ND) { - Call(CXCursor_ObjCIvarDecl, ND); - } - void VisitFunctionDecl(FunctionDecl *ND) { - if (ND->isThisDeclarationADefinition()) { - VisitDeclContext(dyn_cast(ND)); +void CDeclVisitor::VisitEnumConstantDecl(EnumConstantDecl *ND) { + Call(CXCursor_EnumConstantDecl, ND); +} + +void CDeclVisitor::VisitFieldDecl(FieldDecl *ND) { + Call(CXCursor_FieldDecl, ND); +} + +void CDeclVisitor::VisitFunctionDecl(FunctionDecl *ND) { + if (ND->isThisDeclarationADefinition()) { + VisitDeclContext(dyn_cast(ND)); #if 0 - // Not currently needed. - CompoundStmt *Body = dyn_cast(ND->getBody()); - CRefVisitor RVisit(CDecl, Callback, CData); - RVisit.Visit(Body); + // Not currently needed. + CompoundStmt *Body = dyn_cast(ND->getBody()); + CRefVisitor RVisit(CDecl, Callback, CData); + RVisit.Visit(Body); #endif - } - } - void VisitObjCMethodDecl(ObjCMethodDecl *ND) { - if (ND->getBody()) { - Call(ND->isInstanceMethod() ? CXCursor_ObjCInstanceMethodDefn - : CXCursor_ObjCClassMethodDefn, ND); - VisitDeclContext(dyn_cast(ND)); - } else - Call(ND->isInstanceMethod() ? CXCursor_ObjCInstanceMethodDecl - : CXCursor_ObjCClassMethodDecl, ND); } -}; -} // end anonymous namespace +} + +void CDeclVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) { + // Issue callbacks for the containing class. + Call(CXCursor_ObjCClassRef, ND); + // FIXME: Issue callbacks for protocol refs. + VisitDeclContext(dyn_cast(ND)); +} + +void CDeclVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { + VisitDeclContext(dyn_cast(D)); +} + +void CDeclVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) { + VisitDeclContext(dyn_cast(D)); +} + +void CDeclVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) { + // Issue callbacks for super class. + if (D->getSuperClass()) + Call(CXCursor_ObjCSuperClassRef, D); + + for (ObjCProtocolDecl::protocol_iterator I = D->protocol_begin(), + E = D->protocol_end(); I != E; ++I) + Call(CXCursor_ObjCProtocolRef, *I); + VisitDeclContext(dyn_cast(D)); +} + +void CDeclVisitor::VisitObjCIvarDecl(ObjCIvarDecl *ND) { + Call(CXCursor_ObjCIvarDecl, ND); +} + +void CDeclVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) { + if (ND->getBody()) { + Call(ND->isInstanceMethod() ? CXCursor_ObjCInstanceMethodDefn + : CXCursor_ObjCClassMethodDefn, ND); + VisitDeclContext(dyn_cast(ND)); + } else + Call(ND->isInstanceMethod() ? CXCursor_ObjCInstanceMethodDecl + : CXCursor_ObjCClassMethodDecl, ND); +} + +void CDeclVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *ND) { + Call(CXCursor_ObjCPropertyDecl, ND); +} + +void CDeclVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) { + for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(), + E = PID->protocol_end(); I != E; ++I) + Call(CXCursor_ObjCProtocolRef, *I); + + VisitDeclContext(dyn_cast(PID)); +} + +void CDeclVisitor::VisitParmVarDecl(ParmVarDecl *ND) { + Call(CXCursor_ParmDecl, ND); +} + +void CDeclVisitor::VisitTagDecl(TagDecl *D) { + VisitDeclContext(dyn_cast(D)); +} + +void CDeclVisitor::VisitVarDecl(VarDecl *ND) { + Call(CXCursor_VarDecl, ND); +} static SourceLocation getLocationFromCursor(CXCursor C, SourceManager &SourceMgr, From rjmccall at apple.com Tue Jan 12 18:25:20 2010 From: rjmccall at apple.com (John McCall) Date: Wed, 13 Jan 2010 00:25:20 -0000 Subject: [cfe-commits] r93277 - in /cfe/trunk: include/clang/Basic/ lib/Sema/ test/CXX/dcl.decl/dcl.init/dcl.init.ref/ test/CXX/temp/temp.decls/temp.class/temp.static/ test/CXX/temp/temp.param/ test/CXX/temp/temp.spec/temp.expl.spec/ test/CXX/temp/temp.spec/temp.explicit/ test/SemaCXX/ test/SemaTemplate/ Message-ID: <201001130025.o0D0PLIA024078@zion.cs.uiuc.edu> Author: rjmccall Date: Tue Jan 12 18:25:19 2010 New Revision: 93277 URL: http://llvm.org/viewvc/llvm-project?rev=93277&view=rev Log: Improve the reporting of non-viable overload candidates by noting the reason why the candidate is non-viable. There's a lot we can do to improve this, but it's a good start. Further improvements should probably be integrated with the bad-initialization reporting routines. Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/SemaOverload.cpp cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp cfe/trunk/test/CXX/temp/temp.decls/temp.class/temp.static/p1-inst.cpp cfe/trunk/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp cfe/trunk/test/CXX/temp/temp.param/p3.cpp cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp cfe/trunk/test/CXX/temp/temp.spec/temp.explicit/p1.cpp cfe/trunk/test/SemaCXX/condition.cpp cfe/trunk/test/SemaCXX/constructor-initializer.cpp cfe/trunk/test/SemaCXX/converting-constructor.cpp cfe/trunk/test/SemaCXX/dcl_init_aggr.cpp cfe/trunk/test/SemaCXX/direct-initializer.cpp cfe/trunk/test/SemaCXX/functional-cast.cpp cfe/trunk/test/SemaCXX/namespace.cpp cfe/trunk/test/SemaCXX/nested-name-spec.cpp cfe/trunk/test/SemaCXX/overload-call.cpp cfe/trunk/test/SemaCXX/overloaded-builtin-operators.cpp cfe/trunk/test/SemaTemplate/ambiguous-ovl-print.cpp cfe/trunk/test/SemaTemplate/default-expr-arguments.cpp cfe/trunk/test/SemaTemplate/explicit-instantiation.cpp cfe/trunk/test/SemaTemplate/fun-template-def.cpp cfe/trunk/test/SemaTemplate/instantiate-expr-4.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=93277&r1=93276&r2=93277&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Jan 12 18:25:19 2010 @@ -899,19 +899,29 @@ "call to %select{unavailable|deleted}0 member function %1">; def note_ovl_candidate : Note<"candidate " "%select{function|function|constructor|" + "function |function |constructor |" "is the implicit default constructor|" "is the implicit copy constructor|" - "is the implicit copy assignment operator}0">; -def note_ovl_template_candidate : Note< - "candidate function template specialization %0">; + "is the implicit copy assignment operator}0%1">; +// Note that we don't treat templates differently for this diagnostic. +def note_ovl_candidate_arity : Note<"candidate " + "%select{function|function|constructor|function|function|constructor|" + "constructor (the implicit default constructor)|" + "constructor (the implicit copy constructor)|" + "function (the implicit copy assignment operator)}0 not viable: requires" + "%select{ at least| at most|}2 %3 argument%s3, but %4 %plural{1:was|:were}4 " + "provided">; def note_ovl_candidate_deleted : Note< - "candidate %select{function|function|constructor}0 has been explicitly " - "%select{made unavailable|deleted}1">; -def note_ovl_template_candidate_deleted : Note< - "candidate function template specialization %0 has been explicit " - "&select{made unavailable|deleted}1">; -def note_ovl_candidate_not_viable : Note<"function not viable because" - " of ambiguity in conversion of argument %0">; + "candidate %select{function|function|constructor|" + "function |function |constructor |||}0%1 " + "has been explicitly %select{made unavailable|deleted}2">; +def note_ovl_candidate_bad_conv : Note<"candidate " + "%select{function|function|constructor|" + "function |function |constructor |" + "constructor (the implicit default constructor)|" + "constructor (the implicit copy constructor)|" + "function (the implicit copy assignment operator)}0%1" + " not viable: no known conversion from %2 to %3 for argument %4">; def note_ambiguous_type_conversion: Note< "because of ambiguity in conversion of %0 to %1">; def note_ovl_builtin_binary_candidate : Note< Modified: cfe/trunk/lib/Sema/SemaOverload.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=93277&r1=93276&r2=93277&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOverload.cpp (original) +++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Jan 12 18:25:19 2010 @@ -4269,19 +4269,28 @@ oc_function, oc_method, oc_constructor, + oc_function_template, + oc_method_template, + oc_constructor_template, oc_implicit_default_constructor, oc_implicit_copy_constructor, - oc_implicit_copy_assignment, - oc_template_specialization // function, constructor, or conversion template + oc_implicit_copy_assignment }; -OverloadCandidateKind ClassifyOverloadCandidate(FunctionDecl *Fn) { - if (Fn->getPrimaryTemplate()) - return oc_template_specialization; +OverloadCandidateKind ClassifyOverloadCandidate(Sema &S, + FunctionDecl *Fn, + std::string &Description) { + bool isTemplate = false; + + if (FunctionTemplateDecl *FunTmpl = Fn->getPrimaryTemplate()) { + isTemplate = true; + Description = S.getTemplateArgumentBindingsText( + FunTmpl->getTemplateParameters(), *Fn->getTemplateSpecializationArgs()); + } if (CXXConstructorDecl *Ctor = dyn_cast(Fn)) { if (!Ctor->isImplicit()) - return oc_constructor; + return isTemplate ? oc_constructor_template : oc_constructor; return Ctor->isCopyConstructor() ? oc_implicit_copy_constructor : oc_implicit_default_constructor; @@ -4291,34 +4300,24 @@ // This actually gets spelled 'candidate function' for now, but // it doesn't hurt to split it out. if (!Meth->isImplicit()) - return oc_method; + return isTemplate ? oc_method_template : oc_method; assert(Meth->isCopyAssignment() && "implicit method is not copy assignment operator?"); return oc_implicit_copy_assignment; } - return oc_function; -} - -std::string DescribeFunctionTemplate(Sema &S, FunctionDecl *Fn) { - FunctionTemplateDecl *FunTmpl = Fn->getPrimaryTemplate(); - return S.getTemplateArgumentBindingsText(FunTmpl->getTemplateParameters(), - *Fn->getTemplateSpecializationArgs()); + return isTemplate ? oc_function_template : oc_function; } } // end anonymous namespace // Notes the location of an overload candidate. void Sema::NoteOverloadCandidate(FunctionDecl *Fn) { - OverloadCandidateKind K = ClassifyOverloadCandidate(Fn); - if (K == oc_template_specialization) { - Diag(Fn->getLocation(), diag::note_ovl_template_candidate) - << DescribeFunctionTemplate(*this, Fn); - return; - } - - Diag(Fn->getLocation(), diag::note_ovl_candidate) << (unsigned) K; + std::string FnDesc; + OverloadCandidateKind K = ClassifyOverloadCandidate(*this, Fn, FnDesc); + Diag(Fn->getLocation(), diag::note_ovl_candidate) + << (unsigned) K << FnDesc; } /// Diagnoses an ambiguous conversion. The partial diagnostic is the @@ -4337,41 +4336,104 @@ namespace { -void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand) { +void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, unsigned I, + Expr **Args, unsigned NumArgs) { + assert(Cand->Function && "for now, candidate must be a function"); + FunctionDecl *Fn = Cand->Function; + + // There's a conversion slot for the object argument if this is a + // non-constructor method. Note that 'I' corresponds the + // conversion-slot index. + if (isa(Fn) && !isa(Fn)) { + // FIXME: talk usefully about bad conversions for object arguments. + if (I == 0) return S.NoteOverloadCandidate(Fn); + else I--; + } + + // FIXME: can we have a bad conversion on an ellipsis parameter? + assert(I < NumArgs && "index exceeds number of formal arguments"); + assert(I < Fn->getType()->getAs()->getNumArgs() && + "index exceeds number of formal parameters"); + + std::string FnDesc; + OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Fn, FnDesc); + + QualType FromTy = Args[I]->getType(); + QualType ToTy = Fn->getType()->getAs()->getArgType(I); + + // TODO: specialize based on the kind of mismatch + S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_conv) + << (unsigned) FnKind << FnDesc + << Args[I]->getSourceRange() << FromTy << ToTy + << I+1; +} + +void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, + Expr **Args, unsigned NumArgs) { FunctionDecl *Fn = Cand->Function; // Note deleted candidates, but only if they're viable. if (Cand->Viable && (Fn->isDeleted() || Fn->hasAttr())) { - OverloadCandidateKind FnKind = ClassifyOverloadCandidate(Fn); - - if (FnKind == oc_template_specialization) { - S.Diag(Fn->getLocation(), diag::note_ovl_template_candidate_deleted) - << DescribeFunctionTemplate(S, Fn) << Fn->isDeleted(); - return; - } + std::string FnDesc; + OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Fn, FnDesc); S.Diag(Fn->getLocation(), diag::note_ovl_candidate_deleted) - << FnKind << Fn->isDeleted(); + << FnKind << FnDesc << Fn->isDeleted(); return; } - bool errReported = false; - if (!Cand->Viable && Cand->Conversions.size() > 0) { - for (int i = Cand->Conversions.size()-1; i >= 0; i--) { - const ImplicitConversionSequence &Conversion = - Cand->Conversions[i]; + // We don't really have anything else to say about viable candidates. + if (Cand->Viable) { + S.NoteOverloadCandidate(Fn); + return; + } - if (!Conversion.isAmbiguous()) + // Diagnose arity mismatches. + // TODO: treat calls to a missing default constructor as a special case + unsigned NumFormalArgs = NumArgs; + if (isa(Fn) && !isa(Fn)) + NumFormalArgs--; + const FunctionProtoType *FnTy = Fn->getType()->getAs(); + unsigned MinParams = Fn->getMinRequiredArguments(); + if (NumFormalArgs < MinParams || + (NumFormalArgs > FnTy->getNumArgs() && !FnTy->isVariadic())) { + std::string Description; + OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Fn, Description); + + // at least / at most / exactly + unsigned mode, modeCount; + if (NumFormalArgs < MinParams) { + if (MinParams != FnTy->getNumArgs()) + mode = 0; // "at least" + else + mode = 2; // "exactly" + modeCount = MinParams; + } else { + if (MinParams != FnTy->getNumArgs()) + mode = 1; // "at most" + else + mode = 2; // "exactly" + modeCount = FnTy->getNumArgs(); + } + + S.Diag(Fn->getLocation(), diag::note_ovl_candidate_arity) + << (unsigned) FnKind << Description << mode << modeCount << NumFormalArgs; + return; + } + + // Look for bad conversions. + if (!Cand->Conversions.empty()) { + for (unsigned I = 0, N = Cand->Conversions.size(); I != N; ++I) { + if (!Cand->Conversions[I].isBad()) continue; - S.DiagnoseAmbiguousConversion(Conversion, Fn->getLocation(), - PDiag(diag::note_ovl_candidate_not_viable) << (i+1)); - errReported = true; + DiagnoseBadConversion(S, Cand, I, Args, NumArgs); + return; } } - if (!errReported) - S.NoteOverloadCandidate(Fn); + // Give up and give the generic message. + S.NoteOverloadCandidate(Fn); } void NoteSurrogateCandidate(Sema &S, OverloadCandidate *Cand) { @@ -4506,7 +4568,7 @@ OverloadCandidate *Cand = *I; if (Cand->Function) - NoteFunctionCandidate(*this, Cand); + NoteFunctionCandidate(*this, Cand, Args, NumArgs); else if (Cand->IsSurrogate) NoteSurrogateCandidate(*this, Cand); @@ -4714,7 +4776,8 @@ PDiag(), PDiag(diag::err_addr_ovl_ambiguous) << TemplateMatches[0]->getDeclName(), - PDiag(diag::note_ovl_template_candidate)); + PDiag(diag::note_ovl_candidate) + << (unsigned) oc_function_template); MarkDeclarationReferenced(From->getLocStart(), Result); return Result; } Modified: cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp?rev=93277&r1=93276&r2=93277&view=diff ============================================================================== --- cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp (original) +++ cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp Tue Jan 12 18:25:19 2010 @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s struct Base { }; // expected-note{{candidate is the implicit copy constructor}} -struct Derived : Base { }; // expected-note{{candidate is the implicit copy constructor}} +struct Derived : Base { }; // expected-note{{candidate constructor (the implicit copy constructor) not viable}} struct Unrelated { }; struct Derived2 : Base { }; struct Diamond : Derived, Derived2 { }; Modified: cfe/trunk/test/CXX/temp/temp.decls/temp.class/temp.static/p1-inst.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.class/temp.static/p1-inst.cpp?rev=93277&r1=93276&r2=93277&view=diff ============================================================================== --- cfe/trunk/test/CXX/temp/temp.decls/temp.class/temp.static/p1-inst.cpp (original) +++ cfe/trunk/test/CXX/temp/temp.decls/temp.class/temp.static/p1-inst.cpp Tue Jan 12 18:25:19 2010 @@ -14,7 +14,7 @@ InitOkay(int) { } }; -struct CannotInit { }; // expected-note{{candidate is the implicit copy constructor}} +struct CannotInit { }; // expected-note{{candidate constructor (the implicit copy constructor) not viable}} int &returnInt() { return X::value; } float &returnFloat() { return X::value; } Modified: cfe/trunk/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp?rev=93277&r1=93276&r2=93277&view=diff ============================================================================== --- cfe/trunk/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp (original) +++ cfe/trunk/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp Tue Jan 12 18:25:19 2010 @@ -12,7 +12,7 @@ X1(int); }; -struct X2 { }; // expected-note{{candidate is the implicit copy constructor}} +struct X2 { }; // expected-note{{candidate constructor (the implicit copy constructor) not viable}} int& get_int() { return X0::value; } X1& get_X1() { return X0::value; } Modified: cfe/trunk/test/CXX/temp/temp.param/p3.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.param/p3.cpp?rev=93277&r1=93276&r2=93277&view=diff ============================================================================== --- cfe/trunk/test/CXX/temp/temp.param/p3.cpp (original) +++ cfe/trunk/test/CXX/temp/temp.param/p3.cpp Tue Jan 12 18:25:19 2010 @@ -15,7 +15,7 @@ // could be interpreted as either a non-type template-parameter or a // type-parameter (because its identifier is the name of an already // existing class) is taken as a type-parameter. For example, -class T { /* ... */ }; // expected-note{{candidate is the implicit copy constructor}} +class T { /* ... */ }; // expected-note{{candidate constructor (the implicit copy constructor) not viable}} int i; template struct X2 { Modified: cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp?rev=93277&r1=93276&r2=93277&view=diff ============================================================================== --- cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp (original) +++ cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp Tue Jan 12 18:25:19 2010 @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -struct IntHolder { // expected-note{{here}} // expected-note 2{{candidate is the implicit copy constructor}} +struct IntHolder { // expected-note{{here}} // expected-note 2{{candidate constructor (the implicit copy constructor)}} IntHolder(int); // expected-note 2{{candidate constructor}} }; Modified: cfe/trunk/test/CXX/temp/temp.spec/temp.explicit/p1.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/temp.explicit/p1.cpp?rev=93277&r1=93276&r2=93277&view=diff ============================================================================== --- cfe/trunk/test/CXX/temp/temp.spec/temp.explicit/p1.cpp (original) +++ cfe/trunk/test/CXX/temp/temp.spec/temp.explicit/p1.cpp Tue Jan 12 18:25:19 2010 @@ -48,7 +48,7 @@ // Explicitly instantiate members of a class template struct Incomplete; // expected-note{{forward declaration}} -struct NonDefaultConstructible { // expected-note{{candidate is the implicit copy constructor}} +struct NonDefaultConstructible { // expected-note{{candidate constructor (the implicit copy constructor) not viable}} NonDefaultConstructible(int); // expected-note{{candidate constructor}} }; Modified: cfe/trunk/test/SemaCXX/condition.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/condition.cpp?rev=93277&r1=93276&r2=93277&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/condition.cpp (original) +++ cfe/trunk/test/SemaCXX/condition.cpp Tue Jan 12 18:25:19 2010 @@ -16,8 +16,8 @@ for (;s;) ; // expected-error {{value of type 'struct S' is not contextually convertible to 'bool'}} switch (s) {} // expected-error {{statement requires expression of integer type ('struct S' invalid)}} - while (struct S {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{no viable conversion}} expected-error {{value of type 'struct S' is not contextually convertible to 'bool'}} expected-note{{candidate is the implicit copy constructor}} - while (struct {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{no viable conversion}} expected-error {{value of type 'struct ' is not contextually convertible to 'bool'}} expected-note{{candidate is the implicit copy constructor}} + while (struct S {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{no viable conversion}} expected-error {{value of type 'struct S' is not contextually convertible to 'bool'}} expected-note{{candidate constructor (the implicit copy constructor)}} + while (struct {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{no viable conversion}} expected-error {{value of type 'struct ' is not contextually convertible to 'bool'}} expected-note{{candidate constructor (the implicit copy constructor)}} switch (enum {E} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{cannot initialize}} if (int x=0) { // expected-note 2 {{previous definition is here}} Modified: cfe/trunk/test/SemaCXX/constructor-initializer.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constructor-initializer.cpp?rev=93277&r1=93276&r2=93277&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/constructor-initializer.cpp (original) +++ cfe/trunk/test/SemaCXX/constructor-initializer.cpp Tue Jan 12 18:25:19 2010 @@ -97,7 +97,7 @@ // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}} }; -struct M { // expected-note 2 {{candidate is the implicit copy constructor}} \ +struct M { // expected-note 2 {{candidate constructor (the implicit copy constructor)}} \ // expected-note {{declared here}} \ // expected-note {{declared here}} M(int i, int j); // expected-note 2 {{candidate constructor}} Modified: cfe/trunk/test/SemaCXX/converting-constructor.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/converting-constructor.cpp?rev=93277&r1=93276&r2=93277&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/converting-constructor.cpp (original) +++ cfe/trunk/test/SemaCXX/converting-constructor.cpp Tue Jan 12 18:25:19 2010 @@ -27,7 +27,7 @@ FromShort(short s); }; -class FromShortExplicitly { // expected-note{{candidate is the implicit copy constructor}} +class FromShortExplicitly { // expected-note{{candidate constructor (the implicit copy constructor)}} public: explicit FromShortExplicitly(short s); }; Modified: cfe/trunk/test/SemaCXX/dcl_init_aggr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/dcl_init_aggr.cpp?rev=93277&r1=93276&r2=93277&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/dcl_init_aggr.cpp (original) +++ cfe/trunk/test/SemaCXX/dcl_init_aggr.cpp Tue Jan 12 18:25:19 2010 @@ -40,7 +40,7 @@ struct TooFew { int a; char* b; int c; }; TooFew too_few = { 1, "asdf" }; // okay -struct NoDefaultConstructor { // expected-note 3 {{candidate is the implicit copy constructor}} \ +struct NoDefaultConstructor { // expected-note 3 {{candidate constructor (the implicit copy constructor)}} \ // expected-note{{declared here}} NoDefaultConstructor(int); // expected-note 3 {{candidate constructor}} }; @@ -115,7 +115,7 @@ B2 b2_3 = { c2, a2, a2 }; // C++ [dcl.init.aggr]p15: -union u { int a; char* b; }; // expected-note{{candidate is the implicit copy constructor}} +union u { int a; char* b; }; // expected-note{{candidate constructor (the implicit copy constructor)}} u u1 = { 1 }; u u2 = u1; u u3 = 1; // expected-error{{no viable conversion}} Modified: cfe/trunk/test/SemaCXX/direct-initializer.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/direct-initializer.cpp?rev=93277&r1=93276&r2=93277&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/direct-initializer.cpp (original) +++ cfe/trunk/test/SemaCXX/direct-initializer.cpp Tue Jan 12 18:25:19 2010 @@ -13,14 +13,14 @@ explicit Y(float); }; -class X { // expected-note{{candidate is the implicit copy constructor}} +class X { // expected-note{{candidate constructor (the implicit copy constructor)}} public: explicit X(int); // expected-note{{candidate constructor}} X(float, float, float); // expected-note{{candidate constructor}} X(float, Y); // expected-note{{candidate constructor}} }; -class Z { // expected-note{{candidate is the implicit copy constructor}} +class Z { // expected-note{{candidate constructor (the implicit copy constructor)}} public: Z(int); // expected-note{{candidate constructor}} }; Modified: cfe/trunk/test/SemaCXX/functional-cast.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/functional-cast.cpp?rev=93277&r1=93276&r2=93277&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/functional-cast.cpp (original) +++ cfe/trunk/test/SemaCXX/functional-cast.cpp Tue Jan 12 18:25:19 2010 @@ -10,7 +10,7 @@ InitViaConstructor(int i = 7); }; -struct NoValueInit { // expected-note 2 {{candidate is the implicit copy constructor}} +struct NoValueInit { // expected-note 2 {{candidate constructor (the implicit copy constructor)}} NoValueInit(int i, int j); // expected-note 2 {{candidate constructor}} }; Modified: cfe/trunk/test/SemaCXX/namespace.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/namespace.cpp?rev=93277&r1=93276&r2=93277&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/namespace.cpp (original) +++ cfe/trunk/test/SemaCXX/namespace.cpp Tue Jan 12 18:25:19 2010 @@ -9,7 +9,7 @@ class A; // expected-error {{redefinition of 'A' as different kind of symbol}} class B {}; // expected-note {{previous definition is here}} \ - // expected-note{{candidate is the implicit copy assignment operator}} + // expected-note{{candidate function (the implicit copy assignment operator)}} void C(); // expected-note {{previous definition is here}} namespace C {} // expected-error {{redefinition of 'C' as different kind of symbol}} Modified: cfe/trunk/test/SemaCXX/nested-name-spec.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nested-name-spec.cpp?rev=93277&r1=93276&r2=93277&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/nested-name-spec.cpp (original) +++ cfe/trunk/test/SemaCXX/nested-name-spec.cpp Tue Jan 12 18:25:19 2010 @@ -178,7 +178,7 @@ namespace somens { - struct a { }; // expected-note{{candidate is the implicit copy constructor}} + struct a { }; // expected-note{{candidate constructor (the implicit copy constructor)}} } template Modified: cfe/trunk/test/SemaCXX/overload-call.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/overload-call.cpp?rev=93277&r1=93276&r2=93277&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/overload-call.cpp (original) +++ cfe/trunk/test/SemaCXX/overload-call.cpp Tue Jan 12 18:25:19 2010 @@ -304,7 +304,7 @@ // Tests the exact text used to note the candidates namespace test1 { - template void foo(T t, unsigned N); // expected-note {{candidate function template specialization [with T = int]}} + template void foo(T t, unsigned N); // expected-note {{candidate function [with T = int]}} void foo(int n, char N); // expected-note {{candidate function}} void test() { Modified: cfe/trunk/test/SemaCXX/overloaded-builtin-operators.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/overloaded-builtin-operators.cpp?rev=93277&r1=93276&r2=93277&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/overloaded-builtin-operators.cpp (original) +++ cfe/trunk/test/SemaCXX/overloaded-builtin-operators.cpp Tue Jan 12 18:25:19 2010 @@ -59,7 +59,7 @@ // FIXME: should pass (void)static_cast(islong(e1 % e2)); } -struct ShortRef { // expected-note{{candidate is the implicit copy assignment operator}} +struct ShortRef { // expected-note{{candidate function (the implicit copy assignment operator)}} operator short&(); }; @@ -67,7 +67,7 @@ operator volatile long&(); }; -struct XpmfRef { // expected-note{{candidate is the implicit copy assignment operator}} +struct XpmfRef { // expected-note{{candidate function (the implicit copy assignment operator)}} operator pmf&(); }; Modified: cfe/trunk/test/SemaTemplate/ambiguous-ovl-print.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/ambiguous-ovl-print.cpp?rev=93277&r1=93276&r2=93277&view=diff ============================================================================== --- cfe/trunk/test/SemaTemplate/ambiguous-ovl-print.cpp (original) +++ cfe/trunk/test/SemaTemplate/ambiguous-ovl-print.cpp Tue Jan 12 18:25:19 2010 @@ -2,7 +2,7 @@ void f(void*, int); // expected-note{{candidate function}} template - void f(T*, long); // expected-note{{candidate function template}} + void f(T*, long); // expected-note{{candidate function}} void test_f(int *ip, int i) { f(ip, i); // expected-error{{ambiguous}} Modified: cfe/trunk/test/SemaTemplate/default-expr-arguments.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/default-expr-arguments.cpp?rev=93277&r1=93276&r2=93277&view=diff ============================================================================== --- cfe/trunk/test/SemaTemplate/default-expr-arguments.cpp (original) +++ cfe/trunk/test/SemaTemplate/default-expr-arguments.cpp Tue Jan 12 18:25:19 2010 @@ -5,7 +5,7 @@ template<> C::C(int a0); -struct S { }; // expected-note 3 {{candidate is the implicit copy constructor}} +struct S { }; // expected-note 3 {{candidate constructor (the implicit copy constructor)}} template void f1(T a, T b = 10) { } // expected-error{{no viable conversion}} Modified: cfe/trunk/test/SemaTemplate/explicit-instantiation.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/explicit-instantiation.cpp?rev=93277&r1=93276&r2=93277&view=diff ============================================================================== --- cfe/trunk/test/SemaTemplate/explicit-instantiation.cpp (original) +++ cfe/trunk/test/SemaTemplate/explicit-instantiation.cpp Tue Jan 12 18:25:19 2010 @@ -25,7 +25,7 @@ template int X0::value; -struct NotDefaultConstructible { // expected-note{{candidate is the implicit copy constructor}} +struct NotDefaultConstructible { // expected-note{{candidate constructor (the implicit copy constructor)}} NotDefaultConstructible(int); // expected-note{{candidate constructor}} }; Modified: cfe/trunk/test/SemaTemplate/fun-template-def.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/fun-template-def.cpp?rev=93277&r1=93276&r2=93277&view=diff ============================================================================== --- cfe/trunk/test/SemaTemplate/fun-template-def.cpp (original) +++ cfe/trunk/test/SemaTemplate/fun-template-def.cpp Tue Jan 12 18:25:19 2010 @@ -8,7 +8,7 @@ // Fake typeid, lacking a typeinfo header. namespace std { class type_info {}; } -struct dummy {}; // expected-note 3 {{candidate is the implicit copy constructor}} +struct dummy {}; // expected-note 3 {{candidate constructor (the implicit copy constructor)}} template int f0(T x) { Modified: cfe/trunk/test/SemaTemplate/instantiate-expr-4.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-expr-4.cpp?rev=93277&r1=93276&r2=93277&view=diff ============================================================================== --- cfe/trunk/test/SemaTemplate/instantiate-expr-4.cpp (original) +++ cfe/trunk/test/SemaTemplate/instantiate-expr-4.cpp Tue Jan 12 18:25:19 2010 @@ -21,7 +21,7 @@ template struct FunctionalCast0<5>; -struct X { // expected-note 3 {{candidate is the implicit copy constructor}} +struct X { // expected-note 3 {{candidate constructor (the implicit copy constructor)}} X(int, int); // expected-note 3 {{candidate constructor}} }; From dgregor at apple.com Tue Jan 12 18:42:46 2010 From: dgregor at apple.com (Douglas Gregor) Date: Tue, 12 Jan 2010 16:42:46 -0800 Subject: [cfe-commits] r93271 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaExpr.cpp test/SemaObjC/ivar-lookup-resolution-builtin.m In-Reply-To: <201001122358.o0CNwxBS023020@zion.cs.uiuc.edu> References: <201001122358.o0CNwxBS023020@zion.cs.uiuc.edu> Message-ID: <75567F60-2366-455C-B1AC-B727E10CD615@apple.com> On Jan 12, 2010, at 3:58 PM, Fariborz Jahanian wrote: > Author: fjahanian > Date: Tue Jan 12 17:58:59 2010 > New Revision: 93271 > > URL: http://llvm.org/viewvc/llvm-project?rev=93271&view=rev > Log: > When in objective-c methods, do the built-in name lookup after > ivar name lookup. Fixes pr5986. > > Added: > cfe/trunk/test/SemaObjC/ivar-lookup-resolution-builtin.m > Modified: > cfe/trunk/lib/Sema/Sema.h > cfe/trunk/lib/Sema/SemaExpr.cpp > > Modified: cfe/trunk/lib/Sema/Sema.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=93271&r1=93270&r2=93271&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- cfe/trunk/lib/Sema/Sema.h (original) > +++ cfe/trunk/lib/Sema/Sema.h Tue Jan 12 17:58:59 2010 > @@ -1481,7 +1481,8 @@ > > OwningExprResult LookupInObjCMethod(LookupResult &R, > Scope *S, > - IdentifierInfo *II); > + IdentifierInfo *II, > + bool > AllowBuiltinCreation=false); > > OwningExprResult ActOnDependentIdExpression(const CXXScopeSpec &SS, > DeclarationName Name, > > Modified: cfe/trunk/lib/Sema/SemaExpr.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=93271&r1=93270&r2=93271&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) > +++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Jan 12 17:58:59 2010 > @@ -1033,12 +1033,13 @@ > // Just re-use the lookup done by isTemplateName. > DecomposeTemplateName(R, Id); > } else { > - LookupParsedName(R, S, &SS, true); > + bool IvarLookupFollowUp = (!SS.isSet() && II && getCurMethodDecl > ()); > + LookupParsedName(R, S, &SS, !IvarLookupFollowUp); > > // If this reference is in an Objective-C method, then we need > to do > // some special Objective-C lookup, too. > - if (!SS.isSet() && II && getCurMethodDecl()) { > - OwningExprResult E(LookupInObjCMethod(R, S, II)); > + if (IvarLookupFollowUp) { > + OwningExprResult E(LookupInObjCMethod(R, S, II, true)); > if (E.isInvalid()) > return ExprError(); > > @@ -1218,7 +1219,8 @@ > /// Returns a null sentinel to indicate trivial success. > Sema::OwningExprResult > Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, > - IdentifierInfo *II) { > + IdentifierInfo *II, > + bool AllowBuiltinCreation) { > SourceLocation Loc = Lookup.getNameLoc(); > > // There are two cases to handle here. 1) scoped lookup could > have failed, > @@ -1299,7 +1301,18 @@ > T = Context.getObjCClassType(); > return Owned(new (Context) ObjCSuperExpr(Loc, T)); > } > - > + if (Lookup.empty() && II && AllowBuiltinCreation) { > + // FIXME. Consolidate this with similar code in LookupName. > + if (unsigned BuiltinID = II->getBuiltinID()) { > + if (!(getLangOptions().CPlusPlus && > + Context.BuiltinInfo.isPredefinedLibFunction > (BuiltinID))) { > + NamedDecl *D = LazilyCreateBuiltin((IdentifierInfo *)II, > BuiltinID, > + S, > Lookup.isForRedeclaration(), > + Lookup.getNameLoc()); > + if (D) Lookup.addDecl(D); > + } > + } > + } > // Sentinel value saying that we didn't do anything special. > return Owned((Expr*) 0); > } C++ has a cleaner way of handling lookup for its data members, e.g., struct X { int member; int getMember() { return member; } }; C++ actually walks the Scope chain upward, and checks for each Scope whether it has an Entity (which is a DeclContext). For entities that are C++ member functions (like X::getMember()), it then performs lookup into the class type (X), its base classes, and so on. Now, the C++ implementation is slower than just checking the identifier chain, but it would make sense to take this slower path when we know we're in an Objective-C method (getCurMethodDecl() != 0). That would unify the name-lookup logic for Objective-C and C++ somewhat, which is good for Objective-C++ and also would probably address http://llvm.org/bugs/show_bug.cgi?id=5984 - Doug From daniel at zuster.org Tue Jan 12 18:47:51 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 13 Jan 2010 00:47:51 -0000 Subject: [cfe-commits] r93281 - /cfe/trunk/tools/driver/cc1_main.cpp Message-ID: <201001130047.o0D0lplr025186@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Jan 12 18:47:51 2010 New Revision: 93281 URL: http://llvm.org/viewvc/llvm-project?rev=93281&view=rev Log: cc1: Lift creation of the FrontendAction higher. Modified: cfe/trunk/tools/driver/cc1_main.cpp Modified: cfe/trunk/tools/driver/cc1_main.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/driver/cc1_main.cpp?rev=93281&r1=93280&r2=93281&view=diff ============================================================================== --- cfe/trunk/tools/driver/cc1_main.cpp (original) +++ cfe/trunk/tools/driver/cc1_main.cpp Tue Jan 12 18:47:51 2010 @@ -249,8 +249,11 @@ Diags.Report(diag::err_fe_unable_to_load_plugin) << Path << Error; } + // Create the frontend action. + llvm::OwningPtr Act(CreateFrontendAction(Clang)); + // If there were any errors in processing arguments, exit now. - if (Clang.getDiagnostics().getNumErrors()) + if (!Act || Clang.getDiagnostics().getNumErrors()) return 1; // Create the target instance. @@ -259,13 +262,13 @@ if (!Clang.hasTarget()) return 1; - // Inform the target of the language options + // Inform the target of the language options. // // FIXME: We shouldn't need to do this, the target should be immutable once // created. This complexity should be lifted elsewhere. Clang.getTarget().setForcedLangOptions(Clang.getLangOpts()); - // Validate/process some options + // Validate/process some options. if (Clang.getHeaderSearchOpts().Verbose) llvm::errs() << "clang -cc1 version " CLANG_VERSION_STRING << " based upon " << PACKAGE_STRING @@ -298,10 +301,6 @@ Clang.createPreprocessor(); } - llvm::OwningPtr Act(CreateFrontendAction(Clang)); - if (!Act) - break; - if (Act->BeginSourceFile(Clang, InFile, IsAST)) { Act->Execute(); Act->EndSourceFile(); From daniel at zuster.org Tue Jan 12 18:48:06 2010 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 13 Jan 2010 00:48:06 -0000 Subject: [cfe-commits] r93282 - in /cfe/trunk: include/clang/Frontend/CompilerInstance.h lib/Frontend/CompilerInstance.cpp tools/driver/cc1_main.cpp Message-ID: <201001130048.o0D0m6R0025205@zion.cs.uiuc.edu> Author: ddunbar Date: Tue Jan 12 18:48:06 2010 New Revision: 93282 URL: http://llvm.org/viewvc/llvm-project?rev=93282&view=rev Log: cc1: Factor out CompilerInstance::ExecuteAction which has the majority of the clang -cc1 logic for running an action against a set of options. - This should make it easier to build tools that have a clang -cc1 like interface, but aren't actually part of clang -cc1. Modified: cfe/trunk/include/clang/Frontend/CompilerInstance.h cfe/trunk/lib/Frontend/CompilerInstance.cpp cfe/trunk/tools/driver/cc1_main.cpp Modified: cfe/trunk/include/clang/Frontend/CompilerInstance.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CompilerInstance.h?rev=93282&r1=93281&r2=93282&view=diff ============================================================================== --- cfe/trunk/include/clang/Frontend/CompilerInstance.h (original) +++ cfe/trunk/include/clang/Frontend/CompilerInstance.h Tue Jan 12 18:48:06 2010 @@ -32,6 +32,7 @@ class DiagnosticClient; class ExternalASTSource; class FileManager; +class FrontendAction; class Preprocessor; class Source; class SourceManager; @@ -103,6 +104,42 @@ bool _OwnsLLVMContext = true); ~CompilerInstance(); + /// @name High-Level Operations + /// { + + /// ExecuteAction - Execute the provided action against the compiler's + /// CompilerInvocation object. + /// + /// This function makes the following assumptions: + /// + /// - The invocation options should be initialized. This function does not + /// handle the '-help' or '-version' options, clients should handle those + /// directly. + /// + /// - The diagnostics engine should have already been created by the client. + /// + /// - No other CompilerInstance state should have been initialized (this is + /// an unchecked error). + /// + /// - Clients should have initialized any LLVM target features that may be + /// required. + /// + /// - Clients should eventually call llvm_shutdown() upon the completion of + /// this routine to ensure that any managed objects are properly destroyed. + /// + /// Note that this routine may write output to 'stderr'. + /// + /// \param Act - The action to execute. + /// \return - True on success. + // + // FIXME: This function should take the stream to write any debugging / + // verbose output to as an argument. + // + // FIXME: Eliminate the llvm_shutdown requirement, that should either be part + // of the context or else not CompilerInstance specific. + bool ExecuteAction(FrontendAction &Act); + + /// } /// @name LLVM Context /// { Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=93282&r1=93281&r2=93282&view=diff ============================================================================== --- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original) +++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Tue Jan 12 18:48:06 2010 @@ -14,10 +14,12 @@ #include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" +#include "clang/Basic/Version.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/PTHManager.h" #include "clang/Frontend/ChainedDiagnosticClient.h" +#include "clang/Frontend/FrontendAction.h" #include "clang/Frontend/PCHReader.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Frontend/TextDiagnosticPrinter.h" @@ -28,6 +30,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Timer.h" +#include "llvm/System/Host.h" #include "llvm/System/Path.h" #include "llvm/System/Program.h" using namespace clang; @@ -409,3 +412,87 @@ return true; } + +// High-Level Operations + +bool CompilerInstance::ExecuteAction(FrontendAction &Act) { + assert(hasDiagnostics() && "Diagnostics engine is not initialized!"); + assert(!getFrontendOpts().ShowHelp && "Client must handle '-help'!"); + assert(!getFrontendOpts().ShowVersion && "Client must handle '-version'!"); + + // FIXME: Take this as an argument, once all the APIs we used have moved to + // taking it as an input instead of hard-coding llvm::errs. + llvm::raw_ostream &OS = llvm::errs(); + + // Create the target instance. + setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), getTargetOpts())); + if (!hasTarget()) + return false; + + // Inform the target of the language options. + // + // FIXME: We shouldn't need to do this, the target should be immutable once + // created. This complexity should be lifted elsewhere. + getTarget().setForcedLangOptions(getLangOpts()); + + // Validate/process some options. + if (getHeaderSearchOpts().Verbose) + OS << "clang -cc1 version " CLANG_VERSION_STRING + << " based upon " << PACKAGE_STRING + << " hosted on " << llvm::sys::getHostTriple() << "\n"; + + if (getFrontendOpts().ShowTimers) + createFrontendTimer(); + + for (unsigned i = 0, e = getFrontendOpts().Inputs.size(); i != e; ++i) { + const std::string &InFile = getFrontendOpts().Inputs[i].second; + + // If we aren't using an AST file, setup the file and source managers and + // the preprocessor. + bool IsAST = getFrontendOpts().Inputs[i].first == FrontendOptions::IK_AST; + if (!IsAST) { + if (!i) { + // Create a file manager object to provide access to and cache the + // filesystem. + createFileManager(); + + // Create the source manager. + createSourceManager(); + } else { + // Reset the ID tables if we are reusing the SourceManager. + getSourceManager().clearIDTables(); + } + + // Create the preprocessor. + createPreprocessor(); + } + + if (Act.BeginSourceFile(*this, InFile, IsAST)) { + Act.Execute(); + Act.EndSourceFile(); + } + } + + if (getDiagnosticOpts().ShowCarets) + if (unsigned NumDiagnostics = getDiagnostics().getNumDiagnostics()) + OS << NumDiagnostics << " diagnostic" + << (NumDiagnostics == 1 ? "" : "s") + << " generated.\n"; + + if (getFrontendOpts().ShowStats) { + getFileManager().PrintStats(); + OS << "\n"; + } + + // Return the appropriate status when verifying diagnostics. + // + // FIXME: If we could make getNumErrors() do the right thing, we wouldn't need + // this. + if (getDiagnosticOpts().VerifyDiagnostics) + return !static_cast( + getDiagnosticClient()).HadErrors(); + + return !getDiagnostics().getNumErrors(); +} + + Modified: cfe/trunk/tools/driver/cc1_main.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/driver/cc1_main.cpp?rev=93282&r1=93281&r2=93282&view=diff ============================================================================== --- cfe/trunk/tools/driver/cc1_main.cpp (original) +++ cfe/trunk/tools/driver/cc1_main.cpp Tue Jan 12 18:48:06 2010 @@ -14,10 +14,6 @@ //===----------------------------------------------------------------------===// #include "clang/Basic/Diagnostic.h" -#include "clang/Basic/FileManager.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Basic/TargetInfo.h" -#include "clang/Basic/Version.h" #include "clang/Driver/Arg.h" #include "clang/Driver/ArgList.h" #include "clang/Driver/CC1Options.h" @@ -30,7 +26,6 @@ #include "clang/Frontend/FrontendPluginRegistry.h" #include "clang/Frontend/TextDiagnosticBuffer.h" #include "clang/Frontend/TextDiagnosticPrinter.h" -#include "clang/Frontend/VerifyDiagnosticsClient.h" #include "llvm/LLVMContext.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/Support/ErrorHandling.h" @@ -38,8 +33,6 @@ #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/raw_ostream.h" #include "llvm/System/DynamicLibrary.h" -#include "llvm/System/Host.h" -#include "llvm/System/Path.h" #include "llvm/System/Signals.h" #include "llvm/Target/TargetSelect.h" #include @@ -207,13 +200,13 @@ Diags); // Infer the builtin include path if unspecified. - if (Clang.getInvocation().getHeaderSearchOpts().UseBuiltinIncludes && - Clang.getInvocation().getHeaderSearchOpts().ResourceDir.empty()) - Clang.getInvocation().getHeaderSearchOpts().ResourceDir = + if (Clang.getHeaderSearchOpts().UseBuiltinIncludes && + Clang.getHeaderSearchOpts().ResourceDir.empty()) + Clang.getHeaderSearchOpts().ResourceDir = CompilerInvocation::GetResourcesPath(Argv0, MainAddr); // Honor -help. - if (Clang.getInvocation().getFrontendOpts().ShowHelp) { + if (Clang.getFrontendOpts().ShowHelp) { llvm::OwningPtr Opts(driver::createCC1OptTable()); Opts->PrintHelp(llvm::outs(), "clang -cc1", "LLVM 'Clang' Compiler: http://clang.llvm.org"); @@ -223,7 +216,7 @@ // Honor -version. // // FIXME: Use a better -version message? - if (Clang.getInvocation().getFrontendOpts().ShowVersion) { + if (Clang.getFrontendOpts().ShowVersion) { llvm::cl::PrintVersionMessage(); return 0; } @@ -249,85 +242,18 @@ Diags.Report(diag::err_fe_unable_to_load_plugin) << Path << Error; } - // Create the frontend action. - llvm::OwningPtr Act(CreateFrontendAction(Clang)); - - // If there were any errors in processing arguments, exit now. - if (!Act || Clang.getDiagnostics().getNumErrors()) - return 1; - - // Create the target instance. - Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(), - Clang.getTargetOpts())); - if (!Clang.hasTarget()) - return 1; - - // Inform the target of the language options. - // - // FIXME: We shouldn't need to do this, the target should be immutable once - // created. This complexity should be lifted elsewhere. - Clang.getTarget().setForcedLangOptions(Clang.getLangOpts()); - - // Validate/process some options. - if (Clang.getHeaderSearchOpts().Verbose) - llvm::errs() << "clang -cc1 version " CLANG_VERSION_STRING - << " based upon " << PACKAGE_STRING - << " hosted on " << llvm::sys::getHostTriple() << "\n"; - - if (Clang.getFrontendOpts().ShowTimers) - Clang.createFrontendTimer(); - - for (unsigned i = 0, e = Clang.getFrontendOpts().Inputs.size(); i != e; ++i) { - const std::string &InFile = Clang.getFrontendOpts().Inputs[i].second; - - // If we aren't using an AST file, setup the file and source managers and - // the preprocessor. - bool IsAST = - Clang.getFrontendOpts().Inputs[i].first == FrontendOptions::IK_AST; - if (!IsAST) { - if (!i) { - // Create a file manager object to provide access to and cache the - // filesystem. - Clang.createFileManager(); - - // Create the source manager. - Clang.createSourceManager(); - } else { - // Reset the ID tables if we are reusing the SourceManager. - Clang.getSourceManager().clearIDTables(); - } - - // Create the preprocessor. - Clang.createPreprocessor(); - } - - if (Act->BeginSourceFile(Clang, InFile, IsAST)) { - Act->Execute(); - Act->EndSourceFile(); - } + // If there were errors in processing arguments, don't do anything else. + bool Success = false; + if (!Clang.getDiagnostics().getNumErrors()) { + // Create and execute the frontend action. + llvm::OwningPtr Act(CreateFrontendAction(Clang)); + if (Act) + Success = Clang.ExecuteAction(*Act); } - if (Clang.getDiagnosticOpts().ShowCarets) - if (unsigned NumDiagnostics = Clang.getDiagnostics().getNumDiagnostics()) - fprintf(stderr, "%d diagnostic%s generated.\n", NumDiagnostics, - (NumDiagnostics == 1 ? "" : "s")); - - if (Clang.getFrontendOpts().ShowStats) { - Clang.getFileManager().PrintStats(); - fprintf(stderr, "\n"); - } - - // Return the appropriate status when verifying diagnostics. - // - // FIXME: If we could make getNumErrors() do the right thing, we wouldn't need - // this. - if (Clang.getDiagnosticOpts().VerifyDiagnostics) - return static_cast( - Clang.getDiagnosticClient()).HadErrors(); - // Managed static deconstruction. Useful for making things like // -time-passes usable. llvm::llvm_shutdown(); - return (Clang.getDiagnostics().getNumErrors() != 0); + return !Success; } From fjahanian at apple.com Tue Jan 12 19:07:47 2010 From: fjahanian at apple.com (Fariborz Jahanian) Date: Tue, 12 Jan 2010 17:07:47 -0800 Subject: [cfe-commits] r93271 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaExpr.cpp test/SemaObjC/ivar-lookup-resolution-builtin.m In-Reply-To: <75567F60-2366-455C-B1AC-B727E10CD615@apple.com> References: <201001122358.o0CNwxBS023020@zion.cs.uiuc.edu> <75567F60-2366-455C-B1AC-B727E10CD615@apple.com> Message-ID: On Jan 12, 2010, at 4:42 PM, Douglas Gregor wrote: > > On Jan 12, 2010, at 3:58 PM, Fariborz Jahanian wrote: > >> Author: fjahanian >> Date: Tue Jan 12 17:58:59 2010 >> New Revision: 93271 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=93271&view=rev >> Log: >> When in objective-c methods, do the built-in name lookup after >> ivar name lookup. Fixes pr5986. >> >> Added: >> cfe/trunk/test/SemaObjC/ivar-lookup-resolution-builtin.m >> Modified: >> cfe/trunk/lib/Sema/Sema.h >> cfe/trunk/lib/Sema/SemaExpr.cpp >> >> Modified: cfe/trunk/lib/Sema/Sema.h >> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=93271&r1=93270&r2=93271&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- cfe/trunk/lib/Sema/Sema.h (original) >> +++ cfe/trunk/lib/Sema/Sema.h Tue Jan 12 17:58:59 2010 >> @@ -1481,7 +1481,8 @@ >> >> OwningExprResult LookupInObjCMethod(LookupResult &R, >> Scope *S, >> - IdentifierInfo *II); >> + IdentifierInfo *II, >> + bool >> AllowBuiltinCreation=false); >> >> OwningExprResult ActOnDependentIdExpression(const CXXScopeSpec &SS, >> DeclarationName Name, >> >> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp >> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=93271&r1=93270&r2=93271&view=diff >> >> = >> = >> = >> = >> = >> = >> = >> = >> = >> ===================================================================== >> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) >> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Jan 12 17:58:59 2010 >> @@ -1033,12 +1033,13 @@ >> // Just re-use the lookup done by isTemplateName. >> DecomposeTemplateName(R, Id); >> } else { >> - LookupParsedName(R, S, &SS, true); >> + bool IvarLookupFollowUp = (!SS.isSet() && II && >> getCurMethodDecl()); >> + LookupParsedName(R, S, &SS, !IvarLookupFollowUp); >> >> // If this reference is in an Objective-C method, then we need >> to do >> // some special Objective-C lookup, too. >> - if (!SS.isSet() && II && getCurMethodDecl()) { >> - OwningExprResult E(LookupInObjCMethod(R, S, II)); >> + if (IvarLookupFollowUp) { >> + OwningExprResult E(LookupInObjCMethod(R, S, II, true)); >> if (E.isInvalid()) >> return ExprError(); >> >> @@ -1218,7 +1219,8 @@ >> /// Returns a null sentinel to indicate trivial success. >> Sema::OwningExprResult >> Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, >> - IdentifierInfo *II) { >> + IdentifierInfo *II, >> + bool AllowBuiltinCreation) { >> SourceLocation Loc = Lookup.getNameLoc(); >> >> // There are two cases to handle here. 1) scoped lookup could >> have failed, >> @@ -1299,7 +1301,18 @@ >> T = Context.getObjCClassType(); >> return Owned(new (Context) ObjCSuperExpr(Loc, T)); >> } >> - >> + if (Lookup.empty() && II && AllowBuiltinCreation) { >> + // FIXME. Consolidate this with similar code in LookupName. >> + if (unsigned BuiltinID = II->getBuiltinID()) { >> + if (!(getLangOptions().CPlusPlus && >> + >> Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))) { >> + NamedDecl *D = LazilyCreateBuiltin((IdentifierInfo *)II, >> BuiltinID, >> + S, >> Lookup.isForRedeclaration(), >> + Lookup.getNameLoc()); >> + if (D) Lookup.addDecl(D); >> + } >> + } >> + } >> // Sentinel value saying that we didn't do anything special. >> return Owned((Expr*) 0); >> } > C++ has a cleaner way of handling lookup for its data members, e.g., > > struct X { > int member; > int getMember() { return member; } > }; > > C++ actually walks the Scope chain upward, and checks for each Scope > whether it has an Entity (which is a DeclContext). For entities that > are C++ member functions (like X::getMember()), it then performs > lookup into the class type (X), its base classes, and so on. > > Now, the C++ implementation is slower than just checking the > identifier chain, but it would make sense to take this slower path > when we know we're in an Objective-C method (getCurMethodDecl() != > 0). That would unify the name-lookup logic for Objective-C and C++ > somewhat, which is good for Objective-C++ and also would probably > address > > http://llvm.org/bugs/show_bug.cgi?id=5984 Agreed as a long term redo of objective-c's lookup. But above patch (for pr5986) doesn't depend on it. It is more for pr5984 as you pointed out. - Fariborz > > > - Doug From dgregor at apple.com Tue Jan 12 19:10:43 2010 From: dgregor at apple.com (Douglas Gregor) Date: Tue, 12 Jan 2010 17:10:43 -0800 Subject: [cfe-commits] [REVIEW] Literal operator semantic improvements In-Reply-To: <4B45A125.9050809@gmail.com> References: <4B45A125.9050809@gmail.com> Message-ID: <56AE41E6-264A-4BAB-B711-1CAAF522B59C@apple.com> On Jan 7, 2010, at 12:53 AM, Sean Hunt wrote: > This patch actually gets CXX literal operator names into the > DeclarationNameTable (oops), and also adds semantic analysis of the > literal operator's signature. A couple of comments: +/// CheckLiteralOperatorDeclaration - Check whether the declaration +/// of this literal operator function is well-formed. If so, returns +/// false; otherwise, emits appropriate diagnostics and returns true. +bool Sema::CheckLiteralOperatorDeclaration(FunctionDecl *FnDecl) { + DeclContext *DC = FnDecl->getDeclContext(); + if (!isa(DC) && !isa(DC)) { + Diag(FnDecl->getLocation(), diag::err_literal_operator_outside_namespace) + << FnDecl->getDeclName(); + return true; + } Can a literal operator be declared in a linkage-specification, e.g., extern "C++" { void operator "" good (char16_t); } ? This code would reject that. + // The second and final parameter must be an std::size_t + if (Context.hasSameType((*Param)->getType(), Context.getSizeType ()) && + ++Param == FnDecl->param_end()) + Valid = true; It can probably be a const-qualified std::size_t, right? We allow this for, e.g., operator new's size_t parameter. Everything else seems reasonable. Please go ahead and commit once those issues above are resolved. - Doug From mrs at apple.com Tue Jan 12 20:59:55 2010 From: mrs at apple.com (Mike Stump) Date: Wed, 13 Jan 2010 02:59:55 -0000 Subject: [cfe-commits] r93287 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Analysis/AnalysisContext.cpp lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaExpr.cpp test/SemaCXX/unreachable-code.cpp Message-ID: <201001130259.o0D2xtdp030006@zion.cs.uiuc.edu> Author: mrs Date: Tue Jan 12 20:59:54 2010 New Revision: 93287 URL: http://llvm.org/viewvc/llvm-project?rev=93287&view=rev Log: Add an unreachable code checker. Added: cfe/trunk/test/SemaCXX/unreachable-code.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Analysis/AnalysisContext.cpp cfe/trunk/lib/Sema/Sema.h cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/lib/Sema/SemaExpr.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=93287&r1=93286&r2=93287&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Jan 12 20:59:54 2010 @@ -160,6 +160,8 @@ def warn_suggest_noreturn_block : Warning< "block could be attribute 'noreturn'">, InGroup>, DefaultIgnore; +def warn_unreachable : Warning<"will never be executed">, + InGroup>, DefaultIgnore; /// Built-in functions. def ext_implicit_lib_function_decl : ExtWarn< Modified: cfe/trunk/lib/Analysis/AnalysisContext.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/AnalysisContext.cpp?rev=93287&r1=93286&r2=93287&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/AnalysisContext.cpp (original) +++ cfe/trunk/lib/Analysis/AnalysisContext.cpp Tue Jan 12 20:59:54 2010 @@ -18,6 +18,7 @@ #include "clang/Analysis/CFG.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclTemplate.h" #include "clang/AST/ParentMap.h" #include "clang/AST/StmtVisitor.h" #include "clang/Analysis/Support/BumpVector.h" @@ -38,6 +39,9 @@ return MD->getBody(); else if (const BlockDecl *BD = dyn_cast(D)) return BD->getBody(); + else if (const FunctionTemplateDecl *FunTmpl + = dyn_cast_or_null(D)) + return FunTmpl->getTemplatedDecl()->getBody(); llvm_unreachable("unknown code decl"); } Modified: cfe/trunk/lib/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=93287&r1=93286&r2=93287&view=diff ============================================================================== --- cfe/trunk/lib/Sema/Sema.h (original) +++ cfe/trunk/lib/Sema/Sema.h Tue Jan 12 20:59:54 2010 @@ -42,6 +42,7 @@ } namespace clang { + class AnalysisContext; class ASTContext; class ASTConsumer; class CodeCompleteConsumer; @@ -1097,6 +1098,9 @@ OwningExprResult BuildOverloadedArrowExpr(Scope *S, ExprArg Base, SourceLocation OpLoc); + /// CheckUnreachable - Check for unreachable code. + void CheckUnreachable(AnalysisContext &); + /// CheckCallReturnType - Checks that a call expression's return type is /// complete. Returns true on failure. The location passed in is the location /// that best represents the call. @@ -1104,14 +1108,14 @@ CallExpr *CE, FunctionDecl *FD); /// Helpers for dealing with blocks and functions. - void CheckFallThroughForFunctionDef(Decl *D, Stmt *Body); - void CheckFallThroughForBlock(QualType BlockTy, Stmt *Body); + void CheckFallThroughForFunctionDef(Decl *D, Stmt *Body, AnalysisContext &); + void CheckFallThroughForBlock(QualType BlockTy, Stmt *, AnalysisContext &); bool CheckParmsForFunctionDef(FunctionDecl *FD); void CheckCXXDefaultArguments(FunctionDecl *FD); void CheckExtraCXXDefaultArguments(Declarator &D); enum ControlFlowKind { NeverFallThrough = 0, MaybeFallThrough = 1, AlwaysFallThrough = 2, NeverFallThroughOrReturn = 3 }; - ControlFlowKind CheckFallThrough(Stmt *); + ControlFlowKind CheckFallThrough(AnalysisContext &); Scope *getNonFieldDeclScope(Scope *S); Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=93287&r1=93286&r2=93287&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Jan 12 20:59:54 2010 @@ -14,6 +14,7 @@ #include "Sema.h" #include "SemaInit.h" #include "Lookup.h" +#include "clang/Analysis/PathSensitive/AnalysisContext.h" #include "clang/AST/APValue.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" @@ -1305,30 +1306,10 @@ New->setPreviousDeclaration(Old); } -/// CheckFallThrough - Check that we don't fall off the end of a -/// Statement that should return a value. -/// -/// \returns AlwaysFallThrough iff we always fall off the end of the statement, -/// MaybeFallThrough iff we might or might not fall off the end, -/// NeverFallThroughOrReturn iff we never fall off the end of the statement or -/// return. We assume NeverFallThrough iff we never fall off the end of the -/// statement but we may return. We assume that functions not marked noreturn -/// will return. -Sema::ControlFlowKind Sema::CheckFallThrough(Stmt *Root) { - // FIXME: Eventually share this CFG object when we have other warnings based - // of the CFG. This can be done using AnalysisContext. - llvm::OwningPtr cfg (CFG::buildCFG(Root, &Context)); - - // FIXME: They should never return 0, fix that, delete this code. - if (cfg == 0) - // FIXME: This should be NeverFallThrough - return NeverFallThroughOrReturn; - // The CFG leaves in dead things, and we don't want to dead code paths to - // confuse us, so we mark all live things first. +static void MarkLive(CFGBlock *e, llvm::BitVector &live) { std::queue workq; - llvm::BitVector live(cfg->getNumBlockIDs()); // Prep work queue - workq.push(&cfg->getEntry()); + workq.push(e); // Solve while (!workq.empty()) { CFGBlock *item = workq.front(); @@ -1344,6 +1325,54 @@ } } } +} + +/// CheckUnreachable - Check for unreachable code. +void Sema::CheckUnreachable(AnalysisContext &AC) { + if (Diags.getDiagnosticLevel(diag::warn_unreachable) == Diagnostic::Ignored) + return; + + CFG *cfg = AC.getCFG(); + // FIXME: They should never return 0, fix that, delete this code. + if (cfg == 0) + return; + + llvm::BitVector live(cfg->getNumBlockIDs()); + // Mark all live things first. + MarkLive(&cfg->getEntry(), live); + + for (unsigned i = 0; i < cfg->getNumBlockIDs(); ++i) { + if (!live[i]) { + CFGBlock &b = *(cfg->begin()[i]); + if (!b.empty()) + Diag(b[0].getStmt()->getLocStart(), diag::warn_unreachable); + // Avoid excessive errors by marking everything reachable from here + MarkLive(&b, live); + } + } +} + +/// CheckFallThrough - Check that we don't fall off the end of a +/// Statement that should return a value. +/// +/// \returns AlwaysFallThrough iff we always fall off the end of the statement, +/// MaybeFallThrough iff we might or might not fall off the end, +/// NeverFallThroughOrReturn iff we never fall off the end of the statement or +/// return. We assume NeverFallThrough iff we never fall off the end of the +/// statement but we may return. We assume that functions not marked noreturn +/// will return. +Sema::ControlFlowKind Sema::CheckFallThrough(AnalysisContext &AC) { + CFG *cfg = AC.getCFG(); + // FIXME: They should never return 0, fix that, delete this code. + if (cfg == 0) + // FIXME: This should be NeverFallThrough + return NeverFallThroughOrReturn; + + // The CFG leaves in dead things, and we don't want to dead code paths to + // confuse us, so we mark all live things first. + std::queue workq; + llvm::BitVector live(cfg->getNumBlockIDs()); + MarkLive(&cfg->getEntry(), live); // Now we know what is live, we check the live precessors of the exit block // and look for fall through paths, being careful to ignore normal returns, @@ -1419,7 +1448,8 @@ /// function that should return a value. Check that we don't fall off the end /// of a noreturn function. We assume that functions and blocks not marked /// noreturn will return. -void Sema::CheckFallThroughForFunctionDef(Decl *D, Stmt *Body) { +void Sema::CheckFallThroughForFunctionDef(Decl *D, Stmt *Body, + AnalysisContext &AC) { // FIXME: Would be nice if we had a better way to control cascading errors, // but for now, avoid them. The problem is that when Parse sees: // int foo() { return a; } @@ -1457,7 +1487,7 @@ return; // FIXME: Function try block if (CompoundStmt *Compound = dyn_cast(Body)) { - switch (CheckFallThrough(Body)) { + switch (CheckFallThrough(AC)) { case MaybeFallThrough: if (HasNoReturn) Diag(Compound->getRBracLoc(), diag::warn_falloff_noreturn_function); @@ -1484,7 +1514,8 @@ /// that should return a value. Check that we don't fall off the end of a /// noreturn block. We assume that functions and blocks not marked noreturn /// will return. -void Sema::CheckFallThroughForBlock(QualType BlockTy, Stmt *Body) { +void Sema::CheckFallThroughForBlock(QualType BlockTy, Stmt *Body, + AnalysisContext &AC) { // FIXME: Would be nice if we had a better way to control cascading errors, // but for now, avoid them. The problem is that when Parse sees: // int foo() { return a; } @@ -1510,7 +1541,7 @@ return; // FIXME: Funtion try block if (CompoundStmt *Compound = dyn_cast(Body)) { - switch (CheckFallThrough(Body)) { + switch (CheckFallThrough(AC)) { case MaybeFallThrough: if (HasNoReturn) Diag(Compound->getRBracLoc(), diag::err_noreturn_block_has_return_expr); @@ -4330,6 +4361,7 @@ Decl *dcl = D.getAs(); Stmt *Body = BodyArg.takeAs(); + AnalysisContext AC(dcl); FunctionDecl *FD = 0; FunctionTemplateDecl *FunTmpl = dyn_cast_or_null(dcl); if (FunTmpl) @@ -4344,7 +4376,7 @@ // Implements C++ [basic.start.main]p5 and C99 5.1.2.2.3. FD->setHasImplicitReturnZero(true); else - CheckFallThroughForFunctionDef(FD, Body); + CheckFallThroughForFunctionDef(FD, Body, AC); if (!FD->isInvalidDecl()) DiagnoseUnusedParameters(FD->param_begin(), FD->param_end()); @@ -4356,7 +4388,7 @@ } else if (ObjCMethodDecl *MD = dyn_cast_or_null(dcl)) { assert(MD == getCurMethodDecl() && "Method parsing confused"); MD->setBody(Body); - CheckFallThroughForFunctionDef(MD, Body); + CheckFallThroughForFunctionDef(MD, Body, AC); MD->setEndLoc(Body->getLocEnd()); if (!MD->isInvalidDecl()) @@ -4414,6 +4446,8 @@ if (!Body) return D; + CheckUnreachable(AC); + // Verify that that gotos and switch cases don't jump into scopes illegally. if (CurFunctionNeedsScopeChecking) DiagnoseInvalidJumps(Body); Modified: cfe/trunk/lib/Sema/SemaExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=93287&r1=93286&r2=93287&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) +++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Jan 12 20:59:54 2010 @@ -14,6 +14,7 @@ #include "Sema.h" #include "SemaInit.h" #include "Lookup.h" +#include "clang/Analysis/PathSensitive/AnalysisContext.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" @@ -6859,7 +6860,9 @@ CurFunctionNeedsScopeChecking = BSI->SavedFunctionNeedsScopeChecking; BSI->TheDecl->setBody(body.takeAs()); - CheckFallThroughForBlock(BlockTy, BSI->TheDecl->getBody()); + AnalysisContext AC(BSI->TheDecl); + CheckFallThroughForBlock(BlockTy, BSI->TheDecl->getBody(), AC); + CheckUnreachable(AC); return Owned(new (Context) BlockExpr(BSI->TheDecl, BlockTy, BSI->hasBlockDeclRefExprs)); } Added: cfe/trunk/test/SemaCXX/unreachable-code.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/unreachable-code.cpp?rev=93287&view=auto ============================================================================== --- cfe/trunk/test/SemaCXX/unreachable-code.cpp (added) +++ cfe/trunk/test/SemaCXX/unreachable-code.cpp Tue Jan 12 20:59:54 2010 @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -Wunreachable-code -fblocks -verify %s + +int j; +void bar() { } +int test1() { + for (int i = 0; + i != 10; + ++i) { // expected-warning {{will never be executed}} + if (j == 23) // missing {}'s + bar(); + return 1; + } + return 0; + return 1; // expected-warning {{will never be executed}} +} + +void test2(int i) { + switch (i) { + case 0: + break; + bar(); // expected-warning {{will never be executed}} + case 2: + switch (i) { + default: + a: goto a; + } + bar(); // expected-warning {{will never be executed}} + } + b: goto b; + bar(); // expected-warning {{will never be executed}} +} + +void test3() { + ^{ return; + bar(); // expected-warning {{will never be executed}} + }(); + while (++j) { + continue; + bar(); // expected-warning {{will never be executed}} + } +} From sabre at nondot.org Tue Jan 12 21:06:51 2010 From: sabre at nondot.org (Chris Lattner) Date: Wed, 13 Jan 2010 03:06:51 -0000 Subject: [cfe-commits] r93288 - in /cfe/trunk: include/clang/Basic/DiagnosticDriverKinds.td include/clang/Frontend/DiagnosticOptions.h lib/Frontend/CompilerInvocation.cpp lib/Frontend/TextDiagnosticPrinter.cpp Message-ID: <201001130306.o0D36paN030321@zion.cs.uiuc.edu> Author: lattner Date: Tue Jan 12 21:06:50 2010 New Revision: 93288 URL: http://llvm.org/viewvc/llvm-project?rev=93288&view=rev Log: diagnose invalid values of -ftabstop, patch by Christian Adaker! Modified: cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td cfe/trunk/include/clang/Frontend/DiagnosticOptions.h cfe/trunk/lib/Frontend/CompilerInvocation.cpp cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td?rev=93288&r1=93287&r2=93288&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td Tue Jan 12 21:06:50 2010 @@ -81,5 +81,7 @@ "the clang compiler does not support '%0'">; def warn_drv_assuming_mfloat_abi_is : Warning< "unknown platform, assuming -mfloat-abi=%0">; +def warn_ignoring_ftabstop_value : Warning< + "ignoring invalid -ftabstop value '%0', using default value %1">; } Modified: cfe/trunk/include/clang/Frontend/DiagnosticOptions.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/DiagnosticOptions.h?rev=93288&r1=93287&r2=93288&view=diff ============================================================================== --- cfe/trunk/include/clang/Frontend/DiagnosticOptions.h (original) +++ cfe/trunk/include/clang/Frontend/DiagnosticOptions.h Tue Jan 12 21:06:50 2010 @@ -37,6 +37,7 @@ /// The distance between tab stops. unsigned TabStop; + enum { DefaultTabStop = 8, MaxTabStop = 100 }; /// Column limit for formatting message diagnostics, or 0 if unused. unsigned MessageLength; @@ -52,7 +53,7 @@ public: DiagnosticOptions() { IgnoreWarnings = 0; - TabStop = 8; + TabStop = DefaultTabStop; MessageLength = 0; NoRewriteMacros = 0; Pedantic = 0; Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=93288&r1=93287&r2=93288&view=diff ============================================================================== --- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original) +++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Tue Jan 12 21:06:50 2010 @@ -222,7 +222,7 @@ Res.push_back("-verify"); if (Opts.ShowOptionNames) Res.push_back("-fdiagnostics-show-option"); - if (Opts.TabStop != 8) { + if (Opts.TabStop != DiagnosticOptions::DefaultTabStop) { Res.push_back("-ftabstop"); Res.push_back(llvm::utostr(Opts.TabStop)); } @@ -808,7 +808,13 @@ Opts.ShowOptionNames = Args.hasArg(OPT_fdiagnostics_show_option); Opts.ShowSourceRanges = Args.hasArg(OPT_fdiagnostics_print_source_range_info); Opts.VerifyDiagnostics = Args.hasArg(OPT_verify); - Opts.TabStop = getLastArgIntValue(Args, OPT_ftabstop, 8, Diags); + Opts.TabStop = getLastArgIntValue(Args, OPT_ftabstop, + DiagnosticOptions::DefaultTabStop, Diags); + if (Opts.TabStop == 0 || Opts.TabStop > DiagnosticOptions::MaxTabStop) { + Diags.Report(diag::warn_ignoring_ftabstop_value) + << Opts.TabStop << DiagnosticOptions::DefaultTabStop; + Opts.TabStop = DiagnosticOptions::DefaultTabStop; + } Opts.MessageLength = getLastArgIntValue(Args, OPT_fmessage_length, 0, Diags); Opts.DumpBuildInformation = getLastArgValue(Args, OPT_dump_build_information); Opts.Warnings = getAllArgValues(Args, OPT_W); Modified: cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp?rev=93288&r1=93287&r2=93288&view=diff ============================================================================== --- cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp (original) +++ cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp Tue Jan 12 21:06:50 2010 @@ -371,15 +371,17 @@ CaretLine.push_back('^'); // Scan the source line, looking for tabs. If we find any, manually expand - // them to 8 characters and update the CaretLine to match. + // them to spaces and update the CaretLine to match. for (unsigned i = 0; i != SourceLine.size(); ++i) { if (SourceLine[i] != '\t') continue; // Replace this tab with at least one space. SourceLine[i] = ' '; - unsigned TabStop = DiagOpts->TabStop > 0 ? DiagOpts->TabStop : 8; // Compute the number of spaces we need to insert. + unsigned TabStop = DiagOpts->TabStop; + assert(0 < TabStop && TabStop <= DiagnosticOptions::MaxTabStop && + "Invalid -ftabstop value"); unsigned NumSpaces = ((i+TabStop)/TabStop * TabStop) - (i+1); assert(NumSpaces < TabStop && "Invalid computation of space amt"); From clattner at apple.com Tue Jan 12 21:07:00 2010 From: clattner at apple.com (Chris Lattner) Date: Tue, 12 Jan 2010 19:07:00 -0800 Subject: [cfe-commits] [PATCH] -ftabstop In-Reply-To: <199d10ce1001121530t1f7a9760p13d4c5bd2dc06278@mail.gmail.com> References: <199d10ce1001051444q7788750dw2b63291ab9c6d7ff@mail.gmail.com> <35C064DB-70A1-4190-8A6D-E350C2067CAE@apple.com> <199d10ce1001101223w2849c906h974b545a0e9ec642@mail.gmail.com> <3D9C1A3C-1DB8-478E-959E-FB4B357509FE@apple.com> <199d10ce1001121530t1f7a9760p13d4c5bd2dc06278@mail.gmail.com> Message-ID: <9D81D646-891C-4F8A-A619-25D76F86CC90@apple.com> On Jan 12, 2010, at 3:30 PM, Christian Ad?ker wrote: > On Tue, Jan 12, 2010 at 11:07 PM, Chris Lattner wrote: >> I think the driver should produce a warning on -ftabstop=0 or >> -ftabstop=10231231, not just silently ignore the error. What do you think? > > Of course it should. Especially now when I noticed a Diagnostic object > was so readily available. :) Fixed. > > I also noticed that code modification hints are not printed properly > around tabs. I'll fix those as well. Nice, applied as r93288, thanks! -Chris From rjmccall at apple.com Wed Jan 13 00:44:51 2010 From: rjmccall at apple.com (John McCall) Date: Wed, 13 Jan 2010 06:44:51 -0000 Subject: [cfe-commits] r93299 - /cfe/trunk/utils/clang-completion-mode.el Message-ID: <201001130644.o0D6ipEV005011@zion.cs.uiuc.edu> Author: rjmccall Date: Wed Jan 13 00:44:51 2010 New Revision: 93299 URL: http://llvm.org/viewvc/llvm-project?rev=93299&view=rev Log: Insert clang-flags into the clang command. Currently it needs to be a list; future work should permit strings (by splitting them into a list o' strings). Modified: cfe/trunk/utils/clang-completion-mode.el Modified: cfe/trunk/utils/clang-completion-mode.el URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/clang-completion-mode.el?rev=93299&r1=93298&r2=93299&view=diff ============================================================================== --- cfe/trunk/utils/clang-completion-mode.el (original) +++ cfe/trunk/utils/clang-completion-mode.el Wed Jan 13 00:44:51 2010 @@ -144,12 +144,21 @@ )))) (defun clang-complete () - (let ((ccstring (concat (buffer-file-name) - ":" - (number-to-string (+ 1 (current-line))) - ":" - (number-to-string (+ 1 (current-column))))) - (cc-buffer-name (concat "*Clang Completion for " (buffer-name) "*"))) + (let* ((cc-point (concat (buffer-file-name) + ":" + (number-to-string (+ 1 (current-line))) + ":" + (number-to-string (+ 1 (current-column))))) + (cc-pch (if (equal clang-completion-prefix-header "") nil + (list "-include-pch" + (concat clang-completion-prefix-header ".pch")))) + (cc-flags (if (listp clang-flags) clang-flags nil)) + (cc-command (append `(,clang "-cc1" "-fsyntax-only") + cc-flags + cc-pch + `("-code-completion-at" ,cc-point) + (list (buffer-file-name)))) + (cc-buffer-name (concat "*Clang Completion for " (buffer-name) "*"))) ;; Start the code-completion process (if (buffer-file-name) (progn @@ -162,18 +171,9 @@ (setq clang-result-string "") (setq clang-completion-buffer cc-buffer-name) - (let ((cc-proc - (if (equal clang-completion-prefix-header "") - (start-process "Clang Code-Completion" cc-buffer-name - clang "-cc1" "-fsyntax-only" - "-code-completion-at" ccstring - (buffer-file-name)) - (start-process "Clang Code-Completion" cc-buffer-name - clang "-cc1" "-fsyntax-only" - "-code-completion-at" ccstring - "-include-pch" - (concat clang-completion-prefix-header ".pch") - (buffer-file-name))))) + (let ((cc-proc (apply 'start-process + (append (list "Clang Code-Completion" cc-buffer-name) + cc-command)))) (set-process-filter cc-proc 'clang-completion-stash-filter) (set-process-sentinel cc-proc 'clang-completion-sentinel) ))))) From rideau3 at gmail.com Wed Jan 13 02:31:50 2010 From: rideau3 at gmail.com (Sean Hunt) Date: Wed, 13 Jan 2010 08:31:50 -0000 Subject: [cfe-commits] r93312 - in /cfe/trunk: docs/LanguageExtensions.html lib/Lex/PPMacroExpansion.cpp test/Lexer/has_feature_cxx0x.cpp Message-ID: <201001130831.o0D8VoKK009005@zion.cs.uiuc.edu> Author: coppro Date: Wed Jan 13 02:31:49 2010 New Revision: 93312 URL: http://llvm.org/viewvc/llvm-project?rev=93312&view=rev Log: Add a bunch more feature-checking macros for C++0x features. Some of these are disabled with the intent that users can start with them now and not have to change a thing to have them work when we implement the features. Added: cfe/trunk/test/Lexer/has_feature_cxx0x.cpp Modified: cfe/trunk/docs/LanguageExtensions.html cfe/trunk/lib/Lex/PPMacroExpansion.cpp Modified: cfe/trunk/docs/LanguageExtensions.html URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.html?rev=93312&r1=93311&r2=93312&view=diff ============================================================================== --- cfe/trunk/docs/LanguageExtensions.html (original) +++ cfe/trunk/docs/LanguageExtensions.html Wed Jan 13 02:31:49 2010 @@ -28,6 +28,19 @@
  • C++ exceptions
  • C++ RTTI
  • +
  • Checks for Upcoming Standard Language Features
  • +
  • Blocks
  • Function Overloading in C
  • Builtin Functions @@ -216,6 +229,70 @@ compiling code with -fno-rtti disables the use of RTTI.

    +

    Checks for Upcoming Standard Language Features

    + + +

    The __has_feature macro can be used to query if certain upcoming +standard language features are enabled. Those features are listed here.

    + +

    Currently, all features listed here are slated for inclusion in the upcoming +C++0x standard. As a result, all the features that clang supports are enabled +with the -std=c++0x option when compiling C++ code. Features that are +not yet implemented will be noted.

    + +

    C++0x decltype()

    + +

    Use __has_feature(cxx_decltype) to determine if support for the +decltype() specifier is enabled.

    + +

    C++0x attributes

    + +

    Use __has_feature(cxx_attributes) to determine if support for +attribute parsing with C++0x's square bracket notation is enabled. + +

    C++0x deleted functions

    + +

    Use __has_feature(cxx_deleted_functions) to determine if support for +deleted function definitions (with = delete) is enabled. + +

    C++ TR concepts

    + +

    Use __has_feature(cxx_lambdas) to determine if support for +concepts is enabled. clang does not currently implement this feature. + +

    C++0x nullptr

    + +

    Use __has_feature(cxx_lambdas) to determine if support for +lambdas is enabled. clang does not currently implement this feature. + +

    C++0x nullptr

    + +

    Use __has_feature(cxx_nullptr) to determine if support for +nullptr is enabled. clang does not yet fully implement this feature. + +

    C++0x rvalue references

    + +

    Use __has_feature(cxx_rvalue_references) to determine if support for +rvalue references is enabled. clang does not yet fully implement this feature. + +

    C++0x static_assert()

    + +

    Use __has_feature(cxx_static_assert) to determine if support for +compile-time assertions using static_assert is enabled.

    + +

    C++0x type inference

    + +

    Use __has_feature(cxx_auto_type) to determine C++0x type inference +is supported using the auto specifier. If this is disabled, +auto will instead be a storage class specifier, as in C or C++98.

    + +

    C++0x variadic templates

    + +

    Use __has_feature(cxx_variadic_templates) to determine if support +for templates taking any number of arguments with the ellipsis notation is +enabled. clang does not yet fully implement this feature.

    + +

    Blocks

    Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=93312&r1=93311&r2=93312&view=diff ============================================================================== --- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original) +++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Wed Jan 13 02:31:49 2010 @@ -485,9 +485,19 @@ return llvm::StringSwitch(II->getName()) .Case("blocks", LangOpts.Blocks) .Case("cxx_rtti", LangOpts.RTTI) + //.Case("cxx_lambdas", false) + //.Case("cxx_nullptr", false) + //.Case("cxx_concepts", false) + .Case("cxx_decltype", LangOpts.CPlusPlus0x) + .Case("cxx_auto_type", LangOpts.CPlusPlus0x) .Case("cxx_exceptions", LangOpts.Exceptions) + .Case("cxx_attributes", LangOpts.CPlusPlus0x) + .Case("cxx_static_assert", LangOpts.CPlusPlus0x) .Case("objc_nonfragile_abi", LangOpts.ObjCNonFragileABI) + .Case("cxx_deleted_functions", LangOpts.CPlusPlus0x) + //.Case("cxx_rvalue_references", false) .Case("attribute_overloadable", true) + //.Case("cxx_variadic_templates", false) .Case("attribute_ext_vector_type", true) .Case("attribute_analyzer_noreturn", true) .Case("attribute_ns_returns_retained", true) Added: cfe/trunk/test/Lexer/has_feature_cxx0x.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/has_feature_cxx0x.cpp?rev=93312&view=auto ============================================================================== --- cfe/trunk/test/Lexer/has_feature_cxx0x.cpp (added) +++ cfe/trunk/test/Lexer/has_feature_cxx0x.cpp Wed Jan 13 02:31:49 2010 @@ -0,0 +1,101 @@ +// RUN: %clang -E -std=c++0x %s -o - | FileCheck --check-prefix=CHECK-0X %s +// RUN: %clang -E %s -o - | FileCheck --check-prefix=CHECK-NO-0X %s + +#if __has_feature(cxx_lambdas) +int lambdas(); +#else +int no_lambdas(); +#endif + +// CHECK-0X: no_lambdas +// CHECK-NO-0X: no_lambdas + + +#if __has_feature(cxx_nullptr) +int nullptr(); +#else +int no_nullptr(); +#endif + +// CHECK-0X: no_nullptr +// CHECK-NO-0X: no_nullptr + + +#if __has_feature(cxx_concepts) +int concepts(); +#else +int no_concepts(); +#endif + +// CHECK-0X: no_concepts +// CHECK-NO-0X: no_concepts + + +#if __has_feature(cxx_decltype) +int decltype(); +#else +int no_decltype(); +#endif + +// CHECK-0X: decltype +// CHECK-NO-0X: no_decltype + + +#if __has_feature(cxx_auto_type) +int auto_type(); +#else +int no_auto_type(); +#endif + +// CHECK-0X: auto_type +// CHECK-NO-0X: no_auto_type + + +#if __has_feature(cxx_attributes) +int attributes(); +#else +int no_attributes(); +#endif + +// CHECK-0X: attributes +// CHECK-NO-0X: no_attributes + + +#if __has_feature(cxx_static_assert) +int static_assert(); +#else +int no_static_assert(); +#endif + +// CHECK-0X: static_assert +// CHECK-NO-0X: no_static_assert + + +#if __has_feature(cxx_deleted_functions) +int deleted_functions(); +#else +int no_deleted_functions(); +#endif + +// CHECK-0X: deleted_functions +// CHECK-NO-0X: no_deleted_functions + + +#if __has_feature(cxx_rvalue_references) +int rvalue_references(); +#else +int no_rvalue_references(); +#endif + +// CHECK-0X: no_rvalue_references +// CHECK-NO-0X: no_rvalue_references + + +#if __has_feature(cxx_variadic_templates) +int variadic_templates(); +#else +int no_variadic_templates(); +#endif + +// CHECK-0X: no_variadic_templates +// CHECK-NO-0X: no_variadic_templates From sebastian.redl at getdesigned.at Wed Jan 13 02:44:43 2010 From: sebastian.redl at getdesigned.at (Sebastian Redl) Date: Wed, 13 Jan 2010 09:44:43 +0100 Subject: [cfe-commits] =?utf-8?q?r93312_-_in_/cfe/trunk=3A_docs/LanguageEx?= =?utf-8?q?tensions=2Ehtml__lib/Lex/PPMacroExpansion=2Ecpp_test/Lexer/has?= =?utf-8?q?=5Ffeature=5Fcxx0x__=2Ecpp?= In-Reply-To: <201001130831.o0D8VoKK009005@zion.cs.uiuc.edu> References: <201001130831.o0D8VoKK009005@zion.cs.uiuc.edu> Message-ID: On Wed, 13 Jan 2010 08:31:50 -0000, Sean Hunt wrote: > Author: coppro > Date: Wed Jan 13 02:31:49 2010 > New Revision: 93312 > > URL: http://llvm.org/viewvc/llvm-project?rev=93312&view=rev > Log: > Add a bunch more feature-checking macros for C++0x features. Some of these > are > disabled with the intent that users can start with them now and not have > to change > a thing to have them work when we implement the features. > > ============================================================================== > --- cfe/trunk/docs/LanguageExtensions.html (original) > +++ cfe/trunk/docs/LanguageExtensions.html Wed Jan 13 02:31:49 2010 > + > +

    C++ TR concepts

    > + > +

    Use __has_feature(cxx_lambdas) to determine if support for __has_feature(cxx_concepts) > ============================================================================== > --- cfe/trunk/test/Lexer/has_feature_cxx0x.cpp (added) > +++ cfe/trunk/test/Lexer/has_feature_cxx0x.cpp Wed Jan 13 02:31:49 2010 > @@ -0,0 +1,101 @@ > +// RUN: %clang -E -std=c++0x %s -o - | FileCheck --check-prefix=CHECK-0X > %s > +// RUN: %clang -E %s -o - | FileCheck --check-prefix=CHECK-NO-0X %s > + > +#if __has_feature(cxx_lambdas) > +int lambdas(); > +#else > +int no_lambdas(); > +#endif > + > +// CHECK-0X: no_lambdas > +// CHECK-NO-0X: no_lambdas > + > + > +#if __has_feature(cxx_nullptr) > +int nullptr(); It's probably not a good idea to use the keyword nullptr in the path that expects it to exist. Even though this will only get preprocessed, it still looks wrong. > + > +#if __has_feature(cxx_decltype) > +int decltype(); Same here. > + > +#if __has_feature(cxx_static_assert) > +int static_assert(); And here. From rideau3 at gmail.com Wed Jan 13 02:58:42 2010 From: rideau3 at gmail.com (Sean Hunt) Date: Wed, 13 Jan 2010 08:58:42 -0000 Subject: [cfe-commits] r93314 - /cfe/trunk/test/Lexer/has_feature_cxx0x.cpp Message-ID: <201001130858.o0D8whJG016150@zion.cs.uiuc.edu> Author: coppro Date: Wed Jan 13 02:58:42 2010 New Revision: 93314 URL: http://llvm.org/viewvc/llvm-project?rev=93314&view=rev Log: Update test function names so as not to use potential keywords. Modified: cfe/trunk/test/Lexer/has_feature_cxx0x.cpp Modified: cfe/trunk/test/Lexer/has_feature_cxx0x.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/has_feature_cxx0x.cpp?rev=93314&r1=93313&r2=93314&view=diff ============================================================================== --- cfe/trunk/test/Lexer/has_feature_cxx0x.cpp (original) +++ cfe/trunk/test/Lexer/has_feature_cxx0x.cpp Wed Jan 13 02:58:42 2010 @@ -12,7 +12,7 @@ #if __has_feature(cxx_nullptr) -int nullptr(); +int has_nullptr(); #else int no_nullptr(); #endif @@ -32,12 +32,12 @@ #if __has_feature(cxx_decltype) -int decltype(); +int has_decltype(); #else int no_decltype(); #endif -// CHECK-0X: decltype +// CHECK-0X: has_decltype // CHECK-NO-0X: no_decltype @@ -62,12 +62,12 @@ #if __has_feature(cxx_static_assert) -int static_assert(); +int has_static_assert(); #else int no_static_assert(); #endif -// CHECK-0X: static_assert +// CHECK-0X: has_static_assert // CHECK-NO-0X: no_static_assert From rideau3 at gmail.com Wed Jan 13 03:01:03 2010 From: rideau3 at gmail.com (Sean Hunt) Date: Wed, 13 Jan 2010 09:01:03 -0000 Subject: [cfe-commits] r93315 - in /cfe/trunk: include/clang/AST/Decl.h include/clang/AST/DeclarationName.h include/clang/Basic/DiagnosticSemaKinds.td lib/AST/Decl.cpp lib/AST/DeclarationName.cpp lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp test/Parser/cxx0x-literal-operators.cpp test/SemaCXX/literal-operators.cpp Message-ID: <201001130901.o0D914NE016881@zion.cs.uiuc.edu> Author: coppro Date: Wed Jan 13 03:01:02 2010 New Revision: 93315 URL: http://llvm.org/viewvc/llvm-project?rev=93315&view=rev Log: Implement semantic checking for C++ literal operators. This now rejects literal operators that don't meet the requirements. Templates are not yet checked for. Added: cfe/trunk/test/SemaCXX/literal-operators.cpp Modified: cfe/trunk/include/clang/AST/Decl.h cfe/trunk/include/clang/AST/DeclarationName.h cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/AST/Decl.cpp cfe/trunk/lib/AST/DeclarationName.cpp cfe/trunk/lib/Sema/Sema.h cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/lib/Sema/SemaDeclCXX.cpp cfe/trunk/test/Parser/cxx0x-literal-operators.cpp Modified: cfe/trunk/include/clang/AST/Decl.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=93315&r1=93314&r2=93315&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/Decl.h (original) +++ cfe/trunk/include/clang/AST/Decl.h Wed Jan 13 03:01:02 2010 @@ -1184,6 +1184,8 @@ OverloadedOperatorKind getOverloadedOperator() const; + const IdentifierInfo *getLiteralIdentifier() const; + /// \brief If this function is an instantiation of a member function /// of a class template specialization, retrieves the function from /// which it was instantiated. Modified: cfe/trunk/include/clang/AST/DeclarationName.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclarationName.h?rev=93315&r1=93314&r2=93315&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/DeclarationName.h (original) +++ cfe/trunk/include/clang/AST/DeclarationName.h Wed Jan 13 03:01:02 2010 @@ -309,6 +309,7 @@ class DeclarationNameTable { void *CXXSpecialNamesImpl; // Actually a FoldingSet * CXXOperatorIdName *CXXOperatorNames; // Operator names + void *CXXLiteralOperatorNames; // Actually a FoldingSet<...> * DeclarationNameTable(const DeclarationNameTable&); // NONCOPYABLE DeclarationNameTable& operator=(const DeclarationNameTable&); // NONCOPYABLE Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=93315&r1=93314&r2=93315&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Jan 13 03:01:02 2010 @@ -2341,6 +2341,13 @@ def err_operator_delete_param_type : Error< "%0 takes type %1 as first parameter">; +// C++ literal operators +def err_literal_operator_outside_namespace : Error< + "literal operator %0 must be in a namespace or global scope">; +// FIXME: This diagnostic sucks +def err_literal_operator_params : Error< + "parameter declaration for literal operator %0 is not valid">; + // C++ conversion functions def err_conv_function_not_member : Error< "conversion function must be a non-static member function">; Modified: cfe/trunk/lib/AST/Decl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=93315&r1=93314&r2=93315&view=diff ============================================================================== --- cfe/trunk/lib/AST/Decl.cpp (original) +++ cfe/trunk/lib/AST/Decl.cpp Wed Jan 13 03:01:02 2010 @@ -1039,6 +1039,15 @@ return OO_None; } +/// getLiteralIdentifier - The literal suffix identifier this function +/// represents, if any. +const IdentifierInfo *FunctionDecl::getLiteralIdentifier() const { + if (getDeclName().getNameKind() == DeclarationName::CXXLiteralOperatorName) + return getDeclName().getCXXLiteralIdentifier(); + else + return 0; +} + FunctionDecl *FunctionDecl::getInstantiatedFromMemberFunction() const { if (MemberSpecializationInfo *Info = getMemberSpecializationInfo()) return cast(Info->getInstantiatedFrom()); Modified: cfe/trunk/lib/AST/DeclarationName.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclarationName.cpp?rev=93315&r1=93314&r2=93315&view=diff ============================================================================== --- cfe/trunk/lib/AST/DeclarationName.cpp (original) +++ cfe/trunk/lib/AST/DeclarationName.cpp Wed Jan 13 03:01:02 2010 @@ -56,9 +56,14 @@ /// This identifier is stored here rather than directly in DeclarationName so as /// to allow Objective-C selectors, which are about a million times more common, /// to consume minimal memory. -class CXXLiteralOperatorIdName : public DeclarationNameExtra { +class CXXLiteralOperatorIdName + : public DeclarationNameExtra, public llvm::FoldingSetNode { public: IdentifierInfo *ID; + + void Profile(llvm::FoldingSetNodeID &FSID) { + FSID.AddPointer(ID); + } }; bool operator<(DeclarationName LHS, DeclarationName RHS) { @@ -358,6 +363,7 @@ DeclarationNameTable::DeclarationNameTable() { CXXSpecialNamesImpl = new llvm::FoldingSet; + CXXLiteralOperatorNames = new llvm::FoldingSet; // Initialize the overloaded operator names. CXXOperatorNames = new CXXOperatorIdName[NUM_OVERLOADED_OPERATORS]; @@ -369,16 +375,30 @@ } DeclarationNameTable::~DeclarationNameTable() { - llvm::FoldingSet *set = + llvm::FoldingSet *SpecialNames = static_cast*>(CXXSpecialNamesImpl); - llvm::FoldingSetIterator I = set->begin(), E = set->end(); + llvm::FoldingSetIterator + SI = SpecialNames->begin(), SE = SpecialNames->end(); + + while (SI != SE) { + CXXSpecialName *n = &*SI++; + delete n; + } + + + llvm::FoldingSet *LiteralNames + = static_cast*> + (CXXLiteralOperatorNames); + llvm::FoldingSetIterator + LI = LiteralNames->begin(), LE = LiteralNames->end(); - while (I != E) { - CXXSpecialName *n = &*I++; + while (LI != LE) { + CXXLiteralOperatorIdName *n = &*LI++; delete n; } - delete set; + delete SpecialNames; + delete LiteralNames; delete [] CXXOperatorNames; } @@ -433,9 +453,23 @@ DeclarationName DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) { + llvm::FoldingSet *LiteralNames + = static_cast*> + (CXXLiteralOperatorNames); + + llvm::FoldingSetNodeID ID; + ID.AddPointer(II); + + void *InsertPos = 0; + if (CXXLiteralOperatorIdName *Name = + LiteralNames->FindNodeOrInsertPos(ID, InsertPos)) + return DeclarationName (Name); + CXXLiteralOperatorIdName *LiteralName = new CXXLiteralOperatorIdName; LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator; LiteralName->ID = II; + + LiteralNames->InsertNode(LiteralName, InsertPos); return DeclarationName(LiteralName); } Modified: cfe/trunk/lib/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=93315&r1=93314&r2=93315&view=diff ============================================================================== --- cfe/trunk/lib/Sema/Sema.h (original) +++ cfe/trunk/lib/Sema/Sema.h Wed Jan 13 03:01:02 2010 @@ -2360,6 +2360,8 @@ bool CheckOverloadedOperatorDeclaration(FunctionDecl *FnDecl); + bool CheckLiteralOperatorDeclaration(FunctionDecl *FnDecl); + //===--------------------------------------------------------------------===// // C++ Templates [C++ 14] // Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=93315&r1=93314&r2=93315&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Jan 13 03:01:02 2010 @@ -3487,7 +3487,12 @@ if (NewFD->isOverloadedOperator() && CheckOverloadedOperatorDeclaration(NewFD)) return NewFD->setInvalidDecl(); - + + // Extra checking for C++0x literal operators (C++0x [over.literal]). + if (NewFD->getLiteralIdentifier() && + CheckLiteralOperatorDeclaration(NewFD)) + return NewFD->setInvalidDecl(); + // In C++, check default arguments now that we have merged decls. Unless // the lexical context is the class, because in this case this is done // during delayed parsing anyway. Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=93315&r1=93314&r2=93315&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Jan 13 03:01:02 2010 @@ -5006,6 +5006,88 @@ return false; } +/// CheckLiteralOperatorDeclaration - Check whether the declaration +/// of this literal operator function is well-formed. If so, returns +/// false; otherwise, emits appropriate diagnostics and returns true. +bool Sema::CheckLiteralOperatorDeclaration(FunctionDecl *FnDecl) { + DeclContext *DC = FnDecl->getDeclContext(); + Decl::Kind Kind = DC->getDeclKind(); + if (Kind != Decl::TranslationUnit && Kind != Decl::Namespace && + Kind != Decl::LinkageSpec) { + Diag(FnDecl->getLocation(), diag::err_literal_operator_outside_namespace) + << FnDecl->getDeclName(); + return true; + } + + bool Valid = false; + + // FIXME: Check for the one valid template signature + // template type operator "" name(); + + if (FunctionDecl::param_iterator Param = FnDecl->param_begin()) { + // Check the first parameter + QualType T = (*Param)->getType(); + + // unsigned long long int and long double are allowed, but only + // alone. + // We also allow any character type; their omission seems to be a bug + // in n3000 + if (Context.hasSameType(T, Context.UnsignedLongLongTy) || + Context.hasSameType(T, Context.LongDoubleTy) || + Context.hasSameType(T, Context.CharTy) || + Context.hasSameType(T, Context.WCharTy) || + Context.hasSameType(T, Context.Char16Ty) || + Context.hasSameType(T, Context.Char32Ty)) { + if (++Param == FnDecl->param_end()) + Valid = true; + goto FinishedParams; + } + + // Otherwise it must be a pointer to const; let's strip those. + const PointerType *PT = T->getAs(); + if (!PT) + goto FinishedParams; + T = PT->getPointeeType(); + if (!T.isConstQualified()) + goto FinishedParams; + T = T.getUnqualifiedType(); + + // Move on to the second parameter; + ++Param; + + // If there is no second parameter, the first must be a const char * + if (Param == FnDecl->param_end()) { + if (Context.hasSameType(T, Context.CharTy)) + Valid = true; + goto FinishedParams; + } + + // const char *, const wchar_t*, const char16_t*, and const char32_t* + // are allowed as the first parameter to a two-parameter function + if (!(Context.hasSameType(T, Context.CharTy) || + Context.hasSameType(T, Context.WCharTy) || + Context.hasSameType(T, Context.Char16Ty) || + Context.hasSameType(T, Context.Char32Ty))) + goto FinishedParams; + + // The second and final parameter must be an std::size_t + T = (*Param)->getType().getUnqualifiedType(); + if (Context.hasSameType(T, Context.getSizeType()) && + ++Param == FnDecl->param_end()) + Valid = true; + } + + // FIXME: This diagnostic is absolutely terrible. +FinishedParams: + if (!Valid) { + Diag(FnDecl->getLocation(), diag::err_literal_operator_params) + << FnDecl->getDeclName(); + return true; + } + + return false; +} + /// ActOnStartLinkageSpecification - Parsed the beginning of a C++ /// linkage specification, including the language and (if present) /// the '{'. ExternLoc is the location of the 'extern', LangLoc is Modified: cfe/trunk/test/Parser/cxx0x-literal-operators.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-literal-operators.cpp?rev=93315&r1=93314&r2=93315&view=diff ============================================================================== --- cfe/trunk/test/Parser/cxx0x-literal-operators.cpp (original) +++ cfe/trunk/test/Parser/cxx0x-literal-operators.cpp Wed Jan 13 03:01:02 2010 @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s -void operator "" (); // expected-error {{expected identifier}} -void operator "k" foo(); // expected-error {{string literal after 'operator' must be '""'}} -void operator "" tester (int); +void operator "" (const char *); // expected-error {{expected identifier}} +void operator "k" foo(const char *); // expected-error {{string literal after 'operator' must be '""'}} +void operator "" tester (const char *); Added: cfe/trunk/test/SemaCXX/literal-operators.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/literal-operators.cpp?rev=93315&view=auto ============================================================================== --- cfe/trunk/test/SemaCXX/literal-operators.cpp (added) +++ cfe/trunk/test/SemaCXX/literal-operators.cpp Wed Jan 13 03:01:02 2010 @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s + +#include + +struct tag { + void operator "" tag_bad (const char *); // expected-error {{literal operator 'operator "" tag_bad' must be in a namespace or global scope}} + friend void operator "" tag_good (const char *); +}; + +namespace ns { void operator "" ns_good (const char *); } + +// Check extern "C++" declarations +extern "C++" void operator "" extern_good (const char *); +extern "C++" { void operator "" extern_good (const char *); } + +void fn () { void operator "" fn_bad (const char *); } // expected-error {{literal operator 'operator "" fn_bad' must be in a namespace or global scope}} + +// One-param declarations (const char * was already checked) +void operator "" good (char); +void operator "" good (wchar_t); +void operator "" good (char16_t); +void operator "" good (char32_t); +void operator "" good (unsigned long long); +void operator "" good (long double); + +// Two-param declarations +void operator "" good (const char *, size_t); +void operator "" good (const wchar_t *, size_t); +void operator "" good (const char16_t *, size_t); +void operator "" good (const char32_t *, size_t); + +// Check typedef and array equivalences +void operator "" good (const char[]); +typedef const char c; +void operator "" good (c*); + +// Check extra cv-qualifiers +void operator "" cv_good (volatile const char *, const size_t); + +// Template delcaration (not implemented yet) +// template void operator "" good (); + +// FIXME: Test some invalid decls that might crop up. From rjmccall at apple.com Wed Jan 13 03:16:55 2010 From: rjmccall at apple.com (John McCall) Date: Wed, 13 Jan 2010 09:16:55 -0000 Subject: [cfe-commits] r93316 - in /cfe/trunk: lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaOverload.cpp lib/Sema/SemaOverload.h test/SemaCXX/overload-call.cpp test/SemaCXX/overload-member-call.cpp Message-ID: <201001130916.o0D9GujW019908@zion.cs.uiuc.edu> Author: rjmccall Date: Wed Jan 13 03:16:55 2010 New Revision: 93316 URL: http://llvm.org/viewvc/llvm-project?rev=93316&view=rev Log: Record some basic information about bad conversion sequences. Use that information to feed diagnostics instead of regenerating it. Much room for improvement here, but fixes some unfortunate problems reporting on method calls. Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp cfe/trunk/lib/Sema/SemaExprCXX.cpp cfe/trunk/lib/Sema/SemaOverload.cpp cfe/trunk/lib/Sema/SemaOverload.h cfe/trunk/test/SemaCXX/overload-call.cpp cfe/trunk/test/SemaCXX/overload-member-call.cpp Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=93316&r1=93315&r2=93316&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Jan 13 03:16:55 2010 @@ -4389,7 +4389,10 @@ = CompareReferenceRelationship(DeclLoc, T1, T2, DerivedToBase); // Most paths end in a failed conversion. - if (ICS) ICS->setBad(); + if (ICS) { + ICS->setBad(); + ICS->Bad.init(BadConversionSequence::no_conversion, Init, DeclType); + } // C++ [dcl.init.ref]p5: // A reference to type "cv1 T1" is initialized by an expression Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=93316&r1=93315&r2=93316&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Jan 13 03:16:55 2010 @@ -1076,6 +1076,7 @@ bool Elidable, ImplicitConversionSequence& ICS) { ICS.setBad(); + ICS.Bad.init(BadConversionSequence::no_conversion, From, ToType); if (Elidable && getLangOptions().CPlusPlus0x) { ICS = TryImplicitConversion(From, ToType, /*SuppressUserConversions=*/false, @@ -1942,7 +1943,7 @@ ImplicitConversionSequence E1ToC2, E2ToC2; E1ToC2.setBad(); - E2ToC2.setBad(); + E2ToC2.setBad(); if (Context.getCanonicalType(Composite1) != Context.getCanonicalType(Composite2)) { E1ToC2 = TryImplicitConversion(E1, Composite2, Modified: cfe/trunk/lib/Sema/SemaOverload.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=93316&r1=93315&r2=93316&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOverload.cpp (original) +++ cfe/trunk/lib/Sema/SemaOverload.cpp Wed Jan 13 03:16:55 2010 @@ -489,8 +489,10 @@ // of a class copy-initialization, or by 13.3.1.4, 13.3.1.5, or // 13.3.1.6 in all cases, only standard conversion sequences and // ellipsis conversion sequences are allowed. - if (SuppressUserConversions && ICS.isUserDefined()) + if (SuppressUserConversions && ICS.isUserDefined()) { ICS.setBad(); + ICS.Bad.init(BadConversionSequence::suppressed_user, From, ToType); + } } else if (UserDefResult == OR_Ambiguous) { ICS.setAmbiguous(); ICS.Ambiguous.setFromType(From->getType()); @@ -501,6 +503,7 @@ ICS.Ambiguous.addConversion(Cand->Function); } else { ICS.setBad(); + ICS.Bad.init(BadConversionSequence::no_conversion, From, ToType); } return ICS; @@ -2129,6 +2132,7 @@ bool InOverloadResolution) { if (ToType->isReferenceType()) { ImplicitConversionSequence ICS; + ICS.Bad.init(BadConversionSequence::no_conversion, From, ToType); CheckReferenceInit(From, ToType, /*FIXME:*/From->getLocStart(), SuppressUserConversions, @@ -2223,8 +2227,10 @@ QualType FromTypeCanon = Context.getCanonicalType(FromType); if (ImplicitParamType.getCVRQualifiers() != FromTypeCanon.getLocalCVRQualifiers() && - !ImplicitParamType.isAtLeastAsQualifiedAs(FromTypeCanon)) + !ImplicitParamType.isAtLeastAsQualifiedAs(FromTypeCanon)) { + ICS.Bad.init(BadConversionSequence::bad_qualifiers, FromType, ImplicitParamType); return ICS; + } // Check that we have either the same type or a derived type. It // affects the conversion rank. @@ -2233,8 +2239,10 @@ ICS.Standard.Second = ICK_Identity; else if (IsDerivedFrom(FromType, ClassType)) ICS.Standard.Second = ICK_Derived_To_Base; - else + else { + ICS.Bad.init(BadConversionSequence::unrelated_class, FromType, ImplicitParamType); return ICS; + } // Success. Mark this as a reference binding. ICS.setStandard(); @@ -2385,6 +2393,7 @@ if ((NumArgs + (PartialOverloading && NumArgs)) > NumArgsInProto && !Proto->isVariadic()) { Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_too_many_arguments; return; } @@ -2397,6 +2406,7 @@ if (NumArgs < MinRequiredArgs && !PartialOverloading) { // Not enough arguments. Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_too_few_arguments; return; } @@ -2416,6 +2426,7 @@ /*InOverloadResolution=*/true); if (Candidate.Conversions[ArgIdx].isBad()) { Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_bad_conversion; break; } } else { @@ -2532,6 +2543,7 @@ // list (8.3.5). if (NumArgs > NumArgsInProto && !Proto->isVariadic()) { Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_too_many_arguments; return; } @@ -2544,6 +2556,7 @@ if (NumArgs < MinRequiredArgs) { // Not enough arguments. Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_too_few_arguments; return; } @@ -2560,6 +2573,7 @@ = TryObjectArgumentInitialization(ObjectType, Method, ActingContext); if (Candidate.Conversions[0].isBad()) { Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_bad_conversion; return; } } @@ -2579,6 +2593,7 @@ /*InOverloadResolution=*/true); if (Candidate.Conversions[ArgIdx + 1].isBad()) { Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_bad_conversion; break; } } else { @@ -2670,6 +2685,7 @@ OverloadCandidate &Candidate = CandidateSet.back(); Candidate.Function = FunctionTemplate->getTemplatedDecl(); Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_bad_deduction; Candidate.IsSurrogate = false; Candidate.IgnoreObjectArgument = false; return; @@ -2726,6 +2742,7 @@ Candidate.Conversions[0].Standard.Second = ICK_Identity; if (Candidate.Conversions[0].isBad()) { Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_bad_conversion; return; } @@ -2737,6 +2754,7 @@ QualType ToCanon = Context.getCanonicalType(ToType).getUnqualifiedType(); if (FromCanon == ToCanon || IsDerivedFrom(FromCanon, ToCanon)) { Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_bad_conversion; return; } @@ -2774,6 +2792,7 @@ case ImplicitConversionSequence::BadConversion: Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_bad_conversion; break; default: @@ -2847,6 +2866,7 @@ = TryObjectArgumentInitialization(ObjectType, Conversion, ActingContext); if (ObjectInit.isBad()) { Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_bad_conversion; return; } @@ -2869,6 +2889,7 @@ // list (8.3.5). if (NumArgs > NumArgsInProto && !Proto->isVariadic()) { Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_too_many_arguments; return; } @@ -2877,6 +2898,7 @@ if (NumArgs < NumArgsInProto) { // Not enough arguments. Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_too_few_arguments; return; } @@ -2896,6 +2918,7 @@ /*InOverloadResolution=*/false); if (Candidate.Conversions[ArgIdx + 1].isBad()) { Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_bad_conversion; break; } } else { @@ -3038,6 +3061,7 @@ } if (Candidate.Conversions[ArgIdx].isBad()) { Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_bad_conversion; break; } } @@ -4336,36 +4360,69 @@ namespace { -void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, unsigned I, - Expr **Args, unsigned NumArgs) { +void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, unsigned I) { + const ImplicitConversionSequence &Conv = Cand->Conversions[I]; + assert(Conv.isBad()); assert(Cand->Function && "for now, candidate must be a function"); FunctionDecl *Fn = Cand->Function; // There's a conversion slot for the object argument if this is a // non-constructor method. Note that 'I' corresponds the // conversion-slot index. + bool isObjectArgument = false; if (isa(Fn) && !isa(Fn)) { - // FIXME: talk usefully about bad conversions for object arguments. - if (I == 0) return S.NoteOverloadCandidate(Fn); - else I--; + if (I == 0) + isObjectArgument = true; + else + I--; } - // FIXME: can we have a bad conversion on an ellipsis parameter? - assert(I < NumArgs && "index exceeds number of formal arguments"); - assert(I < Fn->getType()->getAs()->getNumArgs() && - "index exceeds number of formal parameters"); - std::string FnDesc; OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Fn, FnDesc); - QualType FromTy = Args[I]->getType(); - QualType ToTy = Fn->getType()->getAs()->getArgType(I); + Expr *FromExpr = Conv.Bad.FromExpr; + QualType FromTy = Conv.Bad.getFromType(); + QualType ToTy = Conv.Bad.getToType(); // TODO: specialize based on the kind of mismatch S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_conv) << (unsigned) FnKind << FnDesc - << Args[I]->getSourceRange() << FromTy << ToTy - << I+1; + << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) + << FromTy << ToTy << I+1; +} + +void DiagnoseArityMismatch(Sema &S, OverloadCandidate *Cand, + unsigned NumFormalArgs) { + // TODO: treat calls to a missing default constructor as a special case + + FunctionDecl *Fn = Cand->Function; + const FunctionProtoType *FnTy = Fn->getType()->getAs(); + + unsigned MinParams = Fn->getMinRequiredArguments(); + + // at least / at most / exactly + unsigned mode, modeCount; + if (NumFormalArgs < MinParams) { + assert(Cand->FailureKind == ovl_fail_too_few_arguments); + if (MinParams != FnTy->getNumArgs() || FnTy->isVariadic()) + mode = 0; // "at least" + else + mode = 2; // "exactly" + modeCount = MinParams; + } else { + assert(Cand->FailureKind == ovl_fail_too_many_arguments); + if (MinParams != FnTy->getNumArgs()) + mode = 1; // "at most" + else + mode = 2; // "exactly" + modeCount = FnTy->getNumArgs(); + } + + std::string Description; + OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Fn, Description); + + S.Diag(Fn->getLocation(), diag::note_ovl_candidate_arity) + << (unsigned) FnKind << Description << mode << modeCount << NumFormalArgs; } void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, @@ -4388,52 +4445,24 @@ return; } - // Diagnose arity mismatches. - // TODO: treat calls to a missing default constructor as a special case - unsigned NumFormalArgs = NumArgs; - if (isa(Fn) && !isa(Fn)) - NumFormalArgs--; - const FunctionProtoType *FnTy = Fn->getType()->getAs(); - unsigned MinParams = Fn->getMinRequiredArguments(); - if (NumFormalArgs < MinParams || - (NumFormalArgs > FnTy->getNumArgs() && !FnTy->isVariadic())) { - std::string Description; - OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Fn, Description); - - // at least / at most / exactly - unsigned mode, modeCount; - if (NumFormalArgs < MinParams) { - if (MinParams != FnTy->getNumArgs()) - mode = 0; // "at least" - else - mode = 2; // "exactly" - modeCount = MinParams; - } else { - if (MinParams != FnTy->getNumArgs()) - mode = 1; // "at most" - else - mode = 2; // "exactly" - modeCount = FnTy->getNumArgs(); - } - - S.Diag(Fn->getLocation(), diag::note_ovl_candidate_arity) - << (unsigned) FnKind << Description << mode << modeCount << NumFormalArgs; - return; - } - - // Look for bad conversions. - if (!Cand->Conversions.empty()) { - for (unsigned I = 0, N = Cand->Conversions.size(); I != N; ++I) { - if (!Cand->Conversions[I].isBad()) - continue; - - DiagnoseBadConversion(S, Cand, I, Args, NumArgs); - return; - } + switch (Cand->FailureKind) { + case ovl_fail_too_many_arguments: + case ovl_fail_too_few_arguments: + return DiagnoseArityMismatch(S, Cand, NumArgs); + + case ovl_fail_bad_deduction: + return S.NoteOverloadCandidate(Fn); + + case ovl_fail_bad_conversion: + for (unsigned I = 0, N = Cand->Conversions.size(); I != N; ++I) + if (Cand->Conversions[I].isBad()) + return DiagnoseBadConversion(S, Cand, I); + + // FIXME: this currently happens when we're called from SemaInit + // when user-conversion overload fails. Figure out how to handle + // those conditions and diagnose them well. + return S.NoteOverloadCandidate(Fn); } - - // Give up and give the generic message. - S.NoteOverloadCandidate(Fn); } void NoteSurrogateCandidate(Sema &S, OverloadCandidate *Cand) { Modified: cfe/trunk/lib/Sema/SemaOverload.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.h?rev=93316&r1=93315&r2=93316&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOverload.h (original) +++ cfe/trunk/lib/Sema/SemaOverload.h Wed Jan 13 03:16:55 2010 @@ -16,6 +16,7 @@ #define LLVM_CLANG_SEMA_OVERLOAD_H #include "clang/AST/Decl.h" +#include "clang/AST/Expr.h" #include "clang/AST/Type.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" @@ -241,6 +242,51 @@ void copyFrom(const AmbiguousConversionSequence &); }; + /// BadConversionSequence - Records information about an invalid + /// conversion sequence. + struct BadConversionSequence { + enum FailureKind { + no_conversion, + unrelated_class, + suppressed_user, + bad_qualifiers + }; + + // This can be null, e.g. for implicit object arguments. + Expr *FromExpr; + + FailureKind Kind; + + private: + // The type we're converting from (an opaque QualType). + void *FromTy; + + // The type we're converting to (an opaque QualType). + void *ToTy; + + public: + void init(FailureKind K, Expr *From, QualType To) { + init(K, From->getType(), To); + FromExpr = From; + } + void init(FailureKind K, QualType From, QualType To) { + Kind = K; + FromExpr = 0; + setFromType(From); + setToType(To); + } + + QualType getFromType() const { return QualType::getFromOpaquePtr(FromTy); } + QualType getToType() const { return QualType::getFromOpaquePtr(ToTy); } + + void setFromExpr(Expr *E) { + FromExpr = E; + setFromType(E->getType()); + } + void setFromType(QualType T) { FromTy = T.getAsOpaquePtr(); } + void setToType(QualType T) { ToTy = T.getAsOpaquePtr(); } + }; + /// ImplicitConversionSequence - Represents an implicit conversion /// sequence, which may be a standard conversion sequence /// (C++ 13.3.3.1.1), user-defined conversion sequence (C++ 13.3.3.1.2), @@ -280,6 +326,10 @@ /// When ConversionKind == AmbiguousConversion, provides the /// details of the ambiguous conversion. AmbiguousConversionSequence Ambiguous; + + /// When ConversionKind == BadConversion, provides the details + /// of the bad conversion. + BadConversionSequence Bad; }; ImplicitConversionSequence() : ConversionKind(BadConversion) {} @@ -294,7 +344,7 @@ case UserDefinedConversion: UserDefined = Other.UserDefined; break; case AmbiguousConversion: Ambiguous.copyFrom(Other.Ambiguous); break; case EllipsisConversion: break; - case BadConversion: break; + case BadConversion: Bad = Other.Bad; break; } } @@ -336,6 +386,13 @@ void DebugPrint() const; }; + enum OverloadFailureKind { + ovl_fail_too_many_arguments, + ovl_fail_too_few_arguments, + ovl_fail_bad_conversion, + ovl_fail_bad_deduction + }; + /// OverloadCandidate - A single candidate in an overload set (C++ 13.3). struct OverloadCandidate { /// Function - The actual function that this candidate @@ -376,6 +433,10 @@ /// object argument. bool IgnoreObjectArgument; + /// FailureKind - The reason why this candidate is not viable. + /// Actually an OverloadFailureKind. + unsigned char FailureKind; + /// FinalConversion - For a conversion function (where Function is /// a CXXConversionDecl), the standard conversion that occurs /// after the call to the overload candidate to convert the result Modified: cfe/trunk/test/SemaCXX/overload-call.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/overload-call.cpp?rev=93316&r1=93315&r2=93316&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/overload-call.cpp (original) +++ cfe/trunk/test/SemaCXX/overload-call.cpp Wed Jan 13 03:16:55 2010 @@ -304,10 +304,16 @@ // Tests the exact text used to note the candidates namespace test1 { - template void foo(T t, unsigned N); // expected-note {{candidate function [with T = int]}} - void foo(int n, char N); // expected-note {{candidate function}} + template void foo(T t, unsigned N); // expected-note {{candidate function [with T = int] not viable: no known conversion from 'char const [6]' to 'unsigned int' for argument 2}} + void foo(int n, char N); // expected-note {{candidate function not viable: no known conversion from 'char const [6]' to 'char' for argument 2}} + void foo(int n); // expected-note {{candidate function not viable: requires 1 argument, but 2 were provided}} + void foo(unsigned n = 10); // expected-note {{candidate function not viable: requires at most 1 argument, but 2 were provided}} + void foo(int n, const char *s, int t); // expected-note {{candidate function not viable: requires 3 arguments, but 2 were provided}} + void foo(int n, const char *s, int t, ...); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}} + void foo(int n, const char *s, int t, int u = 0); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}} void test() { foo(4, "hello"); //expected-error {{no matching function for call to 'foo'}} } } + Modified: cfe/trunk/test/SemaCXX/overload-member-call.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/overload-member-call.cpp?rev=93316&r1=93315&r2=93316&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/overload-member-call.cpp (original) +++ cfe/trunk/test/SemaCXX/overload-member-call.cpp Wed Jan 13 03:16:55 2010 @@ -66,3 +66,22 @@ int &ir = x2p->member(); float &fr = cx2p->member(); } + +// Tests the exact text used to note the candidates +namespace test1 { + class A { + template void foo(T t, unsigned N); // expected-note {{candidate function [with T = int] not viable: no known conversion from 'char const [6]' to 'unsigned int' for argument 2}} + void foo(int n, char N); // expected-note {{candidate function not viable: no known conversion from 'char const [6]' to 'char' for argument 2}} + void foo(int n); // expected-note {{candidate function not viable: requires 1 argument, but 2 were provided}} + void foo(unsigned n = 10); // expected-note {{candidate function not viable: requires at most 1 argument, but 2 were provided}} + void foo(int n, const char *s, int t); // expected-note {{candidate function not viable: requires 3 arguments, but 2 were provided}} + void foo(int n, const char *s, int t, ...); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}} + void foo(int n, const char *s, int t, int u = 0); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}} + }; + + void test() { + A a; + a.foo(4, "hello"); //expected-error {{no matching member function for call to 'foo'}} + } +} + From dgregor at apple.com Wed Jan 13 09:31:15 2010 From: dgregor at apple.com (Douglas Gregor) Date: Wed, 13 Jan 2010 07:31:15 -0800 Subject: [cfe-commits] r93312 - in /cfe/trunk: docs/LanguageExtensions.html lib/Lex/PPMacroExpansion.cpp test/Lexer/has_feature_cxx0x .cpp In-Reply-To: References: <201001130831.o0D8VoKK009005@zion.cs.uiuc.edu> Message-ID: <77EAF950-F5D5-470E-AAA3-8C8A47A51060@apple.com> On Jan 13, 2010, at 12:44 AM, Sebastian Redl wrote: > > On Wed, 13 Jan 2010 08:31:50 -0000, Sean Hunt wrote: >> Author: coppro >> Date: Wed Jan 13 02:31:49 2010 >> New Revision: 93312 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=93312&view=rev >> Log: >> Add a bunch more feature-checking macros for C++0x features. Some of > these >> are >> disabled with the intent that users can start with them now and not have >> to change >> a thing to have them work when we implement the features. >> >> > ============================================================================== >> --- cfe/trunk/docs/LanguageExtensions.html (original) >> +++ cfe/trunk/docs/LanguageExtensions.html Wed Jan 13 02:31:49 2010 >> + >> +

    C++ TR concepts

    >> + >> +

    Use __has_feature(cxx_lambdas) to determine if support for > > __has_feature(cxx_concepts) Concepts isn't in any working paper, and there isn't an actively-maintained implementation anywhere. It doesn't need a __has_feature check until one of those two things changes. - Doug From dgregor at apple.com Wed Jan 13 10:27:50 2010 From: dgregor at apple.com (Douglas Gregor) Date: Wed, 13 Jan 2010 16:27:50 -0000 Subject: [cfe-commits] r93320 - /cfe/trunk/docs/LanguageExtensions.html Message-ID: <201001131627.o0DGRoQm009451@zion.cs.uiuc.edu> Author: dgregor Date: Wed Jan 13 10:27:49 2010 New Revision: 93320 URL: http://llvm.org/viewvc/llvm-project?rev=93320&view=rev Log: Fix pasto in __has_feature(cxx_lambdas) docs Modified: cfe/trunk/docs/LanguageExtensions.html Modified: cfe/trunk/docs/LanguageExtensions.html URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.html?rev=93320&r1=93319&r2=93320&view=diff ============================================================================== --- cfe/trunk/docs/LanguageExtensions.html (original) +++ cfe/trunk/docs/LanguageExtensions.html Wed Jan 13 10:27:49 2010 @@ -260,7 +260,7 @@

    Use __has_feature(cxx_lambdas) to determine if support for concepts is enabled. clang does not currently implement this feature. -

    C++0x nullptr

    +

    C++0x lambdas

    Use __has_feature(cxx_lambdas) to determine if support for lambdas is enabled. clang does not currently implement this feature. From dgregor at apple.com Wed Jan 13 11:31:36 2010 From: dgregor at apple.com (Douglas Gregor) Date: Wed, 13 Jan 2010 17:31:36 -0000 Subject: [cfe-commits] r93322 - in /cfe/trunk: include/clang/Basic/DiagnosticParseKinds.td include/clang/Parse/DeclSpec.h include/clang/Parse/Parser.h lib/Parse/DeclSpec.cpp lib/Parse/ParseDecl.cpp lib/Parse/ParseExprCXX.cpp lib/Parse/ParseTemplate.cpp lib/Parse/Parser.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaType.cpp test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp test/CXX/special/class.ctor/p1.cpp test/SemaTemplate/injected-class-name.cpp test/SemaTemplate/instantiate-member-class.cpp Message-ID: <201001131731.o0DHVb1W011971@zion.cs.uiuc.edu> Author: dgregor Date: Wed Jan 13 11:31:36 2010 New Revision: 93322 URL: http://llvm.org/viewvc/llvm-project?rev=93322&view=rev Log: Reimplement constructor declarator parsing to cope with template-ids that name constructors, the endless joys of out-of-line constructor definitions, and various other corner cases that the previous hack never imagined. Fixes PR5688 and tightens up semantic analysis for constructor names. Additionally, fixed a problem where we wouldn't properly enter the declarator scope of a parenthesized declarator. We were entering the scope, then leaving it when we saw the ")"; now, we re-enter the declarator scope before parsing the parameter list. Note that we are forced to perform some tentative parsing within a class (call it C) to tell the difference between C(int); // constructor and C (f)(int); // member function which is rather unfortunate. And, although it isn't necessary for correctness, we use the same tentative-parsing mechanism for out-of-line constructors to improve diagnostics in icky cases like: C::C C::f(int); // error: C::C refers to the constructor name, but // we complain nicely and recover by treating it as // a type. Added: cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp (with props) cfe/trunk/test/CXX/special/class.ctor/p1.cpp (with props) Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td cfe/trunk/include/clang/Parse/DeclSpec.h cfe/trunk/include/clang/Parse/Parser.h cfe/trunk/lib/Parse/DeclSpec.cpp cfe/trunk/lib/Parse/ParseDecl.cpp cfe/trunk/lib/Parse/ParseExprCXX.cpp cfe/trunk/lib/Parse/ParseTemplate.cpp cfe/trunk/lib/Parse/Parser.cpp cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/lib/Sema/SemaDeclCXX.cpp cfe/trunk/lib/Sema/SemaType.cpp cfe/trunk/test/SemaTemplate/injected-class-name.cpp cfe/trunk/test/SemaTemplate/instantiate-member-class.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=93322&r1=93321&r2=93322&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Wed Jan 13 11:31:36 2010 @@ -291,6 +291,16 @@ "definition is meant to be an explicit specialization, add '<>' after the " "'template' keyword">; +// Constructor template diagnostics. +def err_out_of_line_constructor_template_id : Error< + "out-of-line constructor for %0 cannot have template arguments">; +def err_out_of_line_template_id_names_constructor : Error< + "qualified reference to %0 is a constructor name rather than a " + "template name wherever a constructor can be declared">; +def err_out_of_line_type_names_constructor : Error< + "qualified reference to %0 is a constructor name rather than a " + "type wherever a constructor can be declared">; + def err_expected_qualified_after_typename : Error< "expected a qualified name after 'typename'">; def err_typename_refers_to_non_type_template : Error< Modified: cfe/trunk/include/clang/Parse/DeclSpec.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/DeclSpec.h?rev=93322&r1=93321&r2=93322&view=diff ============================================================================== --- cfe/trunk/include/clang/Parse/DeclSpec.h (original) +++ cfe/trunk/include/clang/Parse/DeclSpec.h Wed Jan 13 11:31:36 2010 @@ -493,6 +493,8 @@ IK_LiteralOperatorId, /// \brief A constructor name. IK_ConstructorName, + /// \brief A constructor named via a template-id. + IK_ConstructorTemplateId, /// \brief A destructor name. IK_DestructorName, /// \brief A template-id, e.g., f. @@ -534,8 +536,9 @@ /// class-name. ActionBase::TypeTy *DestructorName; - /// \brief When Kind == IK_TemplateId, the template-id annotation that - /// contains the template name and template arguments. + /// \brief When Kind == IK_TemplateId or IK_ConstructorTemplateId, + /// the template-id annotation that contains the template name and + /// template arguments. TemplateIdAnnotation *TemplateId; }; @@ -648,6 +651,14 @@ ConstructorName = ClassType; } + /// \brief Specify that this unqualified-id was parsed as a + /// template-id that names a constructor. + /// + /// \param TemplateId the template-id annotation that describes the parsed + /// template-id. This UnqualifiedId instance will take ownership of the + /// \p TemplateId and will free it on destruction. + void setConstructorTemplateId(TemplateIdAnnotation *TemplateId); + /// \brief Specify that this unqualified-id was parsed as a destructor name. /// /// \param TildeLoc the location of the '~' that introduces the destructor Modified: cfe/trunk/include/clang/Parse/Parser.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=93322&r1=93321&r2=93322&view=diff ============================================================================== --- cfe/trunk/include/clang/Parse/Parser.h (original) +++ cfe/trunk/include/clang/Parse/Parser.h Wed Jan 13 11:31:36 2010 @@ -1037,7 +1037,8 @@ /// would be best implemented in the parser. enum DeclSpecContext { DSC_normal, // normal context - DSC_class // class context, enables 'friend' + DSC_class, // class context, enables 'friend' + DSC_top_level // top-level/namespace declaration context }; DeclGroupPtrTy ParseDeclaration(unsigned Context, SourceLocation &DeclEnd, @@ -1056,6 +1057,7 @@ bool ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS, const ParsedTemplateInfo &TemplateInfo, AccessSpecifier AS); + DeclSpecContext getDeclSpecContextFromDeclaratorContext(unsigned Context); void ParseDeclarationSpecifiers(DeclSpec &DS, const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(), AccessSpecifier AS = AS_none, @@ -1109,6 +1111,11 @@ return isDeclarationSpecifier(); } + /// \brief Starting with a scope specifier, identifier, or + /// template-id that refers to the current class, determine whether + /// this is a constructor declarator. + bool isConstructorDeclarator(); + /// \brief Specifies the context in which type-id/expression /// disambiguation will occur. enum TentativeCXXTypeIdContext { Modified: cfe/trunk/lib/Parse/DeclSpec.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/DeclSpec.cpp?rev=93322&r1=93321&r2=93322&view=diff ============================================================================== --- cfe/trunk/lib/Parse/DeclSpec.cpp (original) +++ cfe/trunk/lib/Parse/DeclSpec.cpp Wed Jan 13 11:31:36 2010 @@ -36,6 +36,14 @@ EndLocation = TemplateId->RAngleLoc; } +void UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) { + assert(TemplateId && "NULL template-id annotation?"); + Kind = IK_ConstructorTemplateId; + this->TemplateId = TemplateId; + StartLocation = TemplateId->TemplateNameLoc; + EndLocation = TemplateId->RAngleLoc; +} + /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function. /// "TheDeclarator" is the declarator that this will be added to. DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic, Modified: cfe/trunk/lib/Parse/ParseDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=93322&r1=93321&r2=93322&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseDecl.cpp (original) +++ cfe/trunk/lib/Parse/ParseDecl.cpp Wed Jan 13 11:31:36 2010 @@ -356,7 +356,8 @@ ParsingDeclSpec DS(*this); if (Attr) DS.AddAttributes(Attr); - ParseDeclarationSpecifiers(DS); + ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none, + getDeclSpecContextFromDeclaratorContext(Context)); // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };" // declaration-specifiers init-declarator-list[opt] ';' @@ -786,6 +787,20 @@ return false; } +/// \brief Determine the declaration specifier context from the declarator +/// context. +/// +/// \param Context the declarator context, which is one of the +/// Declarator::TheContext enumerator values. +Parser::DeclSpecContext +Parser::getDeclSpecContextFromDeclaratorContext(unsigned Context) { + if (Context == Declarator::MemberContext) + return DSC_class; + if (Context == Declarator::FileContext) + return DSC_top_level; + return DSC_normal; +} + /// ParseDeclarationSpecifiers /// declaration-specifiers: [C99 6.7] /// storage-class-specifier declaration-specifiers[opt] @@ -861,6 +876,47 @@ static_cast(Next.getAnnotationValue()) ->Kind == TNK_Type_template) { // We have a qualified template-id, e.g., N::A + + // C++ [class.qual]p2: + // In a lookup in which the constructor is an acceptable lookup + // result and the nested-name-specifier nominates a class C: + // + // - if the name specified after the + // nested-name-specifier, when looked up in C, is the + // injected-class-name of C (Clause 9), or + // + // - if the name specified after the nested-name-specifier + // is the same as the identifier or the + // simple-template-id's template-name in the last + // component of the nested-name-specifier, + // + // the name is instead considered to name the constructor of + // class C. + // + // Thus, if the template-name is actually the constructor + // name, then the code is ill-formed; this interpretation is + // reinforced by the NAD status of core issue 635. + TemplateIdAnnotation *TemplateId + = static_cast(Next.getAnnotationValue()); + if (DSContext == DSC_top_level && TemplateId->Name && + Actions.isCurrentClassName(*TemplateId->Name, CurScope, &SS)) { + if (isConstructorDeclarator()) { + // The user meant this to be an out-of-line constructor + // definition, but template arguments are not allowed + // there. Just allow this as a constructor; we'll + // complain about it later. + goto DoneWithDeclSpec; + } + + // The user meant this to name a type, but it actually names + // a constructor with some extraneous template + // arguments. Complain, then parse it as a type as the user + // intended. + Diag(TemplateId->TemplateNameLoc, + diag::err_out_of_line_template_id_names_constructor) + << TemplateId->Name; + } + DS.getTypeSpecScope() = SS; ConsumeToken(); // The C++ scope. assert(Tok.is(tok::annot_template_id) && @@ -885,13 +941,23 @@ if (Next.isNot(tok::identifier)) goto DoneWithDeclSpec; - // If the next token is the name of the class type that the C++ scope - // denotes, followed by a '(', then this is a constructor declaration. - // We're done with the decl-specifiers. - if (Actions.isCurrentClassName(*Next.getIdentifierInfo(), - CurScope, &SS) && - GetLookAheadToken(2).is(tok::l_paren)) - goto DoneWithDeclSpec; + // If we're in a context where the identifier could be a class name, + // check whether this is a constructor declaration. + if (DSContext == DSC_top_level && + Actions.isCurrentClassName(*Next.getIdentifierInfo(), CurScope, + &SS)) { + if (isConstructorDeclarator()) + goto DoneWithDeclSpec; + + // As noted in C++ [class.qual]p2 (cited above), when the name + // of the class is qualified in a context where it could name + // a constructor, its a constructor name. However, we've + // looked at the declarator, and the user probably meant this + // to be a type. Complain that it isn't supposed to be treated + // as a type, then proceed to parse it as a type. + Diag(Next.getLocation(), diag::err_out_of_line_type_names_constructor) + << Next.getIdentifierInfo(); + } TypeTy *TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(), Next.getLocation(), CurScope, &SS); @@ -972,16 +1038,11 @@ goto DoneWithDeclSpec; } - // C++: If the identifier is actually the name of the class type - // being defined and the next token is a '(', then this is a - // constructor declaration. We're done with the decl-specifiers - // and will treat this token as an identifier. - if (getLang().CPlusPlus && - (CurScope->isClassScope() || - (CurScope->isTemplateParamScope() && - CurScope->getParent()->isClassScope())) && + // If we're in a context where the identifier could be a class name, + // check whether this is a constructor declaration. + if (getLang().CPlusPlus && DSContext == DSC_class && Actions.isCurrentClassName(*Tok.getIdentifierInfo(), CurScope) && - NextToken().getKind() == tok::l_paren) + isConstructorDeclarator()) goto DoneWithDeclSpec; isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, @@ -1024,6 +1085,14 @@ goto DoneWithDeclSpec; } + // If we're in a context where the template-id could be a + // constructor name or specialization, check whether this is a + // constructor declaration. + if (getLang().CPlusPlus && DSContext == DSC_class && + Actions.isCurrentClassName(*TemplateId->Name, CurScope) && + isConstructorDeclarator()) + goto DoneWithDeclSpec; + // Turn the template-id annotation token into a type annotation // token, then try again to parse it as a type-specifier. AnnotateTemplateIdTokenAsType(); @@ -2089,6 +2158,48 @@ } } +bool Parser::isConstructorDeclarator() { + TentativeParsingAction TPA(*this); + + // Parse the C++ scope specifier. + CXXScopeSpec SS; + ParseOptionalCXXScopeSpecifier(SS, 0, true); + + // Parse the constructor name. + if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id)) { + // We already know that we have a constructor name; just consume + // the token. + ConsumeToken(); + } else { + TPA.Revert(); + return false; + } + + // Current class name must be followed by a left parentheses. + if (Tok.isNot(tok::l_paren)) { + TPA.Revert(); + return false; + } + ConsumeParen(); + + // A right parentheses or ellipsis signals that we have a constructor. + if (Tok.is(tok::r_paren) || Tok.is(tok::ellipsis)) { + TPA.Revert(); + return true; + } + + // If we need to, enter the specified scope. + DeclaratorScopeObj DeclScopeObj(*this, SS); + if (SS.isSet() && Actions.ShouldEnterDeclaratorScope(CurScope, SS)) + DeclScopeObj.EnterDeclaratorScope(); + + // Check whether the next token(s) are part of a declaration + // specifier, in which case we have the start of a parameter and, + // therefore, we know that this is a constructor. + bool IsConstructor = isDeclarationSpecifier(); + TPA.Revert(); + return IsConstructor; +} /// ParseTypeQualifierListOpt /// type-qualifier-list: [C99 6.7.5] @@ -2373,10 +2484,16 @@ Tok.is(tok::annot_template_id) || Tok.is(tok::tilde)) { // We found something that indicates the start of an unqualified-id. // Parse that unqualified-id. + bool AllowConstructorName + = ((D.getCXXScopeSpec().isSet() && + D.getContext() == Declarator::FileContext) || + (!D.getCXXScopeSpec().isSet() && + D.getContext() == Declarator::MemberContext)) && + !D.getDeclSpec().hasTypeSpecifier(); if (ParseUnqualifiedId(D.getCXXScopeSpec(), /*EnteringContext=*/true, /*AllowDestructorName=*/true, - /*AllowConstructorName=*/!D.getDeclSpec().hasTypeSpecifier(), + AllowConstructorName, /*ObjectType=*/0, D.getName())) { D.SetIdentifier(0, Tok.getLocation()); @@ -2403,6 +2520,16 @@ // direct-declarator: '(' attributes declarator ')' // Example: 'char (*X)' or 'int (*XX)(void)' ParseParenDeclarator(D); + + // If the declarator was parenthesized, we entered the declarator + // scope when parsing the parenthesized declarator, then exited + // the scope already. Re-enter the scope, if we need to. + if (D.getCXXScopeSpec().isSet()) { + if (Actions.ShouldEnterDeclaratorScope(CurScope, D.getCXXScopeSpec())) + // Change the declaration context for name lookup, until this function + // is exited (and the declarator has been parsed). + DeclScopeObj.EnterDeclaratorScope(); + } } else if (D.mayOmitIdentifier()) { // This could be something simple like "int" (in which case the declarator // portion is empty), if an abstract-declarator is allowed. Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=93322&r1=93321&r2=93322&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original) +++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Wed Jan 13 11:31:36 2010 @@ -1182,12 +1182,41 @@ // unqualified-id: // template-id (already parsed and annotated) if (Tok.is(tok::annot_template_id)) { - // FIXME: Could this be a constructor name??? - + TemplateIdAnnotation *TemplateId + = static_cast(Tok.getAnnotationValue()); + + // If the template-name names the current class, then this is a constructor + if (AllowConstructorName && TemplateId->Name && + Actions.isCurrentClassName(*TemplateId->Name, CurScope, &SS)) { + if (SS.isSet()) { + // C++ [class.qual]p2 specifies that a qualified template-name + // is taken as the constructor name where a constructor can be + // declared. Thus, the template arguments are extraneous, so + // complain about them and remove them entirely. + Diag(TemplateId->TemplateNameLoc, + diag::err_out_of_line_constructor_template_id) + << TemplateId->Name + << CodeModificationHint::CreateRemoval( + SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc)); + Result.setConstructorName(Actions.getTypeName(*TemplateId->Name, + TemplateId->TemplateNameLoc, + CurScope, + &SS, false), + TemplateId->TemplateNameLoc, + TemplateId->RAngleLoc); + TemplateId->Destroy(); + ConsumeToken(); + return false; + } + + Result.setConstructorTemplateId(TemplateId); + ConsumeToken(); + return false; + } + // We have already parsed a template-id; consume the annotation token as // our unqualified-id. - Result.setTemplateId( - static_cast(Tok.getAnnotationValue())); + Result.setTemplateId(TemplateId); ConsumeToken(); return false; } Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=93322&r1=93321&r2=93322&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseTemplate.cpp (original) +++ cfe/trunk/lib/Parse/ParseTemplate.cpp Wed Jan 13 11:31:36 2010 @@ -196,7 +196,8 @@ if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) DS.AddAttributes(ParseCXX0XAttributes().AttrList); - ParseDeclarationSpecifiers(DS, TemplateInfo, AS); + ParseDeclarationSpecifiers(DS, TemplateInfo, AS, + getDeclSpecContextFromDeclaratorContext(Context)); if (Tok.is(tok::semi)) { DeclEnd = ConsumeToken(); Modified: cfe/trunk/lib/Parse/Parser.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=93322&r1=93321&r2=93322&view=diff ============================================================================== --- cfe/trunk/lib/Parse/Parser.cpp (original) +++ cfe/trunk/lib/Parse/Parser.cpp Wed Jan 13 11:31:36 2010 @@ -541,7 +541,7 @@ if (Attr) DS.AddAttributes(Attr); - ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS); + ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC_top_level); // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };" // declaration-specifiers init-declarator-list[opt] ';' Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=93322&r1=93321&r2=93322&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Jan 13 11:31:36 2010 @@ -1972,6 +1972,30 @@ Context.getCanonicalType(Ty)); } + case UnqualifiedId::IK_ConstructorTemplateId: { + // In well-formed code, we can only have a constructor + // template-id that refers to the current context, so go there + // to find the actual type being constructed. + CXXRecordDecl *CurClass = dyn_cast(CurContext); + if (!CurClass || CurClass->getIdentifier() != Name.TemplateId->Name) + return DeclarationName(); + + // Determine the type of the class being constructed. + QualType CurClassType; + if (ClassTemplateDecl *ClassTemplate + = CurClass->getDescribedClassTemplate()) + CurClassType = ClassTemplate->getInjectedClassNameType(Context); + else + CurClassType = Context.getTypeDeclType(CurClass); + + // FIXME: Check two things: that the template-id names the same type as + // CurClassType, and that the template-id does not occur when the name + // was qualified. + + return Context.DeclarationNames.getCXXConstructorName( + Context.getCanonicalType(CurClassType)); + } + case UnqualifiedId::IK_DestructorName: { QualType Ty = GetTypeFromParser(Name.DestructorName); if (Ty.isNull()) Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=93322&r1=93321&r2=93322&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Jan 13 11:31:36 2010 @@ -3002,6 +3002,7 @@ break; case UnqualifiedId::IK_ConstructorName: + case UnqualifiedId::IK_ConstructorTemplateId: // C++0x inherited constructors. if (getLangOptions().CPlusPlus0x) break; Modified: cfe/trunk/lib/Sema/SemaType.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=93322&r1=93321&r2=93322&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaType.cpp (original) +++ cfe/trunk/lib/Sema/SemaType.cpp Wed Jan 13 11:31:36 2010 @@ -897,6 +897,7 @@ break; case UnqualifiedId::IK_ConstructorName: + case UnqualifiedId::IK_ConstructorTemplateId: case UnqualifiedId::IK_DestructorName: // Constructors and destructors don't have return types. Use // "void" instead. Added: cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp?rev=93322&view=auto ============================================================================== --- cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp (added) +++ cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp Wed Jan 13 11:31:36 2010 @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +struct X0 { + X0 f1(); + X0 f2(); +}; + +template +struct X1 { + X1(int); + (X1)(float); + X1 f2(); + X1 f2(int); + X1 f2(float); +}; + +// Error recovery: out-of-line constructors whose names have template arguments. +template X1::X1(int) { } // expected-error{{out-of-line constructor for 'X1' cannot have template arguments}} +template (X1::X1)(float) { } // expected-error{{out-of-line constructor for 'X1' cannot have template arguments}} + +// Error recovery: out-of-line constructor names intended to be types +X0::X0 X0::f1() { return X0(); } // expected-error{{qualified reference to 'X0' is a constructor name rather than a type wherever a constructor can be declared}} + +struct X0::X0 X0::f2() { return X0(); } + +template X1::X1 X1::f2() { } // expected-error{{qualified reference to 'X1' is a constructor name rather than a template name wherever a constructor can be declared}} +template X1::X1 (X1::f2)(int) { } // expected-error{{qualified reference to 'X1' is a constructor name rather than a template name wherever a constructor can be declared}} +template struct X1::X1 (X1::f2)(float) { } Propchange: cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp ------------------------------------------------------------------------------ svn:keywords = Id Propchange: cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: cfe/trunk/test/CXX/special/class.ctor/p1.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/special/class.ctor/p1.cpp?rev=93322&view=auto ============================================================================== --- cfe/trunk/test/CXX/special/class.ctor/p1.cpp (added) +++ cfe/trunk/test/CXX/special/class.ctor/p1.cpp Wed Jan 13 11:31:36 2010 @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +struct X0 { + struct type { }; + + X0(); + X0(int); + (X0)(float); + X0 (f0)(int); + X0 (f0)(type); + + X0 f1(); + X0 f1(double); +}; + +X0::X0() { } +(X0::X0)(int) { } + +X0 (X0::f0)(int) { return X0(); } + +template +struct X1 { + struct type { }; + + X1(); + X1(int); + (X1)(float); + X1(float, float); + (X1)(double); + X1 (f0)(int); + X1 (f0)(type); + X1 (f1)(int); + X1 (f1)(type); + + template X1(U); + X1 f2(); + X1 f2(int); +}; + +template X1::X1() { } +template (X1::X1)(double) { } +template X1 X1::f1(int) { return 0; } +template X1 (X1::f1)(type) { return 0; } Propchange: cfe/trunk/test/CXX/special/class.ctor/p1.cpp ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cfe/trunk/test/CXX/special/class.ctor/p1.cpp ------------------------------------------------------------------------------ svn:keywords = Id Propchange: cfe/trunk/test/CXX/special/class.ctor/p1.cpp ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: cfe/trunk/test/SemaTemplate/injected-class-name.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/injected-class-name.cpp?rev=93322&r1=93321&r2=93322&view=diff ============================================================================== --- cfe/trunk/test/SemaTemplate/injected-class-name.cpp (original) +++ cfe/trunk/test/SemaTemplate/injected-class-name.cpp Wed Jan 13 11:31:36 2010 @@ -11,11 +11,7 @@ typedef X *ptr; }; -// FIXME: EDG rejects this in their strict-conformance mode, but I -// don't see any wording making this ill-formed. Actually, -// [temp.local]p2 might make it ill-formed. Are we "in the scope of -// the class template specialization?" -X::X xi = x; +X::X xi = x; // expected-error{{qualified reference to 'X' is a constructor name rather than a template name wherever a constructor can be declared}} // [temp.local]p1: Modified: cfe/trunk/test/SemaTemplate/instantiate-member-class.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-member-class.cpp?rev=93322&r1=93321&r2=93322&view=diff ============================================================================== --- cfe/trunk/test/SemaTemplate/instantiate-member-class.cpp (original) +++ cfe/trunk/test/SemaTemplate/instantiate-member-class.cpp Wed Jan 13 11:31:36 2010 @@ -14,8 +14,8 @@ X::C *c1; X::C *c2; -X::X *xi; -X::X *xf; +X::X *xi; // expected-error{{qualified reference to 'X' is a constructor name rather than a type wherever a constructor can be declared}} +X::X *xf; // expected-error{{qualified reference to 'X' is a constructor name rather than a type wherever a constructor can be declared}} void test_naming() { c1 = c2; // expected-error{{incompatible type assigning 'X::C *', expected 'X::C *'}} From kremenek at apple.com Wed Jan 13 12:45:36 2010 From: kremenek at apple.com (Ted Kremenek) Date: Wed, 13 Jan 2010 18:45:36 -0000 Subject: [cfe-commits] r93328 - /cfe/trunk/tools/CIndex/CIndex.cpp Message-ID: <201001131845.o0DIjb24015109@zion.cs.uiuc.edu> Author: kremenek Date: Wed Jan 13 12:45:36 2010 New Revision: 93328 URL: http://llvm.org/viewvc/llvm-project?rev=93328&view=rev Log: Add extra null check in clang_disposeString(). Modified: cfe/trunk/tools/CIndex/CIndex.cpp Modified: cfe/trunk/tools/CIndex/CIndex.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndex.cpp?rev=93328&r1=93327&r2=93328&view=diff ============================================================================== --- cfe/trunk/tools/CIndex/CIndex.cpp (original) +++ cfe/trunk/tools/CIndex/CIndex.cpp Wed Jan 13 12:45:36 2010 @@ -1065,7 +1065,7 @@ } void clang_disposeString(CXString string) { - if (string.MustFreeString) + if (string.MustFreeString && string.Spelling) free((void*)string.Spelling); } From fjahanian at apple.com Wed Jan 13 12:51:17 2010 From: fjahanian at apple.com (Fariborz Jahanian) Date: Wed, 13 Jan 2010 18:51:17 -0000 Subject: [cfe-commits] r93331 - in /cfe/trunk: include/clang/Frontend/CompilerInstance.h include/clang/Frontend/Utils.h lib/Basic/Targets.cpp lib/Frontend/CompilerInstance.cpp lib/Frontend/InitPreprocessor.cpp Message-ID: <201001131851.o0DIpIkb015438@zion.cs.uiuc.edu> Author: fjahanian Date: Wed Jan 13 12:51:17 2010 New Revision: 93331 URL: http://llvm.org/viewvc/llvm-project?rev=93331&view=rev Log: Predefine __weak attribute when doing objective-c rewriting for any target. (refixes radar 7530235). Modified: cfe/trunk/include/clang/Frontend/CompilerInstance.h cfe/trunk/include/clang/Frontend/Utils.h cfe/trunk/lib/Basic/Targets.cpp cfe/trunk/lib/Frontend/CompilerInstance.cpp cfe/trunk/lib/Frontend/InitPreprocessor.cpp Modified: cfe/trunk/include/clang/Frontend/CompilerInstance.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CompilerInstance.h?rev=93331&r1=93330&r2=93331&view=diff ============================================================================== --- cfe/trunk/include/clang/Frontend/CompilerInstance.h (original) +++ cfe/trunk/include/clang/Frontend/CompilerInstance.h Wed Jan 13 12:51:17 2010 @@ -488,6 +488,7 @@ const HeaderSearchOptions &, const DependencyOutputOptions &, const TargetInfo &, + const FrontendOptions &, SourceManager &, FileManager &); /// Create the AST context. Modified: cfe/trunk/include/clang/Frontend/Utils.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/Utils.h?rev=93331&r1=93330&r2=93331&view=diff ============================================================================== --- cfe/trunk/include/clang/Frontend/Utils.h (original) +++ cfe/trunk/include/clang/Frontend/Utils.h Wed Jan 13 12:51:17 2010 @@ -39,6 +39,7 @@ class SourceManager; class Stmt; class TargetInfo; +class FrontendOptions; class MacroBuilder { llvm::raw_ostream &Out; @@ -76,7 +77,8 @@ /// environment ready to process a single file. void InitializePreprocessor(Preprocessor &PP, const PreprocessorOptions &PPOpts, - const HeaderSearchOptions &HSOpts); + const HeaderSearchOptions &HSOpts, + const FrontendOptions &FEOpts); /// ProcessWarningOptions - Initialize the diagnostic client and process the /// warning options specified on the command line. Modified: cfe/trunk/lib/Basic/Targets.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets.cpp?rev=93331&r1=93330&r2=93331&view=diff ============================================================================== --- cfe/trunk/lib/Basic/Targets.cpp (original) +++ cfe/trunk/lib/Basic/Targets.cpp Wed Jan 13 12:51:17 2010 @@ -994,10 +994,6 @@ DefineStd(Builder, "WIN32", Opts); DefineStd(Builder, "WINNT", Opts); Builder.defineMacro("_X86_"); - if (Opts.ObjC1) - // __weak is always defined, for use in blocks and with objc pointers, - // even for i686-pc-win32 targets. - Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))"); } }; } // end anonymous namespace Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=93331&r1=93330&r2=93331&view=diff ============================================================================== --- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original) +++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Wed Jan 13 12:51:17 2010 @@ -158,7 +158,8 @@ PP.reset(createPreprocessor(getDiagnostics(), getLangOpts(), getPreprocessorOpts(), getHeaderSearchOpts(), getDependencyOutputOpts(), getTarget(), - getSourceManager(), getFileManager())); + getFrontendOpts(), getSourceManager(), + getFileManager())); } Preprocessor * @@ -168,6 +169,7 @@ const HeaderSearchOptions &HSOpts, const DependencyOutputOptions &DepOpts, const TargetInfo &Target, + const FrontendOptions &FEOpts, SourceManager &SourceMgr, FileManager &FileMgr) { // Create a PTH manager if we are using some form of a token cache. @@ -189,7 +191,7 @@ PP->setPTHManager(PTHMgr); } - InitializePreprocessor(*PP, PPOpts, HSOpts); + InitializePreprocessor(*PP, PPOpts, HSOpts, FEOpts); // Handle generating dependencies, if requested. if (!DepOpts.OutputFile.empty()) Modified: cfe/trunk/lib/Frontend/InitPreprocessor.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/InitPreprocessor.cpp?rev=93331&r1=93330&r2=93331&view=diff ============================================================================== --- cfe/trunk/lib/Frontend/InitPreprocessor.cpp (original) +++ cfe/trunk/lib/Frontend/InitPreprocessor.cpp Wed Jan 13 12:51:17 2010 @@ -14,6 +14,7 @@ #include "clang/Frontend/Utils.h" #include "clang/Basic/TargetInfo.h" #include "clang/Frontend/FrontendDiagnostic.h" +#include "clang/Frontend/FrontendOptions.h" #include "clang/Frontend/PreprocessorOptions.h" #include "clang/Lex/Preprocessor.h" #include "clang/Basic/FileManager.h" @@ -202,6 +203,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI, const LangOptions &LangOpts, + const FrontendOptions &FEOpts, MacroBuilder &Builder) { // Compiler version introspection macros. Builder.defineMacro("__llvm__"); // LLVM Backend @@ -406,6 +408,8 @@ else if (LangOpts.getStackProtectorMode() == LangOptions::SSPReq) Builder.defineMacro("__SSP_ALL__", "2"); + if (FEOpts.ProgramAction == frontend::RewriteObjC) + Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))"); // Get other target #defines. TI.getTargetDefines(LangOpts, Builder); } @@ -461,7 +465,8 @@ /// void clang::InitializePreprocessor(Preprocessor &PP, const PreprocessorOptions &InitOpts, - const HeaderSearchOptions &HSOpts) { + const HeaderSearchOptions &HSOpts, + const FrontendOptions &FEOpts) { std::string PredefineBuffer; PredefineBuffer.reserve(4080); llvm::raw_string_ostream Predefines(PredefineBuffer); @@ -475,7 +480,7 @@ // Install things like __POWERPC__, __GNUC__, etc into the macro table. if (InitOpts.UsePredefines) InitializePredefinedMacros(PP.getTargetInfo(), PP.getLangOptions(), - Builder); + FEOpts, Builder); // Add on the predefines from the driver. Wrap in a #line directive to report // that they come from the command line. From mrs at apple.com Wed Jan 13 13:40:38 2010 From: mrs at apple.com (Mike Stump) Date: Wed, 13 Jan 2010 19:40:38 -0000 Subject: [cfe-commits] r93340 - /cfe/trunk/test/CodeGen/object-size.c Message-ID: <201001131940.o0DJecx5017852@zion.cs.uiuc.edu> Author: mrs Date: Wed Jan 13 13:40:37 2010 New Revision: 93340 URL: http://llvm.org/viewvc/llvm-project?rev=93340&view=rev Log: Fix for Release-Asserts. Modified: cfe/trunk/test/CodeGen/object-size.c Modified: cfe/trunk/test/CodeGen/object-size.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/object-size.c?rev=93340&r1=93339&r2=93340&view=diff ============================================================================== --- cfe/trunk/test/CodeGen/object-size.c (original) +++ cfe/trunk/test/CodeGen/object-size.c Wed Jan 13 13:40:37 2010 @@ -14,99 +14,98 @@ int gi, gj; void test1() { - // CHECK: %call = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i64 4), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 59) + // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i64 4), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 59) strcpy(&gbuf[4], "Hi there"); } void test2() { - // CHECK: %call = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 63) + // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 63) strcpy(gbuf, "Hi there"); } void test3() { - // CHECK: %call = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i64 1, i64 37), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 0) + // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i64 1, i64 37), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 0) strcpy(&gbuf[100], "Hi there"); } void test4() { - // CHECK: %call = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i64 -1), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 0) + // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i64 -1), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 0) strcpy((char*)(void*)&gbuf[-1], "Hi there"); } void test5() { - // CHECK: %tmp = load i8** @gp - // CHECK-NEXT:%0 = call i64 @llvm.objectsize.i64(i8* %tmp, i1 false) - // CHECK-NEXT:%cmp = icmp ne i64 %0, -1 + // CHECK: = load i8** @gp + // CHECK-NEXT:= call i64 @llvm.objectsize.i64(i8* %{{.*}}, i1 false) strcpy(gp, "Hi there"); } void test6() { char buf[57]; - // CHECK: %call = call i8* @__strcpy_chk(i8* %arrayidx, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 53) + // CHECK: = call i8* @__strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 53) strcpy(&buf[4], "Hi there"); } void test7() { int i; // CHECK-NOT: __strcpy_chk - // CHECK: %call = call i8* @__inline_strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + // CHECK: = call i8* @__inline_strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) strcpy((++i, gbuf), "Hi there"); } void test8() { char *buf[50]; // CHECK-NOT: __strcpy_chk - // CHECK: %call = call i8* @__inline_strcpy_chk(i8* %tmp1, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) strcpy(buf[++gi], "Hi there"); } void test9() { // CHECK-NOT: __strcpy_chk - // CHECK: %call = call i8* @__inline_strcpy_chk(i8* %0, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) strcpy((char *)((++gi) + gj), "Hi there"); } char **p; void test10() { // CHECK-NOT: __strcpy_chk - // CHECK: %call = call i8* @__inline_strcpy_chk(i8* %tmp1, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) strcpy(*(++p), "Hi there"); } void test11() { // CHECK-NOT: __strcpy_chk - // CHECK: %call = call i8* @__inline_strcpy_chk(i8* %tmp, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) strcpy(gp = gbuf, "Hi there"); } void test12() { // CHECK-NOT: __strcpy_chk - // CHECK: %call = call i8* @__inline_strcpy_chk(i8* %ptrincdec, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) strcpy(++gp, "Hi there"); } void test13() { // CHECK-NOT: __strcpy_chk - // CHECK: %call = call i8* @__inline_strcpy_chk(i8* %tmp, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) strcpy(gp++, "Hi there"); } void test14() { // CHECK-NOT: __strcpy_chk - // CHECK: %call = call i8* @__inline_strcpy_chk(i8* %ptrincdec, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) strcpy(--gp, "Hi there"); } void test15() { // CHECK-NOT: __strcpy_chk - // CHECK: %call = call i8* @__inline_strcpy_chk(i8* %tmp, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{..*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) strcpy(gp--, "Hi there"); } void test16() { // CHECK-NOT: __strcpy_chk - // CHECK: %call = call i8* @__inline_strcpy_chk(i8* %tmp1, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) strcpy(gp += 1, "Hi there"); } From kremenek at apple.com Wed Jan 13 13:59:20 2010 From: kremenek at apple.com (Ted Kremenek) Date: Wed, 13 Jan 2010 19:59:20 -0000 Subject: [cfe-commits] r93343 - in /cfe/trunk: include/clang-c/Index.h tools/CIndex/CIndex.cpp Message-ID: <201001131959.o0DJxLjR019048@zion.cs.uiuc.edu> Author: kremenek Date: Wed Jan 13 13:59:20 2010 New Revision: 93343 URL: http://llvm.org/viewvc/llvm-project?rev=93343&view=rev Log: Add 'referringDecl' field to CXCursor to prepare the way to better model declaration references from other delcarations. Modified: cfe/trunk/include/clang-c/Index.h cfe/trunk/tools/CIndex/CIndex.cpp Modified: cfe/trunk/include/clang-c/Index.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=93343&r1=93342&r2=93343&view=diff ============================================================================== --- cfe/trunk/include/clang-c/Index.h (original) +++ cfe/trunk/include/clang-c/Index.h Wed Jan 13 13:59:20 2010 @@ -139,6 +139,7 @@ enum CXCursorKind kind; CXDecl decl; CXStmt stmt; /* expression reference */ + CXDecl referringDecl; } CXCursor; /* A unique token for looking up "visible" CXDecls from a CXTranslationUnit. */ Modified: cfe/trunk/tools/CIndex/CIndex.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndex.cpp?rev=93343&r1=93342&r2=93343&view=diff ============================================================================== --- cfe/trunk/tools/CIndex/CIndex.cpp (original) +++ cfe/trunk/tools/CIndex/CIndex.cpp Wed Jan 13 13:59:20 2010 @@ -188,7 +188,7 @@ if (ND->isImplicit()) return; - CXCursor C = { CK, ND, 0 }; + CXCursor C = { CK, ND, 0, 0 }; Callback(Root, C, CData); } @@ -289,7 +289,7 @@ if (ND->getPCHLevel() > MaxPCHLevel) return; - CXCursor C = { CK, ND, 0 }; + CXCursor C = { CK, ND, 0, 0 }; Callback(CDecl, C, CData); } public: @@ -931,7 +931,7 @@ const FileEntry *File = FMgr.getFile(source_name, source_name+strlen(source_name)); if (!File) { - CXCursor C = { CXCursor_InvalidFile, 0, 0 }; + CXCursor C = { CXCursor_InvalidFile, 0, 0, 0 }; return C; } SourceLocation SLoc = @@ -951,28 +951,28 @@ if (Dcl) { if (Stm) { if (DeclRefExpr *DRE = dyn_cast(Stm)) { - CXCursor C = { TranslateDeclRefExpr(DRE), Dcl, Stm }; + CXCursor C = { TranslateDeclRefExpr(DRE), Dcl, Stm, 0 }; return C; } else if (ObjCMessageExpr *MExp = dyn_cast(Stm)) { - CXCursor C = { CXCursor_ObjCSelectorRef, Dcl, MExp }; + CXCursor C = { CXCursor_ObjCSelectorRef, Dcl, MExp, 0 }; return C; } // Fall through...treat as a decl, not a ref. } if (ALoc.isNamedRef()) { if (isa(Dcl)) { - CXCursor C = { CXCursor_ObjCClassRef, Dcl, ALoc.getParentDecl() }; + CXCursor C = { CXCursor_ObjCClassRef, Dcl, ALoc.getParentDecl(), 0 }; return C; } if (isa(Dcl)) { - CXCursor C = { CXCursor_ObjCProtocolRef, Dcl, ALoc.getParentDecl() }; + CXCursor C = { CXCursor_ObjCProtocolRef, Dcl, ALoc.getParentDecl(), 0 }; return C; } } - CXCursor C = { TranslateKind(Dcl), Dcl, 0 }; + CXCursor C = { TranslateKind(Dcl), Dcl, 0, 0 }; return C; } - CXCursor C = { CXCursor_NoDeclFound, 0, 0 }; + CXCursor C = { CXCursor_NoDeclFound, 0, 0, 0 }; return C; } @@ -992,7 +992,7 @@ assert(AnonDecl && "Passed null CXDecl"); NamedDecl *ND = static_cast(AnonDecl); - CXCursor C = { TranslateKind(ND), ND, 0 }; + CXCursor C = { TranslateKind(ND), ND, 0, 0 }; return C; } From rjmccall at apple.com Wed Jan 13 14:03:27 2010 From: rjmccall at apple.com (John McCall) Date: Wed, 13 Jan 2010 20:03:27 -0000 Subject: [cfe-commits] r93344 - in /cfe/trunk: include/clang/AST/TypeLoc.h include/clang/Parse/DeclSpec.h lib/AST/TypeLoc.cpp lib/Frontend/PCHReader.cpp lib/Frontend/PCHWriter.cpp lib/Parse/ParseDecl.cpp lib/Sema/SemaType.cpp lib/Sema/TreeTransform.h Message-ID: <201001132003.o0DK3SD8019210@zion.cs.uiuc.edu> Author: rjmccall Date: Wed Jan 13 14:03:27 2010 New Revision: 93344 URL: http://llvm.org/viewvc/llvm-project?rev=93344&view=rev Log: Add type source information for both kinds of typeof types. Patch by Enea Zaffanella. Modified: cfe/trunk/include/clang/AST/TypeLoc.h cfe/trunk/include/clang/Parse/DeclSpec.h cfe/trunk/lib/AST/TypeLoc.cpp cfe/trunk/lib/Frontend/PCHReader.cpp cfe/trunk/lib/Frontend/PCHWriter.cpp cfe/trunk/lib/Parse/ParseDecl.cpp cfe/trunk/lib/Sema/SemaType.cpp cfe/trunk/lib/Sema/TreeTransform.h Modified: cfe/trunk/include/clang/AST/TypeLoc.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=93344&r1=93343&r2=93344&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/TypeLoc.h (original) +++ cfe/trunk/include/clang/AST/TypeLoc.h Wed Jan 13 14:03:27 2010 @@ -1029,18 +1029,88 @@ ComplexType> { }; -// FIXME: location of the 'typeof' and parens (the expression is -// carried by the type). -class TypeOfExprTypeLoc : public InheritingConcreteTypeLoc { -}; - -// FIXME: location of the 'typeof' and parens; also the TypeSourceInfo -// for the inner type, or (maybe) just express that inline to the TypeLoc. -class TypeOfTypeLoc : public InheritingConcreteTypeLoc { +struct TypeofLocInfo { + SourceLocation TypeofLoc; + SourceLocation LParenLoc; + SourceLocation RParenLoc; +}; + +struct TypeOfExprTypeLocInfo : public TypeofLocInfo { +}; + +struct TypeOfTypeLocInfo : public TypeofLocInfo { + TypeSourceInfo* UnderlyingTInfo; +}; + +template +class TypeofLikeTypeLoc + : public ConcreteTypeLoc { +public: + SourceLocation getTypeofLoc() const { + return this->getLocalData()->TypeofLoc; + } + void setTypeofLoc(SourceLocation Loc) { + this->getLocalData()->TypeofLoc = Loc; + } + + SourceLocation getLParenLoc() const { + return this->getLocalData()->LParenLoc; + } + void setLParenLoc(SourceLocation Loc) { + this->getLocalData()->LParenLoc = Loc; + } + + SourceLocation getRParenLoc() const { + return this->getLocalData()->RParenLoc; + } + void setRParenLoc(SourceLocation Loc) { + this->getLocalData()->RParenLoc = Loc; + } + + SourceRange getParensRange() const { + return SourceRange(getLParenLoc(), getRParenLoc()); + } + void setParensRange(SourceRange range) { + setLParenLoc(range.getBegin()); + setRParenLoc(range.getEnd()); + } + + SourceRange getSourceRange() const { + return SourceRange(getTypeofLoc(), getRParenLoc()); + } + + void initializeLocal(SourceLocation Loc) { + setTypeofLoc(Loc); + setLParenLoc(Loc); + setRParenLoc(Loc); + } +}; + +class TypeOfExprTypeLoc : public TypeofLikeTypeLoc { +public: + Expr* getUnderlyingExpr() const { + return getTypePtr()->getUnderlyingExpr(); + } + // Reimplemented to account for GNU/C++ extension + // typeof unary-expression + // where there are no parentheses. + SourceRange getSourceRange() const; +}; + +class TypeOfTypeLoc + : public TypeofLikeTypeLoc { +public: + QualType getUnderlyingType() const { + return this->getTypePtr()->getUnderlyingType(); + } + TypeSourceInfo* getUnderlyingTInfo() const { + return this->getLocalData()->UnderlyingTInfo; + } + void setUnderlyingTInfo(TypeSourceInfo* TI) const { + this->getLocalData()->UnderlyingTInfo = TI; + } }; // FIXME: location of the 'decltype' and parens. Modified: cfe/trunk/include/clang/Parse/DeclSpec.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/DeclSpec.h?rev=93344&r1=93343&r2=93344&view=diff ============================================================================== --- cfe/trunk/include/clang/Parse/DeclSpec.h (original) +++ cfe/trunk/include/clang/Parse/DeclSpec.h Wed Jan 13 14:03:27 2010 @@ -194,6 +194,7 @@ SourceLocation StorageClassSpecLoc, SCS_threadLoc; SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc; + SourceRange TypeofParensRange; SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc; SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc; SourceLocation FriendLoc, ConstexprLoc; @@ -257,6 +258,9 @@ SourceLocation getTypeSpecSignLoc() const { return TSSLoc; } SourceLocation getTypeSpecTypeLoc() const { return TSTLoc; } + SourceRange getTypeofParensRange() const { return TypeofParensRange; } + void setTypeofParensRange(SourceRange range) { TypeofParensRange = range; } + /// getSpecifierName - Turn a type-specifier-type into a string like "_Bool" /// or "union". static const char *getSpecifierName(DeclSpec::TST T); Modified: cfe/trunk/lib/AST/TypeLoc.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypeLoc.cpp?rev=93344&r1=93343&r2=93344&view=diff ============================================================================== --- cfe/trunk/lib/AST/TypeLoc.cpp (original) +++ cfe/trunk/lib/AST/TypeLoc.cpp Wed Jan 13 14:03:27 2010 @@ -13,6 +13,7 @@ #include "llvm/Support/raw_ostream.h" #include "clang/AST/TypeLocVisitor.h" +#include "clang/AST/Expr.h" using namespace clang; //===----------------------------------------------------------------------===// @@ -123,3 +124,14 @@ if (TL->getType().hasLocalQualifiers()) return false; return TSTChecker().Visit(*TL); } + +// Reimplemented to account for GNU/C++ extension +// typeof unary-expression +// where there are no parentheses. +SourceRange TypeOfExprTypeLoc::getSourceRange() const { + if (getRParenLoc().isValid()) + return SourceRange(getTypeofLoc(), getRParenLoc()); + else + return SourceRange(getTypeofLoc(), + getUnderlyingExpr()->getSourceRange().getEnd()); +} Modified: cfe/trunk/lib/Frontend/PCHReader.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=93344&r1=93343&r2=93344&view=diff ============================================================================== --- cfe/trunk/lib/Frontend/PCHReader.cpp (original) +++ cfe/trunk/lib/Frontend/PCHReader.cpp Wed Jan 13 14:03:27 2010 @@ -2111,10 +2111,15 @@ TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); } void TypeLocReader::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { - TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setTypeofLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); } void TypeLocReader::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { - TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setTypeofLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setUnderlyingTInfo(Reader.GetTypeSourceInfo(Record, Idx)); } void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=93344&r1=93343&r2=93344&view=diff ============================================================================== --- cfe/trunk/lib/Frontend/PCHWriter.cpp (original) +++ cfe/trunk/lib/Frontend/PCHWriter.cpp Wed Jan 13 14:03:27 2010 @@ -344,10 +344,15 @@ Writer.AddSourceLocation(TL.getNameLoc(), Record); } void TypeLocWriter::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { - Writer.AddSourceLocation(TL.getNameLoc(), Record); + Writer.AddSourceLocation(TL.getTypeofLoc(), Record); + Writer.AddSourceLocation(TL.getLParenLoc(), Record); + Writer.AddSourceLocation(TL.getRParenLoc(), Record); } void TypeLocWriter::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { - Writer.AddSourceLocation(TL.getNameLoc(), Record); + Writer.AddSourceLocation(TL.getTypeofLoc(), Record); + Writer.AddSourceLocation(TL.getLParenLoc(), Record); + Writer.AddSourceLocation(TL.getRParenLoc(), Record); + Writer.AddTypeSourceInfo(TL.getUnderlyingTInfo(), Record); } void TypeLocWriter::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { Writer.AddSourceLocation(TL.getNameLoc(), Record); Modified: cfe/trunk/lib/Parse/ParseDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=93344&r1=93343&r2=93344&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseDecl.cpp (original) +++ cfe/trunk/lib/Parse/ParseDecl.cpp Wed Jan 13 14:03:27 2010 @@ -3154,6 +3154,8 @@ Token OpTok = Tok; SourceLocation StartLoc = ConsumeToken(); + const bool hasParens = Tok.is(tok::l_paren); + bool isCastExpr; TypeTy *CastTy; SourceRange CastRange; @@ -3161,6 +3163,8 @@ isCastExpr, CastTy, CastRange); + if (hasParens) + DS.setTypeofParensRange(CastRange); if (CastRange.getEnd().isInvalid()) // FIXME: Not accurate, the range gets one token more than it should. Modified: cfe/trunk/lib/Sema/SemaType.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=93344&r1=93343&r2=93344&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaType.cpp (original) +++ cfe/trunk/lib/Sema/SemaType.cpp Wed Jan 13 14:03:27 2010 @@ -1360,6 +1360,20 @@ cast(TInfo->getTypeLoc()); TL.copy(OldTL); } + void VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { + assert(DS.getTypeSpecType() == DeclSpec::TST_typeofExpr); + TL.setTypeofLoc(DS.getTypeSpecTypeLoc()); + TL.setParensRange(DS.getTypeofParensRange()); + } + void VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { + assert(DS.getTypeSpecType() == DeclSpec::TST_typeofType); + TL.setTypeofLoc(DS.getTypeSpecTypeLoc()); + TL.setParensRange(DS.getTypeofParensRange()); + assert(DS.getTypeRep()); + TypeSourceInfo *TInfo = 0; + Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo); + TL.setUnderlyingTInfo(TInfo); + } void VisitTypeLoc(TypeLoc TL) { // FIXME: add other typespec types and change this to an assert. TL.initialize(DS.getTypeSpecTypeLoc()); Modified: cfe/trunk/lib/Sema/TreeTransform.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=93344&r1=93343&r2=93344&view=diff ============================================================================== --- cfe/trunk/lib/Sema/TreeTransform.h (original) +++ cfe/trunk/lib/Sema/TreeTransform.h Wed Jan 13 14:03:27 2010 @@ -2619,18 +2619,16 @@ template QualType TreeTransform::TransformTypeOfExprType(TypeLocBuilder &TLB, TypeOfExprTypeLoc TL) { - TypeOfExprType *T = TL.getTypePtr(); - // typeof expressions are not potentially evaluated contexts EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated); - Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr()); + Sema::OwningExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr()); if (E.isInvalid()) return QualType(); QualType Result = TL.getType(); if (getDerived().AlwaysRebuild() || - E.get() != T->getUnderlyingExpr()) { + E.get() != TL.getUnderlyingExpr()) { Result = getDerived().RebuildTypeOfExprType(move(E)); if (Result.isNull()) return QualType(); @@ -2638,7 +2636,9 @@ else E.take(); TypeOfExprTypeLoc NewTL = TLB.push(Result); - NewTL.setNameLoc(TL.getNameLoc()); + NewTL.setTypeofLoc(TL.getTypeofLoc()); + NewTL.setLParenLoc(TL.getLParenLoc()); + NewTL.setRParenLoc(TL.getRParenLoc()); return Result; } @@ -2646,23 +2646,23 @@ template QualType TreeTransform::TransformTypeOfType(TypeLocBuilder &TLB, TypeOfTypeLoc TL) { - TypeOfType *T = TL.getTypePtr(); - - // FIXME: should be an inner type, or at least have a TypeSourceInfo. - QualType Underlying = getDerived().TransformType(T->getUnderlyingType()); - if (Underlying.isNull()) + TypeSourceInfo* Old_Under_TI = TL.getUnderlyingTInfo(); + TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI); + if (!New_Under_TI) return QualType(); QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - Underlying != T->getUnderlyingType()) { - Result = getDerived().RebuildTypeOfType(Underlying); + if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) { + Result = getDerived().RebuildTypeOfType(New_Under_TI->getType()); if (Result.isNull()) return QualType(); } TypeOfTypeLoc NewTL = TLB.push(Result); - NewTL.setNameLoc(TL.getNameLoc()); + NewTL.setTypeofLoc(TL.getTypeofLoc()); + NewTL.setLParenLoc(TL.getLParenLoc()); + NewTL.setRParenLoc(TL.getRParenLoc()); + NewTL.setUnderlyingTInfo(New_Under_TI); return Result; } From andersca at mac.com Wed Jan 13 14:11:16 2010 From: andersca at mac.com (Anders Carlsson) Date: Wed, 13 Jan 2010 20:11:16 -0000 Subject: [cfe-commits] r93345 - /cfe/trunk/lib/CodeGen/CGVtable.h Message-ID: <201001132011.o0DKBG6Q019478@zion.cs.uiuc.edu> Author: andersca Date: Wed Jan 13 14:11:15 2010 New Revision: 93345 URL: http://llvm.org/viewvc/llvm-project?rev=93345&view=rev Log: Add a BaseSubobject class to uniquely identify a base class subobject. Not yet used. Modified: cfe/trunk/lib/CodeGen/CGVtable.h Modified: cfe/trunk/lib/CodeGen/CGVtable.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVtable.h?rev=93345&r1=93344&r2=93345&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGVtable.h (original) +++ cfe/trunk/lib/CodeGen/CGVtable.h Wed Jan 13 14:11:15 2010 @@ -61,6 +61,31 @@ ThunkAdjustment ReturnAdjustment; }; +// BaseSubobject - Uniquely identifies a direct or indirect base class. +// Stores both the base class decl and the offset from the most derived class to +// the base class. +class BaseSubobject { + /// Base - The base class declaration. + const CXXRecordDecl *Base; + + /// BaseOffset - The offset from the most derived class to the base class. + uint64_t BaseOffset; + +public: + BaseSubobject(const CXXRecordDecl *Base, uint64_t BaseOffset) + : Base(Base), BaseOffset(BaseOffset) { } + + /// getBase - Returns the base class declaration. + const CXXRecordDecl *getBase() const { return Base; } + + /// getBaseOffset - Returns the base class offset. + uint64_t getBaseOffset() const { return BaseOffset; } + + friend bool operator==(const BaseSubobject &LHS, const BaseSubobject &RHS) { + return LHS.Base == RHS.Base && LHS.BaseOffset == RHS.BaseOffset; + } +}; + class CGVtableInfo { public: typedef std::vector > From mrs at apple.com Wed Jan 13 14:43:31 2010 From: mrs at apple.com (Mike Stump) Date: Wed, 13 Jan 2010 20:43:31 -0000 Subject: [cfe-commits] r93346 - /cfe/trunk/test/CodeGenCXX/virt.cpp Message-ID: <201001132043.o0DKhV6s020632@zion.cs.uiuc.edu> Author: mrs Date: Wed Jan 13 14:43:31 2010 New Revision: 93346 URL: http://llvm.org/viewvc/llvm-project?rev=93346&view=rev Log: Fix Release-Asserts. Modified: cfe/trunk/test/CodeGenCXX/virt.cpp Modified: cfe/trunk/test/CodeGenCXX/virt.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/virt.cpp?rev=93346&r1=93345&r2=93346&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/virt.cpp (original) +++ cfe/trunk/test/CodeGenCXX/virt.cpp Wed Jan 13 14:43:31 2010 @@ -153,7 +153,7 @@ // CHECK-LPLL64: call void % // CHECK-LPLL64: call void % // CHECK-LPLL64: call void % -// CHECK-LPLL64: call void @_ZN8test12_A3fooEv(%class.test14* %tmp11) +// CHECK-LPLL64: call void @_ZN8test12_A3fooEv(%class.test14* %{{.*}}) struct test6_B2 { virtual void funcB2(); char b[1000]; }; @@ -769,55 +769,53 @@ // FIXME: This is the wrong thunk, but until these issues are fixed, better // than nothing. // CHECK-LPLL64:define weak %class.test8_D* @_ZTcvn16_n72_v16_n32_N8test16_D4foo1Ev(%class.test8_D*) -// CHECK-LPLL64:entry: -// CHECK-LPLL64: %retval = alloca %class.test8_D* +// CHECK-LPLL64: %{{retval|2}} = alloca %class.test8_D* // CHECK-LPLL64: %.addr = alloca %class.test8_D* // CHECK-LPLL64: store %class.test8_D* %0, %class.test8_D** %.addr -// CHECK-LPLL64: %this = load %class.test8_D** %.addr -// CHECK-LPLL64: %1 = bitcast %class.test8_D* %this to i8* -// CHECK-LPLL64: %2 = getelementptr inbounds i8* %1, i64 -16 -// CHECK-LPLL64: %3 = bitcast i8* %2 to %class.test8_D* -// CHECK-LPLL64: %4 = bitcast %class.test8_D* %3 to i8* -// CHECK-LPLL64: %5 = bitcast %class.test8_D* %3 to i64** -// CHECK-LPLL64: %vtable = load i64** %5 -// CHECK-LPLL64: %6 = getelementptr inbounds i64* %vtable, i64 -9 -// CHECK-LPLL64: %7 = load i64* %6 -// CHECK-LPLL64: %8 = getelementptr i8* %4, i64 %7 -// CHECK-LPLL64: %9 = bitcast i8* %8 to %class.test8_D* -// CHECK-LPLL64: %call = call %class.test8_D* @_ZTch0_v16_n32_N8test16_D4foo1Ev(%class.test8_D* %9) -// CHECK-LPLL64: store %class.test8_D* %call, %class.test8_D** %retval -// CHECK-LPLL64: %10 = load %class.test8_D** %retval -// CHECK-LPLL64: ret %class.test8_D* %10 +// CHECK-LPLL64: %{{this|3}} = load %class.test8_D** %.addr +// CHECK-LPLL64: %{{1|4}} = bitcast %class.test8_D* %{{this|3}} to i8* +// CHECK-LPLL64: %{{2|5}} = getelementptr inbounds i8* %{{1|4}}, i64 -16 +// CHECK-LPLL64: %{{3|6}} = bitcast i8* %{{2|5}} to %class.test8_D* +// CHECK-LPLL64: %{{4|7}} = bitcast %class.test8_D* %{{3|6}} to i8* +// CHECK-LPLL64: %{{5|8}} = bitcast %class.test8_D* %3 to i64** +// CHECK-LPLL64: %{{vtable|9}} = load i64** %{{5|8}} +// CHECK-LPLL64: %{{6|10}} = getelementptr inbounds i64* %{{vtable|9}}, i64 -9 +// CHECK-LPLL64: %{{7|11}} = load i64* %{{6|10}} +// CHECK-LPLL64: %{{8|12}} = getelementptr i8* %{{4|7}}, i64 %{{7|11}} +// CHECK-LPLL64: %{{9|13}} = bitcast i8* %{{8|12}} to %class.test8_D* +// CHECK-LPLL64: %{{call|14}} = call %class.test8_D* @_ZTch0_v16_n32_N8test16_D4foo1Ev(%class.test8_D* %{{9|13}}) +// CHECK-LPLL64: store %class.test8_D* %{{call|14}}, %class.test8_D** %{{retval|2}} +// CHECK-LPLL64: %{{10|15}} = load %class.test8_D** %{{retval|2}} +// CHECK-LPLL64: ret %class.test8_D* %{{10|15}} // CHECK-LPLL64:} -// CHECK-LPLL64:define weak %class.test8_D* @_ZTch0_v16_n32_N8test16_D4foo1Ev(%class.test8_D*) -// CHECK-LPLL64:entry: -// CHECK-LPLL64: %retval = alloca %class.test8_D* +// CHECK-LPLL64:define weak %class.test8_D* @_ZTch0_v16_n32_N8test16_D4foo1Ev(%{{class.test8_D|.*}}*) +// CHECK-LPLL64: %{{retval|2}} = alloca %class.test8_D* // CHECK-LPLL64: %.addr = alloca %class.test8_D* // CHECK-LPLL64: store %class.test8_D* %0, %class.test8_D** %.addr -// CHECK-LPLL64: %this = load %class.test8_D** %.addr -// CHECK-LPLL64: %call = call %class.test8_D* @_ZN8test16_D4foo1Ev(%class.test8_D* %this) -// CHECK-LPLL64: %1 = icmp ne %class.test8_D* %call, null -// CHECK-LPLL64: br i1 %1, label %2, label %12 -// CHECK-LPLL64:;

    This format specifier is used to merge multiple related diagnostics together into one common one, without requiring the difference to be specified as an English string argument. Instead of specifying the string, the diagnostic gets an integer argument and the @@ -298,7 +298,8 @@ it is 1 it prints 'binary' if it is 2, it prints 'unary or binary'. This allows other language translations to substitute reasonable words (or entire phrases) based on the semantics of the diagnostic instead of having to do - things textually. + things textually.

    +

    The selected string does undergo formatting.

    "plural" format Example:"you have %1 %plural{1:mouse|:mice}1 connected to @@ -330,6 +331,15 @@ abort, as will a failure to match the argument against any expression.

    +"ordinal" format +Example:"ambiguity in %ordinal0 argument" +Class:Integers +Description:

    This is a formatter which represents the + argument number as an ordinal: the value 1 becomes 1st, + 3 becomes 3rd, and so on. Values less than 1 + are not supported.

    +

    This formatter is currently hard-coded to use English ordinals.

    + "objcclass" format Example:"method %objcclass0 not found" Class:DeclarationName From kremenek at apple.com Thu Jan 14 13:38:41 2010 From: kremenek at apple.com (Ted Kremenek) Date: Thu, 14 Jan 2010 19:38:41 -0000 Subject: [cfe-commits] r93440 - /cfe/trunk/test/Analysis/casts.c Message-ID: <201001141938.o0EJcf3G022826@zion.cs.uiuc.edu> Author: kremenek Date: Thu Jan 14 13:38:41 2010 New Revision: 93440 URL: http://llvm.org/viewvc/llvm-project?rev=93440&view=rev Log: Associate test case with Bugzilla PR. Modified: cfe/trunk/test/Analysis/casts.c Modified: cfe/trunk/test/Analysis/casts.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/casts.c?rev=93440&r1=93439&r2=93440&view=diff ============================================================================== --- cfe/trunk/test/Analysis/casts.c (original) +++ cfe/trunk/test/Analysis/casts.c Thu Jan 14 13:38:41 2010 @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -verify %s +// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -verify %s // Test if the 'storage' region gets properly initialized after it is cast to // 'struct sockaddr *'. @@ -58,13 +59,13 @@ } } -struct pcm_feeder { +// PR 6035 - Test that a cast of a pointer to long and then to int does not crash SValuator. +struct pr6035 { void *data; }; -// Test cast a pointer to long and then to int does not crash SValuator. -void feed_swaplr (struct pcm_feeder *f) -{ - int bps; - bps = (long) f->data; - (void) bps; + +void pr6035_test (struct pr6035 *f) { + int x; + x = (long) f->data; + (void) x; } From kremenek at apple.com Thu Jan 14 13:47:50 2010 From: kremenek at apple.com (Ted Kremenek) Date: Thu, 14 Jan 2010 19:47:50 -0000 Subject: [cfe-commits] r93444 - /cfe/trunk/test/Analysis/casts.c Message-ID: <201001141947.o0EJlooM023387@zion.cs.uiuc.edu> Author: kremenek Date: Thu Jan 14 13:47:50 2010 New Revision: 93444 URL: http://llvm.org/viewvc/llvm-project?rev=93444&view=rev Log: Simplify test case. This test case also applies to PR 6013. Modified: cfe/trunk/test/Analysis/casts.c Modified: cfe/trunk/test/Analysis/casts.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/casts.c?rev=93444&r1=93443&r2=93444&view=diff ============================================================================== --- cfe/trunk/test/Analysis/casts.c (original) +++ cfe/trunk/test/Analysis/casts.c Thu Jan 14 13:47:50 2010 @@ -59,13 +59,9 @@ } } -// PR 6035 - Test that a cast of a pointer to long and then to int does not crash SValuator. -struct pr6035 { - void *data; -}; - -void pr6035_test (struct pr6035 *f) { - int x; - x = (long) f->data; - (void) x; +// PR 6013 and 6035 - Test that a cast of a pointer to long and then to int does not crash SValuator. +void pr6013_6035_test(void *p) { + unsigned int foo; + foo = ((long)(p)); + (void) foo; } From rjmccall at apple.com Thu Jan 14 14:11:40 2010 From: rjmccall at apple.com (John McCall) Date: Thu, 14 Jan 2010 20:11:40 -0000 Subject: [cfe-commits] r93447 - /cfe/trunk/lib/Basic/Diagnostic.cpp Message-ID: <201001142011.o0EKBeML024751@zion.cs.uiuc.edu> Author: rjmccall Date: Thu Jan 14 14:11:39 2010 New Revision: 93447 URL: http://llvm.org/viewvc/llvm-project?rev=93447&view=rev Log: Pre-emptive bugfixes in the diagnostics code: allow arbitrary punctuation characters to be escaped and implement a scan-forward function which properly respects brace nesting. Modified: cfe/trunk/lib/Basic/Diagnostic.cpp Modified: cfe/trunk/lib/Basic/Diagnostic.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Diagnostic.cpp?rev=93447&r1=93446&r2=93447&view=diff ============================================================================== --- cfe/trunk/lib/Basic/Diagnostic.cpp (original) +++ cfe/trunk/lib/Basic/Diagnostic.cpp Thu Jan 14 14:11:39 2010 @@ -541,6 +541,33 @@ return StrLen-1 == ModifierLen && !memcmp(Modifier, Str, StrLen-1); } +/// ScanForward - Scans forward, looking for the given character, skipping +/// nested clauses and escaped characters. +static const char *ScanFormat(const char *I, const char *E, char Target) { + unsigned Depth = 0; + + for ( ; I != E; ++I) { + if (Depth == 0 && *I == Target) return I; + if (Depth != 0 && *I == '}') Depth--; + + if (*I == '%') { + I++; + if (I == E) break; + + // Escaped characters get implicitly skipped here. + + // Format specifier. + if (!isdigit(*I) && !ispunct(*I)) { + for (I++; I != E && !isdigit(*I) && *I != '{'; I++) ; + if (I == E) break; + if (*I == '{') + Depth++; + } + } + } + return E; +} + /// HandleSelectModifier - Handle the integer 'select' modifier. This is used /// like this: %select{foo|bar|baz}2. This means that the integer argument /// "%2" has a value from 0-2. If the value is 0, the diagnostic prints 'foo'. @@ -553,7 +580,7 @@ // Skip over 'ValNo' |'s. while (ValNo) { - const char *NextVal = std::find(Argument, ArgumentEnd, '|'); + const char *NextVal = ScanFormat(Argument, ArgumentEnd, '|'); assert(NextVal != ArgumentEnd && "Value for integer select modifier was" " larger than the number of options in the diagnostic string!"); Argument = NextVal+1; // Skip this string. @@ -561,7 +588,7 @@ } // Get the end of the value. This is either the } or the |. - const char *EndPtr = std::find(Argument, ArgumentEnd, '|'); + const char *EndPtr = ScanFormat(Argument, ArgumentEnd, '|'); // Recursively format the result of the select clause into the output string. DInfo.FormatDiagnostic(Argument, EndPtr, OutStr); @@ -717,11 +744,11 @@ } if (EvalPluralExpr(ValNo, Argument, ExprEnd)) { Argument = ExprEnd + 1; - ExprEnd = std::find(Argument, ArgumentEnd, '|'); + ExprEnd = ScanFormat(Argument, ArgumentEnd, '|'); OutStr.append(Argument, ExprEnd); return; } - Argument = std::find(Argument, ArgumentEnd - 1, '|') + 1; + Argument = ScanFormat(Argument, ArgumentEnd - 1, '|') + 1; } } @@ -754,8 +781,8 @@ OutStr.append(DiagStr, StrEnd); DiagStr = StrEnd; continue; - } else if (DiagStr[1] == '%') { - OutStr.push_back('%'); // %% -> %. + } else if (ispunct(DiagStr[1])) { + OutStr.push_back(DiagStr[1]); // %% -> %. DiagStr += 2; continue; } @@ -784,8 +811,8 @@ ++DiagStr; // Skip {. Argument = DiagStr; - for (; DiagStr[0] != '}'; ++DiagStr) - assert(DiagStr[0] && "Mismatched {}'s in diagnostic string!"); + DiagStr = ScanFormat(DiagStr, DiagEnd, '}'); + assert(DiagStr != DiagEnd && "Mismatched {}'s in diagnostic string!"); ArgumentLen = DiagStr-Argument; ++DiagStr; // Skip }. } From asl at math.spbu.ru Thu Jan 14 14:22:45 2010 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Thu, 14 Jan 2010 20:22:45 -0000 Subject: [cfe-commits] r93451 - /cfe/trunk/lib/Basic/Targets.cpp Message-ID: <201001142022.o0EKMjBr025322@zion.cs.uiuc.edu> Author: asl Date: Thu Jan 14 14:22:45 2010 New Revision: 93451 URL: http://llvm.org/viewvc/llvm-project?rev=93451&view=rev Log: long long is 64 bits on msp430 Modified: cfe/trunk/lib/Basic/Targets.cpp Modified: cfe/trunk/lib/Basic/Targets.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets.cpp?rev=93451&r1=93450&r2=93451&view=diff ============================================================================== --- cfe/trunk/lib/Basic/Targets.cpp (original) +++ cfe/trunk/lib/Basic/Targets.cpp Thu Jan 14 14:22:45 2010 @@ -1657,7 +1657,8 @@ MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) { TLSSupported = false; IntWidth = 16; - LongWidth = LongLongWidth = 32; + LongWidth = 32; + LongLongWidth = 64; PointerWidth = 16; IntAlign = 8; LongAlign = LongLongAlign = 8; From Ken.Dyck at onsemi.com Thu Jan 14 14:39:17 2010 From: Ken.Dyck at onsemi.com (Ken Dyck) Date: Thu, 14 Jan 2010 13:39:17 -0700 Subject: [cfe-commits] r93451 - /cfe/trunk/lib/Basic/Targets.cpp In-Reply-To: <201001142022.o0EKMjBr025322@zion.cs.uiuc.edu> References: <201001142022.o0EKMjBr025322@zion.cs.uiuc.edu> Message-ID: <8F2E4A8BCDA0B84DA6C9088EB5B27747E660EC@NAMAIL.ad.onsemi.com> Hi Anton, Have you tried running the Preprocessor tests after making this change? I believe init.c and stdint.c tests will need updating. -Ken > -----Original Message----- > From: cfe-commits-bounces at cs.uiuc.edu > [mailto:cfe-commits-bounces at cs.uiuc.edu] On Behalf Of Anton > Korobeynikov > Sent: Thursday, January 14, 2010 3:23 PM > To: cfe-commits at cs.uiuc.edu > Subject: [cfe-commits] r93451 - /cfe/trunk/lib/Basic/Targets.cpp > > Author: asl > Date: Thu Jan 14 14:22:45 2010 > New Revision: 93451 > > URL: http://llvm.org/viewvc/llvm-project?rev=93451&view=rev > Log: > long long is 64 bits on msp430 > > Modified: > cfe/trunk/lib/Basic/Targets.cpp > > Modified: cfe/trunk/lib/Basic/Targets.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Target > s.cpp?rev=93451&r1=93450&r2=93451&view=diff > > ============================================================== > ================ > --- cfe/trunk/lib/Basic/Targets.cpp (original) > +++ cfe/trunk/lib/Basic/Targets.cpp Thu Jan 14 14:22:45 2010 > @@ -1657,7 +1657,8 @@ > MSP430TargetInfo(const std::string& triple) : > TargetInfo(triple) { > TLSSupported = false; > IntWidth = 16; > - LongWidth = LongLongWidth = 32; > + LongWidth = 32; > + LongLongWidth = 64; > PointerWidth = 16; > IntAlign = 8; > LongAlign = LongLongAlign = 8; > > > _______________________________________________ > cfe-commits mailing list > cfe-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits > From sabre at nondot.org Thu Jan 14 15:00:58 2010 From: sabre at nondot.org (Chris Lattner) Date: Thu, 14 Jan 2010 21:00:58 -0000 Subject: [cfe-commits] r93452 - /cfe/trunk/lib/Sema/SemaDecl.cpp Message-ID: <201001142100.o0EL0xav026753@zion.cs.uiuc.edu> Author: lattner Date: Thu Jan 14 15:00:58 2010 New Revision: 93452 URL: http://llvm.org/viewvc/llvm-project?rev=93452&view=rev Log: fix grammaro Modified: cfe/trunk/lib/Sema/SemaDecl.cpp Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=93452&r1=93451&r2=93452&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Jan 14 15:00:58 2010 @@ -1330,7 +1330,7 @@ /// CheckUnreachable - Check for unreachable code. void Sema::CheckUnreachable(AnalysisContext &AC) { // We avoid checking when there are errors, as the CFG won't faithfully match - // the users code. + // the user's code. if (getDiagnostics().hasErrorOccurred()) return; if (Diags.getDiagnosticLevel(diag::warn_unreachable) == Diagnostic::Ignored) From asl at math.spbu.ru Thu Jan 14 15:36:52 2010 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Thu, 14 Jan 2010 21:36:52 -0000 Subject: [cfe-commits] r93458 - in /cfe/trunk/test/Preprocessor: init.c stdint.c Message-ID: <201001142136.o0ELaqiG028178@zion.cs.uiuc.edu> Author: asl Date: Thu Jan 14 15:36:52 2010 New Revision: 93458 URL: http://llvm.org/viewvc/llvm-project?rev=93458&view=rev Log: Forgot to commit these Modified: cfe/trunk/test/Preprocessor/init.c cfe/trunk/test/Preprocessor/stdint.c Modified: cfe/trunk/test/Preprocessor/init.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/init.c?rev=93458&r1=93457&r2=93458&view=diff ============================================================================== --- cfe/trunk/test/Preprocessor/init.c (original) +++ cfe/trunk/test/Preprocessor/init.c Thu Jan 14 15:36:52 2010 @@ -420,7 +420,7 @@ // MSP430:#define __LDBL_MIN_10_EXP__ (-307) // MSP430:#define __LDBL_MIN_EXP__ (-1021) // MSP430:#define __LDBL_MIN__ 2.2250738585072014e-308 -// MSP430:#define __LONG_LONG_MAX__ 2147483647LL +// MSP430:#define __LONG_LONG_MAX__ 9223372036854775807LL // MSP430:#define __LONG_MAX__ 2147483647L // MSP430:#define __MSP430__ 1 // MSP430:#define __NO_INLINE__ 1 Modified: cfe/trunk/test/Preprocessor/stdint.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/stdint.c?rev=93458&r1=93457&r2=93458&view=diff ============================================================================== --- cfe/trunk/test/Preprocessor/stdint.c (original) +++ cfe/trunk/test/Preprocessor/stdint.c Thu Jan 14 15:36:52 2010 @@ -380,15 +380,15 @@ // MSP430:INT_FAST32_MAX_ 2147483647L // MSP430:UINT_FAST32_MAX_ 4294967295UL // -// MSP430:INT64_MAX_ INT64_MAX -// MSP430:INT64_MIN_ INT64_MIN -// MSP430:UINT64_MAX_ UINT64_MAX -// MSP430:INT_LEAST64_MIN_ INT_LEAST64_MIN -// MSP430:INT_LEAST64_MAX_ INT_LEAST64_MAX -// MSP430:UINT_LEAST64_MAX_ UINT_LEAST64_MAX -// MSP430:INT_FAST64_MIN_ INT_FAST64_MIN -// MSP430:INT_FAST64_MAX_ INT_FAST64_MAX -// MSP430:UINT_FAST64_MAX_ UINT_FAST64_MAX +// MSP430:INT64_MAX_ 9223372036854775807LL +// MSP430:INT64_MIN_ (-9223372036854775807LL -1) +// MSP430:UINT64_MAX_ 18446744073709551615ULL +// MSP430:INT_LEAST64_MIN_ (-9223372036854775807LL -1) +// MSP430:INT_LEAST64_MAX_ 9223372036854775807LL +// MSP430:UINT_LEAST64_MAX_ 18446744073709551615ULL +// MSP430:INT_FAST64_MIN_ (-9223372036854775807LL -1) +// MSP430:INT_FAST64_MAX_ 9223372036854775807LL +// MSP430:UINT_FAST64_MAX_ 18446744073709551615ULL // // MSP430:INTPTR_MIN_ (-32767 -1) // MSP430:INTPTR_MAX_ 32767 @@ -415,8 +415,8 @@ // MSP430:UINT16_C_(0) 0U // MSP430:INT32_C_(0) 0L // MSP430:UINT32_C_(0) 0UL -// MSP430:INT64_C_(0) INT64_C(0) -// MSP430:UINT64_C_(0) UINT64_C(0) +// MSP430:INT64_C_(0) 0LL +// MSP430:UINT64_C_(0) 0ULL // // MSP430:INTMAX_C_(0) 0L // MSP430:UINTMAX_C_(0) 0UL From asl at math.spbu.ru Thu Jan 14 15:39:40 2010 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Fri, 15 Jan 2010 00:39:40 +0300 Subject: [cfe-commits] r93451 - /cfe/trunk/lib/Basic/Targets.cpp In-Reply-To: <8F2E4A8BCDA0B84DA6C9088EB5B27747E660EC@NAMAIL.ad.onsemi.com> References: <201001142022.o0EKMjBr025322@zion.cs.uiuc.edu> <8F2E4A8BCDA0B84DA6C9088EB5B27747E660EC@NAMAIL.ad.onsemi.com> Message-ID: Hi, Ken > Have you tried running the Preprocessor tests after making this change? > I believe init.c and stdint.c tests will need updating. Doh, forgot to commit them! -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From dpatel at apple.com Thu Jan 14 15:46:57 2010 From: dpatel at apple.com (Devang Patel) Date: Thu, 14 Jan 2010 21:46:57 -0000 Subject: [cfe-commits] r93461 - /cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Message-ID: <201001142146.o0ELkw9G028666@zion.cs.uiuc.edu> Author: dpatel Date: Thu Jan 14 15:46:57 2010 New Revision: 93461 URL: http://llvm.org/viewvc/llvm-project?rev=93461&view=rev Log: Emit linkage name even if it matches regular name. The code generator uses linkage name to find subprogram entry for the current function. Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=93461&r1=93460&r2=93461&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original) +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Thu Jan 14 15:46:57 2010 @@ -1001,10 +1001,10 @@ const Decl *D = GD.getDecl(); if (const FunctionDecl *FD = dyn_cast(D)) { Name = getFunctionName(FD); + if (Name[0] == '\01') + Name = Name.substr(1); // Use mangled name as linkage name for c/c++ functions. - llvm::StringRef MangledName(CGM.getMangledName(GD)); - if (!Name.equals(MangledName)) - LinkageName = MangledName; + LinkageName = CGM.getMangledName(GD); } else { // Use llvm function name as linkage name. Name = Fn->getName(); From fjahanian at apple.com Thu Jan 14 17:05:53 2010 From: fjahanian at apple.com (Fariborz Jahanian) Date: Thu, 14 Jan 2010 23:05:53 -0000 Subject: [cfe-commits] r93474 - in /cfe/trunk: lib/Frontend/RewriteObjC.cpp test/Rewriter/rewrite-byref-vars.mm Message-ID: <201001142305.o0EN5rdf032232@zion.cs.uiuc.edu> Author: fjahanian Date: Thu Jan 14 17:05:52 2010 New Revision: 93474 URL: http://llvm.org/viewvc/llvm-project?rev=93474&view=rev Log: Patch to avoid duplicate declaration of byref structs for __block variables of same name declared in multiple scopes. Fixes radar 7540194 Added: cfe/trunk/test/Rewriter/rewrite-byref-vars.mm Modified: cfe/trunk/lib/Frontend/RewriteObjC.cpp Modified: cfe/trunk/lib/Frontend/RewriteObjC.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/RewriteObjC.cpp?rev=93474&r1=93473&r2=93474&view=diff ============================================================================== --- cfe/trunk/lib/Frontend/RewriteObjC.cpp (original) +++ cfe/trunk/lib/Frontend/RewriteObjC.cpp Thu Jan 14 17:05:52 2010 @@ -126,6 +126,7 @@ // Block related declarations. llvm::SmallPtrSet BlockByCopyDecls; llvm::SmallPtrSet BlockByRefDecls; + llvm::DenseMap BlockByRefDeclNo; llvm::SmallPtrSet ImportedBlockDecls; llvm::DenseMap RewrittenBlockExprs; @@ -252,6 +253,8 @@ void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl); void RewriteImplementationDecl(Decl *Dcl); void RewriteObjCMethodDecl(ObjCMethodDecl *MDecl, std::string &ResultStr); + void RewriteByRefString(std::string &ResultStr, const std::string &Name, + ValueDecl *VD); void RewriteCategoryDecl(ObjCCategoryDecl *Dcl); void RewriteProtocolDecl(ObjCProtocolDecl *Dcl); void RewriteForwardProtocolDecl(ObjCForwardProtocolDecl *Dcl); @@ -3760,6 +3763,15 @@ } } +void RewriteObjC::RewriteByRefString(std::string &ResultStr, + const std::string &Name, + ValueDecl *VD) { + assert(BlockByRefDeclNo.count(VD) && + "RewriteByRefString: ByRef decl missing"); + ResultStr += "struct __Block_byref_" + Name + + "_" + utostr(BlockByRefDeclNo[VD]) ; +} + std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i, const char *funcName, std::string Tag) { @@ -3805,7 +3817,9 @@ E = BlockByRefDecls.end(); I != E; ++I) { S += " "; std::string Name = (*I)->getNameAsString(); - std::string TypeString = "struct __Block_byref_" + Name + " *"; + std::string TypeString; + RewriteByRefString(TypeString, Name, (*I)); + TypeString += " *"; Name = TypeString + Name; S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n"; } @@ -3940,7 +3954,8 @@ S += "struct __block_impl *"; Constructor += ", void *" + ArgName; } else { - std::string TypeString = "struct __Block_byref_" + FieldName; + std::string TypeString; + RewriteByRefString(TypeString, FieldName, (*I)); TypeString += " *"; FieldName = TypeString + FieldName; ArgName = TypeString + ArgName; @@ -4521,11 +4536,12 @@ X = SM->getInstantiationLoc(X); const char *endBuf = SM->getCharacterData(X); std::string Name(ND->getNameAsString()); - std::string ByrefType = "struct __Block_byref_"; - ByrefType += Name; + std::string ByrefType; + RewriteByRefString(ByrefType, Name, ND); ByrefType += " {\n"; ByrefType += " void *__isa;\n"; - ByrefType += " struct __Block_byref_" + Name + " *__forwarding;\n"; + RewriteByRefString(ByrefType, Name, ND); + ByrefType += " *__forwarding;\n"; ByrefType += " int __flags;\n"; ByrefType += " int __size;\n"; // Add void *__Block_byref_id_object_copy; @@ -4570,14 +4586,17 @@ if (HasCopyAndDispose) flags |= BLOCK_HAS_COPY_DISPOSE; Name = ND->getNameAsString(); - ByrefType = "struct __Block_byref_" + Name; + ByrefType.clear(); + RewriteByRefString(ByrefType, Name, ND); if (!hasInit) { ByrefType += " " + Name + " = {(void*)"; ByrefType += utostr(isa); ByrefType += ", &" + Name + ", "; ByrefType += utostr(flags); ByrefType += ", "; - ByrefType += "sizeof(struct __Block_byref_" + Name + ")"; + ByrefType += "sizeof("; + RewriteByRefString(ByrefType, Name, ND); + ByrefType += ")"; if (HasCopyAndDispose) { ByrefType += ", __Block_byref_id_object_copy_"; ByrefType += utostr(flag); @@ -4599,7 +4618,9 @@ ByrefType += ", &" + Name + ", "; ByrefType += utostr(flags); ByrefType += ", "; - ByrefType += "sizeof(struct __Block_byref_" + Name + "), "; + ByrefType += "sizeof("; + RewriteByRefString(ByrefType, Name, ND); + ByrefType += "), "; if (HasCopyAndDispose) { ByrefType += "__Block_byref_id_object_copy_"; ByrefType += utostr(flag); @@ -4971,8 +4992,13 @@ else if (ND->getType()->isFunctionPointerType()) CheckFunctionPointerDecl(ND->getType(), ND); if (VarDecl *VD = dyn_cast(SD)) - if (VD->hasAttr()) + if (VD->hasAttr()) { + static unsigned uniqueByrefDeclCount = 0; + assert(!BlockByRefDeclNo.count(ND) && + "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl"); + BlockByRefDeclNo[ND] = uniqueByrefDeclCount++; RewriteByRefVar(VD); + } } if (TypedefDecl *TD = dyn_cast(SD)) { if (isTopLevelBlockPointerType(TD->getUnderlyingType())) Added: cfe/trunk/test/Rewriter/rewrite-byref-vars.mm URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Rewriter/rewrite-byref-vars.mm?rev=93474&view=auto ============================================================================== --- cfe/trunk/test/Rewriter/rewrite-byref-vars.mm (added) +++ cfe/trunk/test/Rewriter/rewrite-byref-vars.mm Thu Jan 14 17:05:52 2010 @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -fms-extensions -rewrite-objc -x objective-c++ -fblocks -o - %s +// radar 7540194 + +extern "C" __declspec(dllexport) void BreakTheRewriter(int i) { + __block int aBlockVariable = 0; + void (^aBlock)(void) = ^ { + aBlockVariable = 42; + }; + aBlockVariable++; + if (i) { + __block int bbBlockVariable = 0; + void (^aBlock)(void) = ^ { + bbBlockVariable = 42; + }; + } +} + +__declspec(dllexport) extern "C" __declspec(dllexport) void XXXXBreakTheRewriter(void) { + + __block int aBlockVariable = 0; + void (^aBlock)(void) = ^ { + aBlockVariable = 42; + }; + aBlockVariable++; + void (^bBlocks)(void) = ^ { + aBlockVariable = 43; + }; + void (^c)(void) = ^ { + aBlockVariable = 44; + }; + +} + +// $CLANG -cc1 -fms-extensions -rewrite-objc -x objective-c++ -fblocks bug.mm +// g++ -c -D"__declspec(X)=" bug.cpp From mrs at apple.com Thu Jan 14 18:50:36 2010 From: mrs at apple.com (Mike Stump) Date: Fri, 15 Jan 2010 00:50:36 -0000 Subject: [cfe-commits] r93493 - /cfe/trunk/test/CodeGenCXX/dyncast.cpp Message-ID: <201001150050.o0F0oaIa003519@zion.cs.uiuc.edu> Author: mrs Date: Thu Jan 14 18:50:35 2010 New Revision: 93493 URL: http://llvm.org/viewvc/llvm-project?rev=93493&view=rev Log: Fix Release-Asserts for the time being. Modified: cfe/trunk/test/CodeGenCXX/dyncast.cpp Modified: cfe/trunk/test/CodeGenCXX/dyncast.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dyncast.cpp?rev=93493&r1=93492&r2=93493&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/dyncast.cpp (original) +++ cfe/trunk/test/CodeGenCXX/dyncast.cpp Thu Jan 14 18:50:35 2010 @@ -59,356 +59,355 @@ } // CHECK-LL: define void @_Z5test1v() nounwind { -// CHECK-LL-NEXT:entry: -// CHECK-LL-NEXT: %bp = alloca %class.test1_A*, align 8 -// CHECK-LL-NEXT: %ap = alloca %class.test1_A*, align 8 -// CHECK-LL-NEXT: %dp = alloca %class.test1_D*, align 8 -// CHECK-LL-NEXT: %ap37 = alloca %class.test1_A*, align 8 -// CHECK-LL-NEXT: %dp53 = alloca %class.test1_D*, align 8 -// CHECK-LL-NEXT: %ep1 = alloca %class.test1_E*, align 8 -// CHECK-LL-NEXT: %cdp = alloca %class.test1_D*, align 8 -// CHECK-LL-NEXT: %ep = alloca %class.test1_E*, align 8 -// CHECK-LL-NEXT: %vp = alloca i8*, align 8 -// CHECK-LL-NEXT: %cvp = alloca i8*, align 8 -// CHECK-LL-NEXT: br i1 false, label %cast.null, label %cast.notnull -// CHECK-LL: cast.notnull: -// CHECK-LL-NEXT: br label %cast.end -// CHECK-LL: cast.null: -// CHECK-LL-NEXT: br label %cast.end -// CHECK-LL: cast.end: -// CHECK-LL-NEXT: %0 = phi %class.test1_A* [ bitcast (%class.test1_D* @test1_d to %class.test1_A*), %cast.notnull ], [ null, %cast.null ] -// CHECK-LL-NEXT: store %class.test1_A* %0, %class.test1_A** %bp -// CHECK-LL-NEXT: br i1 false, label %cast.null2, label %cast.notnull1 -// CHECK-LL: cast.notnull1: -// CHECK-LL-NEXT: %vtable = load i8** bitcast (%class.test1_D* @test1_d to i8**) -// CHECK-LL-NEXT: %vbase.offset.ptr = getelementptr i8* %vtable, i64 -24 -// CHECK-LL-NEXT: %1 = bitcast i8* %vbase.offset.ptr to i64* -// CHECK-LL-NEXT: %vbase.offset = load i64* %1 -// CHECK-LL-NEXT: %add.ptr = getelementptr i8* getelementptr inbounds (%class.test1_D* @test1_d, i32 0, i32 0, i32 0), i64 %vbase.offset -// CHECK-LL-NEXT: %2 = bitcast i8* %add.ptr to %class.test1_A* -// CHECK-LL-NEXT: br label %cast.end3 -// CHECK-LL: cast.null2: -// CHECK-LL-NEXT: br label %cast.end3 -// CHECK-LL: cast.end3: -// CHECK-LL-NEXT: %3 = phi %class.test1_A* [ %2, %cast.notnull1 ], [ null, %cast.null2 ] -// CHECK-LL-NEXT: store %class.test1_A* %3, %class.test1_A** %ap -// CHECK-LL-NEXT: %tmp = load %class.test1_A** %bp -// CHECK-LL-NEXT: %4 = icmp ne %class.test1_A* %tmp, null -// CHECK-LL-NEXT: br i1 %4, label %5, label %9 -// CHECK-LL: ;