[cfe-commits] r126716 - in /cfe/trunk: include/clang/AST/NestedNameSpecifier.h include/clang/Sema/DeclSpec.h lib/AST/NestedNameSpecifier.cpp lib/Sema/DeclSpec.cpp lib/Serialization/ASTReader.cpp
Douglas Gregor
dgregor at apple.com
Mon Feb 28 15:58:31 PST 2011
Author: dgregor
Date: Mon Feb 28 17:58:31 2011
New Revision: 126716
URL: http://llvm.org/viewvc/llvm-project?rev=126716&view=rev
Log:
Refactor the construction of nested-name-specifiers with
source-location information into a NestedNameSpecifierLocBuilder
class, which lives within the AST library and centralize all knowledge
of the format of nested-name-specifier location information here.
No functionality change.
Modified:
cfe/trunk/include/clang/AST/NestedNameSpecifier.h
cfe/trunk/include/clang/Sema/DeclSpec.h
cfe/trunk/lib/AST/NestedNameSpecifier.cpp
cfe/trunk/lib/Sema/DeclSpec.cpp
cfe/trunk/lib/Serialization/ASTReader.cpp
Modified: cfe/trunk/include/clang/AST/NestedNameSpecifier.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/NestedNameSpecifier.h?rev=126716&r1=126715&r2=126716&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/NestedNameSpecifier.h (original)
+++ cfe/trunk/include/clang/AST/NestedNameSpecifier.h Mon Feb 28 17:58:31 2011
@@ -312,6 +312,146 @@
}
};
+/// \brief Class that aids in the construction of nested-name-specifiers along
+/// with source-location information for all of the components of the
+/// nested-name-specifier.
+class NestedNameSpecifierLocBuilder {
+ /// \brief The current representation of the nested-name-specifier we're
+ /// building.
+ NestedNameSpecifier *Representation;
+
+ /// \brief Buffer used to store source-location information for the
+ /// nested-name-specifier.
+ ///
+ /// Note that we explicitly manage the buffer (rather than using a
+ /// SmallVector) because \c Declarator expects it to be possible to memcpy()
+ /// a \c CXXScopeSpec, and CXXScopeSpec uses a NestedNameSpecifierLocBuilder.
+ char *Buffer;
+
+ /// \brief The size of the buffer used to store source-location information
+ /// for the nested-name-specifier.
+ unsigned BufferSize;
+
+ /// \brief The capacity of the buffer used to store source-location
+ /// information for the nested-name-specifier.
+ unsigned BufferCapacity;
+
+public:
+ NestedNameSpecifierLocBuilder();
+
+ NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other);
+
+ NestedNameSpecifierLocBuilder &
+ operator=(const NestedNameSpecifierLocBuilder &Other);
+
+ ~NestedNameSpecifierLocBuilder();
+
+ /// \brief Retrieve the representation of the nested-name-specifier.
+ NestedNameSpecifier *getRepresentation() const { return Representation; }
+
+ /// \brief Extend the current nested-name-specifier by another
+ /// nested-name-specifier component of the form 'type::'.
+ ///
+ /// \param Context The AST context in which this nested-name-specifier
+ /// resides.
+ ///
+ /// \param TemplateKWLoc The location of the 'template' keyword, if present.
+ ///
+ /// \param TL The TypeLoc that describes the type preceding the '::'.
+ ///
+ /// \param ColonColonLoc The location of the trailing '::'.
+ void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL,
+ SourceLocation ColonColonLoc);
+
+ /// \brief Extend the current nested-name-specifier by another
+ /// nested-name-specifier component of the form 'identifier::'.
+ ///
+ /// \param Context The AST context in which this nested-name-specifier
+ /// resides.
+ ///
+ /// \param Identifier The identifier.
+ ///
+ /// \param IdentifierLoc The location of the identifier.
+ ///
+ /// \param ColonColonLoc The location of the trailing '::'.
+ void Extend(ASTContext &Context, IdentifierInfo *Identifier,
+ SourceLocation IdentifierLoc, SourceLocation ColonColonLoc);
+
+ /// \brief Extend the current nested-name-specifier by another
+ /// nested-name-specifier component of the form 'namespace::'.
+ ///
+ /// \param Context The AST context in which this nested-name-specifier
+ /// resides.
+ ///
+ /// \param Namespace The namespace.
+ ///
+ /// \param NamespaceLoc The location of the namespace name.
+ ///
+ /// \param ColonColonLoc The location of the trailing '::'.
+ void Extend(ASTContext &Context, NamespaceDecl *Namespace,
+ SourceLocation NamespaceLoc, SourceLocation ColonColonLoc);
+
+ /// \brief Extend the current nested-name-specifier by another
+ /// nested-name-specifier component of the form 'namespace-alias::'.
+ ///
+ /// \param Context The AST context in which this nested-name-specifier
+ /// resides.
+ ///
+ /// \param Alias The namespace alias.
+ ///
+ /// \param AliasLoc The location of the namespace alias
+ /// name.
+ ///
+ /// \param ColonColonLoc The location of the trailing '::'.
+ void Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
+ SourceLocation AliasLoc, SourceLocation ColonColonLoc);
+
+ /// \brief Turn this (empty) nested-name-specifier into the global
+ /// nested-name-specifier '::'.
+ void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
+
+ /// \brief Make a new nested-name-specifier from incomplete source-location
+ /// information.
+ ///
+ /// This routine should be used very, very rarely, in cases where we
+ /// need to synthesize a nested-name-specifier. Most code should instead use
+ /// \c Adopt() with a proper \c NestedNameSpecifierLoc.
+ void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier,
+ SourceRange R);
+
+ /// \brief Adopt an existing nested-name-specifier (with source-range
+ /// information).
+ void Adopt(NestedNameSpecifierLoc Other);
+
+ /// \brief Retrieve the source range covered by this nested-name-specifier.
+ SourceRange getSourceRange() const {
+ return NestedNameSpecifierLoc(Representation, Buffer).getSourceRange();
+ }
+
+ /// \brief Retrieve a nested-name-specifier with location information,
+ /// copied into the given AST context.
+ ///
+ /// \param Context The context into which this nested-name-specifier will be
+ /// copied.
+ NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const;
+
+ /// \brief Clear out this builder, and prepare it to build another
+ /// nested-name-specifier with source-location information.
+ void Clear() {
+ Representation = 0;
+ BufferSize = 0;
+ }
+
+ /// \brief Retrieve the underlying buffer.
+ ///
+ /// \returns A pair containing a pointer to the buffer of source-location
+ /// data and the size of the source-location data that resides in that
+ /// buffer.
+ std::pair<char *, unsigned> getBuffer() const {
+ return std::make_pair(Buffer, BufferSize);
+ }
+};
+
/// Insertion operator for diagnostics. This allows sending NestedNameSpecifiers
/// into a diagnostic with <<.
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
Modified: cfe/trunk/include/clang/Sema/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=126716&r1=126715&r2=126716&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Sema/DeclSpec.h Mon Feb 28 17:58:31 2011
@@ -22,6 +22,7 @@
#include "clang/Sema/AttributeList.h"
#include "clang/Sema/Ownership.h"
+#include "clang/AST/NestedNameSpecifier.h"
#include "clang/Lex/Token.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/Specifiers.h"
@@ -54,32 +55,10 @@
///
/// The actual scope is described by getScopeRep().
class CXXScopeSpec {
- SourceRange Range;
- NestedNameSpecifier *ScopeRep;
-
- /// \brief Buffer used to store source-location information for the
- /// nested-name-specifier.
- ///
- /// Note that we explicitly manage the buffer (rather than using a
- /// SmallVector) because \c Declarator expects it to be possible to memcpy()
- /// a \c CXXScopeSpec.
- char *Buffer;
-
- /// \brief The size of the buffer used to store source-location information
- /// for the nested-name-specifier.
- unsigned BufferSize;
-
- /// \brief The capacity of the buffer used to store source-location
- /// information for the nested-name-specifier.
- unsigned BufferCapacity;
+ SourceRange Range;
+ NestedNameSpecifierLocBuilder Builder;
public:
- CXXScopeSpec() : Range(), ScopeRep(), Buffer(0), BufferSize(0),
- BufferCapacity(0) { }
- CXXScopeSpec(const CXXScopeSpec &Other);
- CXXScopeSpec &operator=(const CXXScopeSpec &Other);
- ~CXXScopeSpec();
-
const SourceRange &getRange() const { return Range; }
void setRange(const SourceRange &R) { Range = R; }
void setBeginLoc(SourceLocation Loc) { Range.setBegin(Loc); }
@@ -87,7 +66,10 @@
SourceLocation getBeginLoc() const { return Range.getBegin(); }
SourceLocation getEndLoc() const { return Range.getEnd(); }
- NestedNameSpecifier *getScopeRep() const { return ScopeRep; }
+ /// \brief Retrieve the representation of the nested-name-specifier.
+ NestedNameSpecifier *getScopeRep() const {
+ return Builder.getRepresentation();
+ }
/// \brief Extend the current nested-name-specifier by another
/// nested-name-specifier component of the form 'type::'.
@@ -176,9 +158,9 @@
bool isNotEmpty() const { return !isEmpty(); }
/// An error occured during parsing of the scope specifier.
- bool isInvalid() const { return isNotEmpty() && ScopeRep == 0; }
+ bool isInvalid() const { return isNotEmpty() && getScopeRep() == 0; }
/// A scope specifier is present, and it refers to a real scope.
- bool isValid() const { return isNotEmpty() && ScopeRep != 0; }
+ bool isValid() const { return isNotEmpty() && getScopeRep() != 0; }
/// \brief Indicate that this nested-name-specifier is invalid.
void SetInvalid(SourceRange R) {
@@ -186,24 +168,24 @@
if (Range.getBegin().isInvalid())
Range.setBegin(R.getBegin());
Range.setEnd(R.getEnd());
- ScopeRep = 0;
+ Builder.Clear();
}
/// Deprecated. Some call sites intend isNotEmpty() while others intend
/// isValid().
- bool isSet() const { return ScopeRep != 0; }
+ bool isSet() const { return getScopeRep() != 0; }
void clear() {
Range = SourceRange();
- ScopeRep = 0;
+ Builder.Clear();
}
/// \brief Retrieve the data associated with the source-location information.
- char *location_data() const { return Buffer; }
+ char *location_data() const { return Builder.getBuffer().first; }
/// \brief Retrieve the size of the data associated with source-location
/// information.
- unsigned location_size() const { return BufferSize; }
+ unsigned location_size() const { return Builder.getBuffer().second; }
};
/// DeclSpec - This class captures information about "declaration specifiers",
Modified: cfe/trunk/lib/AST/NestedNameSpecifier.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/NestedNameSpecifier.cpp?rev=126716&r1=126715&r2=126716&view=diff
==============================================================================
--- cfe/trunk/lib/AST/NestedNameSpecifier.cpp (original)
+++ cfe/trunk/lib/AST/NestedNameSpecifier.cpp Mon Feb 28 17:58:31 2011
@@ -371,3 +371,249 @@
void *TypeData = LoadPointer(Data, Offset);
return TypeLoc(Qualifier->getAsType(), TypeData);
}
+
+namespace {
+ void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize,
+ unsigned &BufferCapacity) {
+ if (BufferSize + (End - Start) > BufferCapacity) {
+ // Reallocate the buffer.
+ unsigned NewCapacity
+ = std::max((unsigned)(BufferCapacity? BufferCapacity * 2
+ : sizeof(void*) * 2),
+ (unsigned)(BufferSize + (End - Start)));
+ char *NewBuffer = static_cast<char *>(malloc(NewCapacity));
+ memcpy(NewBuffer, Buffer, BufferSize);
+
+ if (BufferCapacity)
+ free(Buffer);
+ Buffer = NewBuffer;
+ BufferCapacity = NewCapacity;
+ }
+
+ memcpy(Buffer + BufferSize, Start, End - Start);
+ BufferSize += End-Start;
+ }
+
+ /// \brief Save a source location to the given buffer.
+ void SaveSourceLocation(SourceLocation Loc, char *&Buffer,
+ unsigned &BufferSize, unsigned &BufferCapacity) {
+ unsigned Raw = Loc.getRawEncoding();
+ Append(reinterpret_cast<char *>(&Raw),
+ reinterpret_cast<char *>(&Raw) + sizeof(unsigned),
+ Buffer, BufferSize, BufferCapacity);
+ }
+
+ /// \brief Save a pointer to the given buffer.
+ void SavePointer(void *Ptr, char *&Buffer, unsigned &BufferSize,
+ unsigned &BufferCapacity) {
+ Append(reinterpret_cast<char *>(&Ptr),
+ reinterpret_cast<char *>(&Ptr) + sizeof(void *),
+ Buffer, BufferSize, BufferCapacity);
+ }
+}
+
+NestedNameSpecifierLocBuilder::NestedNameSpecifierLocBuilder()
+ : Representation(0), Buffer(0), BufferSize(0), BufferCapacity(0) { }
+
+NestedNameSpecifierLocBuilder::
+NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other)
+ : Representation(Other.Representation), Buffer(0),
+ BufferSize(0), BufferCapacity(0)
+{
+ if (!Other.Buffer)
+ return;
+
+ if (Other.BufferCapacity == 0) {
+ // Shallow copy is okay.
+ Buffer = Other.Buffer;
+ BufferSize = Other.BufferSize;
+ return;
+ }
+
+ // Deep copy
+ BufferSize = Other.BufferSize;
+ BufferCapacity = Other.BufferSize;
+ Buffer = static_cast<char *>(malloc(BufferCapacity));
+ memcpy(Buffer, Other.Buffer, BufferSize);
+}
+
+NestedNameSpecifierLocBuilder &
+NestedNameSpecifierLocBuilder::
+operator=(const NestedNameSpecifierLocBuilder &Other) {
+ Representation = Other.Representation;
+
+ if (Buffer && Other.Buffer && BufferCapacity >= Other.BufferSize) {
+ // Re-use our storage.
+ BufferSize = Other.BufferSize;
+ memcpy(Buffer, Other.Buffer, BufferSize);
+ return *this;
+ }
+
+ // Free our storage, if we have any.
+ if (BufferCapacity) {
+ free(Buffer);
+ BufferCapacity = 0;
+ }
+
+ if (!Other.Buffer) {
+ // Empty.
+ Buffer = 0;
+ BufferSize = 0;
+ return *this;
+ }
+
+ if (Other.BufferCapacity == 0) {
+ // Shallow copy is okay.
+ Buffer = Other.Buffer;
+ BufferSize = Other.BufferSize;
+ return *this;
+ }
+
+ // Deep copy.
+ BufferSize = Other.BufferSize;
+ BufferCapacity = BufferSize;
+ Buffer = static_cast<char *>(malloc(BufferSize));
+ memcpy(Buffer, Other.Buffer, BufferSize);
+ return *this;
+}
+
+NestedNameSpecifierLocBuilder::~NestedNameSpecifierLocBuilder() {
+ if (BufferCapacity)
+ free(Buffer);
+}
+
+void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
+ SourceLocation TemplateKWLoc,
+ TypeLoc TL,
+ SourceLocation ColonColonLoc) {
+ Representation = NestedNameSpecifier::Create(Context, Representation,
+ TemplateKWLoc.isValid(),
+ TL.getTypePtr());
+
+ // Push source-location info into the buffer.
+ SavePointer(TL.getOpaqueData(), Buffer, BufferSize, BufferCapacity);
+ SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
+}
+
+void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
+ IdentifierInfo *Identifier,
+ SourceLocation IdentifierLoc,
+ SourceLocation ColonColonLoc) {
+ Representation = NestedNameSpecifier::Create(Context, Representation,
+ Identifier);
+
+ // Push source-location info into the buffer.
+ SaveSourceLocation(IdentifierLoc, Buffer, BufferSize, BufferCapacity);
+ SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
+}
+
+void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
+ NamespaceDecl *Namespace,
+ SourceLocation NamespaceLoc,
+ SourceLocation ColonColonLoc) {
+ Representation = NestedNameSpecifier::Create(Context, Representation,
+ Namespace);
+
+ // Push source-location info into the buffer.
+ SaveSourceLocation(NamespaceLoc, Buffer, BufferSize, BufferCapacity);
+ SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
+}
+
+void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
+ NamespaceAliasDecl *Alias,
+ SourceLocation AliasLoc,
+ SourceLocation ColonColonLoc) {
+ Representation = NestedNameSpecifier::Create(Context, Representation, Alias);
+
+ // Push source-location info into the buffer.
+ SaveSourceLocation(AliasLoc, Buffer, BufferSize, BufferCapacity);
+ SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
+}
+
+void NestedNameSpecifierLocBuilder::MakeGlobal(ASTContext &Context,
+ SourceLocation ColonColonLoc) {
+ assert(!Representation && "Already have a nested-name-specifier!?");
+ Representation = NestedNameSpecifier::GlobalSpecifier(Context);
+
+ // Push source-location info into the buffer.
+ SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
+}
+
+void NestedNameSpecifierLocBuilder::MakeTrivial(ASTContext &Context,
+ NestedNameSpecifier *Qualifier,
+ SourceRange R) {
+ Representation = Qualifier;
+
+ // Construct bogus (but well-formed) source information for the
+ // nested-name-specifier.
+ BufferSize = 0;
+ llvm::SmallVector<NestedNameSpecifier *, 4> Stack;
+ for (NestedNameSpecifier *NNS = Qualifier; NNS; NNS = NNS->getPrefix())
+ Stack.push_back(NNS);
+ while (!Stack.empty()) {
+ NestedNameSpecifier *NNS = Stack.back();
+ Stack.pop_back();
+ switch (NNS->getKind()) {
+ case NestedNameSpecifier::Identifier:
+ case NestedNameSpecifier::Namespace:
+ case NestedNameSpecifier::NamespaceAlias:
+ SaveSourceLocation(R.getBegin(), Buffer, BufferSize, BufferCapacity);
+ break;
+
+ case NestedNameSpecifier::TypeSpec:
+ case NestedNameSpecifier::TypeSpecWithTemplate: {
+ TypeSourceInfo *TSInfo
+ = Context.getTrivialTypeSourceInfo(QualType(NNS->getAsType(), 0),
+ R.getBegin());
+ SavePointer(TSInfo->getTypeLoc().getOpaqueData(), Buffer, BufferSize,
+ BufferCapacity);
+ break;
+ }
+
+ case NestedNameSpecifier::Global:
+ break;
+ }
+
+ // Save the location of the '::'.
+ SaveSourceLocation(Stack.empty()? R.getEnd() : R.getBegin(),
+ Buffer, BufferSize, BufferCapacity);
+ }
+}
+
+void NestedNameSpecifierLocBuilder::Adopt(NestedNameSpecifierLoc Other) {
+ if (BufferCapacity)
+ free(Buffer);
+
+ if (!Other) {
+ Representation = 0;
+ BufferSize = 0;
+ return;
+ }
+
+ // Rather than copying the data (which is wasteful), "adopt" the
+ // pointer (which points into the ASTContext) but set the capacity to zero to
+ // indicate that we don't own it.
+ Representation = Other.getNestedNameSpecifier();
+ Buffer = static_cast<char *>(Other.getOpaqueData());
+ BufferSize = Other.getDataLength();
+ BufferCapacity = 0;
+}
+
+NestedNameSpecifierLoc
+NestedNameSpecifierLocBuilder::getWithLocInContext(ASTContext &Context) const {
+ if (!Representation)
+ return NestedNameSpecifierLoc();
+
+ // If we adopted our data pointer from elsewhere in the AST context, there's
+ // no need to copy the memory.
+ if (BufferCapacity == 0)
+ return NestedNameSpecifierLoc(Representation, Buffer);
+
+ // FIXME: After copying the source-location information, should we free
+ // our (temporary) buffer and adopt the ASTContext-allocated memory?
+ // Doing so would optimize repeated calls to getWithLocInContext().
+ void *Mem = Context.Allocate(BufferSize, llvm::alignOf<void *>());
+ memcpy(Mem, Buffer, BufferSize);
+ return NestedNameSpecifierLoc(Representation, Mem);
+}
+
Modified: cfe/trunk/lib/Sema/DeclSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/DeclSpec.cpp?rev=126716&r1=126715&r2=126716&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/DeclSpec.cpp (original)
+++ cfe/trunk/lib/Sema/DeclSpec.cpp Mon Feb 28 17:58:31 2011
@@ -47,222 +47,81 @@
EndLocation = TemplateId->RAngleLoc;
}
-CXXScopeSpec::CXXScopeSpec(const CXXScopeSpec &Other)
- : Range(Other.Range), ScopeRep(Other.ScopeRep), Buffer(0),
- BufferSize(Other.BufferSize), BufferCapacity(Other.BufferSize)
-{
- if (BufferSize) {
- Buffer = static_cast<char *>(malloc(BufferSize));
- memcpy(Buffer, Other.Buffer, BufferSize);
- }
-}
-
-CXXScopeSpec &CXXScopeSpec::operator=(const CXXScopeSpec &Other) {
- Range = Other.Range;
- ScopeRep = Other.ScopeRep;
- if (Buffer && Other.Buffer && BufferCapacity >= Other.BufferSize) {
- // Re-use our storage.
- BufferSize = Other.BufferSize;
- memcpy(Buffer, Other.Buffer, BufferSize);
- return *this;
- }
-
- if (BufferCapacity)
- free(Buffer);
- if (Other.Buffer) {
- BufferSize = Other.BufferSize;
- BufferCapacity = BufferSize;
- Buffer = static_cast<char *>(malloc(BufferSize));
- memcpy(Buffer, Other.Buffer, BufferSize);
- } else {
- Buffer = 0;
- BufferSize = 0;
- BufferCapacity = 0;
- }
- return *this;
-}
-
-CXXScopeSpec::~CXXScopeSpec() {
- if (BufferCapacity)
- free(Buffer);
-}
-
-namespace {
- void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize,
- unsigned &BufferCapacity) {
- if (BufferSize + (End - Start) > BufferCapacity) {
- // Reallocate the buffer.
- unsigned NewCapacity
- = std::max((unsigned)(BufferCapacity? BufferCapacity * 2
- : sizeof(void*) * 2),
- (unsigned)(BufferSize + (End - Start)));
- char *NewBuffer = static_cast<char *>(malloc(NewCapacity));
- memcpy(NewBuffer, Buffer, BufferSize);
-
- if (BufferCapacity)
- free(Buffer);
- Buffer = NewBuffer;
- BufferCapacity = NewCapacity;
- }
-
- memcpy(Buffer + BufferSize, Start, End - Start);
- BufferSize += End-Start;
- }
-
- /// \brief Save a source location to the given buffer.
- void SaveSourceLocation(SourceLocation Loc, char *&Buffer,
- unsigned &BufferSize, unsigned &BufferCapacity) {
- unsigned Raw = Loc.getRawEncoding();
- Append(reinterpret_cast<char *>(&Raw),
- reinterpret_cast<char *>(&Raw) + sizeof(unsigned),
- Buffer, BufferSize, BufferCapacity);
- }
-
- /// \brief Save a pointer to the given buffer.
- void SavePointer(void *Ptr, char *&Buffer, unsigned &BufferSize,
- unsigned &BufferCapacity) {
- Append(reinterpret_cast<char *>(&Ptr),
- reinterpret_cast<char *>(&Ptr) + sizeof(void *),
- Buffer, BufferSize, BufferCapacity);
- }
-}
void CXXScopeSpec::Extend(ASTContext &Context, SourceLocation TemplateKWLoc,
TypeLoc TL, SourceLocation ColonColonLoc) {
- ScopeRep = NestedNameSpecifier::Create(Context, ScopeRep,
- TemplateKWLoc.isValid(),
- TL.getTypePtr());
+ Builder.Extend(Context, TemplateKWLoc, TL, ColonColonLoc);
if (Range.getBegin().isInvalid())
Range.setBegin(TL.getBeginLoc());
Range.setEnd(ColonColonLoc);
- // Push source-location info into the buffer.
- SavePointer(TL.getOpaqueData(), Buffer, BufferSize, BufferCapacity);
- SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
-
- assert(Range == NestedNameSpecifierLoc(ScopeRep, Buffer).getSourceRange() &&
+ assert(Range == Builder.getSourceRange() &&
"NestedNameSpecifierLoc range computation incorrect");
}
void CXXScopeSpec::Extend(ASTContext &Context, IdentifierInfo *Identifier,
SourceLocation IdentifierLoc,
SourceLocation ColonColonLoc) {
- ScopeRep = NestedNameSpecifier::Create(Context, ScopeRep, Identifier);
+ Builder.Extend(Context, Identifier, IdentifierLoc, ColonColonLoc);
+
if (Range.getBegin().isInvalid())
Range.setBegin(IdentifierLoc);
Range.setEnd(ColonColonLoc);
- // Push source-location info into the buffer.
- SaveSourceLocation(IdentifierLoc, Buffer, BufferSize, BufferCapacity);
- SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
-
- assert(Range == NestedNameSpecifierLoc(ScopeRep, Buffer).getSourceRange() &&
+ assert(Range == Builder.getSourceRange() &&
"NestedNameSpecifierLoc range computation incorrect");
}
void CXXScopeSpec::Extend(ASTContext &Context, NamespaceDecl *Namespace,
SourceLocation NamespaceLoc,
SourceLocation ColonColonLoc) {
- ScopeRep = NestedNameSpecifier::Create(Context, ScopeRep, Namespace);
+ Builder.Extend(Context, Namespace, NamespaceLoc, ColonColonLoc);
+
if (Range.getBegin().isInvalid())
Range.setBegin(NamespaceLoc);
Range.setEnd(ColonColonLoc);
- // Push source-location info into the buffer.
- SaveSourceLocation(NamespaceLoc, Buffer, BufferSize, BufferCapacity);
- SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
-
- assert(Range == NestedNameSpecifierLoc(ScopeRep, Buffer).getSourceRange() &&
+ assert(Range == Builder.getSourceRange() &&
"NestedNameSpecifierLoc range computation incorrect");
}
void CXXScopeSpec::Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
SourceLocation AliasLoc,
SourceLocation ColonColonLoc) {
- ScopeRep = NestedNameSpecifier::Create(Context, ScopeRep, Alias);
+ Builder.Extend(Context, Alias, AliasLoc, ColonColonLoc);
+
if (Range.getBegin().isInvalid())
Range.setBegin(AliasLoc);
Range.setEnd(ColonColonLoc);
- // Push source-location info into the buffer.
- SaveSourceLocation(AliasLoc, Buffer, BufferSize, BufferCapacity);
- SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
-
- assert(Range == NestedNameSpecifierLoc(ScopeRep, Buffer).getSourceRange() &&
+ assert(Range == Builder.getSourceRange() &&
"NestedNameSpecifierLoc range computation incorrect");
}
void CXXScopeSpec::MakeGlobal(ASTContext &Context,
SourceLocation ColonColonLoc) {
- assert(!ScopeRep && "Already have a nested-name-specifier!?");
- ScopeRep = NestedNameSpecifier::GlobalSpecifier(Context);
- Range = SourceRange(ColonColonLoc);
+ Builder.MakeGlobal(Context, ColonColonLoc);
- // Push source-location info into the buffer.
- SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
+ Range = SourceRange(ColonColonLoc);
- assert(Range == NestedNameSpecifierLoc(ScopeRep, Buffer).getSourceRange() &&
+ assert(Range == Builder.getSourceRange() &&
"NestedNameSpecifierLoc range computation incorrect");
}
void CXXScopeSpec::MakeTrivial(ASTContext &Context,
NestedNameSpecifier *Qualifier, SourceRange R) {
- ScopeRep = Qualifier;
+ Builder.MakeTrivial(Context, Qualifier, R);
Range = R;
-
- // Construct bogus (but well-formed) source information for the
- // nested-name-specifier.
- BufferSize = 0;
- llvm::SmallVector<NestedNameSpecifier *, 4> Stack;
- for (NestedNameSpecifier *NNS = Qualifier; NNS; NNS = NNS->getPrefix())
- Stack.push_back(NNS);
- while (!Stack.empty()) {
- NestedNameSpecifier *NNS = Stack.back();
- Stack.pop_back();
- switch (NNS->getKind()) {
- case NestedNameSpecifier::Identifier:
- case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
- SaveSourceLocation(R.getBegin(), Buffer, BufferSize, BufferCapacity);
- break;
-
- case NestedNameSpecifier::TypeSpec:
- case NestedNameSpecifier::TypeSpecWithTemplate: {
- TypeSourceInfo *TSInfo
- = Context.getTrivialTypeSourceInfo(QualType(NNS->getAsType(), 0),
- R.getBegin());
- SavePointer(TSInfo->getTypeLoc().getOpaqueData(), Buffer, BufferSize,
- BufferCapacity);
- break;
- }
-
- case NestedNameSpecifier::Global:
- break;
- }
-
- // Save the location of the '::'.
- SaveSourceLocation(Stack.empty()? R.getEnd() : R.getBegin(),
- Buffer, BufferSize, BufferCapacity);
- }
}
void CXXScopeSpec::Adopt(NestedNameSpecifierLoc Other) {
if (!Other) {
Range = SourceRange();
- ScopeRep = 0;
+ Builder.Clear();
return;
}
-
- if (BufferCapacity)
- free(Buffer);
-
- // Rather than copying the data (which is wasteful), "adopt" the
- // pointer (which points into the ASTContext) but set the capacity to zero to
- // indicate that we don't own it.
+
Range = Other.getSourceRange();
- ScopeRep = Other.getNestedNameSpecifier();
- Buffer = static_cast<char *>(Other.getOpaqueData());
- BufferSize = Other.getDataLength();
- BufferCapacity = 0;
+ Builder.Adopt(Other);
}
NestedNameSpecifierLoc
@@ -270,14 +129,7 @@
if (isEmpty() || isInvalid())
return NestedNameSpecifierLoc();
- // If we adopted our data pointer from elsewhere in the AST context, there's
- // no need to copy the memory.
- if (BufferCapacity == 0)
- return NestedNameSpecifierLoc(ScopeRep, Buffer);
-
- void *Mem = Context.Allocate(BufferSize, llvm::alignOf<void *>());
- memcpy(Mem, Buffer, BufferSize);
- return NestedNameSpecifierLoc(ScopeRep, Mem);
+ return Builder.getWithLocInContext(Context);
}
/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=126716&r1=126715&r2=126716&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Mon Feb 28 17:58:31 2011
@@ -23,6 +23,7 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
+#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLocVisitor.h"
#include "clang/Lex/MacroInfo.h"
@@ -4762,103 +4763,57 @@
ASTReader::ReadNestedNameSpecifierLoc(PerFileData &F, const RecordData &Record,
unsigned &Idx) {
unsigned N = Record[Idx++];
- NestedNameSpecifier *NNS = 0, *Prev = 0;
- llvm::SmallVector<char, 32> LocationData;
+ NestedNameSpecifierLocBuilder Builder;
for (unsigned I = 0; I != N; ++I) {
NestedNameSpecifier::SpecifierKind Kind
= (NestedNameSpecifier::SpecifierKind)Record[Idx++];
switch (Kind) {
case NestedNameSpecifier::Identifier: {
- // Nested-name-specifier
- IdentifierInfo *II = GetIdentifierInfo(Record, Idx);
- NNS = NestedNameSpecifier::Create(*Context, Prev, II);
-
- // Location information
+ IdentifierInfo *II = GetIdentifierInfo(Record, Idx);
SourceRange Range = ReadSourceRange(F, Record, Idx);
- unsigned RawStart = Range.getBegin().getRawEncoding();
- unsigned RawEnd = Range.getEnd().getRawEncoding();
- LocationData.append(reinterpret_cast<char*>(&RawStart),
- reinterpret_cast<char*>(&RawStart) +sizeof(unsigned));
- LocationData.append(reinterpret_cast<char*>(&RawEnd),
- reinterpret_cast<char*>(&RawEnd) + sizeof(unsigned));
+ Builder.Extend(*Context, II, Range.getBegin(), Range.getEnd());
break;
}
case NestedNameSpecifier::Namespace: {
- // Nested-name-specifier
NamespaceDecl *NS = cast<NamespaceDecl>(GetDecl(Record[Idx++]));
- NNS = NestedNameSpecifier::Create(*Context, Prev, NS);
-
- // Location information
SourceRange Range = ReadSourceRange(F, Record, Idx);
- unsigned RawStart = Range.getBegin().getRawEncoding();
- unsigned RawEnd = Range.getEnd().getRawEncoding();
- LocationData.append(reinterpret_cast<char*>(&RawStart),
- reinterpret_cast<char*>(&RawStart) +sizeof(unsigned));
- LocationData.append(reinterpret_cast<char*>(&RawEnd),
- reinterpret_cast<char*>(&RawEnd) + sizeof(unsigned));
+ Builder.Extend(*Context, NS, Range.getBegin(), Range.getEnd());
break;
}
case NestedNameSpecifier::NamespaceAlias: {
- // Nested-name-specifier
NamespaceAliasDecl *Alias
= cast<NamespaceAliasDecl>(GetDecl(Record[Idx++]));
- NNS = NestedNameSpecifier::Create(*Context, Prev, Alias);
-
- // Location information
SourceRange Range = ReadSourceRange(F, Record, Idx);
- unsigned RawStart = Range.getBegin().getRawEncoding();
- unsigned RawEnd = Range.getEnd().getRawEncoding();
- LocationData.append(reinterpret_cast<char*>(&RawStart),
- reinterpret_cast<char*>(&RawStart) +sizeof(unsigned));
- LocationData.append(reinterpret_cast<char*>(&RawEnd),
- reinterpret_cast<char*>(&RawEnd) + sizeof(unsigned));
-
+ Builder.Extend(*Context, Alias, Range.getBegin(), Range.getEnd());
break;
}
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate: {
- // Nested-name-specifier
bool Template = Record[Idx++];
TypeSourceInfo *T = GetTypeSourceInfo(F, Record, Idx);
if (!T)
return NestedNameSpecifierLoc();
- NNS = NestedNameSpecifier::Create(*Context, Prev, Template,
- T->getType().getTypePtr());
-
- // Location information.
SourceLocation ColonColonLoc = ReadSourceLocation(F, Record, Idx);
- unsigned RawLocation = ColonColonLoc.getRawEncoding();
- void *OpaqueTypeData = T->getTypeLoc().getOpaqueData();
- LocationData.append(reinterpret_cast<char*>(&OpaqueTypeData),
- (reinterpret_cast<char*>(&OpaqueTypeData)
- + sizeof(void *)));
- LocationData.append(reinterpret_cast<char*>(&RawLocation),
- (reinterpret_cast<char*>(&RawLocation) +
- sizeof(unsigned)));
+
+ // FIXME: 'template' keyword location not saved anywhere, so we fake it.
+ Builder.Extend(*Context,
+ Template? T->getTypeLoc().getBeginLoc() : SourceLocation(),
+ T->getTypeLoc(), ColonColonLoc);
break;
}
case NestedNameSpecifier::Global: {
- // Nested-name-specifier
- NNS = NestedNameSpecifier::GlobalSpecifier(*Context);
-
SourceLocation ColonColonLoc = ReadSourceLocation(F, Record, Idx);
- unsigned RawLocation = ColonColonLoc.getRawEncoding();
- LocationData.append(reinterpret_cast<char*>(&RawLocation),
- (reinterpret_cast<char*>(&RawLocation) +
- sizeof(unsigned)));
+ Builder.MakeGlobal(*Context, ColonColonLoc);
break;
}
}
- Prev = NNS;
}
- void *Mem = Context->Allocate(LocationData.size(), llvm::alignOf<void*>());
- memcpy(Mem, LocationData.data(), LocationData.size());
- return NestedNameSpecifierLoc(NNS, Mem);
+ return Builder.getWithLocInContext(*Context);
}
SourceRange
More information about the cfe-commits
mailing list