move attribute(packed) sema support out of SemaDecl into a new SemaAttr.cpp file.

llvm-svn: 64711
This commit is contained in:
Chris Lattner 2009-02-17 00:57:29 +00:00
parent 8cad67b8a4
commit 2eccbc1e5d
4 changed files with 116 additions and 95 deletions

View File

@ -179,6 +179,7 @@
DEAEED4B0A5AF89A0045101B /* NOTES.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEAEED4A0A5AF89A0045101B /* NOTES.txt */; };
DEB076CF0F3A222200F5A2BE /* DeclTemplate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEB076CE0F3A222200F5A2BE /* DeclTemplate.cpp */; };
DEB077990F44F97800F5A2BE /* TokenConcatenation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEB077980F44F97800F5A2BE /* TokenConcatenation.cpp */; };
DEB07AC80F4A427E00F5A2BE /* SemaAttr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEB07AC70F4A427E00F5A2BE /* SemaAttr.cpp */; };
DEC63B1A0C7B940200DBF169 /* CFG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEC63B190C7B940200DBF169 /* CFG.cpp */; };
DEC63B1C0C7B940600DBF169 /* CFG.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEC63B1B0C7B940600DBF169 /* CFG.h */; };
DEC8D9910A9433CD00353FCA /* Decl.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEC8D9900A9433CD00353FCA /* Decl.h */; };
@ -557,6 +558,7 @@
DEB076CE0F3A222200F5A2BE /* DeclTemplate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DeclTemplate.cpp; path = lib/AST/DeclTemplate.cpp; sourceTree = "<group>"; };
DEB077930F44F96000F5A2BE /* TokenConcatenation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TokenConcatenation.h; sourceTree = "<group>"; };
DEB077980F44F97800F5A2BE /* TokenConcatenation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TokenConcatenation.cpp; sourceTree = "<group>"; };
DEB07AC70F4A427E00F5A2BE /* SemaAttr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SemaAttr.cpp; path = lib/Sema/SemaAttr.cpp; sourceTree = "<group>"; };
DEB089EE0F12F1D900522C07 /* TypeTraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeTraits.h; sourceTree = "<group>"; };
DEC63B190C7B940200DBF169 /* CFG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CFG.cpp; path = lib/AST/CFG.cpp; sourceTree = "<group>"; tabWidth = 2; };
DEC63B1B0C7B940600DBF169 /* CFG.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CFG.h; path = clang/AST/CFG.h; sourceTree = "<group>"; tabWidth = 2; };
@ -891,6 +893,7 @@
DE67E7190C020F4F00F66BC5 /* ParseAST.cpp */,
DE67E7140C020EDF00F66BC5 /* Sema.h */,
DE67E7160C020EE400F66BC5 /* Sema.cpp */,
DEB07AC70F4A427E00F5A2BE /* SemaAttr.cpp */,
DEF2F00F0C6CFED5000C4259 /* SemaChecking.cpp */,
35E194670ECB82FB00F21733 /* SemaCXXScopeSpec.cpp */,
DE67E7120C020ED900F66BC5 /* SemaDecl.cpp */,
@ -1407,6 +1410,7 @@
1A471AB50F437BC500753CE8 /* CGBlocks.cpp in Sources */,
DEB077990F44F97800F5A2BE /* TokenConcatenation.cpp in Sources */,
1A2193CE0F45EEB700C0713D /* Mangle.cpp in Sources */,
DEB07AC80F4A427E00F5A2BE /* SemaAttr.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -3,8 +3,9 @@ set(LLVM_NO_RTTI 1)
add_clang_library(clangSema
IdentifierResolver.cpp
ParseAST.cpp
SemaChecking.cpp
Sema.cpp
SemaAttr.cpp
SemaChecking.cpp
SemaCXXScopeSpec.cpp
SemaDeclAttr.cpp
SemaDecl.cpp

110
clang/lib/Sema/SemaAttr.cpp Normal file
View File

@ -0,0 +1,110 @@
//===--- SemaAttr.cpp - Semantic Analysis for Attributes ------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements semantic analysis for non-trivial attributes.
//
//===----------------------------------------------------------------------===//
#include "Sema.h"
#include "clang/AST/Expr.h"
using namespace clang;
void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name,
ExprTy *alignment, SourceLocation PragmaLoc,
SourceLocation LParenLoc, SourceLocation RParenLoc) {
Expr *Alignment = static_cast<Expr *>(alignment);
// If specified then alignment must be a "small" power of two.
unsigned AlignmentVal = 0;
if (Alignment) {
llvm::APSInt Val;
if (!Alignment->isIntegerConstantExpr(Val, Context) ||
!Val.isPowerOf2() ||
Val.getZExtValue() > 16) {
Diag(PragmaLoc, diag::warn_pragma_pack_invalid_alignment);
Alignment->Destroy(Context);
return; // Ignore
}
AlignmentVal = (unsigned) Val.getZExtValue();
}
switch (Kind) {
case Action::PPK_Default: // pack([n])
PackContext.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();
// FIXME: This should come from the target.
if (AlignmentVal == 0)
AlignmentVal = 8;
Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal;
break;
case Action::PPK_Push: // pack(push [, id] [, [n])
PackContext.push(Name);
// Set the new alignment if specified.
if (Alignment)
PackContext.setAlignment(AlignmentVal);
break;
case Action::PPK_Pop: // pack(pop [, id] [, n])
// MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack:
// "#pragma pack(pop, identifier, n) is undefined"
if (Alignment && Name)
Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifer_and_alignment);
// Do the pop.
if (!PackContext.pop(Name)) {
// If a name was specified then failure indicates the name
// wasn't found. Otherwise failure indicates the stack was
// empty.
Diag(PragmaLoc, diag::warn_pragma_pack_pop_failed)
<< (Name ? "no record matching name" : "stack empty");
// FIXME: Warn about popping named records as MSVC does.
} else {
// Pop succeeded, set the new alignment if specified.
if (Alignment)
PackContext.setAlignment(AlignmentVal);
}
break;
default:
assert(0 && "Invalid #pragma pack kind.");
}
}
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;
}

View File

@ -3984,97 +3984,3 @@ Sema::DeclTy *Sema::ActOnFileScopeAsmDecl(SourceLocation Loc,
return FileScopeAsmDecl::Create(Context, CurContext, Loc, AsmString);
}
void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name,
ExprTy *alignment, SourceLocation PragmaLoc,
SourceLocation LParenLoc, SourceLocation RParenLoc) {
Expr *Alignment = static_cast<Expr *>(alignment);
// If specified then alignment must be a "small" power of two.
unsigned AlignmentVal = 0;
if (Alignment) {
llvm::APSInt Val;
if (!Alignment->isIntegerConstantExpr(Val, Context) ||
!Val.isPowerOf2() ||
Val.getZExtValue() > 16) {
Diag(PragmaLoc, diag::warn_pragma_pack_invalid_alignment);
Alignment->Destroy(Context);
return; // Ignore
}
AlignmentVal = (unsigned) Val.getZExtValue();
}
switch (Kind) {
case Action::PPK_Default: // pack([n])
PackContext.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();
// FIXME: This should come from the target.
if (AlignmentVal == 0)
AlignmentVal = 8;
Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal;
break;
case Action::PPK_Push: // pack(push [, id] [, [n])
PackContext.push(Name);
// Set the new alignment if specified.
if (Alignment)
PackContext.setAlignment(AlignmentVal);
break;
case Action::PPK_Pop: // pack(pop [, id] [, n])
// MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack:
// "#pragma pack(pop, identifier, n) is undefined"
if (Alignment && Name)
Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifer_and_alignment);
// Do the pop.
if (!PackContext.pop(Name)) {
// If a name was specified then failure indicates the name
// wasn't found. Otherwise failure indicates the stack was
// empty.
Diag(PragmaLoc, diag::warn_pragma_pack_pop_failed)
<< (Name ? "no record matching name" : "stack empty");
// FIXME: Warn about popping named records as MSVC does.
} else {
// Pop succeeded, set the new alignment if specified.
if (Alignment)
PackContext.setAlignment(AlignmentVal);
}
break;
default:
assert(0 && "Invalid #pragma pack kind.");
}
}
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;
}