diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/AST/ASTContext.h | 5 | ||||
| -rw-r--r-- | clang/lib/AST/ASTContext.cpp | 20 | ||||
| -rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 19 | 
3 files changed, 39 insertions, 5 deletions
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 9ac6027570f..927d65b99f5 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -403,6 +403,11 @@ public:      return getTypeInfo(T).second;    } +  /// getDeclAlign - Return a conservative estimate of the alignment of the +  /// specified decl.  Note that bitfields do not have a valid alignment, so +  /// this method will assert on them. +  unsigned getDeclAlign(const Decl *D); +      /// getASTRecordLayout - Get or compute information about the layout of the    /// specified record (struct/union/class), which indicates its size and field    /// position information. diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index f3243c25ae7..63e4ccc2415 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -260,6 +260,26 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {    }  } +/// getDeclAlign - Return a conservative estimate of the alignment of the +/// specified decl.  Note that bitfields do not have a valid alignment, so +/// this method will assert on them. +unsigned ASTContext::getDeclAlign(const Decl *D) { +  // FIXME: If attribute(align) is specified on the decl, round up to it. +   +  if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) { +    QualType T = VD->getType(); +    // Incomplete or function types default to 1. +    if (T->isIncompleteType() || T->isFunctionType()) +      return 1; +     +    while (isa<VariableArrayType>(T) || isa<IncompleteArrayType>(T)) +      T = cast<ArrayType>(T)->getElementType(); +     +    return getTypeAlign(T); +  } +   +  return 1; +}  /// getTypeSize - Return the size of the specified type, in bits.  This method  /// does not work on incomplete types. diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 6d1d150c1c1..49cc3201db9 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -508,8 +508,8 @@ public:  private:    bool HandleCast(CastExpr* E); -  uint64_t GetAlignOfExpr(const Expr *E); -  uint64_t GetAlignOfType(QualType T); +  unsigned GetAlignOfExpr(const Expr *E); +  unsigned GetAlignOfType(QualType T);  };  } // end anonymous namespace @@ -844,7 +844,7 @@ bool IntExprEvaluator::VisitConditionalOperator(const ConditionalOperator *E) {    return Visit(Cond ? E->getTrueExpr() : E->getFalseExpr());  } -uint64_t IntExprEvaluator::GetAlignOfType(QualType T) { +unsigned IntExprEvaluator::GetAlignOfType(QualType T) {    const Type *Ty = Info.Ctx.getCanonicalType(T).getTypePtr();    // __alignof__(void) = 1 as a gcc extension. @@ -873,8 +873,17 @@ uint64_t IntExprEvaluator::GetAlignOfType(QualType T) {    return Info.Ctx.getTypeAlign(Ty) / CharSize;  } -uint64_t IntExprEvaluator::GetAlignOfExpr(const Expr *E) { -   +unsigned IntExprEvaluator::GetAlignOfExpr(const Expr *E) { +  E = E->IgnoreParens(); + +  // alignof decl is always accepted, even if it doesn't make sense: we default +  // to 1 in those cases.  +  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) +    return Info.Ctx.getDeclAlign(DRE->getDecl()); +     +  if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) +    return Info.Ctx.getDeclAlign(ME->getMemberDecl()); +    return GetAlignOfType(E->getType());  }  | 

