forked from OSchip/llvm-project
Simplify CXXScopeSpec a lot. No more weird SmallVector-like hacks here
llvm-svn: 67800
This commit is contained in:
parent
f21eb49a04
commit
c23500ebb3
|
@ -397,36 +397,10 @@ private:
|
||||||
/// specifier.
|
/// specifier.
|
||||||
class CXXScopeSpec {
|
class CXXScopeSpec {
|
||||||
SourceRange Range;
|
SourceRange Range;
|
||||||
|
void *ScopeRep;
|
||||||
/// Storage containing the scope representations for up to four
|
|
||||||
/// levels of nested-name-specifier. NumScopeReps specifiers how
|
|
||||||
/// many levels there are. If there are more than four, we use
|
|
||||||
/// ManyScopeReps.
|
|
||||||
Action::CXXScopeTy *InlineScopeReps[4];
|
|
||||||
|
|
||||||
/// The number of scope representations we've stored.
|
|
||||||
unsigned NumScopeReps;
|
|
||||||
|
|
||||||
/// The number of scope representations we can store without
|
|
||||||
/// allocating new memory.
|
|
||||||
unsigned Capacity;
|
|
||||||
|
|
||||||
// If there are > 4 scope representations, a pointer to those scope
|
|
||||||
// representations.
|
|
||||||
Action::CXXScopeTy **ManyScopeReps;
|
|
||||||
|
|
||||||
void reallocate();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CXXScopeSpec() : Range(), NumScopeReps(0), Capacity(4) { }
|
CXXScopeSpec() : Range(), ScopeRep() { }
|
||||||
|
|
||||||
CXXScopeSpec(const CXXScopeSpec &SS);
|
|
||||||
|
|
||||||
CXXScopeSpec &operator=(const CXXScopeSpec &SS);
|
|
||||||
|
|
||||||
~CXXScopeSpec() {
|
|
||||||
clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
const SourceRange &getRange() const { return Range; }
|
const SourceRange &getRange() const { return Range; }
|
||||||
void setRange(const SourceRange &R) { Range = R; }
|
void setRange(const SourceRange &R) { Range = R; }
|
||||||
|
@ -435,82 +409,21 @@ public:
|
||||||
SourceLocation getBeginLoc() const { return Range.getBegin(); }
|
SourceLocation getBeginLoc() const { return Range.getBegin(); }
|
||||||
SourceLocation getEndLoc() const { return Range.getEnd(); }
|
SourceLocation getEndLoc() const { return Range.getEnd(); }
|
||||||
|
|
||||||
typedef Action::CXXScopeTy * const * iterator;
|
Action::CXXScopeTy *getScopeRep() const { return ScopeRep; }
|
||||||
|
void setScopeRep(Action::CXXScopeTy *S) { ScopeRep = S; }
|
||||||
iterator begin() const {
|
|
||||||
if (NumScopeReps > 4)
|
|
||||||
return ManyScopeReps;
|
|
||||||
else
|
|
||||||
return &InlineScopeReps[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator end() const {
|
|
||||||
return begin() + NumScopeReps;
|
|
||||||
}
|
|
||||||
|
|
||||||
Action::CXXScopeTy *getScopeRep(unsigned I) const {
|
|
||||||
assert(I < size() && "Out-of-range scope index");
|
|
||||||
return begin()[I];
|
|
||||||
}
|
|
||||||
unsigned size() const { return NumScopeReps; }
|
|
||||||
|
|
||||||
void addScopeRep(Action::CXXScopeTy *S) {
|
|
||||||
if (!S)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (NumScopeReps >= Capacity)
|
|
||||||
reallocate();
|
|
||||||
|
|
||||||
if (Capacity == 4)
|
|
||||||
InlineScopeReps[NumScopeReps++] = S;
|
|
||||||
else
|
|
||||||
ManyScopeReps[NumScopeReps++] = S;
|
|
||||||
}
|
|
||||||
|
|
||||||
Action::CXXScopeTy *getCurrentScopeRep() const {
|
|
||||||
if (size() == 0)
|
|
||||||
return 0;
|
|
||||||
return begin()[size() - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
void setScopeRep(Action::CXXScopeTy *S) {
|
|
||||||
if (Capacity > 4)
|
|
||||||
delete [] ManyScopeReps;
|
|
||||||
Capacity = 4;
|
|
||||||
NumScopeReps = 0;
|
|
||||||
addScopeRep(S);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isEmpty() const { return !Range.isValid(); }
|
bool isEmpty() const { return !Range.isValid(); }
|
||||||
bool isNotEmpty() const { return !isEmpty(); }
|
bool isNotEmpty() const { return !isEmpty(); }
|
||||||
|
|
||||||
/// isInvalid - An error occured during parsing of the scope specifier.
|
/// isInvalid - An error occured during parsing of the scope specifier.
|
||||||
bool isInvalid() const { return isNotEmpty() && NumScopeReps == 0; }
|
bool isInvalid() const { return isNotEmpty() && ScopeRep == 0; }
|
||||||
|
|
||||||
/// isSet - A scope specifier was resolved to a valid C++ scope.
|
/// isSet - A scope specifier was resolved to a valid C++ scope.
|
||||||
bool isSet() const { return getCurrentScopeRep() != 0; }
|
bool isSet() const { return ScopeRep != 0; }
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
Range = SourceRange();
|
Range = SourceRange();
|
||||||
if (NumScopeReps > 4)
|
ScopeRep = 0;
|
||||||
delete [] ManyScopeReps;
|
|
||||||
NumScopeReps = 0;
|
|
||||||
Capacity = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Allocate and build the information that will be attached
|
|
||||||
/// to a scope-annotation token.
|
|
||||||
void *buildAnnotationData() const;
|
|
||||||
|
|
||||||
/// \brief Reconstruct a scope specifier from the annotation data.
|
|
||||||
///
|
|
||||||
/// This routine does not free the annotation data; call
|
|
||||||
/// freeAnnotationData for that.
|
|
||||||
void setFromAnnotationData(void *Data);
|
|
||||||
|
|
||||||
/// Frees the annotation data.
|
|
||||||
static void freeAnnotationData(void *Data) {
|
|
||||||
delete [] (uintptr_t *) Data;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -24,67 +24,6 @@ static DiagnosticBuilder Diag(Diagnostic &D, SourceLocation Loc,
|
||||||
return D.Report(FullSourceLoc(Loc, SrcMgr), DiagID);
|
return D.Report(FullSourceLoc(Loc, SrcMgr), DiagID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Double the capacity of this scope specifier.
|
|
||||||
void CXXScopeSpec::reallocate() {
|
|
||||||
Action::CXXScopeTy **Data = new Action::CXXScopeTy *[Capacity * 2];
|
|
||||||
|
|
||||||
Action::CXXScopeTy **From
|
|
||||||
= Capacity == 4? &InlineScopeReps[0] : ManyScopeReps;
|
|
||||||
std::memcpy(Data, From, Capacity * sizeof(Action::CXXScopeTy *));
|
|
||||||
|
|
||||||
if (Capacity > 4)
|
|
||||||
delete [] ManyScopeReps;
|
|
||||||
ManyScopeReps = Data;
|
|
||||||
Capacity *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
CXXScopeSpec::CXXScopeSpec(const CXXScopeSpec &SS)
|
|
||||||
: Range(SS.Range), NumScopeReps(SS.NumScopeReps), Capacity(SS.Capacity) {
|
|
||||||
|
|
||||||
if (Capacity > 4) {
|
|
||||||
ManyScopeReps = new Action::CXXScopeTy *[Capacity];
|
|
||||||
memcpy(ManyScopeReps, SS.ManyScopeReps,
|
|
||||||
Capacity * sizeof(Action::CXXScopeTy *));
|
|
||||||
} else {
|
|
||||||
memcpy(InlineScopeReps, SS.InlineScopeReps,
|
|
||||||
Capacity * sizeof(Action::CXXScopeTy *));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CXXScopeSpec &CXXScopeSpec::operator=(const CXXScopeSpec &SS) {
|
|
||||||
// FIXME: Does not provide the strong exception safety guarantee.
|
|
||||||
this->~CXXScopeSpec();
|
|
||||||
new (this) CXXScopeSpec(SS);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *CXXScopeSpec::buildAnnotationData() const {
|
|
||||||
uintptr_t *Data = (uintptr_t *)malloc(sizeof(uintptr_t) * (size() + 1));
|
|
||||||
Data[0] = size();
|
|
||||||
for (unsigned I = 0; I < size(); ++I)
|
|
||||||
Data[I + 1] = reinterpret_cast<uintptr_t>(getScopeRep(I));
|
|
||||||
return Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CXXScopeSpec::setFromAnnotationData(void *DataIn) {
|
|
||||||
uintptr_t *Data = static_cast<uintptr_t *>(DataIn);
|
|
||||||
NumScopeReps = *Data;
|
|
||||||
|
|
||||||
// Allocate enough space for the annotation data.
|
|
||||||
if (NumScopeReps > Capacity) {
|
|
||||||
if (Capacity > 4)
|
|
||||||
delete [] ManyScopeReps;
|
|
||||||
|
|
||||||
Capacity = NumScopeReps;
|
|
||||||
ManyScopeReps = new Action::CXXScopeTy *[Capacity];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Capacity > 4)
|
|
||||||
std::memcpy(ManyScopeReps, Data + 1, sizeof(uintptr_t) * NumScopeReps);
|
|
||||||
else
|
|
||||||
std::memcpy(InlineScopeReps, Data + 1, sizeof(uintptr_t) * NumScopeReps);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
|
/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
|
||||||
/// "TheDeclarator" is the declarator that this will be added to.
|
/// "TheDeclarator" is the declarator that this will be added to.
|
||||||
DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
|
DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
|
||||||
|
|
|
@ -515,7 +515,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
||||||
goto DoneWithDeclSpec;
|
goto DoneWithDeclSpec;
|
||||||
|
|
||||||
CXXScopeSpec SS;
|
CXXScopeSpec SS;
|
||||||
SS.setFromAnnotationData(Tok.getAnnotationValue());
|
SS.setScopeRep(Tok.getAnnotationValue());
|
||||||
SS.setRange(Tok.getAnnotationRange());
|
SS.setRange(Tok.getAnnotationRange());
|
||||||
|
|
||||||
// If the next token is the name of the class type that the C++ scope
|
// If the next token is the name of the class type that the C++ scope
|
||||||
|
@ -532,7 +532,6 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
||||||
if (TypeRep == 0)
|
if (TypeRep == 0)
|
||||||
goto DoneWithDeclSpec;
|
goto DoneWithDeclSpec;
|
||||||
|
|
||||||
CXXScopeSpec::freeAnnotationData(Tok.getAnnotationValue());
|
|
||||||
ConsumeToken(); // The C++ scope.
|
ConsumeToken(); // The C++ scope.
|
||||||
|
|
||||||
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
|
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
|
||||||
|
|
|
@ -36,8 +36,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS) {
|
||||||
"Call sites of this function should be guarded by checking for C++");
|
"Call sites of this function should be guarded by checking for C++");
|
||||||
|
|
||||||
if (Tok.is(tok::annot_cxxscope)) {
|
if (Tok.is(tok::annot_cxxscope)) {
|
||||||
SS.setFromAnnotationData(Tok.getAnnotationValue());
|
SS.setScopeRep(Tok.getAnnotationValue());
|
||||||
CXXScopeSpec::freeAnnotationData(Tok.getAnnotationValue());
|
|
||||||
SS.setRange(Tok.getAnnotationRange());
|
SS.setRange(Tok.getAnnotationRange());
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
return true;
|
return true;
|
||||||
|
@ -54,7 +53,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS) {
|
||||||
// '::' - Global scope qualifier.
|
// '::' - Global scope qualifier.
|
||||||
SourceLocation CCLoc = ConsumeToken();
|
SourceLocation CCLoc = ConsumeToken();
|
||||||
SS.setBeginLoc(CCLoc);
|
SS.setBeginLoc(CCLoc);
|
||||||
SS.addScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc));
|
SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc));
|
||||||
SS.setEndLoc(CCLoc);
|
SS.setEndLoc(CCLoc);
|
||||||
HasScopeSpecifier = true;
|
HasScopeSpecifier = true;
|
||||||
}
|
}
|
||||||
|
@ -80,7 +79,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS) {
|
||||||
if (SS.isInvalid())
|
if (SS.isInvalid())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SS.addScopeRep(
|
SS.setScopeRep(
|
||||||
Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, IdLoc, CCLoc, *II));
|
Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, IdLoc, CCLoc, *II));
|
||||||
SS.setEndLoc(CCLoc);
|
SS.setEndLoc(CCLoc);
|
||||||
continue;
|
continue;
|
||||||
|
@ -165,7 +164,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS) {
|
||||||
HasScopeSpecifier = true;
|
HasScopeSpecifier = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SS.addScopeRep(
|
SS.setScopeRep(
|
||||||
Actions.ActOnCXXNestedNameSpecifier(CurScope, SS,
|
Actions.ActOnCXXNestedNameSpecifier(CurScope, SS,
|
||||||
TypeToken.getAnnotationValue(),
|
TypeToken.getAnnotationValue(),
|
||||||
TypeToken.getAnnotationRange(),
|
TypeToken.getAnnotationRange(),
|
||||||
|
|
|
@ -866,7 +866,7 @@ bool Parser::TryAnnotateTypeOrScopeToken() {
|
||||||
else
|
else
|
||||||
PP.EnterToken(Tok);
|
PP.EnterToken(Tok);
|
||||||
Tok.setKind(tok::annot_cxxscope);
|
Tok.setKind(tok::annot_cxxscope);
|
||||||
Tok.setAnnotationValue(SS.buildAnnotationData());
|
Tok.setAnnotationValue(SS.getScopeRep());
|
||||||
Tok.setAnnotationRange(SS.getRange());
|
Tok.setAnnotationRange(SS.getRange());
|
||||||
|
|
||||||
// In case the tokens were cached, have Preprocessor replace them with the
|
// In case the tokens were cached, have Preprocessor replace them with the
|
||||||
|
@ -898,7 +898,7 @@ bool Parser::TryAnnotateCXXScopeToken() {
|
||||||
else
|
else
|
||||||
PP.EnterToken(Tok);
|
PP.EnterToken(Tok);
|
||||||
Tok.setKind(tok::annot_cxxscope);
|
Tok.setKind(tok::annot_cxxscope);
|
||||||
Tok.setAnnotationValue(SS.buildAnnotationData());
|
Tok.setAnnotationValue(SS.getScopeRep());
|
||||||
Tok.setAnnotationRange(SS.getRange());
|
Tok.setAnnotationRange(SS.getRange());
|
||||||
|
|
||||||
// In case the tokens were cached, have Preprocessor replace them with the
|
// In case the tokens were cached, have Preprocessor replace them with the
|
||||||
|
|
|
@ -25,7 +25,7 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
NestedNameSpecifier *NNS
|
NestedNameSpecifier *NNS
|
||||||
= static_cast<NestedNameSpecifier *>(SS.getCurrentScopeRep());
|
= static_cast<NestedNameSpecifier *>(SS.getScopeRep());
|
||||||
if (NNS->isDependent())
|
if (NNS->isDependent())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ bool Sema::isDependentScopeSpecifier(const CXXScopeSpec &SS) {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
NestedNameSpecifier *NNS
|
NestedNameSpecifier *NNS
|
||||||
= static_cast<NestedNameSpecifier *>(SS.getCurrentScopeRep());
|
= static_cast<NestedNameSpecifier *>(SS.getScopeRep());
|
||||||
return NNS->isDependent();
|
return NNS->isDependent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
|
||||||
SourceLocation CCLoc,
|
SourceLocation CCLoc,
|
||||||
IdentifierInfo &II) {
|
IdentifierInfo &II) {
|
||||||
NestedNameSpecifier *Prefix
|
NestedNameSpecifier *Prefix
|
||||||
= static_cast<NestedNameSpecifier *>(SS.getCurrentScopeRep());
|
= static_cast<NestedNameSpecifier *>(SS.getScopeRep());
|
||||||
|
|
||||||
// If the prefix is already dependent, there is no name lookup to
|
// If the prefix is already dependent, there is no name lookup to
|
||||||
// perform. Just build the resulting nested-name-specifier.
|
// perform. Just build the resulting nested-name-specifier.
|
||||||
|
@ -173,7 +173,7 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
|
||||||
SourceRange TypeRange,
|
SourceRange TypeRange,
|
||||||
SourceLocation CCLoc) {
|
SourceLocation CCLoc) {
|
||||||
NestedNameSpecifier *Prefix
|
NestedNameSpecifier *Prefix
|
||||||
= static_cast<NestedNameSpecifier *>(SS.getCurrentScopeRep());
|
= static_cast<NestedNameSpecifier *>(SS.getScopeRep());
|
||||||
return NestedNameSpecifier::Create(Context, Prefix, /*FIXME:*/false,
|
return NestedNameSpecifier::Create(Context, Prefix, /*FIXME:*/false,
|
||||||
QualType::getFromOpaquePtr(Ty).getTypePtr());
|
QualType::getFromOpaquePtr(Ty).getTypePtr());
|
||||||
}
|
}
|
||||||
|
|
|
@ -442,7 +442,7 @@ Sema::BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc,
|
||||||
if (SS && !SS->isEmpty()) {
|
if (SS && !SS->isEmpty()) {
|
||||||
return new (Context) QualifiedDeclRefExpr(D, Ty, Loc, TypeDependent,
|
return new (Context) QualifiedDeclRefExpr(D, Ty, Loc, TypeDependent,
|
||||||
ValueDependent, SS->getRange(),
|
ValueDependent, SS->getRange(),
|
||||||
static_cast<NestedNameSpecifier *>(SS->getCurrentScopeRep()));
|
static_cast<NestedNameSpecifier *>(SS->getScopeRep()));
|
||||||
} else
|
} else
|
||||||
return new (Context) DeclRefExpr(D, Ty, Loc, TypeDependent, ValueDependent);
|
return new (Context) DeclRefExpr(D, Ty, Loc, TypeDependent, ValueDependent);
|
||||||
}
|
}
|
||||||
|
@ -617,7 +617,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
|
||||||
if (SS && isDependentScopeSpecifier(*SS)) {
|
if (SS && isDependentScopeSpecifier(*SS)) {
|
||||||
return Owned(new (Context) UnresolvedDeclRefExpr(Name, Context.DependentTy,
|
return Owned(new (Context) UnresolvedDeclRefExpr(Name, Context.DependentTy,
|
||||||
Loc, SS->getRange(),
|
Loc, SS->getRange(),
|
||||||
static_cast<NestedNameSpecifier *>(SS->getCurrentScopeRep())));
|
static_cast<NestedNameSpecifier *>(SS->getScopeRep())));
|
||||||
}
|
}
|
||||||
|
|
||||||
LookupResult Lookup = LookupParsedName(S, SS, Name, LookupOrdinaryName,
|
LookupResult Lookup = LookupParsedName(S, SS, Name, LookupOrdinaryName,
|
||||||
|
|
|
@ -1102,6 +1102,6 @@ QualType Sema::getQualifiedNameType(const CXXScopeSpec &SS, QualType T) {
|
||||||
return T;
|
return T;
|
||||||
|
|
||||||
NestedNameSpecifier *NNS
|
NestedNameSpecifier *NNS
|
||||||
= static_cast<NestedNameSpecifier *>(SS.getCurrentScopeRep());
|
= static_cast<NestedNameSpecifier *>(SS.getScopeRep());
|
||||||
return Context.getQualifiedNameType(NNS, T);
|
return Context.getQualifiedNameType(NNS, T);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue