forked from OSchip/llvm-project
Bug #:
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:
parent
29ca72ae02
commit
b309644a35
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue