From 3507369940bfb269551bfa1fec812481f60e3552 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Thu, 26 Mar 2009 23:56:24 +0000 Subject: [PATCH] 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 --- include/clang/Parse/DeclSpec.h | 101 +++------------------------------ lib/Parse/DeclSpec.cpp | 61 -------------------- lib/Parse/ParseDecl.cpp | 3 +- lib/Parse/ParseExprCXX.cpp | 9 ++- lib/Parse/Parser.cpp | 4 +- lib/Sema/SemaCXXScopeSpec.cpp | 8 +-- lib/Sema/SemaExpr.cpp | 4 +- lib/Sema/SemaType.cpp | 2 +- 8 files changed, 21 insertions(+), 171 deletions(-) diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h index 3a6e6f2cff..659a10817d 100644 --- a/include/clang/Parse/DeclSpec.h +++ b/include/clang/Parse/DeclSpec.h @@ -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; } }; diff --git a/lib/Parse/DeclSpec.cpp b/lib/Parse/DeclSpec.cpp index 72ac3112f9..94799c3200 100644 --- a/lib/Parse/DeclSpec.cpp +++ b/lib/Parse/DeclSpec.cpp @@ -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(getScopeRep(I)); - return Data; -} - -void CXXScopeSpec::setFromAnnotationData(void *DataIn) { - uintptr_t *Data = static_cast(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 7a92171908..a9fbbbe498 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -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, diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index 731f4c7957..b3ec24f864 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -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(), diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 7a221d007c..5ce8b3dbcd 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -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 diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp index ca864a2a2e..8fb2811ce5 100644 --- a/lib/Sema/SemaCXXScopeSpec.cpp +++ b/lib/Sema/SemaCXXScopeSpec.cpp @@ -25,7 +25,7 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS) { return 0; NestedNameSpecifier *NNS - = static_cast(SS.getCurrentScopeRep()); + = static_cast(SS.getScopeRep()); if (NNS->isDependent()) return 0; @@ -57,7 +57,7 @@ bool Sema::isDependentScopeSpecifier(const CXXScopeSpec &SS) { return false; NestedNameSpecifier *NNS - = static_cast(SS.getCurrentScopeRep()); + = static_cast(SS.getScopeRep()); return NNS->isDependent(); } @@ -111,7 +111,7 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S, SourceLocation CCLoc, IdentifierInfo &II) { NestedNameSpecifier *Prefix - = static_cast(SS.getCurrentScopeRep()); + = static_cast(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(SS.getCurrentScopeRep()); + = static_cast(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 288b617191..92a4de08e4 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -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(SS->getCurrentScopeRep())); + static_cast(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(SS->getCurrentScopeRep()))); + static_cast(SS->getScopeRep()))); } LookupResult Lookup = LookupParsedName(S, SS, Name, LookupOrdinaryName, diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 0780ad8f4a..f14eb65203 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -1102,6 +1102,6 @@ QualType Sema::getQualifiedNameType(const CXXScopeSpec &SS, QualType T) { return T; NestedNameSpecifier *NNS - = static_cast(SS.getCurrentScopeRep()); + = static_cast(SS.getScopeRep()); return Context.getQualifiedNameType(NNS, T); } -- 2.40.0