Vendor import of clang release_31 final r156748:

http://llvm.org/svn/llvm-project/cfe/tags/RELEASE_31/final@156748
This commit is contained in:
Dimitry Andric 2012-05-22 21:36:38 +00:00
parent 6b9a6e390f
commit e51da3eab6
36 changed files with 546 additions and 390 deletions

View File

@ -118,8 +118,8 @@ modes.</p>
<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
<h4 id="cxx11changes">C++11 Feature Support</h4>
<p>Clang 3.1 adds support for
<a href="http://clang.llvm.org/cxx_status.html#cxx11">more of the language
<p>Clang 3.1 supports
<a href="http://clang.llvm.org/cxx_status.html#cxx11">most of the language
features</a> added in the latest ISO C++ standard,
<a href="http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=50372">C++ 2011</a>.
Use <code>-std=c++11</code> or <code>-std=gnu++11</code> to enable support for

View File

@ -64,9 +64,6 @@ public:
/// \brief Return the TypeLoc wrapper for the type source info.
TypeLoc getTypeLoc() const; // implemented in TypeLoc.h
/// \brief Override the type stored in this TypeSourceInfo. Use with caution!
void overrideType(QualType T) { Ty = T; }
};
/// TranslationUnitDecl - The top declaration context.

View File

@ -410,8 +410,6 @@ def ext_ellipsis_exception_spec : Extension<
"exception specification of '...' is a Microsoft extension">;
def err_dynamic_and_noexcept_specification : Error<
"cannot have both throw() and noexcept() clause on the same function">;
def err_except_spec_unparsed : Error<
"unexpected end of exception specification">;
def warn_cxx98_compat_noexcept_decl : Warning<
"noexcept specifications are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;

View File

@ -105,7 +105,6 @@ TOK(eod) // End of preprocessing directive (end of line inside a
// directive).
TOK(code_completion) // Code completion marker
TOK(cxx_defaultarg_end) // C++ default argument end marker
TOK(cxx_exceptspec_end) // C++ exception-specification end marker
// C99 6.4.9: Comments.
TOK(comment) // Comment (only in -E -C[C] mode)

View File

@ -584,11 +584,15 @@ private:
class TentativeParsingAction {
Parser &P;
Token PrevTok;
unsigned short PrevParenCount, PrevBracketCount, PrevBraceCount;
bool isActive;
public:
explicit TentativeParsingAction(Parser& p) : P(p) {
PrevTok = P.Tok;
PrevParenCount = P.ParenCount;
PrevBracketCount = P.BracketCount;
PrevBraceCount = P.BraceCount;
P.PP.EnableBacktrackAtThisPos();
isActive = true;
}
@ -601,6 +605,9 @@ private:
assert(isActive && "Parsing action was finished!");
P.PP.Backtrack();
P.Tok = PrevTok;
P.ParenCount = PrevParenCount;
P.BracketCount = PrevBracketCount;
P.BraceCount = PrevBraceCount;
isActive = false;
}
~TentativeParsingAction() {
@ -1422,12 +1429,10 @@ private:
ExprResult ParseThrowExpression();
ExceptionSpecificationType tryParseExceptionSpecification(
bool Delayed,
SourceRange &SpecificationRange,
SmallVectorImpl<ParsedType> &DynamicExceptions,
SmallVectorImpl<SourceRange> &DynamicExceptionRanges,
ExprResult &NoexceptExpr,
CachedTokens *&ExceptionSpecTokens);
ExprResult &NoexceptExpr);
// EndLoc is filled with the location of the last token of the specification.
ExceptionSpecificationType ParseDynamicExceptionSpecification(

View File

@ -1150,10 +1150,6 @@ struct DeclaratorChunk {
/// \brief Pointer to the expression in the noexcept-specifier of this
/// function, if it has one.
Expr *NoexceptExpr;
/// \brief Pointer to the cached tokens for an exception-specification
/// that has not yet been parsed.
CachedTokens *ExceptionSpecTokens;
};
/// TrailingReturnType - If this isn't null, it's the trailing return type
@ -1176,8 +1172,6 @@ struct DeclaratorChunk {
delete[] ArgInfo;
if (getExceptionSpecType() == EST_Dynamic)
delete[] Exceptions;
else if (getExceptionSpecType() == EST_Delayed)
delete ExceptionSpecTokens;
}
/// isKNRPrototype - Return true if this is a K&R style identifier list,
@ -1353,7 +1347,6 @@ struct DeclaratorChunk {
SourceRange *ExceptionRanges,
unsigned NumExceptions,
Expr *NoexceptExpr,
CachedTokens *ExceptionSpecTokens,
SourceLocation LocalRangeBegin,
SourceLocation LocalRangeEnd,
Declarator &TheDeclarator,

View File

@ -225,7 +225,9 @@ public:
/// \brief Create the initialization entity for a temporary.
static InitializedEntity InitializeTemporary(QualType Type) {
return InitializedEntity(EK_Temporary, SourceLocation(), Type);
InitializedEntity Result(EK_Temporary, SourceLocation(), Type);
Result.TypeInfo = 0;
return Result;
}
/// \brief Create the initialization entity for a temporary.

View File

@ -331,6 +331,11 @@ public:
/// cycle detection at the end of the TU.
DelegatingCtorDeclsType DelegatingCtorDecls;
/// \brief All the destructors seen during a class definition that had their
/// exception spec computation delayed because it depended on an unparsed
/// exception spec.
SmallVector<CXXDestructorDecl*, 2> DelayedDestructorExceptionSpecs;
/// \brief All the overriding destructors seen during a class definition
/// (there could be multiple due to nested classes) that had their exception
/// spec checks delayed, plus the overridden destructor.
@ -653,23 +658,19 @@ public:
/// SpecialMemberOverloadResult - The overloading result for a special member
/// function.
///
/// This is basically a wrapper around PointerIntPair. The lowest bit of the
/// integer is used to determine whether we have a parameter qualification
/// match, the second-lowest is whether we had success in resolving the
/// overload to a unique non-deleted function.
///
/// The ConstParamMatch bit represents whether, when looking up a copy
/// constructor or assignment operator, we found a potential copy
/// constructor/assignment operator whose first parameter is const-qualified.
/// This is used for determining parameter types of other objects and is
/// utterly meaningless on other types of special members.
/// This is basically a wrapper around PointerIntPair. The lowest bits of the
/// integer are used to determine whether overload resolution succeeded, and
/// whether, when looking up a copy constructor or assignment operator, we
/// found a potential copy constructor/assignment operator whose first
/// parameter is const-qualified. This is used for determining parameter types
/// of other objects and is utterly meaningless on other types of special
/// members.
class SpecialMemberOverloadResult : public llvm::FastFoldingSetNode {
public:
enum Kind {
NoMemberOrDeleted,
Ambiguous,
SuccessNonConst,
SuccessConst
Success
};
private:
@ -685,9 +686,6 @@ public:
Kind getKind() const { return static_cast<Kind>(Pair.getInt()); }
void setKind(Kind K) { Pair.setInt(K); }
bool hasSuccess() const { return getKind() >= SuccessNonConst; }
bool hasConstParamMatch() const { return getKind() == SuccessConst; }
};
/// \brief A cache of special member function overload resolution results
@ -1909,11 +1907,9 @@ public:
DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class);
CXXConstructorDecl *LookupDefaultConstructor(CXXRecordDecl *Class);
CXXConstructorDecl *LookupCopyingConstructor(CXXRecordDecl *Class,
unsigned Quals,
bool *ConstParam = 0);
unsigned Quals);
CXXMethodDecl *LookupCopyingAssignment(CXXRecordDecl *Class, unsigned Quals,
bool RValueThis, unsigned ThisQuals,
bool *ConstParam = 0);
bool RValueThis, unsigned ThisQuals);
CXXConstructorDecl *LookupMovingConstructor(CXXRecordDecl *Class);
CXXMethodDecl *LookupMovingAssignment(CXXRecordDecl *Class, bool RValueThis,
unsigned ThisQuals);
@ -3158,16 +3154,6 @@ public:
llvm::SmallVectorImpl<QualType> &Exceptions,
FunctionProtoType::ExtProtoInfo &EPI);
/// \brief Add an exception-specification to the given member function
/// (or member function template). The exception-specification was parsed
/// after the method itself was declared.
void actOnDelayedExceptionSpecification(Decl *Method,
ExceptionSpecificationType EST,
SourceRange SpecificationRange,
ArrayRef<ParsedType> DynamicExceptions,
ArrayRef<SourceRange> DynamicExceptionRanges,
Expr *NoexceptExpr);
/// \brief Determine if a special member function should have a deleted
/// definition when it is defaulted.
bool ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM,
@ -3205,7 +3191,8 @@ public:
/// C++11 says that user-defined destructors with no exception spec get one
/// that looks as if the destructor was implicitly declared.
void AdjustDestructorExceptionSpec(CXXRecordDecl *ClassDecl,
CXXDestructorDecl *Destructor);
CXXDestructorDecl *Destructor,
bool WasDelayed = false);
/// \brief Declare all inherited constructors for the given class.
///
@ -4043,6 +4030,7 @@ public:
SourceLocation LBrac,
SourceLocation RBrac,
AttributeList *AttrList);
void ActOnFinishCXXMemberDecls();
void ActOnReenterTemplateScope(Scope *S, Decl *Template);
void ActOnReenterDeclaratorTemplateScope(Scope *S, DeclaratorDecl *D);

View File

@ -168,7 +168,8 @@ static const BinaryOperator *getLogicalOperatorInChain(const CFGBlock *block) {
if (block->empty())
return 0;
const CFGStmt *cstmt = block->front().getAs<CFGStmt>();
CFGElement front = block->front();
const CFGStmt *cstmt = front.getAs<CFGStmt>();
if (!cstmt)
return 0;

View File

@ -32,7 +32,7 @@ std::string getClangRepositoryPath() {
// If the SVN_REPOSITORY is empty, try to use the SVN keyword. This helps us
// pick up a tag in an SVN export, for example.
static StringRef SVNRepository("$URL: http://llvm.org/svn/llvm-project/cfe/branches/release_31/lib/Basic/Version.cpp $");
static StringRef SVNRepository("$URL: http://llvm.org/svn/llvm-project/cfe/tags/RELEASE_31/final/lib/Basic/Version.cpp $");
if (URL.empty()) {
URL = SVNRepository.slice(SVNRepository.find(':'),
SVNRepository.find("/lib/Basic"));

View File

@ -1830,6 +1830,7 @@ enum LinuxDistro {
OpenSuse11_3,
OpenSuse11_4,
OpenSuse12_1,
OpenSuse12_2,
UbuntuHardy,
UbuntuIntrepid,
UbuntuJaunty,
@ -1848,7 +1849,7 @@ static bool IsRedhat(enum LinuxDistro Distro) {
}
static bool IsOpenSuse(enum LinuxDistro Distro) {
return Distro >= OpenSuse11_3 && Distro <= OpenSuse12_1;
return Distro >= OpenSuse11_3 && Distro <= OpenSuse12_2;
}
static bool IsDebian(enum LinuxDistro Distro) {
@ -1925,6 +1926,7 @@ static LinuxDistro DetectLinuxDistro(llvm::Triple::ArchType Arch) {
.StartsWith("openSUSE 11.3", OpenSuse11_3)
.StartsWith("openSUSE 11.4", OpenSuse11_4)
.StartsWith("openSUSE 12.1", OpenSuse12_1)
.StartsWith("openSUSE 12.2", OpenSuse12_2)
.Default(UnknownDistro);
bool Exists;

View File

@ -348,77 +348,7 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
LM.DefaultArgs[I].Toks = 0;
}
}
// Parse a delayed exception-specification, if there is one.
if (CachedTokens *Toks = LM.ExceptionSpecTokens) {
// Save the current token position.
SourceLocation origLoc = Tok.getLocation();
// Parse the default argument from its saved token stream.
Toks->push_back(Tok); // So that the current token doesn't get lost
PP.EnterTokenStream(&Toks->front(), Toks->size(), true, false);
// Consume the previously-pushed token.
ConsumeAnyToken();
// C++11 [expr.prim.general]p3:
// If a declaration declares a member function or member function
// template of a class X, the expression this is a prvalue of type
// "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
// and the end of the function-definition, member-declarator, or
// declarator.
CXXMethodDecl *Method;
if (FunctionTemplateDecl *FunTmpl
= dyn_cast<FunctionTemplateDecl>(LM.Method))
Method = cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
else
Method = cast<CXXMethodDecl>(LM.Method);
Sema::CXXThisScopeRAII ThisScope(Actions, Method->getParent(),
Method->getTypeQualifiers(),
getLangOpts().CPlusPlus0x);
// Parse the exception-specification.
SourceRange SpecificationRange;
SmallVector<ParsedType, 4> DynamicExceptions;
SmallVector<SourceRange, 4> DynamicExceptionRanges;
ExprResult NoexceptExpr;
CachedTokens *ExceptionSpecTokens;
ExceptionSpecificationType EST
= tryParseExceptionSpecification(/*Delayed=*/false, SpecificationRange,
DynamicExceptions,
DynamicExceptionRanges, NoexceptExpr,
ExceptionSpecTokens);
// Clean up the remaining tokens.
if (Tok.is(tok::cxx_exceptspec_end))
ConsumeToken();
else if (EST != EST_None)
Diag(Tok.getLocation(), diag::err_except_spec_unparsed);
// Attach the exception-specification to the method.
if (EST != EST_None)
Actions.actOnDelayedExceptionSpecification(LM.Method, EST,
SpecificationRange,
DynamicExceptions,
DynamicExceptionRanges,
NoexceptExpr.isUsable()?
NoexceptExpr.get() : 0);
assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc,
Tok.getLocation()) &&
"tryParseExceptionSpecification went over the exception tokens!");
// There could be leftover tokens (e.g. because of an error).
// Skip through until we reach the original token position.
while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
ConsumeAnyToken();
delete LM.ExceptionSpecTokens;
LM.ExceptionSpecTokens = 0;
}
PrototypeScope.Exit();
// Finish the delayed C++ method declaration.

View File

@ -4197,7 +4197,6 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
SmallVector<ParsedType, 2> DynamicExceptions;
SmallVector<SourceRange, 2> DynamicExceptionRanges;
ExprResult NoexceptExpr;
CachedTokens *ExceptionSpecTokens = 0;
ParsedAttributes FnAttrs(AttrFactory);
ParsedType TrailingReturnType;
@ -4264,18 +4263,12 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
dyn_cast<CXXRecordDecl>(Actions.CurContext),
DS.getTypeQualifiers(),
IsCXX11MemberFunction);
// Parse exception-specification[opt].
bool Delayed = (D.getContext() == Declarator::MemberContext &&
D.getDeclSpec().getStorageClassSpec()
!= DeclSpec::SCS_typedef &&
!D.getDeclSpec().isFriendSpecified());
ESpecType = tryParseExceptionSpecification(Delayed,
ESpecRange,
ESpecType = tryParseExceptionSpecification(ESpecRange,
DynamicExceptions,
DynamicExceptionRanges,
NoexceptExpr,
ExceptionSpecTokens);
NoexceptExpr);
if (ESpecType != EST_None)
EndLoc = ESpecRange.getEnd();
@ -4310,7 +4303,6 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
DynamicExceptions.size(),
NoexceptExpr.isUsable() ?
NoexceptExpr.get() : 0,
ExceptionSpecTokens,
Tracker.getOpenLocation(),
EndLoc, D,
TrailingReturnType),

View File

@ -1535,34 +1535,16 @@ AccessSpecifier Parser::getAccessSpecifierIfPresent() const {
}
/// \brief If the given declarator has any parts for which parsing has to be
/// delayed, e.g., default arguments or an exception-specification, create a
/// late-parsed method declaration record to handle the parsing at the end of
/// the class definition.
/// delayed, e.g., default arguments, create a late-parsed method declaration
/// record to handle the parsing at the end of the class definition.
void Parser::HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo,
Decl *ThisDecl) {
// We just declared a member function. If this member function
// has any default arguments or an exception-specification, we'll need to
// parse them later.
// has any default arguments, we'll need to parse them later.
LateParsedMethodDeclaration *LateMethod = 0;
DeclaratorChunk::FunctionTypeInfo &FTI
= DeclaratorInfo.getFunctionTypeInfo();
// If there was a delayed exception-specification, hold onto its tokens.
if (FTI.getExceptionSpecType() == EST_Delayed) {
// Push this method onto the stack of late-parsed method
// declarations.
LateMethod = new LateParsedMethodDeclaration(this, ThisDecl);
getCurrentClass().LateParsedDeclarations.push_back(LateMethod);
LateMethod->TemplateScope = getCurScope()->isTemplateParamScope();
// Stash the exception-specification tokens in the late-pased mthod.
LateMethod->ExceptionSpecTokens = FTI.ExceptionSpecTokens;
FTI.ExceptionSpecTokens = 0;
// Reserve space for the parameters.
LateMethod->DefaultArgs.reserve(FTI.NumArgs);
}
for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) {
if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) {
if (!LateMethod) {
@ -1846,7 +1828,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
// Parse the first declarator.
ParseDeclarator(DeclaratorInfo);
// Error parsin g the declarator?
// Error parsing the declarator?
if (!DeclaratorInfo.hasName()) {
// If so, skip until the semi-colon or a }.
SkipUntil(tok::r_brace, true, true);
@ -2065,7 +2047,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
DeclsInGroup.push_back(ThisDecl);
}
if (DeclaratorInfo.isFunctionDeclarator() &&
if (ThisDecl && DeclaratorInfo.isFunctionDeclarator() &&
DeclaratorInfo.getDeclSpec().getStorageClassSpec()
!= DeclSpec::SCS_typedef) {
HandleMemberFunctionDeclDelays(DeclaratorInfo, ThisDecl);
@ -2358,7 +2340,7 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
// C++11 [class.mem]p2:
// Within the class member-specification, the class is regarded as complete
// within function bodies, default arguments, exception-specifications, and
// within function bodies, default arguments, and
// brace-or-equal-initializers for non-static data members (including such
// things in nested classes).
if (TagDecl && NonNestedClass) {
@ -2369,6 +2351,10 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
SourceLocation SavedPrevTokLocation = PrevTokLocation;
ParseLexedAttributes(getCurrentClass());
ParseLexedMethodDeclarations(getCurrentClass());
// We've finished with all pending member declarations.
Actions.ActOnFinishCXXMemberDecls();
ParseLexedMemberInitializers(getCurrentClass());
ParseLexedMethodDefs(getCurrentClass());
PrevTokLocation = SavedPrevTokLocation;
@ -2555,63 +2541,13 @@ Parser::MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
/// 'noexcept'
/// 'noexcept' '(' constant-expression ')'
ExceptionSpecificationType
Parser::tryParseExceptionSpecification(bool Delayed,
Parser::tryParseExceptionSpecification(
SourceRange &SpecificationRange,
SmallVectorImpl<ParsedType> &DynamicExceptions,
SmallVectorImpl<SourceRange> &DynamicExceptionRanges,
ExprResult &NoexceptExpr,
CachedTokens *&ExceptionSpecTokens) {
ExprResult &NoexceptExpr) {
ExceptionSpecificationType Result = EST_None;
ExceptionSpecTokens = 0;
// Handle delayed parsing of exception-specifications.
if (Delayed) {
if (Tok.isNot(tok::kw_throw) && Tok.isNot(tok::kw_noexcept))
return EST_None;
// Consume and cache the starting token.
bool IsNoexcept = Tok.is(tok::kw_noexcept);
Token StartTok = Tok;
SpecificationRange = SourceRange(ConsumeToken());
// Check for a '('.
if (!Tok.is(tok::l_paren)) {
// If this is a bare 'noexcept', we're done.
if (IsNoexcept) {
Diag(Tok, diag::warn_cxx98_compat_noexcept_decl);
NoexceptExpr = 0;
return EST_BasicNoexcept;
}
Diag(Tok, diag::err_expected_lparen_after) << "throw";
return EST_DynamicNone;
}
// Cache the tokens for the exception-specification.
ExceptionSpecTokens = new CachedTokens;
ExceptionSpecTokens->push_back(StartTok); // 'throw' or 'noexcept'
ExceptionSpecTokens->push_back(Tok); // '('
SpecificationRange.setEnd(ConsumeParen()); // '('
if (!ConsumeAndStoreUntil(tok::r_paren, *ExceptionSpecTokens,
/*StopAtSemi=*/true,
/*ConsumeFinalToken=*/true)) {
NoexceptExpr = 0;
delete ExceptionSpecTokens;
ExceptionSpecTokens = 0;
return IsNoexcept? EST_BasicNoexcept : EST_DynamicNone;
}
SpecificationRange.setEnd(Tok.getLocation());
// Add the 'stop' token.
Token End;
End.startToken();
End.setKind(tok::cxx_exceptspec_end);
End.setLocation(Tok.getLocation());
ExceptionSpecTokens->push_back(End);
return EST_Delayed;
}
// See if there's a dynamic specification.
if (Tok.is(tok::kw_throw)) {
Result = ParseDynamicExceptionSpecification(SpecificationRange,

View File

@ -2392,7 +2392,7 @@ ExprResult Parser::ParseBlockLiteralExpression() {
SourceLocation(),
EST_None,
SourceLocation(),
0, 0, 0, 0, 0,
0, 0, 0, 0,
CaretLoc, CaretLoc,
ParamInfo),
attrs, CaretLoc);

View File

@ -780,13 +780,10 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
llvm::SmallVector<ParsedType, 2> DynamicExceptions;
llvm::SmallVector<SourceRange, 2> DynamicExceptionRanges;
ExprResult NoexceptExpr;
CachedTokens *ExceptionSpecTokens;
ESpecType = tryParseExceptionSpecification(/*Delayed=*/false,
ESpecRange,
ESpecType = tryParseExceptionSpecification(ESpecRange,
DynamicExceptions,
DynamicExceptionRanges,
NoexceptExpr,
ExceptionSpecTokens);
NoexceptExpr);
if (ESpecType != EST_None)
DeclEndLoc = ESpecRange.getEnd();
@ -821,7 +818,6 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
DynamicExceptions.size(),
NoexceptExpr.isUsable() ?
NoexceptExpr.get() : 0,
0,
DeclLoc, DeclEndLoc, D,
TrailingReturnType),
Attr, DeclEndLoc);
@ -867,7 +863,6 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
/*ExceptionRanges=*/0,
/*NumExceptions=*/0,
/*NoexceptExpr=*/0,
/*ExceptionSpecTokens=*/0,
DeclLoc, DeclEndLoc, D,
TrailingReturnType),
Attr, DeclEndLoc);

View File

@ -162,7 +162,6 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
SourceRange *ExceptionRanges,
unsigned NumExceptions,
Expr *NoexceptExpr,
CachedTokens *ExceptionSpecTokens,
SourceLocation LocalRangeBegin,
SourceLocation LocalRangeEnd,
Declarator &TheDeclarator,
@ -227,10 +226,6 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
case EST_ComputedNoexcept:
I.Fun.NoexceptExpr = NoexceptExpr;
break;
case EST_Delayed:
I.Fun.ExceptionSpecTokens = ExceptionSpecTokens;
break;
}
return I;
}

View File

@ -7635,7 +7635,7 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
SourceLocation(), SourceLocation(),
SourceLocation(),
EST_None, SourceLocation(),
0, 0, 0, 0, 0, Loc, Loc, D),
0, 0, 0, 0, Loc, Loc, D),
DS.getAttributes(),
SourceLocation());
D.SetIdentifier(&II, Loc);
@ -9784,21 +9784,6 @@ void Sema::ActOnFields(Scope* S,
if (!Completed)
Record->completeDefinition();
// Now that the record is complete, do any delayed exception spec checks
// we were missing.
while (!DelayedDestructorExceptionSpecChecks.empty()) {
const CXXDestructorDecl *Dtor =
DelayedDestructorExceptionSpecChecks.back().first;
if (Dtor->getParent() != Record)
break;
assert(!Dtor->getParent()->isDependentType() &&
"Should not ever add destructors of templates into the list.");
CheckOverridingFunctionExceptionSpec(Dtor,
DelayedDestructorExceptionSpecChecks.back().second);
DelayedDestructorExceptionSpecChecks.pop_back();
}
} else {
ObjCIvarDecl **ClsFields =
reinterpret_cast<ObjCIvarDecl**>(RecFields.data());

View File

@ -7319,15 +7319,42 @@ void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
}
}
/// \brief Perform any semantic analysis which needs to be delayed until all
/// pending class member declarations have been parsed.
void Sema::ActOnFinishCXXMemberDecls() {
// Now we have parsed all exception specifications, determine the implicit
// exception specifications for destructors.
for (unsigned i = 0, e = DelayedDestructorExceptionSpecs.size();
i != e; ++i) {
CXXDestructorDecl *Dtor = DelayedDestructorExceptionSpecs[i];
AdjustDestructorExceptionSpec(Dtor->getParent(), Dtor, true);
}
DelayedDestructorExceptionSpecs.clear();
// Perform any deferred checking of exception specifications for virtual
// destructors.
for (unsigned i = 0, e = DelayedDestructorExceptionSpecChecks.size();
i != e; ++i) {
const CXXDestructorDecl *Dtor =
DelayedDestructorExceptionSpecChecks[i].first;
assert(!Dtor->getParent()->isDependentType() &&
"Should not ever add destructors of templates into the list.");
CheckOverridingFunctionExceptionSpec(Dtor,
DelayedDestructorExceptionSpecChecks[i].second);
}
DelayedDestructorExceptionSpecChecks.clear();
}
void Sema::AdjustDestructorExceptionSpec(CXXRecordDecl *classDecl,
CXXDestructorDecl *destructor) {
CXXDestructorDecl *destructor,
bool WasDelayed) {
// C++11 [class.dtor]p3:
// A declaration of a destructor that does not have an exception-
// specification is implicitly considered to have the same exception-
// specification as an implicit declaration.
const FunctionProtoType *dtorType = destructor->getType()->
getAs<FunctionProtoType>();
if (dtorType->hasExceptionSpec())
if (!WasDelayed && dtorType->hasExceptionSpec())
return;
ImplicitExceptionSpecification exceptSpec =
@ -7344,6 +7371,14 @@ void Sema::AdjustDestructorExceptionSpec(CXXRecordDecl *classDecl,
destructor->setType(ty);
// If we can't compute the exception specification for this destructor yet
// (because it depends on an exception specification which we have not parsed
// yet), make a note that we need to try again when the class is complete.
if (epi.ExceptionSpecType == EST_Delayed) {
assert(!WasDelayed && "couldn't compute destructor exception spec");
DelayedDestructorExceptionSpecs.push_back(destructor);
}
// FIXME: If the destructor has a body that could throw, and the newly created
// spec doesn't allow exceptions, we should emit a warning, because this
// change in behavior can break conforming C++03 programs at runtime.
@ -7579,8 +7614,9 @@ Sema::ComputeDefaultedCopyAssignmentExceptionSpecAndConst(
assert(!Base->getType()->isDependentType() &&
"Cannot generate implicit members for class with dependent bases.");
CXXRecordDecl *BaseClassDecl = Base->getType()->getAsCXXRecordDecl();
LookupCopyingAssignment(BaseClassDecl, Qualifiers::Const, false, 0,
&HasConstCopyAssignment);
HasConstCopyAssignment &=
(bool)LookupCopyingAssignment(BaseClassDecl, Qualifiers::Const,
false, 0);
}
// In C++11, the above citation has "or virtual" added
@ -7591,8 +7627,9 @@ Sema::ComputeDefaultedCopyAssignmentExceptionSpecAndConst(
assert(!Base->getType()->isDependentType() &&
"Cannot generate implicit members for class with dependent bases.");
CXXRecordDecl *BaseClassDecl = Base->getType()->getAsCXXRecordDecl();
LookupCopyingAssignment(BaseClassDecl, Qualifiers::Const, false, 0,
&HasConstCopyAssignment);
HasConstCopyAssignment &=
(bool)LookupCopyingAssignment(BaseClassDecl, Qualifiers::Const,
false, 0);
}
}
@ -7606,8 +7643,9 @@ Sema::ComputeDefaultedCopyAssignmentExceptionSpecAndConst(
++Field) {
QualType FieldType = Context.getBaseElementType((*Field)->getType());
if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) {
LookupCopyingAssignment(FieldClassDecl, Qualifiers::Const, false, 0,
&HasConstCopyAssignment);
HasConstCopyAssignment &=
(bool)LookupCopyingAssignment(FieldClassDecl, Qualifiers::Const,
false, 0);
}
}
@ -8610,8 +8648,8 @@ Sema::ComputeDefaultedCopyCtorExceptionSpecAndConst(CXXRecordDecl *ClassDecl) {
CXXRecordDecl *BaseClassDecl
= cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
LookupCopyingConstructor(BaseClassDecl, Qualifiers::Const,
&HasConstCopyConstructor);
HasConstCopyConstructor &=
(bool)LookupCopyingConstructor(BaseClassDecl, Qualifiers::Const);
}
for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
@ -8620,8 +8658,8 @@ Sema::ComputeDefaultedCopyCtorExceptionSpecAndConst(CXXRecordDecl *ClassDecl) {
++Base) {
CXXRecordDecl *BaseClassDecl
= cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
LookupCopyingConstructor(BaseClassDecl, Qualifiers::Const,
&HasConstCopyConstructor);
HasConstCopyConstructor &=
(bool)LookupCopyingConstructor(BaseClassDecl, Qualifiers::Const);
}
// -- for all the nonstatic data members of X that are of a
@ -8634,8 +8672,8 @@ Sema::ComputeDefaultedCopyCtorExceptionSpecAndConst(CXXRecordDecl *ClassDecl) {
++Field) {
QualType FieldType = Context.getBaseElementType((*Field)->getType());
if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) {
LookupCopyingConstructor(FieldClassDecl, Qualifiers::Const,
&HasConstCopyConstructor);
HasConstCopyConstructor &=
(bool)LookupCopyingConstructor(FieldClassDecl, Qualifiers::Const);
}
}
// Otherwise, the implicitly declared copy constructor will have
@ -11260,66 +11298,6 @@ Sema::checkExceptionSpecification(ExceptionSpecificationType EST,
}
}
void Sema::actOnDelayedExceptionSpecification(Decl *MethodD,
ExceptionSpecificationType EST,
SourceRange SpecificationRange,
ArrayRef<ParsedType> DynamicExceptions,
ArrayRef<SourceRange> DynamicExceptionRanges,
Expr *NoexceptExpr) {
if (!MethodD)
return;
// Dig out the method we're referring to.
CXXMethodDecl *Method = 0;
if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(MethodD))
Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
else
Method = dyn_cast<CXXMethodDecl>(MethodD);
if (!Method)
return;
// Dig out the prototype. This should never fail.
const FunctionProtoType *Proto
= dyn_cast<FunctionProtoType>(Method->getType());
if (!Proto)
return;
// Check the exception specification.
llvm::SmallVector<QualType, 4> Exceptions;
FunctionProtoType::ExtProtoInfo EPI = Proto->getExtProtoInfo();
checkExceptionSpecification(EST, DynamicExceptions, DynamicExceptionRanges,
NoexceptExpr, Exceptions, EPI);
// Rebuild the function type.
QualType T = Context.getFunctionType(Proto->getResultType(),
Proto->arg_type_begin(),
Proto->getNumArgs(),
EPI);
if (TypeSourceInfo *TSInfo = Method->getTypeSourceInfo()) {
// FIXME: When we get proper type location information for exceptions,
// we'll also have to rebuild the TypeSourceInfo. For now, we just patch
// up the TypeSourceInfo;
assert(TypeLoc::getFullDataSizeForType(T)
== TypeLoc::getFullDataSizeForType(Method->getType()) &&
"TypeLoc size mismatch with delayed exception specification");
TSInfo->overrideType(T);
}
Method->setType(T);
if (Method->isStatic())
checkThisInStaticMemberFunctionExceptionSpec(Method);
if (Method->isVirtual()) {
// Check overrides, which we previously had to delay.
for (CXXMethodDecl::method_iterator O = Method->begin_overridden_methods(),
OEnd = Method->end_overridden_methods();
O != OEnd; ++O)
CheckOverridingFunctionExceptionSpec(Method, *O);
}
}
/// IdentifyCUDATarget - Determine the CUDA compilation target for this function
Sema::CUDAFunctionTarget Sema::IdentifyCUDATarget(const FunctionDecl *D) {
// Implicitly declared functions (e.g. copy constructors) are

View File

@ -2277,7 +2277,7 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
Result->setMethod(DD);
Result->setKind(DD->isDeleted() ?
SpecialMemberOverloadResult::NoMemberOrDeleted :
SpecialMemberOverloadResult::SuccessNonConst);
SpecialMemberOverloadResult::Success);
return Result;
}
@ -2288,6 +2288,9 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
Expr *Arg = 0;
unsigned NumArgs;
QualType ArgType = CanTy;
ExprValueKind VK = VK_LValue;
if (SM == CXXDefaultConstructor) {
Name = Context.DeclarationNames.getCXXConstructorName(CanTy);
NumArgs = 0;
@ -2308,7 +2311,6 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
DeclareImplicitMoveAssignment(RD);
}
QualType ArgType = CanTy;
if (ConstArg)
ArgType.addConst();
if (VolatileArg)
@ -2321,14 +2323,17 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
// Possibly an XValue is actually correct in the case of move, but
// there is no semantic difference for class types in this restricted
// case.
ExprValueKind VK;
if (SM == CXXCopyConstructor || SM == CXXCopyAssignment)
VK = VK_LValue;
else
VK = VK_RValue;
}
OpaqueValueExpr FakeArg(SourceLocation(), ArgType, VK);
if (SM != CXXDefaultConstructor) {
NumArgs = 1;
Arg = new (Context) OpaqueValueExpr(SourceLocation(), ArgType, VK);
Arg = &FakeArg;
}
// Create the object argument
@ -2338,17 +2343,14 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
if (VolatileThis)
ThisTy.addVolatile();
Expr::Classification Classification =
(new (Context) OpaqueValueExpr(SourceLocation(), ThisTy,
RValueThis ? VK_RValue : VK_LValue))->
Classify(Context);
OpaqueValueExpr(SourceLocation(), ThisTy,
RValueThis ? VK_RValue : VK_LValue).Classify(Context);
// Now we perform lookup on the name we computed earlier and do overload
// resolution. Lookup is only performed directly into the class since there
// will always be a (possibly implicit) declaration to shadow any others.
OverloadCandidateSet OCS((SourceLocation()));
DeclContext::lookup_iterator I, E;
SpecialMemberOverloadResult::Kind SuccessKind =
SpecialMemberOverloadResult::SuccessNonConst;
llvm::tie(I, E) = RD->lookup(Name);
assert((I != E) &&
@ -2378,17 +2380,6 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
else
AddOverloadCandidate(M, DeclAccessPair::make(M, AS_public),
llvm::makeArrayRef(&Arg, NumArgs), OCS, true);
// Here we're looking for a const parameter to speed up creation of
// implicit copy methods.
if ((SM == CXXCopyAssignment && M->isCopyAssignmentOperator()) ||
(SM == CXXCopyConstructor &&
cast<CXXConstructorDecl>(M)->isCopyConstructor())) {
QualType ArgType = M->getType()->getAs<FunctionProtoType>()->getArgType(0);
if (!ArgType->isReferenceType() ||
ArgType->getPointeeType().isConstQualified())
SuccessKind = SpecialMemberOverloadResult::SuccessConst;
}
} else if (FunctionTemplateDecl *Tmpl =
dyn_cast<FunctionTemplateDecl>(Cand)) {
if (SM == CXXCopyAssignment || SM == CXXMoveAssignment)
@ -2409,7 +2400,7 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
switch (OCS.BestViableFunction(*this, SourceLocation(), Best)) {
case OR_Success:
Result->setMethod(cast<CXXMethodDecl>(Best->Function));
Result->setKind(SuccessKind);
Result->setKind(SpecialMemberOverloadResult::Success);
break;
case OR_Deleted:
@ -2442,17 +2433,13 @@ CXXConstructorDecl *Sema::LookupDefaultConstructor(CXXRecordDecl *Class) {
/// \brief Look up the copying constructor for the given class.
CXXConstructorDecl *Sema::LookupCopyingConstructor(CXXRecordDecl *Class,
unsigned Quals,
bool *ConstParamMatch) {
unsigned Quals) {
assert(!(Quals & ~(Qualifiers::Const | Qualifiers::Volatile)) &&
"non-const, non-volatile qualifiers for copy ctor arg");
SpecialMemberOverloadResult *Result =
LookupSpecialMember(Class, CXXCopyConstructor, Quals & Qualifiers::Const,
Quals & Qualifiers::Volatile, false, false, false);
if (ConstParamMatch)
*ConstParamMatch = Result->hasConstParamMatch();
return cast_or_null<CXXConstructorDecl>(Result->getMethod());
}
@ -2485,8 +2472,7 @@ DeclContext::lookup_result Sema::LookupConstructors(CXXRecordDecl *Class) {
/// \brief Look up the copying assignment operator for the given class.
CXXMethodDecl *Sema::LookupCopyingAssignment(CXXRecordDecl *Class,
unsigned Quals, bool RValueThis,
unsigned ThisQuals,
bool *ConstParamMatch) {
unsigned ThisQuals) {
assert(!(Quals & ~(Qualifiers::Const | Qualifiers::Volatile)) &&
"non-const, non-volatile qualifiers for copy assignment arg");
assert(!(ThisQuals & ~(Qualifiers::Const | Qualifiers::Volatile)) &&
@ -2497,9 +2483,6 @@ CXXMethodDecl *Sema::LookupCopyingAssignment(CXXRecordDecl *Class,
ThisQuals & Qualifiers::Const,
ThisQuals & Qualifiers::Volatile);
if (ConstParamMatch)
*ConstParamMatch = Result->hasConstParamMatch();
return Result->getMethod();
}

View File

@ -561,7 +561,7 @@ static void maybeSynthesizeBlockSignature(TypeProcessingState &state,
/*const qualifier*/SourceLocation(),
/*volatile qualifier*/SourceLocation(),
/*mutable qualifier*/SourceLocation(),
/*EH*/ EST_None, SourceLocation(), 0, 0, 0, 0, 0,
/*EH*/ EST_None, SourceLocation(), 0, 0, 0, 0,
/*parens*/ loc, loc,
declarator));
@ -4195,7 +4195,8 @@ bool Sema::RequireCompleteType(SourceLocation Loc, QualType T,
// class template specialization, or an array with known size of such,
// try to instantiate it.
QualType MaybeTemplate = T;
if (const ConstantArrayType *Array = Context.getAsConstantArrayType(T))
while (const ConstantArrayType *Array
= Context.getAsConstantArrayType(MaybeTemplate))
MaybeTemplate = Array->getElementType();
if (const RecordType *Record = MaybeTemplate->getAs<RecordType>()) {
if (ClassTemplateSpecializationDecl *ClassTemplateSpec

View File

@ -3866,6 +3866,9 @@ QualType ASTReader::readTypeRecord(unsigned Index) {
EPI.Exceptions = Exceptions.data();
} else if (EST == EST_ComputedNoexcept) {
EPI.NoexceptExpr = ReadExpr(*Loc.F);
} else if (EST == EST_Uninstantiated) {
EPI.ExceptionSpecDecl = ReadDeclAs<FunctionDecl>(*Loc.F, Record, Idx);
EPI.ExceptionSpecTemplate = ReadDeclAs<FunctionDecl>(*Loc.F, Record, Idx);
}
return Context.getFunctionType(ResultType, ParamTypes.data(), NumParams,
EPI);

View File

@ -195,6 +195,9 @@ void ASTTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) {
Writer.AddTypeRef(T->getExceptionType(I), Record);
} else if (T->getExceptionSpecType() == EST_ComputedNoexcept) {
Writer.AddStmt(T->getNoexceptExpr());
} else if (T->getExceptionSpecType() == EST_Uninstantiated) {
Writer.AddDeclRef(T->getExceptionSpecDecl(), Record);
Writer.AddDeclRef(T->getExceptionSpecTemplate(), Record);
}
Code = TYPE_FUNCTION_PROTO;
}

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
// C++11 [class.mem]p2:
// A class is considered a completely-defined object type (or

View File

@ -91,10 +91,11 @@ namespace Static {
namespace PR12564 {
struct Base {
void bar(Base&) {}
void bar(Base&) {} // unexpected-note {{here}}
};
struct Derived : Base {
void foo(Derived& d) noexcept(noexcept(d.bar(d))) {}
// FIXME: This should be accepted.
void foo(Derived& d) noexcept(noexcept(d.bar(d))) {} // unexpected-error {{cannot bind to a value of unrelated type}}
};
}

View File

@ -198,15 +198,15 @@ namespace DR1402 {
struct NoMove4 : NonTrivialCopyAssign {}; // expected-note 2{{'const DR1402::NoMove4 &'}}
struct NoMove5 : virtual NonTrivialCopyCtor {}; // expected-note 2{{'const DR1402::NoMove5 &'}}
struct NoMove6 : virtual NonTrivialCopyAssign {}; // expected-note 2{{'const DR1402::NoMove6 &'}}
struct NoMove7 : NonTrivialCopyCtorVBase {}; // expected-note 2{{'DR1402::NoMove7 &'}}
struct NoMove8 : NonTrivialCopyAssignVBase {}; // expected-note 2{{'DR1402::NoMove8 &'}}
struct NoMove7 : NonTrivialCopyCtorVBase {}; // expected-note 2{{'const DR1402::NoMove7 &'}}
struct NoMove8 : NonTrivialCopyAssignVBase {}; // expected-note 2{{'const DR1402::NoMove8 &'}}
// A non-trivially-move-assignable virtual base class inhibits the declaration
// of a move assignment (which might move-assign the base class multiple
// times).
struct NoMove9 : NonTrivialMoveAssign {};
struct NoMove10 : virtual NonTrivialMoveAssign {}; // expected-note {{'DR1402::NoMove10 &'}}
struct NoMove11 : NonTrivialMoveAssignVBase {}; // expected-note {{'DR1402::NoMove11 &'}}
struct NoMove10 : virtual NonTrivialMoveAssign {}; // expected-note {{'const DR1402::NoMove10 &'}}
struct NoMove11 : NonTrivialMoveAssignVBase {}; // expected-note {{'const DR1402::NoMove11 &'}}
struct Test {
friend NoMove1::NoMove1(NoMove1 &&); // expected-error {{no matching function}}

View File

@ -0,0 +1,48 @@
// RUN: %clang_cc1 -std=c++11 %s -verify
// C++98 [class.copy]p5 / C++11 [class.copy]p8.
// The implicitly-declared copy constructor for a class X will have the form
// X::X(const X&)
// if [every direct subobject] has a copy constructor whose first parameter is
// of type 'const volatile[opt] T &'. Otherwise, it will have the form
// X::X(X&)
struct ConstCopy {
ConstCopy(const ConstCopy &);
};
struct NonConstCopy {
NonConstCopy(NonConstCopy &);
};
struct DeletedConstCopy {
DeletedConstCopy(const DeletedConstCopy &) = delete;
};
struct DeletedNonConstCopy {
DeletedNonConstCopy(DeletedNonConstCopy &) = delete;
};
struct ImplicitlyDeletedConstCopy {
ImplicitlyDeletedConstCopy(ImplicitlyDeletedConstCopy &&);
};
struct A : ConstCopy {};
struct B : NonConstCopy { ConstCopy a; };
struct C : ConstCopy { NonConstCopy a; };
struct D : DeletedConstCopy {};
struct E : DeletedNonConstCopy {};
struct F { ImplicitlyDeletedConstCopy a; };
struct G : virtual B {};
struct Test {
friend A::A(const A &);
friend B::B(B &);
friend C::C(C &);
friend D::D(const D &);
friend E::E(E &);
friend F::F(const F &);
friend G::G(G &);
};

View File

@ -1,29 +0,0 @@
// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
// XTARGET: x86
// PR4242
// (PR 4242 bug is on 64-bit only, test passes on x86-32 as well)
struct S {
void* data[3];
};
struct T {
void* data[2];
};
// CHECK: %struct.T* byval
extern "C" S fail(int, int, int, int, T t, void* p) {
S s;
s.data[0] = t.data[0];
s.data[1] = t.data[1];
s.data[2] = p;
return s;
}
// CHECK: %struct.T* byval
extern "C" S* succeed(S* sret, int, int, int, int, T t, void* p) {
sret->data[0] = t.data[0];
sret->data[1] = t.data[1];
sret->data[2] = p;
return sret;
}

View File

@ -56,6 +56,7 @@ namespace PR7742 { // Also rdar://8250764
// CHECK: define <2 x float> @_ZN6PR77423fooEPNS_2c2E(%"struct.PR7742::c2"* %P)
c2 foo(c2 *P) {
return c2();
}
}
@ -149,3 +150,34 @@ namespace test8 {
foo(b);
}
}
// PR4242
namespace test9 {
// Large enough to be passed indirectly.
struct S { void *data[3]; };
struct T { void *data[2]; };
// CHECK: define void @_ZN5test93fooEPNS_1SEPNS_1TE([[S:%.*]]*, [[T:%.*]]*)
void foo(S*, T*) {}
// CHECK: define void @_ZN5test91aEiiiiNS_1TEPv([[S]]* noalias sret {{%.*}}, i32, i32, i32, i32, [[T]]* byval align 8, i8*)
S a(int, int, int, int, T, void*) {
return S();
}
// CHECK: define [[S]]* @_ZN5test91bEPNS_1SEiiiiNS_1TEPv([[S]]* {{%.*}}, i32, i32, i32, i32, [[T:%.*]]* byval align 8, i8*)
S* b(S* sret, int, int, int, int, T, void*) {
return sret;
}
// CHECK: define void @_ZN5test91cEiiiNS_1TEPv([[S]]* noalias sret {{%.*}}, i32, i32, i32, i8* {{%.*}}, i8* {{%.*}}, i8*)
S c(int, int, int, T, void*) {
return S();
}
// CHECK: define [[S]]* @_ZN5test91dEPNS_1SEiiiNS_1TEPv([[S]]* {{%.*}}, i32, i32, i32, i8* {{%.*}}, i8* {{%.*}}, i8*)
S* d(S* sret, int, int, int, T, void*) {
return sret;
}
}

View File

@ -0,0 +1,17 @@
// RUN: %clang_cc1 -pedantic-errors -std=c++11 -emit-pch %s -o %t
// RUN: %clang_cc1 -pedantic-errors -std=c++11 -include-pch %t -verify %s
#ifndef HEADER_INCLUDED
#define HEADER_INCLUDED
template<bool b> int f() noexcept(b) {}
decltype(f<false>()) a;
decltype(f<true>()) b;
#else
static_assert(!noexcept(f<false>()), "");
static_assert(noexcept(f<true>()), "");
#endif

View File

@ -0,0 +1,259 @@
// RUN: %clang_cc1 -fsyntax-only %s -verify
class outer {
class inner1 { inner1(); };
class inner2 { inner2(); };
class inner3 { inner3(); };
class inner4 { inner4(); };
class inner5 { inner5(); };
class inner6 { inner6(); };
class inner7 { inner7(); };
class inner8 { inner8(); };
class inner9 { inner9(); };
class inner10 { inner10(); };
class inner11 { inner11(); };
class inner12 { inner12(); };
class inner13 { inner13(); };
class inner14 { inner14(); };
class inner15 { inner15(); };
class inner16 { inner16(); };
class inner17 { inner17(); };
class inner18 { inner18(); };
class inner19 { inner19(); };
class inner20 { inner20(); };
class inner21 { inner21(); };
class inner22 { inner22(); };
class inner23 { inner23(); };
class inner24 { inner24(); };
class inner25 { inner25(); };
class inner26 { inner26(); };
class inner27 { inner27(); };
class inner28 { inner28(); };
class inner29 { inner29(); };
class inner30 { inner30(); };
class inner31 { inner31(); };
class inner32 { inner32(); };
class inner33 { inner33(); };
class inner34 { inner34(); };
class inner35 { inner35(); };
class inner36 { inner36(); };
class inner37 { inner37(); };
class inner38 { inner38(); };
class inner39 { inner39(); };
class inner40 { inner40(); };
class inner41 { inner41(); };
class inner42 { inner42(); };
class inner43 { inner43(); };
class inner44 { inner44(); };
class inner45 { inner45(); };
class inner46 { inner46(); };
class inner47 { inner47(); };
class inner48 { inner48(); };
class inner49 { inner49(); };
class inner50 { inner50(); };
class inner51 { inner51(); };
class inner52 { inner52(); };
class inner53 { inner53(); };
class inner54 { inner54(); };
class inner55 { inner55(); };
class inner56 { inner56(); };
class inner57 { inner57(); };
class inner58 { inner58(); };
class inner59 { inner59(); };
class inner60 { inner60(); };
class inner61 { inner61(); };
class inner62 { inner62(); };
class inner63 { inner63(); };
class inner64 { inner64(); };
class inner65 { inner65(); };
class inner66 { inner66(); };
class inner67 { inner67(); };
class inner68 { inner68(); };
class inner69 { inner69(); };
class inner70 { inner70(); };
class inner71 { inner71(); };
class inner72 { inner72(); };
class inner73 { inner73(); };
class inner74 { inner74(); };
class inner75 { inner75(); };
class inner76 { inner76(); };
class inner77 { inner77(); };
class inner78 { inner78(); };
class inner79 { inner79(); };
class inner80 { inner80(); };
class inner81 { inner81(); };
class inner82 { inner82(); };
class inner83 { inner83(); };
class inner84 { inner84(); };
class inner85 { inner85(); };
class inner86 { inner86(); };
class inner87 { inner87(); };
class inner88 { inner88(); };
class inner89 { inner89(); };
class inner90 { inner90(); };
class inner91 { inner91(); };
class inner92 { inner92(); };
class inner93 { inner93(); };
class inner94 { inner94(); };
class inner95 { inner95(); };
class inner96 { inner96(); };
class inner97 { inner97(); };
class inner98 { inner98(); };
class inner99 { inner99(); };
class inner100 { inner100(); };
class inner101 { inner101(); };
class inner102 { inner102(); };
class inner103 { inner103(); };
class inner104 { inner104(); };
class inner105 { inner105(); };
class inner106 { inner106(); };
class inner107 { inner107(); };
class inner108 { inner108(); };
class inner109 { inner109(); };
class inner110 { inner110(); };
class inner111 { inner111(); };
class inner112 { inner112(); };
class inner113 { inner113(); };
class inner114 { inner114(); };
class inner115 { inner115(); };
class inner116 { inner116(); };
class inner117 { inner117(); };
class inner118 { inner118(); };
class inner119 { inner119(); };
class inner120 { inner120(); };
class inner121 { inner121(); };
class inner122 { inner122(); };
class inner123 { inner123(); };
class inner124 { inner124(); };
class inner125 { inner125(); };
class inner126 { inner126(); };
class inner127 { inner127(); };
class inner128 { inner128(); };
class inner129 { inner129(); };
class inner130 { inner130(); };
class inner131 { inner131(); };
class inner132 { inner132(); };
class inner133 { inner133(); };
class inner134 { inner134(); };
class inner135 { inner135(); };
class inner136 { inner136(); };
class inner137 { inner137(); };
class inner138 { inner138(); };
class inner139 { inner139(); };
class inner140 { inner140(); };
class inner141 { inner141(); };
class inner142 { inner142(); };
class inner143 { inner143(); };
class inner144 { inner144(); };
class inner145 { inner145(); };
class inner146 { inner146(); };
class inner147 { inner147(); };
class inner148 { inner148(); };
class inner149 { inner149(); };
class inner150 { inner150(); };
class inner151 { inner151(); };
class inner152 { inner152(); };
class inner153 { inner153(); };
class inner154 { inner154(); };
class inner155 { inner155(); };
class inner156 { inner156(); };
class inner157 { inner157(); };
class inner158 { inner158(); };
class inner159 { inner159(); };
class inner160 { inner160(); };
class inner161 { inner161(); };
class inner162 { inner162(); };
class inner163 { inner163(); };
class inner164 { inner164(); };
class inner165 { inner165(); };
class inner166 { inner166(); };
class inner167 { inner167(); };
class inner168 { inner168(); };
class inner169 { inner169(); };
class inner170 { inner170(); };
class inner171 { inner171(); };
class inner172 { inner172(); };
class inner173 { inner173(); };
class inner174 { inner174(); };
class inner175 { inner175(); };
class inner176 { inner176(); };
class inner177 { inner177(); };
class inner178 { inner178(); };
class inner179 { inner179(); };
class inner180 { inner180(); };
class inner181 { inner181(); };
class inner182 { inner182(); };
class inner183 { inner183(); };
class inner184 { inner184(); };
class inner185 { inner185(); };
class inner186 { inner186(); };
class inner187 { inner187(); };
class inner188 { inner188(); };
class inner189 { inner189(); };
class inner190 { inner190(); };
class inner191 { inner191(); };
class inner192 { inner192(); };
class inner193 { inner193(); };
class inner194 { inner194(); };
class inner195 { inner195(); };
class inner196 { inner196(); };
class inner197 { inner197(); };
class inner198 { inner198(); };
class inner199 { inner199(); };
class inner200 { inner200(); };
class inner201 { inner201(); };
class inner202 { inner202(); };
class inner203 { inner203(); };
class inner204 { inner204(); };
class inner205 { inner205(); };
class inner206 { inner206(); };
class inner207 { inner207(); };
class inner208 { inner208(); };
class inner209 { inner209(); };
class inner210 { inner210(); };
class inner211 { inner211(); };
class inner212 { inner212(); };
class inner213 { inner213(); };
class inner214 { inner214(); };
class inner215 { inner215(); };
class inner216 { inner216(); };
class inner217 { inner217(); };
class inner218 { inner218(); };
class inner219 { inner219(); };
class inner220 { inner220(); };
class inner221 { inner221(); };
class inner222 { inner222(); };
class inner223 { inner223(); };
class inner224 { inner224(); };
class inner225 { inner225(); };
class inner226 { inner226(); };
class inner227 { inner227(); };
class inner228 { inner228(); };
class inner229 { inner229(); };
class inner230 { inner230(); };
class inner231 { inner231(); };
class inner232 { inner232(); };
class inner233 { inner233(); };
class inner234 { inner234(); };
class inner235 { inner235(); };
class inner236 { inner236(); };
class inner237 { inner237(); };
class inner238 { inner238(); };
class inner239 { inner239(); };
class inner240 { inner240(); };
class inner241 { inner241(); };
class inner242 { inner242(); };
class inner243 { inner243(); };
class inner244 { inner244(); };
class inner245 { inner245(); };
class inner246 { inner246(); };
class inner247 { inner247(); };
class inner248 { inner248(); };
class inner249 { inner249(); };
class inner250 { inner250(); };
class inner251 { inner251(); };
class inner252 { inner252(); };
class inner253 { inner253(); };
class inner254 { inner254(); };
class inner255 { inner255(); };
class inner256 { inner256(); };
};

View File

@ -1,10 +1,7 @@
// RUN: %clang_cc1 -fms-extensions -rewrite-objc -x objective-c++ -fblocks -o %t-rw.cpp %s
// RUN: %clang_cc1 -fsyntax-only -Werror -Wno-address-of-temporary -Wno-attributes -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
// RUN: %clang_cc1 -fms-extensions -U__declspec -rewrite-objc -x objective-c++ -fblocks -o %t-rw.cpp %s
// RUN: %clang_cc1 -fsyntax-only -Werror -Wno-address-of-temporary -Wno-attributes -D"Class=void*" -D"id=void*" -D"SEL=void*" -U__declspec -D"__declspec(X)=" %t-rw.cpp
// rdar://11131490
// XFAIL: mingw
// FIXME: __declspec(X) is predefined on mingw.
extern "C" __declspec(dllexport) void BreakTheRewriter(void) {
__block int aBlockVariable = 0;
void (^aBlock)(void) = ^ {

View File

@ -85,3 +85,8 @@ namespace PR12182 {
f({1, 2});
}
}
namespace PR12660 {
const int &i { 1 };
struct S { S(int); } const &s { 2 };
}

View File

@ -23,7 +23,7 @@ struct array
{
T data[N];
void swap(array& a) noexcept(noexcept(::swap(declval<T&>(), declval<T&>())));
void swap(array& a) noexcept(noexcept(swap(declval<T&>(), declval<T&>())));
};
struct DefaultOnly
@ -38,4 +38,3 @@ int main()
{
array<DefaultOnly, 1> a, b;
}

View File

@ -40,9 +40,12 @@ namespace InClassInitializers {
}
namespace ExceptionSpecification {
struct Nested {
// A type is permitted to be used in a dynamic exception specification when it
// is still being defined, but isn't complete within such an exception
// specification.
struct Nested { // expected-note {{not complete}}
struct T {
T() noexcept(!noexcept(Nested())); // expected-error{{exception specification is not available until end of class definition}}
T() noexcept(!noexcept(Nested())); // expected-error{{incomplete type}}
} t;
};
}
@ -54,3 +57,33 @@ namespace DefaultArgument {
} t; // expected-note {{has no default constructor}}
};
}
namespace ImplicitDtorExceptionSpec {
struct A {
virtual ~A();
struct Inner {
~Inner() throw();
};
Inner inner;
};
struct B {
virtual ~B() {} // expected-note {{here}}
};
struct C : B {
virtual ~C() {}
A a;
};
struct D : B {
~D(); // expected-error {{more lax than base}}
struct E {
~E();
struct F {
~F() throw(A);
} f;
} e;
};
}

View File

@ -27,3 +27,11 @@ struct Z; // expected-note{{forward declaration}}
@implementation B
@end
// <rdar://problem/11284902>
template<typename T> struct Incomplete; // expected-note{{declared here}}
@interface C {
Incomplete<int> a[4][4][4]; // expected-error{{implicit instantiation of undefined template 'Incomplete<int>'}}
}
@end