forked from OSchip/llvm-project
Make PragmaPackStack be a private class in SemaAttr and make its
instance in Sema be a pimpl. llvm-svn: 64718
This commit is contained in:
parent
264ec4f237
commit
31180bbfb4
|
@ -78,37 +78,6 @@ namespace clang {
|
|||
class BasePaths;
|
||||
class MemberLookupCriteria;
|
||||
|
||||
/// PragmaPackStack - Simple class to wrap the stack used by #pragma
|
||||
/// pack.
|
||||
class PragmaPackStack {
|
||||
typedef std::vector< std::pair<unsigned, IdentifierInfo*> > stack_ty;
|
||||
|
||||
/// Alignment - The current user specified alignment.
|
||||
unsigned Alignment;
|
||||
|
||||
/// Stack - Entries in the #pragma pack stack, consisting of saved
|
||||
/// alignments and optional names.
|
||||
stack_ty Stack;
|
||||
|
||||
public:
|
||||
PragmaPackStack(unsigned A) : Alignment(A) {}
|
||||
|
||||
void setAlignment(unsigned A) { Alignment = A; }
|
||||
unsigned getAlignment() { return Alignment; }
|
||||
|
||||
/// push - Push the current alignment onto the stack, optionally
|
||||
/// using the given \arg Name for the record, if non-zero.
|
||||
void push(IdentifierInfo *Name) {
|
||||
Stack.push_back(std::make_pair(Alignment, Name));
|
||||
}
|
||||
|
||||
/// pop - Pop a record from the stack and restore the current
|
||||
/// alignment to the previous value. If \arg Name is non-zero then
|
||||
/// the first such named record is popped, otherwise the top record
|
||||
/// is popped. Returns true if the pop succeeded.
|
||||
bool pop(IdentifierInfo *Name);
|
||||
};
|
||||
|
||||
/// Sema - This implements semantic analysis and AST building for C.
|
||||
class Sema : public Action {
|
||||
Sema(const Sema&); // DO NOT IMPLEMENT
|
||||
|
@ -134,7 +103,7 @@ public:
|
|||
|
||||
/// PackContext - Manages the stack for #pragma pack. An alignment
|
||||
/// of 0 indicates default alignment.
|
||||
PragmaPackStack PackContext;
|
||||
void *PackContext; // Really a "PragmaPackStack*"
|
||||
|
||||
/// LabelMap - This is a mapping from label identifiers to the LabelStmt for
|
||||
/// it (which acts like the label decl in some ways). Forward referenced
|
||||
|
@ -231,6 +200,9 @@ public:
|
|||
llvm::DenseMap<Selector, ObjCMethodList> FactoryMethodPool;
|
||||
public:
|
||||
Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer);
|
||||
~Sema() {
|
||||
if (PackContext) FreePackedContext();
|
||||
}
|
||||
|
||||
const LangOptions &getLangOptions() const { return LangOpts; }
|
||||
Diagnostic &getDiagnostics() const { return Diags; }
|
||||
|
@ -1706,6 +1678,13 @@ public:
|
|||
SourceLocation PragmaLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation RParenLoc);
|
||||
|
||||
/// getPragmaPackAlignment() - Return the current alignment as specified by
|
||||
/// the current #pragma pack directive, or 0 if none is currently active.
|
||||
unsigned getPragmaPackAlignment() const;
|
||||
|
||||
/// FreePackedContext - Deallocate and null out PackContext.
|
||||
void FreePackedContext();
|
||||
|
||||
/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit
|
||||
/// cast. If there is already an implicit cast, merge into the existing one.
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements semantic analysis for non-trivial attributes.
|
||||
// This file implements semantic analysis for non-trivial attributes and
|
||||
// pragmas.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
@ -15,6 +16,83 @@
|
|||
#include "clang/AST/Expr.h"
|
||||
using namespace clang;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Pragma Packed
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace {
|
||||
/// PragmaPackStack - Simple class to wrap the stack used by #pragma
|
||||
/// pack.
|
||||
class PragmaPackStack {
|
||||
typedef std::vector< std::pair<unsigned, IdentifierInfo*> > stack_ty;
|
||||
|
||||
/// Alignment - The current user specified alignment.
|
||||
unsigned Alignment;
|
||||
|
||||
/// Stack - Entries in the #pragma pack stack, consisting of saved
|
||||
/// alignments and optional names.
|
||||
stack_ty Stack;
|
||||
|
||||
public:
|
||||
PragmaPackStack() : Alignment(0) {}
|
||||
|
||||
void setAlignment(unsigned A) { Alignment = A; }
|
||||
unsigned getAlignment() { return Alignment; }
|
||||
|
||||
/// push - Push the current alignment onto the stack, optionally
|
||||
/// using the given \arg Name for the record, if non-zero.
|
||||
void push(IdentifierInfo *Name) {
|
||||
Stack.push_back(std::make_pair(Alignment, Name));
|
||||
}
|
||||
|
||||
/// pop - Pop a record from the stack and restore the current
|
||||
/// alignment to the previous value. If \arg Name is non-zero then
|
||||
/// the first such named record is popped, otherwise the top record
|
||||
/// is popped. Returns true if the pop succeeded.
|
||||
bool pop(IdentifierInfo *Name);
|
||||
};
|
||||
} // end anonymous namespace.
|
||||
|
||||
bool PragmaPackStack::pop(IdentifierInfo *Name) {
|
||||
if (Stack.empty())
|
||||
return false;
|
||||
|
||||
// If name is empty just pop top.
|
||||
if (!Name) {
|
||||
Alignment = Stack.back().first;
|
||||
Stack.pop_back();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise, find the named record.
|
||||
for (unsigned i = Stack.size(); i != 0; ) {
|
||||
--i;
|
||||
if (Stack[i].second == Name) {
|
||||
// Found it, pop up to and including this record.
|
||||
Alignment = Stack[i].first;
|
||||
Stack.erase(Stack.begin() + i, Stack.end());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// FreePackedContext - Deallocate and null out PackContext.
|
||||
void Sema::FreePackedContext() {
|
||||
delete static_cast<PragmaPackStack*>(PackContext);
|
||||
PackContext = 0;
|
||||
}
|
||||
|
||||
/// getPragmaPackAlignment() - Return the current alignment as specified by
|
||||
/// the current #pragma pack directive, or 0 if none is currently active.
|
||||
unsigned Sema::getPragmaPackAlignment() const {
|
||||
if (PackContext)
|
||||
return static_cast<PragmaPackStack*>(PackContext)->getAlignment();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name,
|
||||
ExprTy *alignment, SourceLocation PragmaLoc,
|
||||
SourceLocation LParenLoc, SourceLocation RParenLoc) {
|
||||
|
@ -34,16 +112,22 @@ void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name,
|
|||
|
||||
AlignmentVal = (unsigned) Val.getZExtValue();
|
||||
}
|
||||
|
||||
if (PackContext == 0)
|
||||
PackContext = new PragmaPackStack();
|
||||
|
||||
|
||||
PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext);
|
||||
|
||||
switch (Kind) {
|
||||
case Action::PPK_Default: // pack([n])
|
||||
PackContext.setAlignment(AlignmentVal);
|
||||
Context->setAlignment(AlignmentVal);
|
||||
break;
|
||||
|
||||
case Action::PPK_Show: // pack(show)
|
||||
// Show the current alignment, making sure to show the right value
|
||||
// for the default.
|
||||
AlignmentVal = PackContext.getAlignment();
|
||||
AlignmentVal = Context->getAlignment();
|
||||
// FIXME: This should come from the target.
|
||||
if (AlignmentVal == 0)
|
||||
AlignmentVal = 8;
|
||||
|
@ -51,10 +135,10 @@ void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name,
|
|||
break;
|
||||
|
||||
case Action::PPK_Push: // pack(push [, id] [, [n])
|
||||
PackContext.push(Name);
|
||||
Context->push(Name);
|
||||
// Set the new alignment if specified.
|
||||
if (Alignment)
|
||||
PackContext.setAlignment(AlignmentVal);
|
||||
Context->setAlignment(AlignmentVal);
|
||||
break;
|
||||
|
||||
case Action::PPK_Pop: // pack(pop [, id] [, n])
|
||||
|
@ -64,7 +148,7 @@ void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name,
|
|||
Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifer_and_alignment);
|
||||
|
||||
// Do the pop.
|
||||
if (!PackContext.pop(Name)) {
|
||||
if (!Context->pop(Name)) {
|
||||
// If a name was specified then failure indicates the name
|
||||
// wasn't found. Otherwise failure indicates the stack was
|
||||
// empty.
|
||||
|
@ -75,7 +159,7 @@ void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name,
|
|||
} else {
|
||||
// Pop succeeded, set the new alignment if specified.
|
||||
if (Alignment)
|
||||
PackContext.setAlignment(AlignmentVal);
|
||||
Context->setAlignment(AlignmentVal);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -84,27 +168,3 @@ void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name,
|
|||
}
|
||||
}
|
||||
|
||||
bool PragmaPackStack::pop(IdentifierInfo *Name) {
|
||||
if (Stack.empty())
|
||||
return false;
|
||||
|
||||
// If name is empty just pop top.
|
||||
if (!Name) {
|
||||
Alignment = Stack.back().first;
|
||||
Stack.pop_back();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise, find the named record.
|
||||
for (unsigned i = Stack.size(); i != 0; ) {
|
||||
--i;
|
||||
if (Stack[i].second == Name) {
|
||||
// Found it, pop up to and including this record.
|
||||
Alignment = Stack[i].first;
|
||||
Stack.erase(Stack.begin() + i, Stack.end());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -3276,7 +3276,7 @@ CreateNewDecl:
|
|||
// many points during the parsing of a struct declaration (because
|
||||
// the #pragma tokens are effectively skipped over during the
|
||||
// parsing of the struct).
|
||||
if (unsigned Alignment = PackContext.getAlignment())
|
||||
if (unsigned Alignment = getPragmaPackAlignment())
|
||||
New->addAttr(new PackedAttr(Alignment * 8));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue