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:
commit
64cc5073b2
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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(
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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),
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user