Upgrade our copy of llvm/clang to 3.1 release. Release notes can be

found at: http://llvm.org/releases/3.1/docs/ReleaseNotes.html

MFC after:	3 days
This commit is contained in:
Dimitry Andric 2012-05-23 21:48:49 +00:00
commit 64cc5073b2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=235864
24 changed files with 190 additions and 374 deletions

View File

@ -131,30 +131,16 @@ static void CheckForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op,
}
}
static void AddGlue(SDNode *N, SDValue Glue, bool AddGlue, SelectionDAG *DAG) {
SmallVector<EVT, 4> VTs;
SDNode *GlueDestNode = Glue.getNode();
// Don't add glue from a node to itself.
if (GlueDestNode == N) return;
// Don't add glue to something that already has it, either as a use or value.
if (N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Glue ||
N->getValueType(N->getNumValues() - 1) == MVT::Glue) {
return;
}
for (unsigned I = 0, E = N->getNumValues(); I != E; ++I)
VTs.push_back(N->getValueType(I));
if (AddGlue)
VTs.push_back(MVT::Glue);
// Helper for AddGlue to clone node operands.
static void CloneNodeWithValues(SDNode *N, SelectionDAG *DAG,
SmallVectorImpl<EVT> &VTs,
SDValue ExtraOper = SDValue()) {
SmallVector<SDValue, 4> Ops;
for (unsigned I = 0, E = N->getNumOperands(); I != E; ++I)
Ops.push_back(N->getOperand(I));
if (GlueDestNode)
Ops.push_back(Glue);
if (ExtraOper.getNode())
Ops.push_back(ExtraOper);
SDVTList VTList = DAG->getVTList(&VTs[0], VTs.size());
MachineSDNode::mmo_iterator Begin = 0, End = 0;
@ -173,6 +159,46 @@ static void AddGlue(SDNode *N, SDValue Glue, bool AddGlue, SelectionDAG *DAG) {
MN->setMemRefs(Begin, End);
}
static bool AddGlue(SDNode *N, SDValue Glue, bool AddGlue, SelectionDAG *DAG) {
SmallVector<EVT, 4> VTs;
SDNode *GlueDestNode = Glue.getNode();
// Don't add glue from a node to itself.
if (GlueDestNode == N) return false;
// Don't add a glue operand to something that already uses glue.
if (GlueDestNode &&
N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Glue) {
return false;
}
// Don't add glue to something that already has a glue value.
if (N->getValueType(N->getNumValues() - 1) == MVT::Glue) return false;
for (unsigned I = 0, E = N->getNumValues(); I != E; ++I)
VTs.push_back(N->getValueType(I));
if (AddGlue)
VTs.push_back(MVT::Glue);
CloneNodeWithValues(N, DAG, VTs, Glue);
return true;
}
// Cleanup after unsuccessful AddGlue. Use the standard method of morphing the
// node even though simply shrinking the value list is sufficient.
static void RemoveUnusedGlue(SDNode *N, SelectionDAG *DAG) {
assert((N->getValueType(N->getNumValues() - 1) == MVT::Glue &&
!N->hasAnyUseOfValue(N->getNumValues() - 1)) &&
"expected an unused glue value");
SmallVector<EVT, 4> VTs;
for (unsigned I = 0, E = N->getNumValues()-1; I != E; ++I)
VTs.push_back(N->getValueType(I));
CloneNodeWithValues(N, DAG, VTs);
}
/// ClusterNeighboringLoads - Force nearby loads together by "gluing" them.
/// This function finds loads of the same base and different offsets. If the
/// offsets are not far apart (target specific), it add MVT::Glue inputs and
@ -240,19 +266,23 @@ void ScheduleDAGSDNodes::ClusterNeighboringLoads(SDNode *Node) {
// Cluster loads by adding MVT::Glue outputs and inputs. This also
// ensure they are scheduled in order of increasing addresses.
SDNode *Lead = Loads[0];
AddGlue(Lead, SDValue(0, 0), true, DAG);
SDValue InGlue = SDValue(Lead, Lead->getNumValues() - 1);
SDValue InGlue = SDValue(0, 0);
if (AddGlue(Lead, InGlue, true, DAG))
InGlue = SDValue(Lead, Lead->getNumValues() - 1);
for (unsigned I = 1, E = Loads.size(); I != E; ++I) {
bool OutGlue = I < E - 1;
SDNode *Load = Loads[I];
AddGlue(Load, InGlue, OutGlue, DAG);
// If AddGlue fails, we could leave an unsused glue value. This should not
// cause any
if (AddGlue(Load, InGlue, OutGlue, DAG)) {
if (OutGlue)
InGlue = SDValue(Load, Load->getNumValues() - 1);
if (OutGlue)
InGlue = SDValue(Load, Load->getNumValues() - 1);
++LoadsClustered;
++LoadsClustered;
}
else if (!OutGlue && InGlue.getNode())
RemoveUnusedGlue(InGlue.getNode(), DAG);
}
}

View File

@ -64,9 +64,6 @@ class TypeSourceInfo {
/// \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 @@ class Parser : public CodeCompletionHandler {
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 @@ class Parser : public CodeCompletionHandler {
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 @@ class Parser : public CodeCompletionHandler {
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 @@ class InitializedEntity {
/// \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 @@ class Sema {
/// 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 @@ class Sema {
/// 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 @@ class Sema {
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 @@ class Sema {
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 @@ class Sema {
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 @@ class Sema {
/// 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 @@ class Sema {
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

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

@ -5,6 +5,6 @@
#define CLANG_VERSION_MINOR 1
#define CLANG_VENDOR "FreeBSD "
#define CLANG_VENDOR_SUFFIX " 20120503"
#define CLANG_VENDOR_SUFFIX " 20120523"
#define SVN_REVISION "155985"
#define SVN_REVISION "156863"

View File

@ -663,13 +663,13 @@
#define PACKAGE_NAME "LLVM"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "LLVM 3.1svn"
#define PACKAGE_STRING "LLVM 3.1"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "llvm"
/* Define to the version of this package. */
#define PACKAGE_VERSION "3.1svn"
#define PACKAGE_VERSION "3.1"
/* Define as the return type of signal handlers (`int' or `void'). */
#define RETSIGTYPE void