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.
|
||||
class CXXScopeSpec {
|
||||
SourceRange Range;
|
||||
|
||||
/// 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();
|
||||
void *ScopeRep;
|
||||
|
||||
public:
|
||||
CXXScopeSpec() : Range(), NumScopeReps(0), Capacity(4) { }
|
||||
|
||||
CXXScopeSpec(const CXXScopeSpec &SS);
|
||||
|
||||
CXXScopeSpec &operator=(const CXXScopeSpec &SS);
|
||||
|
||||
~CXXScopeSpec() {
|
||||
clear();
|
||||
}
|
||||
CXXScopeSpec() : Range(), ScopeRep() { }
|
||||
|
||||
const SourceRange &getRange() const { return Range; }
|
||||
void setRange(const SourceRange &R) { Range = R; }
|
||||
|
@ -435,82 +409,21 @@ public:
|
|||
SourceLocation getBeginLoc() const { return Range.getBegin(); }
|
||||
SourceLocation getEndLoc() const { return Range.getEnd(); }
|
||||
|
||||
typedef Action::CXXScopeTy * const * iterator;
|
||||
|
||||
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);
|
||||
}
|
||||
Action::CXXScopeTy *getScopeRep() const { return ScopeRep; }
|
||||
void setScopeRep(Action::CXXScopeTy *S) { ScopeRep = S; }
|
||||
|
||||
bool isEmpty() const { return !Range.isValid(); }
|
||||
bool isNotEmpty() const { return !isEmpty(); }
|
||||
|
||||
/// 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.
|
||||
bool isSet() const { return getCurrentScopeRep() != 0; }
|
||||
bool isSet() const { return ScopeRep != 0; }
|
||||
|
||||
void clear() {
|
||||
Range = SourceRange();
|
||||
if (NumScopeReps > 4)
|
||||
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;
|
||||
ScopeRep = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -24,67 +24,6 @@ static DiagnosticBuilder Diag(Diagnostic &D, SourceLocation Loc,
|
|||
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.
|
||||
/// "TheDeclarator" is the declarator that this will be added to.
|
||||
DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
|
||||
|
|
|
@ -515,7 +515,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
|||
goto DoneWithDeclSpec;
|
||||
|
||||
CXXScopeSpec SS;
|
||||
SS.setFromAnnotationData(Tok.getAnnotationValue());
|
||||
SS.setScopeRep(Tok.getAnnotationValue());
|
||||
SS.setRange(Tok.getAnnotationRange());
|
||||
|
||||
// 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)
|
||||
goto DoneWithDeclSpec;
|
||||
|
||||
CXXScopeSpec::freeAnnotationData(Tok.getAnnotationValue());
|
||||
ConsumeToken(); // The C++ scope.
|
||||
|
||||
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++");
|
||||
|
||||
if (Tok.is(tok::annot_cxxscope)) {
|
||||
SS.setFromAnnotationData(Tok.getAnnotationValue());
|
||||
CXXScopeSpec::freeAnnotationData(Tok.getAnnotationValue());
|
||||
SS.setScopeRep(Tok.getAnnotationValue());
|
||||
SS.setRange(Tok.getAnnotationRange());
|
||||
ConsumeToken();
|
||||
return true;
|
||||
|
@ -54,7 +53,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS) {
|
|||
// '::' - Global scope qualifier.
|
||||
SourceLocation CCLoc = ConsumeToken();
|
||||
SS.setBeginLoc(CCLoc);
|
||||
SS.addScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc));
|
||||
SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc));
|
||||
SS.setEndLoc(CCLoc);
|
||||
HasScopeSpecifier = true;
|
||||
}
|
||||
|
@ -80,7 +79,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS) {
|
|||
if (SS.isInvalid())
|
||||
continue;
|
||||
|
||||
SS.addScopeRep(
|
||||
SS.setScopeRep(
|
||||
Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, IdLoc, CCLoc, *II));
|
||||
SS.setEndLoc(CCLoc);
|
||||
continue;
|
||||
|
@ -165,7 +164,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS) {
|
|||
HasScopeSpecifier = true;
|
||||
}
|
||||
|
||||
SS.addScopeRep(
|
||||
SS.setScopeRep(
|
||||
Actions.ActOnCXXNestedNameSpecifier(CurScope, SS,
|
||||
TypeToken.getAnnotationValue(),
|
||||
TypeToken.getAnnotationRange(),
|
||||
|
|
|
@ -866,7 +866,7 @@ bool Parser::TryAnnotateTypeOrScopeToken() {
|
|||
else
|
||||
PP.EnterToken(Tok);
|
||||
Tok.setKind(tok::annot_cxxscope);
|
||||
Tok.setAnnotationValue(SS.buildAnnotationData());
|
||||
Tok.setAnnotationValue(SS.getScopeRep());
|
||||
Tok.setAnnotationRange(SS.getRange());
|
||||
|
||||
// In case the tokens were cached, have Preprocessor replace them with the
|
||||
|
@ -898,7 +898,7 @@ bool Parser::TryAnnotateCXXScopeToken() {
|
|||
else
|
||||
PP.EnterToken(Tok);
|
||||
Tok.setKind(tok::annot_cxxscope);
|
||||
Tok.setAnnotationValue(SS.buildAnnotationData());
|
||||
Tok.setAnnotationValue(SS.getScopeRep());
|
||||
Tok.setAnnotationRange(SS.getRange());
|
||||
|
||||
// In case the tokens were cached, have Preprocessor replace them with the
|
||||
|
|
|
@ -25,7 +25,7 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS) {
|
|||
return 0;
|
||||
|
||||
NestedNameSpecifier *NNS
|
||||
= static_cast<NestedNameSpecifier *>(SS.getCurrentScopeRep());
|
||||
= static_cast<NestedNameSpecifier *>(SS.getScopeRep());
|
||||
if (NNS->isDependent())
|
||||
return 0;
|
||||
|
||||
|
@ -57,7 +57,7 @@ bool Sema::isDependentScopeSpecifier(const CXXScopeSpec &SS) {
|
|||
return false;
|
||||
|
||||
NestedNameSpecifier *NNS
|
||||
= static_cast<NestedNameSpecifier *>(SS.getCurrentScopeRep());
|
||||
= static_cast<NestedNameSpecifier *>(SS.getScopeRep());
|
||||
return NNS->isDependent();
|
||||
}
|
||||
|
||||
|
@ -111,7 +111,7 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
|
|||
SourceLocation CCLoc,
|
||||
IdentifierInfo &II) {
|
||||
NestedNameSpecifier *Prefix
|
||||
= static_cast<NestedNameSpecifier *>(SS.getCurrentScopeRep());
|
||||
= static_cast<NestedNameSpecifier *>(SS.getScopeRep());
|
||||
|
||||
// If the prefix is already dependent, there is no name lookup to
|
||||
// perform. Just build the resulting nested-name-specifier.
|
||||
|
@ -173,7 +173,7 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
|
|||
SourceRange TypeRange,
|
||||
SourceLocation CCLoc) {
|
||||
NestedNameSpecifier *Prefix
|
||||
= static_cast<NestedNameSpecifier *>(SS.getCurrentScopeRep());
|
||||
= static_cast<NestedNameSpecifier *>(SS.getScopeRep());
|
||||
return NestedNameSpecifier::Create(Context, Prefix, /*FIXME:*/false,
|
||||
QualType::getFromOpaquePtr(Ty).getTypePtr());
|
||||
}
|
||||
|
|
|
@ -442,7 +442,7 @@ Sema::BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc,
|
|||
if (SS && !SS->isEmpty()) {
|
||||
return new (Context) QualifiedDeclRefExpr(D, Ty, Loc, TypeDependent,
|
||||
ValueDependent, SS->getRange(),
|
||||
static_cast<NestedNameSpecifier *>(SS->getCurrentScopeRep()));
|
||||
static_cast<NestedNameSpecifier *>(SS->getScopeRep()));
|
||||
} else
|
||||
return new (Context) DeclRefExpr(D, Ty, Loc, TypeDependent, ValueDependent);
|
||||
}
|
||||
|
@ -617,7 +617,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
|
|||
if (SS && isDependentScopeSpecifier(*SS)) {
|
||||
return Owned(new (Context) UnresolvedDeclRefExpr(Name, Context.DependentTy,
|
||||
Loc, SS->getRange(),
|
||||
static_cast<NestedNameSpecifier *>(SS->getCurrentScopeRep())));
|
||||
static_cast<NestedNameSpecifier *>(SS->getScopeRep())));
|
||||
}
|
||||
|
||||
LookupResult Lookup = LookupParsedName(S, SS, Name, LookupOrdinaryName,
|
||||
|
|
|
@ -1102,6 +1102,6 @@ QualType Sema::getQualifiedNameType(const CXXScopeSpec &SS, QualType T) {
|
|||
return T;
|
||||
|
||||
NestedNameSpecifier *NNS
|
||||
= static_cast<NestedNameSpecifier *>(SS.getCurrentScopeRep());
|
||||
= static_cast<NestedNameSpecifier *>(SS.getScopeRep());
|
||||
return Context.getQualifiedNameType(NNS, T);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue