Submitted by:
Reviewed by:
Lot's of attribute scaffolding.
Modernized ParseArraySubscriptExpr...call DefaultFunctionArrayConversion (which
simplified the logic considerably) and upgrade Diags to use the range support.

llvm-svn: 39628
This commit is contained in:
Steve Naroff 2007-06-09 03:47:53 +00:00
parent 29ca72ae02
commit b309644a35
6 changed files with 36 additions and 91 deletions

View File

@ -17,10 +17,3 @@
using namespace llvm;
using namespace clang;
Attr::Attr(SourceLocation L, IdentifierInfo *aName,
IdentifierInfo *pname, Expr **elist, unsigned numargs)
: AttrName(aName), AttrLoc(L), ParmName(pname), NumArgs(numargs) {
Args = new Expr*[numargs];
for (unsigned i = 0; i != numargs; ++i)
Args[i] = elist[i];
}

View File

@ -110,7 +110,7 @@ private:
virtual DeclTy *ParseTag(Scope *S, unsigned TagType, TagKind TK,
SourceLocation KWLoc, IdentifierInfo *Name,
SourceLocation NameLoc);
SourceLocation NameLoc, AttributeList *Attr);
virtual DeclTy *ParseField(Scope *S, DeclTy *TagDecl,SourceLocation DeclStart,
Declarator &D, ExprTy *BitfieldWidth);
virtual void ParseRecordBody(SourceLocation RecLoc, DeclTy *TagDecl,
@ -250,16 +250,6 @@ public:
/// ParseCXXBoolLiteral - Parse {true,false} literals.
virtual ExprResult ParseCXXBoolLiteral(SourceLocation OpLoc,
tok::TokenKind Kind);
/// ParseAttribute GCC __attribute__
virtual AttrTy *ParseAttribute(
IdentifierInfo *AttrName, SourceLocation AttrNameLoc, AttrTy *PrevAttr,
IdentifierInfo *ParmName = 0, SourceLocation ParmNameLoc = SourceLocation(),
ExprTy **Args = 0, unsigned NumArgs = 0,
SourceLocation LParenLoc = SourceLocation(),
SourceLocation RParenLoc = SourceLocation()
);
private:
// UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
// functions and arrays to their respective pointers (C99 6.3.2.1)

View File

@ -595,7 +595,7 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D,
/// reference/declaration/definition of a tag.
Sema::DeclTy *Sema::ParseTag(Scope *S, unsigned TagType, TagKind TK,
SourceLocation KWLoc, IdentifierInfo *Name,
SourceLocation NameLoc) {
SourceLocation NameLoc, AttributeList *Attr) {
// If this is a use of an existing tag, it must have a name.
assert((Name != 0 || TK == TK_Definition) &&
"Nameless record must be a definition!");
@ -901,17 +901,3 @@ void Sema::AddTopLevelDecl(Decl *current, Decl *last) {
if (last)
LastInGroupList.push_back((Decl*)last);
}
/// ParseAttribute GCC __attribute__
Sema::AttrTy *Sema::ParseAttribute(
IdentifierInfo *AttrName, SourceLocation AttrNameLoc, AttrTy *PrevAttr,
IdentifierInfo *ParmName, SourceLocation ParmNameLoc,
ExprTy **Args, unsigned NumArgs,
SourceLocation LParenLoc, SourceLocation RParenLoc) {
Attr *attrib = new Attr(AttrNameLoc, AttrName, ParmName, (Expr **)Args,
NumArgs);
if (PrevAttr)
// reuse Decl's "Next" pointer for chaining the attribute list
attrib->setNext(static_cast<Attr *>(PrevAttr));
return attrib;
}

View File

@ -283,40 +283,45 @@ ParseArraySubscriptExpr(ExprTy *Base, SourceLocation LLoc,
assert(!t1.isNull() && "no type for array base expression");
assert(!t2.isNull() && "no type for array index expression");
QualType canonT1 = t1.getCanonicalType();
QualType canonT2 = t2.getCanonicalType();
QualType canonT1 = DefaultFunctionArrayConversion(t1).getCanonicalType();
QualType canonT2 = DefaultFunctionArrayConversion(t2).getCanonicalType();
// C99 6.5.2.1p2: the expression e1[e2] is by definition precisely equivalent
// to the expression *((e1)+(e2)). This means the array "Base" may actually be
// in the subscript position. As a result, we need to derive the array base
// and index from the expression types.
Expr *baseExpr, *indexExpr;
QualType baseType, indexType;
if (isa<ArrayType>(canonT1) || isa<PointerType>(canonT1)) {
if (isa<PointerType>(canonT1)) {
baseType = canonT1;
indexType = canonT2;
} else if (isa<ArrayType>(canonT2) || isa<PointerType>(canonT2)) { // uncommon
baseExpr = static_cast<Expr *>(Base);
indexExpr = static_cast<Expr *>(Idx);
} else if (isa<PointerType>(canonT2)) { // uncommon
baseType = canonT2;
indexType = canonT1;
} else
return Diag(LLoc, diag::err_typecheck_subscript_value);
baseExpr = static_cast<Expr *>(Idx);
indexExpr = static_cast<Expr *>(Base);
} else {
return Diag(baseExpr->getLocStart(), diag::err_typecheck_subscript_value,
baseExpr->getSourceRange());
}
// C99 6.5.2.1p1
if (!indexType->isIntegerType())
return Diag(LLoc, diag::err_typecheck_subscript);
if (!indexType->isIntegerType()) {
return Diag(indexExpr->getLocStart(), diag::err_typecheck_subscript,
indexExpr->getSourceRange());
}
// FIXME: need to deal with const...
QualType resultType;
if (ArrayType *ary = dyn_cast<ArrayType>(baseType)) {
resultType = ary->getElementType();
} else if (PointerType *ary = dyn_cast<PointerType>(baseType)) {
resultType = ary->getPointeeType();
// in practice, the following check catches trying to index a pointer
// to a function (e.g. void (*)(int)). Functions are not objects in c99.
if (!resultType->isObjectType())
return Diag(LLoc, diag::err_typecheck_subscript_not_object,
baseType.getAsString());
}
PointerType *ary = cast<PointerType>(baseType);
QualType resultType = ary->getPointeeType();
// in practice, the following check catches trying to index a pointer
// to a function (e.g. void (*)(int)). Functions are not objects in c99.
if (!resultType->isObjectType()) {
return Diag(baseExpr->getLocStart(),
diag::err_typecheck_subscript_not_object,
baseType.getAsString(), baseExpr->getSourceRange());
}
return new ArraySubscriptExpr((Expr*)Base, (Expr*)Idx, resultType, RLoc);
}

View File

@ -12,6 +12,8 @@
1A869AA80BA21ABA008DA07A /* LiteralSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */; };
84916BE50C161E580080778F /* Attr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84916BE40C161E580080778F /* Attr.cpp */; };
84916BE70C161E800080778F /* Attr.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 84916BE60C161E800080778F /* Attr.h */; };
84D9A8880C1A57E100AC7ABC /* AttributeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */; };
84D9A88C0C1A581300AC7ABC /* AttributeList.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 84D9A88B0C1A581300AC7ABC /* AttributeList.h */; };
DE01DA490B12ADA300AC22CE /* PPCallbacks.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE01DA480B12ADA300AC22CE /* PPCallbacks.h */; };
DE06756C0C051CFE00EBBFD8 /* ParseExprCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE06756B0C051CFE00EBBFD8 /* ParseExprCXX.cpp */; };
DE06B73E0A8307640050E87E /* LangOptions.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE06B73D0A8307640050E87E /* LangOptions.h */; };
@ -168,6 +170,7 @@
84916BE70C161E800080778F /* Attr.h in CopyFiles */,
F0226FD30C18084500141F42 /* TextDiagnosticPrinter.h in CopyFiles */,
DEEBBD440C19C5D200A9FE82 /* TODO.txt in CopyFiles */,
84D9A88C0C1A581300AC7ABC /* AttributeList.h in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 1;
};
@ -179,6 +182,8 @@
1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LiteralSupport.cpp; sourceTree = "<group>"; };
84916BE40C161E580080778F /* Attr.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Attr.cpp; path = AST/Attr.cpp; sourceTree = "<group>"; };
84916BE60C161E800080778F /* Attr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Attr.h; path = include/clang/AST/Attr.h; sourceTree = "<group>"; };
84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AttributeList.cpp; path = Parse/AttributeList.cpp; sourceTree = "<group>"; };
84D9A88B0C1A581300AC7ABC /* AttributeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AttributeList.h; path = clang/Parse/AttributeList.h; sourceTree = "<group>"; };
8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = clang; sourceTree = BUILT_PRODUCTS_DIR; };
DE01DA480B12ADA300AC22CE /* PPCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PPCallbacks.h; sourceTree = "<group>"; };
DE06756B0C051CFE00EBBFD8 /* ParseExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseExprCXX.cpp; path = Parse/ParseExprCXX.cpp; sourceTree = "<group>"; };
@ -336,6 +341,7 @@
DE1F21F20A7D84E800FBF588 /* Parse */ = {
isa = PBXGroup;
children = (
84D9A88B0C1A581300AC7ABC /* AttributeList.h */,
DE06E8130A8FF9330050E87E /* Action.h */,
DE17336F0B068DC60080B521 /* DeclSpec.h */,
DE1F22020A7D852A00FBF588 /* Parser.h */,
@ -347,6 +353,7 @@
DE1F22600A7D8C9B00FBF588 /* Parse */ = {
isa = PBXGroup;
children = (
84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */,
DE3461260AFE68BE00DBC861 /* MinimalAction.cpp */,
DE06D42F0A8BB52D0050E87E /* Parser.cpp */,
DE3460040AFDCC6500DBC861 /* ParseInit.cpp */,
@ -631,6 +638,7 @@
DE4264FC0C113592005A861D /* CGDecl.cpp in Sources */,
84916BE50C161E580080778F /* Attr.cpp in Sources */,
F0226FD20C18084500141F42 /* TextDiagnosticPrinter.cpp in Sources */,
84D9A8880C1A57E100AC7ABC /* AttributeList.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -22,43 +22,6 @@ namespace clang {
class IdentifierInfo;
class Expr;
/// Attr - Represents GCC's __attribute__ declaration. There are
/// 4 forms of this construct...they are:
///
/// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused.
/// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused.
/// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used.
/// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
///
class Attr {
IdentifierInfo *AttrName;
SourceLocation AttrLoc;
IdentifierInfo *ParmName;
Expr **Args;
unsigned NumArgs;
Attr *Next;
public:
Attr(SourceLocation L, IdentifierInfo *AttrName,
IdentifierInfo *ParmName, Expr **args, unsigned numargs);
~Attr() {
delete [] Args;
}
IdentifierInfo *getAttributeName() const { return AttrName; }
IdentifierInfo *getParameterName() const { return ParmName; }
Attr *getNext() const { return Next; }
void setNext(Attr *N) { Next = N; }
/// getNumArgs - Return the number of actual arguments to this attribute.
unsigned getNumArgs() const { return NumArgs; }
/// getArg - Return the specified argument.
Expr *getArg(unsigned Arg) const {
assert(Arg < NumArgs && "Arg access out of range!");
return Args[Arg];
}
};
} // end namespace clang
} // end namespace llvm