Simplify CXXScopeSpec a lot. No more weird SmallVector-like hacks here
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67800 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h
index 3a6e6f2..659a108 100644
--- a/include/clang/Parse/DeclSpec.h
+++ b/include/clang/Parse/DeclSpec.h
@@ -397,36 +397,10 @@
/// 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 @@
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;
}
};
diff --git a/lib/Parse/DeclSpec.cpp b/lib/Parse/DeclSpec.cpp
index 72ac311..94799c3 100644
--- a/lib/Parse/DeclSpec.cpp
+++ b/lib/Parse/DeclSpec.cpp
@@ -24,67 +24,6 @@
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,
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 7a92171..a9fbbbe 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -515,7 +515,7 @@
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 @@
if (TypeRep == 0)
goto DoneWithDeclSpec;
- CXXScopeSpec::freeAnnotationData(Tok.getAnnotationValue());
ConsumeToken(); // The C++ scope.
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 731f4c7..b3ec24f 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -36,8 +36,7 @@
"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 @@
// '::' - 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 @@
if (SS.isInvalid())
continue;
- SS.addScopeRep(
+ SS.setScopeRep(
Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, IdLoc, CCLoc, *II));
SS.setEndLoc(CCLoc);
continue;
@@ -165,7 +164,7 @@
HasScopeSpecifier = true;
}
- SS.addScopeRep(
+ SS.setScopeRep(
Actions.ActOnCXXNestedNameSpecifier(CurScope, SS,
TypeToken.getAnnotationValue(),
TypeToken.getAnnotationRange(),
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 7a221d0..5ce8b3d 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -866,7 +866,7 @@
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 @@
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
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index ca864a2..8fb2811 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -25,7 +25,7 @@
return 0;
NestedNameSpecifier *NNS
- = static_cast<NestedNameSpecifier *>(SS.getCurrentScopeRep());
+ = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
if (NNS->isDependent())
return 0;
@@ -57,7 +57,7 @@
return false;
NestedNameSpecifier *NNS
- = static_cast<NestedNameSpecifier *>(SS.getCurrentScopeRep());
+ = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
return NNS->isDependent();
}
@@ -111,7 +111,7 @@
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 @@
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());
}
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 288b617..92a4de0 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -442,7 +442,7 @@
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 @@
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,
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 0780ad8..f14eb65 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -1102,6 +1102,6 @@
return T;
NestedNameSpecifier *NNS
- = static_cast<NestedNameSpecifier *>(SS.getCurrentScopeRep());
+ = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
return Context.getQualifiedNameType(NNS, T);
}